0

SOLVED

I will start off with I've never dealt with HTTP requests, and I've tried a few examples that I saw here on the website, but none of them worked for my case.

I want to "activate" scripts that are on a hardware device that I am trying to control. The device has its own HTTP server and by using various URLs I can change its variables, such url looks like this:

http://ipofdevice/ScriptName?varName=varValue&varName2=varValue2&varNameN=varValueN

I am trying to figure out how can I "activate" such URLs with python and I've gotten as far as, that I have to use post requests (I think?) and here is what I've tried so far:

I have already checked a few other posts and tried sample codes from there, but none of them worked, one such post was this:

How to send POST request?

Here is are two sample codes that I have tried, but did not work:

from urllib.parse import urlencode
from urllib.request import Request, urlopen
url = "http://127.0.0.1/ScriptName"
post_fields = { 'testVar' : 'hello', 'secondVar' : 'fromPython' }
request = Request(url, urlencode(post_fields).encode())
json = urlopen(request).read().decode()

And the json line threw an exception with a very long Traceback

Traceback (most recent call last):
  File "C:\Users\Darkbound\AppData\Local\Programs\Python\Python38\lib\http\client.py", line 289, in _read_status
    status = int(status)
ValueError: invalid literal for int() with base 10: '400,'

During handling of the above exception, another exception occurred:

Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
  File "C:\Users\Darkbound\AppData\Local\Programs\Python\Python38\lib\urllib\request.py", line 222, in urlopen
    return opener.open(url, data, timeout)
  File "C:\Users\Darkbound\AppData\Local\Programs\Python\Python38\lib\urllib\request.py", line 525, in open
    response = self._open(req, data)
  File "C:\Users\Darkbound\AppData\Local\Programs\Python\Python38\lib\urllib\request.py", line 542, in _open
    result = self._call_chain(self.handle_open, protocol, protocol +
  File "C:\Users\Darkbound\AppData\Local\Programs\Python\Python38\lib\urllib\request.py", line 502, in _call_chain
    result = func(*args)
  File "C:\Users\Darkbound\AppData\Local\Programs\Python\Python38\lib\urllib\request.py", line 1348, in http_open
    return self.do_open(http.client.HTTPConnection, req)
  File "C:\Users\Darkbound\AppData\Local\Programs\Python\Python38\lib\urllib\request.py", line 1323, in do_open
    r = h.getresponse()
  File "C:\Users\Darkbound\AppData\Local\Programs\Python\Python38\lib\http\client.py", line 1322, in getresponse
    response.begin()
  File "C:\Users\Darkbound\AppData\Local\Programs\Python\Python38\lib\http\client.py", line 303, in begin
    version, status, reason = self._read_status()
  File "C:\Users\Darkbound\AppData\Local\Programs\Python\Python38\lib\http\client.py", line 293, in _read_status
    raise BadStatusLine(line)
http.client.BadStatusLine: HTTP/1.0 400, Invalid Request

This is the code from my second attempt:

import requests
base_url = "http://127.0.0.1/ScriptName"
post_fields = { 'testVar' : 'hello', 'secondVar' : 'fromPython' }
response = requests.post(final_url, data=post_fields)

With an even much longer traceback, which I will not post simply because it adds too much clutter and I dont think its needed, since obviously I am doing something fundamentally wrong. I dont need anything fancy, just to be able to run a link like the one in the beginning of the thread, I am not even sure if POST request is what I need.

In javascript I was able to do it like this (but javascript lacks other things that I need):

var wnd = window.open("http://127.0.0.1/ScriptName?var=val");
      wnd.close();
      e.preventDefault();

EDIT: Adding the traceback for the second python attempt:

Traceback (most recent call last):
  File "C:\Users\Darkbound\AppData\Local\Programs\Python\Python38\lib\site-packages\urllib3\connectionpool.py", line 665, in urlopen
    httplib_response = self._make_request(
  File "C:\Users\Darkbound\AppData\Local\Programs\Python\Python38\lib\site-packages\urllib3\connectionpool.py", line 421, in _make_request
    six.raise_from(e, None)
  File "<string>", line 3, in raise_from
  File "C:\Users\Darkbound\AppData\Local\Programs\Python\Python38\lib\site-packages\urllib3\connectionpool.py", line 416, in _make_request
    httplib_response = conn.getresponse()
  File "C:\Users\Darkbound\AppData\Local\Programs\Python\Python38\lib\http\client.py", line 1322, in getresponse
    response.begin()
  File "C:\Users\Darkbound\AppData\Local\Programs\Python\Python38\lib\http\client.py", line 303, in begin
    version, status, reason = self._read_status()
  File "C:\Users\Darkbound\AppData\Local\Programs\Python\Python38\lib\http\client.py", line 293, in _read_status
    raise BadStatusLine(line)
http.client.BadStatusLine: HTTP/1.0 400, Invalid Request


During handling of the above exception, another exception occurred:

Traceback (most recent call last):
  File "C:\Users\Darkbound\AppData\Local\Programs\Python\Python38\lib\site-packages\requests\adapters.py", line 439, in send
    resp = conn.urlopen(
  File "C:\Users\Darkbound\AppData\Local\Programs\Python\Python38\lib\site-packages\urllib3\connectionpool.py", line 719, in urlopen
    retries = retries.increment(
  File "C:\Users\Darkbound\AppData\Local\Programs\Python\Python38\lib\site-packages\urllib3\util\retry.py", line 400, in increment
    raise six.reraise(type(error), error, _stacktrace)
  File "C:\Users\Darkbound\AppData\Local\Programs\Python\Python38\lib\site-packages\urllib3\packages\six.py", line 734, in reraise
    raise value.with_traceback(tb)
  File "C:\Users\Darkbound\AppData\Local\Programs\Python\Python38\lib\site-packages\urllib3\connectionpool.py", line 665, in urlopen
    httplib_response = self._make_request(
  File "C:\Users\Darkbound\AppData\Local\Programs\Python\Python38\lib\site-packages\urllib3\connectionpool.py", line 421, in _make_request
    six.raise_from(e, None)
  File "<string>", line 3, in raise_from
  File "C:\Users\Darkbound\AppData\Local\Programs\Python\Python38\lib\site-packages\urllib3\connectionpool.py", line 416, in _make_request
    httplib_response = conn.getresponse()
  File "C:\Users\Darkbound\AppData\Local\Programs\Python\Python38\lib\http\client.py", line 1322, in getresponse
    response.begin()
  File "C:\Users\Darkbound\AppData\Local\Programs\Python\Python38\lib\http\client.py", line 303, in begin
    version, status, reason = self._read_status()
  File "C:\Users\Darkbound\AppData\Local\Programs\Python\Python38\lib\http\client.py", line 293, in _read_status
    raise BadStatusLine(line)
urllib3.exceptions.ProtocolError: ('Connection aborted.', BadStatusLine('HTTP/1.0 400, Invalid Request\r\n'))

During handling of the above exception, another exception occurred:

Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
  File "C:\Users\Darkbound\AppData\Local\Programs\Python\Python38\lib\site-packages\requests\api.py", line 119, in post
    return request('post', url, data=data, json=json, **kwargs)
  File "C:\Users\Darkbound\AppData\Local\Programs\Python\Python38\lib\site-packages\requests\api.py", line 61, in request
    return session.request(method=method, url=url, **kwargs)
  File "C:\Users\Darkbound\AppData\Local\Programs\Python\Python38\lib\site-packages\requests\sessions.py", line 530, in request
    resp = self.send(prep, **send_kwargs)
  File "C:\Users\Darkbound\AppData\Local\Programs\Python\Python38\lib\site-packages\requests\sessions.py", line 643, in send
    r = adapter.send(request, **kwargs)
  File "C:\Users\Darkbound\AppData\Local\Programs\Python\Python38\lib\site-packages\requests\adapters.py", line 498, in send
    raise ConnectionError(err, request=request)
requests.exceptions.ConnectionError: ('Connection aborted.', BadStatusLine('HTTP/1.0 400, Invalid Request\r\n'))

EDIT 2: Solved, turns out that I actually needed a GET request as @MrBean Bremen suggested , all I had to do was:

import requests
requests.get(myurl)
Darkbound
  • 3,026
  • 7
  • 34
  • 72
  • Please add the traceback. It might not mean anything to *you*, but it may make it obvious to someone here what your problem is. – chepner Apr 02 '20 at 17:22
  • 1
    This looks like you need a get request, not a post request. You can add your variables as a dict in the `params` argument. – MrBean Bremen Apr 02 '20 at 17:23
  • @MrBeanBremen thanks that actually worked, I only cant figure out why do I get a 404 response, but it is working, and why is it GET and not POST, isnt GET for receiving and POST for sending? – Darkbound Apr 02 '20 at 17:37

1 Answers1

0

Try this

import requests
tesVar = hello
secondVar = fromPython
baseurl = "http://127.0.0.1/ScriptName?{'tesVar'}&{'secondVar'}"
response = requests.get(baseurl)
print(response)
  • Yes it worked, but it is returning 404 (even tho its working!), any idea why that might be? Also why is it a get and not a post? Isnt get for sending and post for receiving? – Darkbound Apr 02 '20 at 17:42
  • you only need to POST when you're sending a payload. If it's just query parameters, everything is in the request URL, so there's no body to the request. Since there's no body, you can just GET, which by definition has no body. the constraints will also depend on how you've set up your webserver. There may be some security restrictions on the endpoint you're exposing. – David Culbreth Apr 02 '20 at 17:50