Send complex command to API using the & argument - python

I have to send commands to an API using Python.
The API's documentation was written to send receive CURL commands.
I converted the curl string
curl -H "Authorization: Bearer accesstoken" https://www.website.com/feed.php?command=COMMAND
Into this:
import requests
headers = {
'Authorization': 'Bearer accesstoken',
}
params = {
'command': "COMMAND",
}
response = requests.get('https://www.website.com/feed.php', params=params, headers=headers)
The problem is if the command I want to send is a complex command like:
curl -H "Authorization: Bearer accesstoken" https://www.website.com/feed.php?command=COMMAND&wake=10
the conversion to Python won't work as this "&wake=10" isn't accepted.
Any ideas on how to circumvent this?

You can pass multiple query parameters in the params dictionary - requests will turn them into the required URL format.
import requests
headers = {
'Authorization': 'Bearer accesstoken',
}
params = {
'command': "COMMAND",
'wake': 10
}
response = requests.get('https://www.website.com/feed.php', params=params, headers=headers)

You need to split on the &, resulting in multiple key + value pairs in params.
params = {
"command": "COMMAND",
"wake": "10"
}

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 JSON GET Request Like cURL

I have a cURL command that I would like to port to Python.
curl -XGET "http://localhost:9200/nuix-7674bc4a60b74ea7bac8996a98b0cb94;item;schema-version=1/_search" -H 'Content-Type: application/json' -d'
{
"query": {
"regexp": {
"content": "(p)hotos"
}
}
}'
It successfully returns a non-error response.
Here is what I tried in Python 3.6 using the requests package.
import requests
import json
# api-endpoint
url = "http://localhost:9200/nuix-7674bc4a60b74ea7bac8996a98b0cb94;item;schema-version=1/_search"
# headers
headers = {'Content-type': 'application/json'}
# Define JSON String
params = """
{
"query": {
"regexp":{
"content": "(p)hotos"
}
}
}
"""
params = json.loads(params)
print(params)
# sending get request and saving the response as response object
response = requests.get(url=url, params=params, headers=headers)
# extracting data in json format
data = response.json()
print(data['hits']['total'])
print('DONE')
The response response._content states this error:
b'{"error":{"root_cause":[{"type":"illegal_argument_exception","reason":"request [/nuix-7674bc4a60b74ea7bac8996a98b0cb94;item;schema-version=1/_search] contains unrecognized parameter: [query]"}],"type":"illegal_argument_exception","reason":"request [/nuix-7674bc4a60b74ea7bac8996a98b0cb94;item;schema-version=1/_search] contains unrecognized parameter: [query]"},"status":400}'
What is the correct way to set params?
requests expects a dict as params not a string. I'm not sure this is your problem but you could try rewriting as:
params = {
"query": {
"regexp":{
"content": "(p)hotos"
}
}
}
Check out this section from the docs for a walkthrough: http://docs.python-requests.org/en/master/user/quickstart/#passing-parameters-in-urls
The solution is to use the json parameter, rather than params.
response = requests.get(url=url, json=params, headers=headers)
I probably could have rewritten the JSON string to a dictionary, but I am using a tool -- Kibana that automatically generates a cURL payload. This solution allows me to copy and paste the JSON payload into my Python script.

Converting CURL command to Python with requests

I want to use the requests library in Python to make a POST request.
But the API I'm trying to use uses curl to make the request and I don't know how to convert that.
This is the curl command:
curl -X POST "https://api/recognize?secret_key=abc" -H "accept: application/json" -H "Content-Type: multipart/form-data" -F "image=#/path/to/image.jpg;type=image/jpeg"
For the moment I'm just using a URL instead of the image itself as a workaround.
Code:
params = (
('image_url', '2015-BMW-320djpg'),
('secret_key', 'abc'),
)
response = requests.post('https://api/recognize_url', params=params)
As far as I'm aware there's no "cURL -> Requests" translator, but it should be fairly easy to translate that one request (and requests like it) to use the requests module.
files = {'image': open('/path/to/image.jpg', 'rb')}
params = {'secret_key': 'abc'}
headers = {'accept': 'application/json'}
response = requests.post(url, files=files, params=params, headers=headers)
First, paste your command into curlconverter.com/python/ and it will convert it to
import requests
headers = {
'accept': 'application/json',
}
params = {
'secret_key': 'abc',
}
files = {
'image': open('/path/to/image.jpg;type=image/jpeg', 'rb'),
}
response = requests.post('https://api/recognize', params=params, headers=headers, files=files)
Then, the 'image': open('/path/to/image.jpg;type=image/jpeg', 'rb'), line is wrong because the ;type=image/jpeg is not part of the file path to your image. To correct it, you need to read the curl documentation for the -F flag and the Requests documentation for the files= parameter (or just the Advanced Usage page) to know that you need to change it to
files = {
'image': ('image.jpg', open('/path/to/image.jpg', 'rb'), 'image/jpeg'),
}

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))

Calling Curl API on 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.

Categories