Callling a REST API in python - python

I want to call a REST api and get some json data in response in python.
curl https://analysis.lastline.com/analysis/get_completed -X POST -F “key=2AAAD5A21DN0TBDFZZ66” -F “api_token=IwoAGFa344c277Z2” -F “after=2016-03-11 20:00:00”
I know of python request, but how can I pass key, api_token and after? What is -F flag and how to use it in python requests?

Just include the parameter data to the .post function.
requests.post('https://analysis.lastline.com/analysis/get_completed', data = {'key':'2AAAD5A21DN0TBDFZZ66', 'api_token':'IwoAGFa344c277Z2', 'after':'2016-03-11 20:00:00'})

-F stands for form contents
import requests
data = {
'key': '2AAAD5A21DN0TBDFZZ66',
'api_token': 'IwoAGFa344c277Z2',
'after': '2016-03-11',
}
response = requests.post('https://analysis.lastline.com/analysis/get_completed', data=data)

-F means make a POST as form data.
So in requests it would be:
>>> r = requests.post('http://httpbin.org/post', data = {'key':'value'})

Related

Passing a remote file to a http post request in python

I have a rest api that offers an upload file post functionality. To test this, I simply did this on my python test code:
fo = open('file.zip', 'rb')
rb_file = {'confile': ('file.zip', fo, 'multipart/form-data')}
resp = requests.post(url,files=rb_file)
fo.close()
This request returns a uuid response {ce9f2d23-8ecd-4c60-9d31-aef0be103d44} that is needed for initiating another post run for a scan.
From Swagger, manually passing this uuid to the scan post request generates the following curl:
curl -X POST "http://....../scan" -H "Content-Type: multipart/form-data" -F "FilID=ce9f2d23-8ecd-4c60-9d31-aef0be103d44"
My question is how to convert this curl to a python request code noting that I no longer have the file on my local machine. The server seems to be expecting a -F rather than a param. How do I pass a file that doesn't exist on my local machine to http request in this case? All I have is the filID. I tried running as param but that doesn't find the resource.
try this !
import requests
headers = {
'Content-Type': 'multipart/form-data',
}
files = {
'FilID': (None, 'ce9f2d23-8ecd-4c60-9d31-aef0be103d44'),
}
response = requests.post('http://....../scan', headers=headers, files=files)

translating simple curl call to python/django request

I'm attempting to translate the following curl request to something that will run in django.
curl -X POST https://api.lemlist.com/api/hooks --data '{"targetUrl":"https://example.com/lemlist-hook"}' --header "Content-Type: application/json" --user ":1234567980abcedf"
I've run this in git bash and it returns the expected response.
What I have in my django project is the following:
apikey = '1234567980abcedf'
hookurl = 'https://example.com/lemlist-hook'
data = '{"targetUrl":hookurl}'
headers = {'Content-Type': 'application/json'}
response = requests.post(f'https://api.lemlist.com/api/hooks/', data=data, headers=headers, auth=('', apikey))
Running this python code returns this as a json response
{}
Any thoughts on where there might be a problem in my code?
Thanks!
Adding to what nikoola said, I think you want that whole data line to be as follows so you aren't passing that whole thing as a string. Requests will handle serializing and converting python objects to json for you [EDIT: if you use the json argument instead of data].
source: https://requests.readthedocs.io/en/master/user/quickstart/#more-complicated-post-requests
Instead of encoding the dict yourself, you can also pass it directly
using the json parameter (added in version 2.4.2) and it will be
encoded automatically:
Note, the json parameter is ignored if either data or files is passed.
Using the json parameter in the request will change the Content-Type
in the header to application/json.
data = {"targetUrl":hookurl}
import requests
headers = {
'Content-Type': 'application/json',
}
data = '{"targetUrl":"https://example.com/lemlist-hook"}'
response = requests.post('https://api.lemlist.com/api/hooks', headers=headers, data=data, auth=('', '1234567980abcedf'))
You can visit this url:-
https://curl.trillworks.com/

Python 2.7 requests REST API call not working same as curl

I am trying to do a curl post query using requests python 2.7, however the API response differently using curl vs. requests lib.
The post query is pretty simple a file and name-value-pair data as the API params.
Below is the curl multipart post request:
curl -uadmin:blabla123 -X POST 127.0.0.1:8080/alfresco/api/-default-/public/alfresco/versions/1/nodes/6a0ab661-1c43-43ed-b07f-a564f6bcb5ca/children -F filedata=#file1.txt -F name=document__55;nodeType=content
The python 2.7 code is as below:
import requests
from requests.auth import HTTPBasicAuth, HTTPDigestAuth
from config import USER, PASSWD
def createDocument( documentFilename, documentMetadata, targetFolderNodeId):
'''
Uploads a file and its meta-data to the CMIS server under the specified
target folder
'''
with open(documentFilename, 'rb') as file:
files = {'file': file}
# createURL = 'http://127.0.0.1:8080/alfresco/api/-default-/public/alfresco/versions/1/nodes/{0}/children'.format( targetFolderNodeId )
createURL = 'http://127.0.0.1:8080/alfresco/api/-default-/public/alfresco/versions/1/nodes/6a0ab661-1c43-43ed-b07f-a564f6bcb5ca/children'
data = {
"name":"document__55",
"nodeType":"cm:content",
}
response = requests.post( createURL, data = data, files = files, auth=HTTPBasicAuth(USER, PASSWD) )
print(response)
print(response.json)
print(response.text)
createDocument('file1.txt', '', '')
Curl returns 200 http code but the script oddly returns 400.
Any help is much appreciate it.
At a first glace the reasons for that script failing vs curl working could be more than one:
nodeType=content in the curl, while "nodeType":"cm:content" in the script
there's an additional comma in the script's payload second line
you're not setting the Content-Type header as multipart/form-data in the script, which curl's -F option actually does
Also, the endpoint should provide a verbose error along with the 400 response. If it does, that could be helpful to identify the error cause.
in fact in the curl I have -F filedata=#file1.txt but in the script I have files = {'file': file} which is not the same so I just had to use files = {'filedata': file} :)
def createDocument( documentFilename, documentMetadata, targetFolderNodeId):
'''
Uploads a file and its meta-data to the CMIS server under the specified
target folder
'''
with open(documentFilename, 'rb') as file:
files = {'filedata': file}
createURL = 'http://127.0.0.1:8080/alfresco/api/-default-/public/alfresco/versions/1/nodes/{0}/children'.format( targetFolderNodeId )
data = {
"name":"document__77",
"nodeType":"cm:content"
}
response = requests.post( createURL, data = data, files = files, auth=HTTPBasicAuth(USER, PASSWD) )
print(response)
print(response.json)
print(response.text)
print(response.headers)
# print([i for i in dir(response) if 'header' in i])

How to get information without using pyCURL (requests)

I need to implement the following curl:
curl -k https://somelinkhere/get_info -d auth_info='{"session_id":"blablablaidhere"}' -d params='{"id":"12345"}'
Currently I have the following code. It is working, but not exactly as I need. I need to get json content from the reply, just one parameter.
url = 'https://somelinkhere/get_info'
data = {'auth_info':'{"session_id":"blablablaidhere"}', 'params':'{"id":"12345"}'}
response = requests.post(url, data=data)
res = response.content
print res
Now it returns
'�Z[o�6�+���֖���ې�0�{h�`
AK�M�"����o�9�dI���t��#RI<��"�GD�D��.3MDeN��
��hͣw�fY)SW����`0�{��$���L��Zxvww����~�qA��(�u*#��݅Pɣ����Km���'
etc.
What i need is to output
res['balance_info']['balance']
If i launch cURL (provided above) from a command line, i have the following:
{"balance_info":{"enabled":"Y","balance":"0.55000","out_date_format":"MM-DD-YYYY","password":"12345","blocked":"N"
But do not know how to get this parameter using python script
As in documentation,content property gives the binary version of response.
You'll need to get the decoded version of request using .text then load it as json.
response = requests.post(url, data=data)
#load it as json
item = json.loads(response.text)
And now you can access your keys as:
response['balance_info']['balance']
What you get is a Gziped JSON string.
You have to decompress before reading json. Then you can use the response as a python dict.
Something like res = json.loads(zlib.decompress(response.content))
Here is an example using Requests:
>>> import requests
>>> r = requests.post('https://somelinkhere/get_info',
data = {"id": "12345"})
See also the documentation to install Requests on your virtualenv.

Python Requests Put not working with build.phonegap.com

I am making a python build script for a phonegap project.
I need to open the ios key before i build
I am trying to do this with a http put request through the requests module for python.
If i do it with cURL from command line, it works fine
curl -vvv -d 'data={"password":"myPassWord"}' -X PUT https://build.phonegap.com/api/v1/keys/ios/193686?auth_token=passwordlesstokenphg
But from python like this.
password_for_key = {'password': 'myPassword'}
authentication_token = {'auth_token': 'passwordlesstokenphg'}
requests.put('https://build.phonegap.com/api/v1/keys/ios/193686', data=password_for_key, params=authentication_token)
It just returns the json you would recieve if you did a cURL without the data.
For me it seems like the data is not being sent to phonegap correctly.
API reference from build.phonegap.com
docs.build.phonegap.com/en_US/2.9.0/developer_api_write.md.html
Please help :)
So when you do
curl -d "..." -X PUT https://example.com
curl sends exactly what's in that string. requests does not translate so directly to curl. To do something similar in requests you need to do the following:
import json
password_for_key = {'password': 'myPassword'}
authentication_token = {'auth_token': 'passwordlesstokenphg'}
requests.put('https://build.phonegap.com/api/v1/keys/ios/193686',
data={'data': json.dumps(password_for_key)},
params=authentication_token)
What requests will do is build data={"password":"myPassword"} for you if you use the above. First you have to JSON encode the data in password_for_key then pass it in the dictionary to data.

Categories