Python equivalent for Curl giving 400 Response - python

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)

Related

Python Requests hanging when cURL is working just fine

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.

python put requests a file

i'm trying to interact with a website's APIs--specifically how to requests.put() a file (JPEG) to it. the Swagger API has a "try it out" function where I successfully can push a file from its "try it out" but when I try to run it in python it throws a 500 internal server error.
this is the successful curl put request from the Swagger "try it out":
curl -X PUT "https://some_website.com/api/v2/documents" -H "accept: /" -H "Content-Type: multipart/form-data" -H "Authorization: Bearer auth tokenp089u098u08j98jasdfsadgfasdg" -d {"file":{},"metadata":"{ "docType":"BILL_OF_LADING", "docTypeNamespace":"platform", "fileType":"IMAGE", "docReferences":{ "name":"bill o lading pal" }, "identifiers":{ "consignment":{ "carrierBookingNumber":"9876smg", "billOfLadingNumber":"1234smg" } } }"}
url = "https://some_website.com"
auth_token = "Bearer auth tokenp089u098u08j98jasdfsadgfasdg"
headers = {"Content-Type": "multipart/form-data",
"Accept": "*/*",
"Authorization": sa_token}
file_loc = "C:/location/of/file/I/want/to/put/Capture.JPG"
metadata = {
"docType":"doc_file",
"docTypeNamespace": "platform",
"fileType":"IMAGE",
"docReferences": {
"name": "this is the form to confirm receipt"
},
"identifiers": {
"consignment": {
"carrierBookingNumber":"9876smg",
"billOfLadingNumber":"1234smg"
}
}
}
body = {
"file": {},
"metadata": metadata
}
resp = requests.put(url=url, headers=headers, data=body)
You should probably send it via json as thats very easy...
import requets
file = "C:\somedir\somedir\somefile.somext"
with open(file, "rb") as f:
fileData = f.read()
putFile(fileD, site, port=3000):
requets.post(site, json='{"file": "' + str(fileD) + '"}'
But you'll need to convert it back to a file.

PYTHON: requests.post() how to send request_body encoded as application/x-www-form-urlencoded

I'm doign an app with the Spotify API. My problem is I'm trying to get an access_token but It's not working. In the docs it says i need to send the body encoded as application/x-www-form-urlencoded so I search a little bit and It should work just setting request_body as a dictionary.
This is the code of my function:
def get_access_token(self):
auth_code, code_verifier = self.get_auth_code()
endpoint = "https://accounts.spotify.com/api/token"
# as docs said data should be encoded as application/x-www-form-urlencoded
# as internet says i just need to send it as a dictionary. However it's not working
request_body = {
"client_id": f"{self.client_ID}",
"grant_type": "authorization_code",
"code": f"{auth_code}",
"redirect_uri": f"{self.redirect_uri}",
"code_verifier": f"{code_verifier}"
}
response = requests.post(endpoint, data=request_body)
print(response)
The response I'm getting is always <Response [400]>
Here are the docs, step 4 https://developer.spotify.com/documentation/general/guides/authorization-guide/#authorization-code-flow-with-proof-key-for-code-exchange-pkce
NOTE: I tryed executing this as a curl and it works fine I'm not sure what I'm doing wrong in the python code
here's the command:
curl -d client_id={self.client_ID} -d grant_type=authorization_code -d code={auth_code} -d redirect_uri={self.redirect_uri} -d code_verifier={code_verifier} https://accounts.spotify.com/api/token
You can specify the request type in the request header.
headers = {'Content-Type': 'application/x-www-form-urlencoded'}
response = requests.post(endpoint, data=request_body, headers=headers)
print(response)

How to execute the following command using Python?

It would be a great help if somebody helps me to understand how the following command can be executed using python:
curl -X POST https://insights-collector.newrelic.com/v1/accounts/YOUR_ACCOUNT_ID/events -H "Content-Type: application/json" -H "X-Insert-Key: YOUR_KEY_HERE" -d '{"eventType":"Custom Event Name", "attribute1": "value"}'
SQL query results need to be converted to JSON format and need to be pushed to new relic using the above command.
try doing this
import requests
headers = {
'Content-Type': 'application/json',
'X-Insert-Key': 'YOUR_KEY_HERE',
}
data = '{"eventType":"Custom Event Name", "attribute1": "value"}'
response = requests.post('https://insights-collector.newrelic.com/v1/accounts/YOUR_ACCOUNT_ID/events', headers=headers, data=data)

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