Python Requests hanging when cURL is working just fine - python

I'm experiencing a strange issue where Python post Requests are hanging, while cURL post requests are working just fine. I'm making a request to the NIH Reporter API.
Here's the Python code that keeps hanging:
headers = {
"accept": "application/json",
"Content-Type": "application/json"
}
data = {
"criteria": {
"award_notice_date": {
"from_date": "2022-06-22",
}
},
"include_fields": [
"ProjectNum",
"ProjectTitle",
"AbstractText",
"AwardNoticeDate"
],
"offset": 14500,
"limit": 500,
"sort_field": "award_notice_date"
}
response = requests.post('https://api.reporter.nih.gov/v2/projects/search', headers=headers, data=str(data))
And here's the cURL equivalent that works:
curl -X POST "https://api.reporter.nih.gov/v2/projects/search" -H "accept: application/json" -H "Content-Type: application/json" -d "{'criteria': {'award_notice_date': {'from_date': '2022-06-22'}}, 'include_fields': ['ProjectNum', 'ProjectTitle', 'AbstractText', 'AwardNoticeDate'], 'offset': 14500, 'limit': 500, 'sort_field': 'award_notice_date'}"
I'm not sure if I'm missing anything. I'm using Python3 as well, and my Requests library is up-to-date with version 2.27.1.

str(data) is not the same as converting it to json. You need to use data=json.dumps(data) or use json=data. Using the latter will also add the "Content-Type": "application/json" header for you, so you could skip that.

Related

Post method returns 422 using Requests but working fine with CURL and Postman

I am using Python with Requests module to connect to an EasyRedmine API. I'm having trouble creating a project using the post method in order to post a JSON. It returns "[Unprocessable Entity
<Response [422]>]". I have tried the same request using Postman and Curl and it works perfectly. Does anyone know what could be causing this problem? The following curl command works fine.
curl -X 'POST'
'https://cafte.easyredmine.com/projects.json?key=0224b4238XXXX'
-H 'accept: application/json'
-H 'X-Redmine-API-Key: 0224b4238XXX'
-H 'Content-Type: application/json'
-d '{
"project": {
"easy_external_id": "external-system-1",
"name": "Blue 2",
"homepage": "blue-7",
"description": "I can’t abide these Jawas. Disgusting creatures.",
"author_id": 0,
"is_planned": true,
"easy_is_easy_template": true,
"easy_currency_code": "EUR"
}
This is the methode code:
def create_project(self, name: str, description="", external_id="", homepage="", parent_id="", author_id="",
is_planned= 'false', is_easy_template= "true", start_date="", due_date="", custom_fields=[],
tag_list=[], currency='EUR'):
print(name)
data = {"project": {
"easy_external_id": external_id,
"name":name,
"homepage": homepage,
"description": description,
"parent_id": parent_id,
"author_id": author_id,
"is_planned": is_planned,
"easy_is_easy_template": is_easy_template,
"easy_start_date": start_date,
"easy_due_date": due_date,
"custom_fields": custom_fields,
"tag_list": tag_list,
"easy_currency_code": currency
}
}
endpoint_path = "/projects"
endpoint = f'{self.base_url}{endpoint_path}'
headers = {'X-Redmine-API-Key': f'{self.api_key}',
'accept': 'application/json',
'Content-Type': 'application/json'
}
r = requests.post(endpoint, headers=headers, json= data)

Forming a request.post from a curl on python

I have a small project i need a tempmail for, so i found this site https://mail.tm/en, so i was trying to acess the post via the api and instructions given here https://api.mail.tm/.
As I am new at working with curl and so on I have a lot of problems authorizing into an account there.
First of all i got an CURL link on site like this one:
curl -X POST "https://api.mail.tm/accounts" -H "accept: application/ld+json" -H "Authorization: testing" -H "Content-Type: application/ld+json" -d "{\"address\":\"test\",\"password\":\"stackoverflow\"}"
I tried to form it all in a post request, so i did this
headers = {"accept": "application/ld+json", "Authorization": "header", "Content-Type": "application/ld+json"}
data = "{\"address\":\"zashyganii\",\"password\":\"chertila\"}"
mail = requests.post("https://api.mail.tm/accounts", data = data, headers = headers)
print(mail.status_code)
the error code is 400, noted on the api site like this.
400 Error:
Response body
Download
{
"#context": "/contexts/ConstraintViolationList",
"#type": "ConstraintViolationList",
"hydra:title": "An error occurred",
"hydra:description": "address: This value is not a valid email address.\naddress: The domain \"\" is not valid.",
"violations": [
{
"propertyPath": "address",
"message": "This value is not a valid email address."
},
{
"propertyPath": "address",
"message": "The domain \"\" is not valid."
}
]
}
Could you please turn this curl in to a request.post on python so it will work for this api
Seems like there are not any problem with the request. It's a validation fail.

Python equivalent for Curl giving 400 Response

Trying to re-write shell curl to python script with requests module...
My shell script :
#!/bin/bash
ip=$1
url=https://xxx.xx.xx.com
secret=xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
expand=computerStatus
curl --silent -X POST "$url/api/computers/search?expand=$expand" -H "Content-Type: application/json" -H "api-secret-key: $secret" -H "api-version: v1" -d '{"maxItems": 10,"searchCriteria": [{"fieldName": "hostName","stringTest": "equal", "stringValue": "'"$ip"'"}]}' -k > $file
above works fine in bash.
I am trying to convert to similar python equivalent
What I tried
import json
import requests
import sys
ip = sys.argv[1]
sys_info = []
url=https://xxx.xx.xx.com
secret=xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
expand=computerStatus
headers = {
'Content-Type': 'application/json',
'api-secret-key': secret,
'api-version': 'v1',
}
params = (
('expand', 'expand'),
)
data = '{"maxItems": 10,"searchCriteria": [{"fieldName": "hostName","stringTest": "equal", "stringValue": ip}]}'
response = requests.post('https://url/api/computers/search?expand=expand', headers=headers, params=params, data=data)
print(response)
<Response [400]>
I am getting 400 response.. not sure where i am missing in syntax...
data needs to be a dictionary, try this:
data = {
"maxItems": 10,
"searchCriteria": [{"fieldName": "hostName","stringTest": "equal", "stringValue": ip}]
}
Also convert params to a dictionary as well:
params = {"expand" : expand}
And when posting:
response = requests.post(f'https://{url}/api/computers/search', headers=headers, params=params, data=data)
### or alternatively you can
response = requests.post(f'https://{url}/api/computers/search?expand={expand}', headers=headers, data=data)

API requests using python

I am trying to do a request using python. The API uses:
curl -X POST --header 'Content-Type: application/json' --header 'Accept: application/json' -d '{ \
"$class": "org.acme.model.sensor", \
"sensorId": "1", \
"type": "Temperature", \
"value": "10", \
"timestamp": 1234123 \
}' 'http://localhost:3000/api/sensor'
to create a new sensor. I am trying to do it with python and I have created the proof of concept:
data = {
"$class": "org.acme.model.sensor",
"sensorId": "", #change in the loop with i
"type": "Temperature",
"value": "10",
"timestamp": 382453824
}
header = {
"Content-Type" : "application/json",
"Accept":"application/json"
}
url = "http://localhost:3000/api/sensor"
for i in range(2):
data["sensorId"]=str(i+1)
response = requests.post(url, data=data, headers=header)
#Now I modify the data
data["Temperature"]="50"
response = requests.put(url, data=data, headers=header)
Now, for erasing:
for i in range(2):
url="http://localhost:3000/api/sensor/"+str(i+1)
response = requests.delete(url)
With curl, it works properly but no with the python code. It fails even creating the object.
import requests
import json
header = {
"Content-Type" : "application/json",
"Accept":"application/json"
}
You need to convert your dictionary into a proper format using json.dumps and need to use request.post instead of delete
request_url = 'YOUR_END_POINT'
data = json.dumps(data)
response = requests.post(url=request_url,data=data,headers=headers)
I think that should solve it.

Regular JSON Curl to pyCurl

I'd like to get this curl command to run in a Python Script
curl -H "public-api-token: 049cxxxxxc026ef7364fa38c8792" -X PUT -d "urlToShorten=google.com" https://api.shorte.st/v1/data/url
but I have now clue how.
def make_tiny(url):
connection = httplib.HTTPSConnection('api.shorte.st', 443)
connection.connect()
connection.request('PUT', '/v1/data/url', json.dumps({
"urlToShorten": url,
}), {
"public-api-token": "049cd75ad7axxx26ef7364fa38c8792",
"Content-Type": "application/json"
})
results = json.loads(connection.getresponse().read())
return results.get("shortenedUrl", "none").decode('utf-8')
Thanks anyway!

Categories