Format python PATCH request from curl command - python

I have a curl command I can run from my local machine that works, but transferring it to a python script is giving me difficulties. Here's the curl command that works:
curl -X PATCH "http://localhost:9999/pins/1" -H "Content-Type: application/json" -d "{"state": "on"}"
And here is what I have so far as a python request:
import requests
url = 'http://localhost:9999/pins/1'
payload = {'state':'on'}
head = {'Content-Type':'application/json'}
r = requests.patch(url, payload, headers=head)
But I am receiving a 400 response. Any direction?
Also, if I format it as
r = requests.patch(url, data=payload)
I get a 500 response code. Also should be noted: I can run a simple get request easily by running something like
r = requests.get(url)

import requests
url = 'http://localhost:9999/pins/1'
payload = {'state':'on'}
head = {'Content-Type':'application/json'}
r = requests.patch(url, json=payload)
change this r = requests.patch(url, data=payload) to r = requests.patch(url, json=payload)

Try the following to make sure that your payload is valid json.
import requests
import json
url = 'http://localhost:9999/pins/1'
payload = {'state':'on'}
head = {'Content-Type':'application/json'}
r = requests.patch(url, data=json.dumps(payload), headers=head)

Related

Post requests in python vs curl

Can someone please suggest the correct syntax for calling the below using python?
curl "https://sometest.api.token" \
-H "Content-Type: application/x-www-form-urlencoded" \
-d "grant_type=client_credentials&client_id={client_id}&client_secret={client_secret}"
My attempt:
import requests
import json
credentials='1111'
secret='2222'
url = 'https://sometest.api.token'
body = {'client_credentials':credentials,'client_secret':secret}
headers = {'Content-type': 'application/x-www-form-urlencoded'}
r = requests.post(url, data=json.dumps(body), headers=headers)
Due to documentation, if you want to send some form-encoded data, you simply pass a dictionary to the data argument.
So you have to try:
import requests
import json
credentials='1111'
secret='2222'
url = 'https://sometest.api.token'
body = {'client_credentials':credentials, 'client_secret':secret}
headers = {'Content-Type': 'application/x-www-form-urlencoded'}
r = requests.post(url, data=body, headers=headers)
And also your parameters in python code are different from parameters in curl, maybe you have to check it.

get 400 bad request after requesting GET in python

Id like to convert this curl command to python script
curl -v -H "Content-Type: application/json" -H "Authorization: Bearer MYTOKEN" https://www.zopim.com/api/v2/chats
I wrote the python script below but I get <Response [400]>and doesn't work.
import requests
url = "https://www.zopim.com/api/v2/chats"
access_token = "MYTOKEN"
response = requests.post(url,
headers={"Content-Type":"application/json;charset=UTF-8",
"Authorization": "Bearer {}".format(access_token)})
print(response)
Any advice will be appreciated.thanks.
You should be using requests.get instead of requests.post, since what you want is a GET request:
import requests
url = "https://www.zopim.com/api/v2/chats"
access_token = "MYTOKEN"
response = requests.get(url,
headers={"Content-Type":"application/json;charset=UTF-8",
"Authorization": "Bearer {}".format(access_token)})
print(response)

How to curl in Python with header, data?

I'm trying replace the following curl command by a Python script:
curl --request POST \
--url https://xx.com/login \
--header 'Content-Type: application/json' \
--data '{
"email": "user#domain.com",
"password": "PASSWORD"
}'
Script that I tried:
import urllib.request
import json
body = {"email": "xxx#xx.com","password": "xxx"}
myurl = "https://xx.com/login"
req = urllib.request.Request(myurl)
req.add_header('Content-Type', 'application/json; charset=utf-8')
jsondata = json.dumps(body)
jsondataasbytes = jsondata.encode('utf-8') # needs to be bytes
req.add_header('Content-Length', len(jsondataasbytes))
response = urllib.request.urlopen(req, jsondataasbytes)
When I tried to run this script, it doesn't return me anything and show processed completed. Is my code logic correct? Or there is something wrong with my code?
For HTTP and HTTPS URLs, urllib.request.urlopen function returns a http.client.HTTPResponse object. It has different attributes and methods you can use,
For example,
HTTPResponse.read([amt]) - Reads and returns the response body, or up to the next amt bytes.
HTTPResponse.getheaders() - Return a list of (header, value) tuples.
HTTPResponse.status - Status code returned by server.
So in your case you could do check the status using status attribute . If it's successful read the response body using read method.
status_code = response.status
if status_code == 200: # request succeeded
response_body = response.read() # This will be byte object
response_body_as_string = response_body.decode('utf-8')
you can simply just use requests:
import requests
headers = {
'Content-Type': 'application/json',
}
data = '{\n"email": "user#domain.com",\n"password": "PASSWORD"\n}'
response = requests.post('https://xx.com/login', headers=headers, data=data)

how to use curl with -u in python request

I am trying to convert a curl request to python request, but i have problem to convert -u .
curl -X POST \
-u "apikey:yourKey" \
--header "Content-Type: audio/wav" \
--data-binary "#path" \
"https://stream-fra.watsonplatform.net/speech-to-text/api/v1/recognize?model=de-DE_BroadbandModel
My solution:
import requests
data = "path"
url = 'https://stream-fra.watsonplatform.net/speech-to-text/api/v1/recognize?model=de-DE_BroadbandModel'
#payload = open("request.json")
headers = {'content-type': 'audio/wav', 'username': "apikey=yourkey" }
r = requests.post(url, headers=headers, data=data)
Edit:
import requests
data = "path"
url = 'https://stream-fra.watsonplatform.net/speech-to-text/api/v1/recognize?model=de-DE_BroadbandModel'
#payload = open("request.json")
headers = {'Content-Type': 'audio/wav'}
#r = requests.post(url, headers=headers, data=data)
print requests.post(url, verify=False, headers=headers, data=data, auth=('apikey', "key"))
now i get
Response [400]
(the curl cmd is working)
Try this
requests.post(url, headers=headers, data=data, auth=(apiKey, yourApiKey))
-u is short for --user which is used for server authentication see here, also look into Basic authentication for requests library.
Edit: You need to read the file (specified in --data-binary "#path") first before passing it in requests.post. I hope this link helps

Python requests doesn't upload file

I am trying to reproduce this curl command with Python requests:
curl -X POST -H 'Content-Type: application/gpx+xml' -H 'Accept: application/json' --data-binary #test.gpx "http://test.roadmatching.com/rest/mapmatch/?app_id=my_id&app_key=my_key" -o output.json
The request with curl works fine. Now I try it with Python:
import requests
file = {'test.gpx': open('test.gpx', 'rb')}
payload = {'app_id': 'my_id', 'app_key': 'my_key'}
headers = {'Content-Type':'application/gpx+xml', 'Accept':'application/json'}
r = requests.post("https://test.roadmatching.com/rest/mapmatch/", files=file, headers=headers, params=payload)
And I get the error:
<Response [400]>
{u'messages': [], u'error': u'Invalid GPX format'}
What am I doing wrong? Do I have to specify data-binary somewhere?
The API is documented here: https://mapmatching.3scale.net/mmswag
Curl uploads the file as the POST body itself, but you are asking requests to encode it to a multipart/form-data body. Don't use files here, pass in the file object as the data argument:
import requests
file = open('test.gpx', 'rb')
payload = {'app_id': 'my_id', 'app_key': 'my_key'}
headers = {'Content-Type':'application/gpx+xml', 'Accept':'application/json'}
r = requests.post(
"https://test.roadmatching.com/rest/mapmatch/",
data=file, headers=headers, params=payload)
If you use the file in a with statement it'll be closed for you after uploading:
payload = {'app_id': 'my_id', 'app_key': 'my_key'}
headers = {'Content-Type':'application/gpx+xml', 'Accept':'application/json'}
with open('test.gpx', 'rb') as file:
r = requests.post(
"https://test.roadmatching.com/rest/mapmatch/",
data=file, headers=headers, params=payload)
From the curl documentation for --data-binary:
(HTTP) This posts data exactly as specified with no extra processing whatsoever.
If you start the data with the letter #, the rest should be a filename. Data is posted in a similar manner as --data-ascii does, except that newlines and carriage returns are preserved and conversions are never done.

Categories