muchtarsp
muchtarsp

Reputation: 237

POST method not working with Python Request

I have PTZ camera and I'm trying different way to access that camera via CURL. I'm intended to access preset position in the camera via web interface. The logic to access preset of PTZ camera, based on browser debugger is like this:

Following is source code using shell script:

echo "Set PTZ"
echo $1 #IP address
echo $2 #preset

url_login='http://'$1'/login/login/'
url_preset='http://'$1'/ptz/presets.html'

curl -c cookies.txt -s -X POST $url_login --data "user=admin&pass=admin&forceLogin=on"
curl -b cookies.txt -s -X POST $url_preset --data 'PTZInterface!!ptzPositions='$2
curl -b cookies.txt -s -X PUT $url_preset --data 'autobutton=GotoCurrVirtualPreset&object=PTZInterface&id='

I have succeed using shell script, accessing the camera and go to preset.

But my main purpose is to create a program using python. Following is my python using requests:

import requests

URL_LOGIN = "/login/login/"
PARAMS_LOGIN = {"user": "admin", "pass": "admin", "forceLogin": "on"}
URL_PRESET = "/ptz/presets.html"
HEADERS = {'User-Agent': 'Mozilla/5.0 (X11; Linux x86_64; rv:52.0) Gecko/20100101 Firefox/52.0',
    'Accept': '*/*', 'Accept-Language': 'en-US,en;q=0.5',
    'Content-Type': 'application/x-www-form-urlencoded; charset=UTF-8',
    'X-Requested-With': 'XMLHttpRequest',
    'Connection': 'keep-alive', 'Pragma': 'no-cache', 'Cache-Control': 'no-cache'}

def set_ptz(arg_camera = None, arg_preset = None):
    url_login = "http://" + arg_camera + URL_LOGIN
    url_preset = "http://" + arg_camera + URL_PRESET

    HEADERS['Host'] = arg_camera
    HEADERS['Referer'] = 'http://' + arg_camera + '/'

    params = {}
    params["PTZInterface!!ptzPositions"] = arg_preset

    params_put = {}
    params_put["autobutton"] = "GotoCurrVirtualPreset"
    params_put["object"] = "PTZInterface"
    params_put["id"] = ""

    s = requests.Session()
    r1 = s.post(url_login, data = PARAMS_LOGIN) # Login -> success
    var_cookies = r1.cookies
    r2 = s.post(url_preset, cookies = var_cookies, headers = HEADERS, data = params) # Post preset position -> failed
    r3 = s.put(url_preset, cookies = var_cookies, headers = HEADERS, data = params_put) # Put execution -> success

    print r1.headers
    print var_cookies
    print r2.headers
    print r3.headers
    print r3.text
    print r1.status_code
    print r2.status_code
    print r3.status_code

set_ptz('10.26.1.3.61', 1)

I'm succeed to login and submit using PUT, but failed to POST the preset position. What's wrong in my python code? I thought that the result should be same.

Thank you for help.

Upvotes: 0

Views: 1131

Answers (1)

Blender
Blender

Reputation: 298048

requests is escaping the exclamation points in the POST data:

In [1]: import requests

In [2]: requests.post(..., data={"PTZInterface!!ptzPositions": '1'}).request.body
Out[2]: 'PTZInterface%21%21ptzPositions=1'

cURL just sends them as-is. You can pass data directly as a string:

In [3]: requests.post(..., data="PTZInterface!!ptzPositions=1").request.body
Out[3]: 'PTZInterface!!ptzPositions=1'

Or use urllib.parse.urlencode's safe parameter to build it:

In [13]: urllib.parse.urlencode({'PTZInterface!!ptzPositions': 1}, safe='!')
Out[13]: 'PTZInterface!!ptzPositions=1'

Upvotes: 1

Related Questions