Post requests in python vs curl - python

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.

Related

Format python PATCH request from curl command

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)

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 API call not working

I'm having an issue converting a working cURL call to an internal API to a python requests call.
Here's the working cURL call:
curl -k -H 'Authorization:Token token=12345' 'https://server.domain.com/api?query=query'
I then attempted to convert that call into a working python requests script here:
#!/usr/bin/env python
import requests
url = 'https://server.domain.com/api?query=query'
headers = {'Authorization': 'Token token=12345'}
r = requests.get(url, headers=headers, verify=False)
print r
I get a HTTP 401 or 500 error depending on how I change the headers variable around. What I do not understand is how my python request is any different then the cURL request. They are both being run from the same server, as the same user.
Any help would be appreciated
Hard to say without knowing your api, but you may have a redirect that curl is honoring that requests is not (or at least isn't send the headers on redirect).
Try using a session object to ensure all requests (and redirects) have your header.
#!/usr/bin/env python
import requests
url = 'https://server.domain.com/api?query=query'
headers = {'Authorization': 'Token token=12345'}
#start a session
s = requests.Session()
#add headers to session
s.headers.update(headers)
#use session to perform a GET request.
r = s.get(url)
print r
I figured it out, it turns out I had to specify the "accept" header value, the working script looks like this:
#!/usr/bin/env python
import requests
url = 'https://server.domain.com/api?query=query'
headers = {'Accept': 'application/app.app.v2+json', 'Authorization': 'Token token=12345'}
r = requests.get(url, headers=headers, verify=False)
print r.json()

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.

how to make post request in python

Here is the curl command:
curl -H "X-API-TOKEN: <API-TOKEN>" 'http://foo.com/foo/bar' --data #
let me explain what goes into data
POST /foo/bar
Input (request JSON body)
Name Type
title string
body string
So, based on this.. I figured:
curl -H "X-API-TOKEN: " 'http://foo.com/foo/bar' --data '{"title":"foobar","body": "This body has both "double" and 'single' quotes"}'
Unfortunately, I am not able to figure that out as well (like curl from cli)
Though I would like to use python to send this request.
How do i do this?
With the standard Python httplib and urllib libraries you can do
import httplib, urllib
headers = {'X-API-TOKEN': 'your_token_here'}
payload = "'title'='value1'&'name'='value2'"
conn = httplib.HTTPConnection("heise.de")
conn.request("POST", "", payload, headers)
response = conn.getresponse()
print response
or if you want to use the nice HTTP library called "Requests".
import requests
headers = {'X-API-TOKEN': 'your_token_here'}
payload = {'title': 'value1', 'name': 'value2'}
r = requests.post("http://foo.com/foo/bar", data=payload, headers=headers)

Categories