Error passing curl -d parameter in requests library - python

I have a curl POST request that works perfectly in the terminal (macOS), returning a csv as expected. The following format is provided in the RJMetrcis documentation (see "Export figure data"). Here is the curl request in bash:
 curl -d "format=csv&includeColumnHeaders=1" -H "X-RJM-API-Key: myAPIkey" https://api.rjmetrics.com/0.1/figure/0000/export
My objective is to implement the exact same curl request in Python using requests. When I input the same parameters as a POST request, the code does not work returning an error:
import requests
headers = {'X-RJM-API-Key: myAPIkey'}
data= {'format=csv&includeColumnHeaders=1'}
url = "https://api.rjmetrics.com/0.1/figure/0000/export"
response = requests.post(url, data, headers)
This returns the error:
TypeError: memoryview: a bytes-like object is required, not 'str'
On the second try:
response = requests.post(url, data=data, headers=headers)
returns
AttributeError: 'set' object has no attribute 'items'
What is the correct format in python for constructing a POST request so that it matches the data = {'key':'value'} convention, and returns a csv?Any help would be appreciated translating the bash curl POST into a python POST request

Here you are passing a set and you are expected to pass a dict or str object
data= {'format=csv&includeColumnHeaders=1'}
Replacing with
data= {'format':'csv&includeColumnHeaders=1'}
Should fix it.
On the other hand by seeing your curl request..
It all depends how you want to pass the data, following code (passing the data payload as a string) will post the data directly, that will be the equivalent to --data-raw in curl
import requests
url = "https://api.rjmetrics.com/0.1/figure/0000/export"
payload = "'{\"format\":\"csv&includeColumnHeaders=1\"}'"
headers = {
'X-RJM-API-Key': 'myAPIkey'
}
response = requests.request("POST", url, headers=headers, data = payload)
print(response.text.encode('utf8'))

Related

How to perform this python post request

I am new to python requests and do not know how to call this API with a post request.
This is the information I got:
POST /whatcaristhat?key=<CarsXE_API_Key> HTTP/1.1
Host: http://api.carsxe.com
Content-Type: text/plain
https://upload.wikimedia.org/wikipedia/commons/4/44/2019_Acura_RDX_A-Spec_front_red_4.2.18.jpg
What I got so far is:
import requests
api_key = 12345
url = f'http://api.carsxe.com/whatcaristhat?key={api_key}'
data = b'https://upload.wikimedia.org/wikipedia/commons/4/44/2019_Acura_RDX_A-Spec_front_red_4.2.18.jpg'
headers = {'Content-Type' : 'text/plain'}
r = requests.post(url,
data=data,
headers=headers)
print(r.status_code)
But I get this error:
TypeError: a bytes-like object is required, not 'str'
This API takes either an image URL or a base64 encoded image. As of now, data is defined as a set. The fix is pretty straightforward:
data = b'https://upload.wikimedia.org/whatevertheurlis.jpg'

Converting from curl to python request.post

I wish to convert my current curl command to python code to request for access token for an api.
curl -X POST -H "Content-Type:application/json" -d '{"grantType":"client_credentials"}' [Access Token URL]
my attempt:
import requests
api_url_base = "https://api.example.com/api/"
headers ={'Content_Type':'application/json',
'grandType': 'client_credentials'
}
response = requests.post(headers=headers, "https://api.example.com/accesstokens")
if response.status_code == 200:
print(json.loads(response.content.decode('utf-8')))
else:
print(response.status_code)
Expected output:
Should be in python.
You're mismatching posting headers and body data there, not to mention there's a typo with grandType.
Either way, posting JSON and parsing JSON responses is super easy with Requests:
response = requests.post(
"https://api.example.com/accesstokens",
json={"grantType": "client_credentials"},
)
response.raise_for_status() # raise an exception for error statuses
data = response.json()
print(data)

Python post request returns 500

I am using requests to make a POST request to create a user. The request succeeds with 201 created when I use curl, however fails with a 500 response when I use requests. My curl command is
curl --user administrator:password -H "Content-Type: application/json" https://localhost:8080/midpoint/ws/rest/users -d #user.json -v
And my python script is:
import requests
import json
headers = {
'Content-Type': 'application/json',
}
with open('user.json') as j:
data = json.load(j)
response = requests.post('https://localhost:8080/midpoint/ws/rest/users', headers=headers, data=str(data), auth=('Administrator', 'password'))
print(response)
Can anyone see a reason why my python script would be failing? I am at a loss.
str(data) returns the Python representation of data, not its JSON representation. These two forms can differ in things like ' vs. ", True vs. true, and None vs. null. To properly JSONify data, call json.dumps() on it:
response = requests.post(..., data=json.dumps(data))
or let requests do the JSONification:
response = requests.post(..., json=data)
or use the JSON as it appears in user.json directly:
with open('user.json') as j:
data = j.read()
response = requests.post(..., data=data)

curl equivalent post request in python 3

I have to write following curl script in python 3
curl -X POST\
-u '$client_id:$client_secret'\
-d 'grant_type=client_credentials&access_lifetime=7200'
https://www.example.com/oauth/token
I tried doing this
data = {'grant_type': 'client_credentials', 'access_lifetime': '7200'}
response_result = requests.post(
'https://www.example.com/oauth/token',
data=json.dumps(data),
auth=('client_id', 'client_secret)
)
But on print(response_result.text) it gives error as The grant type was not specified in the request
I think the data is not passing or I'm using wrong way to pass data.
How to pass data in the requests?
You need to pass a dictionary to the data keyword argument, not a JSON string:
data = {'grant_type': 'client_credentials', 'access_lifetime': '7200'}
response_result = requests.post(
'https://www.example.com/oauth/token',
data=data,
auth=('client_id', 'client_secret)
)
See the documentation for details.
data=data
Instead of
data=json.dumps(data)

How to make a post request with REQUESTS package for Python?

I am trying to use the toggl api.
I use Requests instead of Urllib2 for doing my GETs en POSTS. But i am stuck.
payload = {
"project":{
"name":"Another Project",
"billable":False,
"workspace":{
"Name":"jorrebor's workspace",
"id":213272
},
"automatically_calculate_estimated_workhours":False
}
}
url = "https://www.toggl.com/api/v6/projects.json"
r = requests.post(url, data=json.dumps(payload), auth=HTTPBasicAuth('j_xxxxx#gmail.com', 'mypassword'))
Authentication seems to be fine, but the payload format probably isn't.
a curl command with the same parameters:
curl -v -u heremytoken:api_token -H "Content-type: application/json" -d "{\"project\":{\"billable\":true,\"workspace\":{\"id\":213272},\"name\":\"Another project\",\"automatically_calculate_estimated_workhours\":false}}" -X POST https://www.toggl.com/api/v6/projects.json
does work fine.
What wrong with my payload? The response is get is:
["Name can't be blank","Workspace can't be blank"]
which leads me to conclude that the authentication works but toggl cannot read my json object.
Seems like you should try setting the header to a JSON application, rather than the default format, and send a JSON object instead of the Python dict. Check it out here:
payload = {"project":{"name":"Another Project",
"billable":False,
"workspace":{"Name":"jorrebor's workspace",
"id":213272},
"automatically_calculate_estimated_workhours":False
} }
parameters_json = json.dumps(payload)
headers = {'Content-Type': 'application/json')
r = client.post(url, data=parameters_json, headers=headers)
which should allow the site to read the json object just fine.

Categories

Resources