Calling Curl API on Python - python

I want to call CURL API on python.
curl -X POST -H "Authorization:Token 00d2e3a10c82420414b2d36d28fb5afc2cd8e8a5" \
-H "Content-Type: application/json" \
-d '{"module_id":"[MODULE_ID]", "text": "example text"}' \
-D - \
https://api.tocall.com/
I used requests module for making request and json module for converting object to string. But I'm getting 404.
Where am I wrong?
import requests
import json
headers = {
'Authorization': 'Token 00d2e3a10c82420414b2d36d28fb5afc2cd8e8a5',
'Content-Type': 'application/json',
}
url = "https://api.tocall.com/"
data = '{"module_id":"[MODULE_ID]", "text": "example text"}'
response= requests.post(url, data=json.dumps(data), headers=headers)
print(response.status_code)

You are encoding your data as JSON twice. json.dumps() takes an object and converts to JSON. In this case, you are converting a string to JSON. This should work better:
import requests
headers = {
'Authorization': 'Token 00d2e3a10c82420414b2d36d28fb5afc2cd8e8a5',
}
url = "https://api.tocall.com/"
data = {"module_id":"[MODULE_ID]", "text": "example text"}
response= requests.post(url, json=data, headers=headers)
print(response.status_code)
If it still doesn't work and you need more help, you should include real details about your API so we can reproduce the issue.

json.dumps turns a Python dict to a string, but your data is already a string. The easiest thing to do is write data as a dict then use json.dumps on that.

Add the Host header, so that the final server knows on which virtual host to route the request,
Change:
headers = {
'Authorization': 'Token 00d2e3a10c82420414b2d36d28fb5afc2cd8e8a5',
'Content-Type': 'application/json',
}
For:
headers = {
'Authorization': 'Token 00d2e3a10c82420414b2d36d28fb5afc2cd8e8a5',
'Content-Type': 'application/json',
'Host' : 'api.tocall.com'
}
I think this will fix your issue. Eventually you might want to update the default headers, not craft your own ones. Try to use the session features of requests to perform consistent queries.
Note: as stated by other answers, you have other JSON encoding issues, but that's not the reason why you are getting 404.

Related

cURL, API in Python

I'm trying to code the following cURL API request in Python:
curl -X POST 'https://api.livecoinwatch.com/coins/list' \
-H 'content-type: application/json' \
-H 'x-api-key: <YOUR_API_KEY>' \
-d '{"currency":"USD","sort":"rank","order":"ascending","offset":0,"limit":2,"meta":false}'
I tried solving it with guidance of another post, like this:
headers = {
'x-api-key': <YOUR_API_KEY>,
'content-type': 'application/json',
'host': https://api.livecoinwatch.com/coins/list
}
url = https://api.livecoinwatch.com/coins/list
data = '{"currency": "USD","sort": "rank","order": "ascending","offset": 0,"limit": 50,"meta": true}'
response = requests.post(url, data=json.dumps(data), headers=headers)
print (response)
Unfortunately I get a "bad request" error.
Can someone please help me where I go wrong?
Assuming you have your urls wrapped in quotes, you should try giving to the data function parameter a dictionary instead of a string as the requests documentation says: data – (optional) Dictionary, list of tuples, bytes, or file-like object to send in the body of the Request.
response = requests.post(url, data=json.loads(data), headers=headers)

Python post request throwing 400 'Bad Request' error with requests library but works with cURL

I have a script that calls a POST endpoint but getting a 400 error. Meanwhile, the corresponding cURL request is successful.
First, here is the cURL:
curl -X 'POST' \
'http://localhost:8080/api/predict?Key=123testkey' \
-H 'accept: application/json' \
-H 'Content-Type: multipart/form-data' \
-F 'file=#156ac81cde4b3f22faa4055b53867f38.jpg;type=image/jpeg'
And translated to requests:
import requests
url = 'http://localhost:8080/api/predict?Key=123testkey'
headers = {
'accept': 'application/json',
'Content-Type': 'multipart/form-data',
}
params = {'Key' : '123testkey'}
files = {'image': open('156ac81cde4b3f22faa4055b53867f38.jpg', 'rb')}
response = requests.post(url, files=files, params=params, headers=headers)
Have also tried using a URL that does not include the key, since the key is already specified in params:
import requests
url = 'http://localhost:8080/api/predict'
headers = {
'accept': 'application/json',
'Content-Type': 'multipart/form-data',
}
params = {'Key' : '123testkey'}
files = {'image': open('156ac81cde4b3f22faa4055b53867f38.jpg', 'rb')}
response = requests.post(url, files=files, params=params, headers=headers)
I thought this should be simple but I consistently get the 400 error with requests no matter what I try. Any suggestions?
Edit: have also tried 'image/jpeg' instead of 'image' to no avail.
Edit: replacing the "image" key with "file" unfortunately didn't work either
Edit: It works in postman desktop just fine, and generates the following code. However, this code also throws an error.
The generated code from postman:
import requests
url = "http://localhost:8080/api/predict?Key=123test"
payload={}
files=[
('file',('images19.jpg',open('156ac81cde4b3f22faa4055b53867f38.jpg','rb'),'image/jpeg'))
]
headers = {
'Accept': 'application/json',
'Content-Type': 'multipart/form-data'
}
response = requests.request("POST", url, headers=headers, data=payload, files=files)
print(response.text)
And the error from the previously generated code from postman:
{"detail":"There was an error parsing the body"}
Any help figuring out what is going on would be much appreciated!
Your issue is in the variable files you need to add with the key 'file' instead of 'image' that's the difference between your curl and your python code, also remove the header because when you pass the file parameter the request set the proper header for send files. for example:
import requests
url = 'http://localhost:8080/api/predict?Key=123testkey'
params = {'Key' : '123testkey'}
files = {'file': open('156ac81cde4b3f22faa4055b53867f38.jpg', 'rb')}
response = requests.post(url, files=files, params=params)

GET Request from API via Python export to csv

I'm trying to write a api script via python. I want to access the URL "https://xxx/2.0/article" via "requests.get" so that it is displayed. If this was successful, I want to reprogram it to write all "articles" into a CSV.
I worked with curl first and it worked well
curl -X GET \
https://xxx/2.0/contact \
-H 'Accept: application/json' \
-H 'Authorization: Bearer {access-token}'
It also displayed the data directly. When I tried this with Python, it gave me an "Unauthorized".
import requests
newHeaders = {'Content-type': 'application/json', 'Accept': 'text/plain'}
response = requests.get('https://api.bexio.com/2.0/article', headers={'Authorization': 'newHeaders'
'Bearer '})
print(response.status_code)
print(response.text)
I don't know exactly what I have to do to make this work and how I can export/write this directly to a CSV.
Can anyone help me here?
Thanks!
I fixed it with the auth
#!/usr/bin/python
import requests
url = "https://api.bexio.com/2.0/article"
headers = {
'Accept': "application/json",
'Content-Type': "application/json",
'Authorization': "Bearer }
response = requests.request("GET", url, headers=headers)
print(response.text)
I saw my fault. The last question is, how can i get the output in a csv file? When I make an export of my stock in the frontend, I get a CSV with the fields "Product" "Code" "Storage location" Purchase value" "Stock" and "Minimum stock". But with the script comes of course much more output.

Squarespace returns no data using both curl and python

I am currently trying to build an integration between Quickbooks POS and squarespace. The official api documentation gives the following example:
curl "https://api.squarespace.com/1.0/commerce/products?cursor=abc" \
-i \
-H "Authorization: Bearer YOUR_API_KEY_OR_OAUTH_TOKEN" \
-H "User-Agent: YOUR_CUSTOM_APP_DESCRIPTION"
which returns with error 52 (no data) from. My attempts to do this with python also returns no data.
import requests
print("start")
headers = {
"Authorization": "API KEY",
"User-Agent": "QBPOS integration"
}
square_api = requests.Session()
data = square_api.get('https://api.squarespace.com/1.0/commerce/products', headers=headers)
print(data)
print(data.text)
and python-squarespace returns an error stating that squarespace thinks this request is bogus.
All of the response codes are <403>.
What could cause it to this, how can I fix this?
Add Bearer before the API KEY!!
import requests
headers = {
'Authorization': 'Bearer INSERT YOUR API KEY',
'User-Agent': 'QBOS INTEGERATION',
'Content-Type': 'application/json',
}
print("Hello World")
response = requests.get('https://api.squarespace.com/1.0/authorization/website', headers=headers)
print(response.text)
The above code is to check your squarespace api key is valid or not. In Authorization you forgot the Bearer, and replace API KEY with your api key which square space provided. I guess that QUBOS integration is the key name of the square space API key.
Squarespace uses some confusing terminology for it's apis. I had not enabled the api I needed.

Converting cURL to Python Requests error

I'm trying to convert the cURL to Python request but doesn't work.
cURL: curl -kv -H 'Content-Type: application/json' 'https://IP-address/api/v1/login' -d '{"username":"api", "password":"APIPassword"}'
My Python requests code:
import requests
url = "https://IP-address/api/v1/login"
payload = "'{\"username\":\"api\", \"password\":\"APIPassword\"}'"
headers = {
'Content-Type': "application/json",
'cache-control': "no-cache",
}
response = requests.request("GET", url, headers=headers, data=payload, verify=False)
print(response.text)
Which doesn't work and gives me 400 bad requests error.
I tried converting using the https://curl.trillworks.com/
which gives me the following code which doesn't work either.
import requests
url = 'https://IP-address/api/v1/login'
headers = {
'Content-Type': 'application/json',
}
data = '{"username":"api", "password":"APIPassword"}'
output = requests.get(url, data=data, verify=False)
print (output)
Can anyone please help me identify the issue here.
Edit: I have edited 2nd script to produce output: Which gives 500 Error
Use the json parameter in requests.post for json data. It also takes care of the headers.
data = {"username":"api", "password":"APIPassword"}
response = requests.post(url, json=data, verify=False)
Another way to make sure you're sending valid JSON in your payload would be to use the json python library to format your payload via json.dumps(), which returns a string representing a json object from an object. This was especially useful to me when I needed to send a nested json object in my payload.
import json
import requests
url = 'https://sample-url.com'
headers = { 'Content-Type': 'application/json', 'Authorization': f'{auth_key}'}
payload = { "key": "value",
"key": ["v1", "v2"],
"key": {
"k": "v"
}
...
}
r = requests.post(url, headers=headers, data=json.dumps(payload))

Categories