Python requests equivalent of following curl code - python

Could you please inform what would be Python requests equivalent of following curl code to upload file to knack? Specifically part after -F option. Thank you
curl -X POST "https://api.knack.com/v1/applications/YOUR-APP-ID/assets/file/upload" \
-H 'content-type: multipart/form-data' \
-H 'x-knack-rest-api-key: YOUR-API-KEY' \
-F "files=#/path/to/your/file.txt"

Use requests.post with files and headers. Your curl code is equivalent to:
url = "https://api.knack.com/v1/applications/YOUR-APP-ID/assets/file/upload"
files = {'files':open('/path/to/your/file.txt', 'rb')}
headers = {'x-knack-rest-api-key': 'YOUR-API-KEY'}
r = requests.post(url, headers=headers, files=files)
When using the files argument, requests creates the necessary headers automatically so you don't need to have "Content-Type" or "Content-Length" in headers.

Related

errors from api when using python requests module for file upload

when i make the following request:
curl -X POST http://localhost:8080/endpoint \
-F "file=filepath/example.zip" \
-H "Content-Type: multipart/form-data"
everything works fine.
However, when i try to do the same in python:
import requests
url = "http://localhost:8080/endpoint"
files = {"file": open("example.zip", "rb")}
headers = {"Content-Type": "multipart/form-data"}
r = requests.post(url, files=files, headers=headers)
the api gives me an error. are these two code snippets not equivalent? thanks
the issue was this:
multipart data POST using python requests: no multipart boundary was found
it seems as though setting
headers = {"Content-Type": "multipart/form-data"}
caused the issue. i removed it and it works

How do I replicate a `curl` with `-F` in Python 3?

I have this curl:
curl -v "http://some.url" \
-X PUT \
-H "X-API-Key: API_KEY" \
-H 'Accept: application/json' \
-H 'Content-Type: multipart/form-data' \
-F "logo=#the_logo.png;type=image/png"
And I am trying to replicate this with Python.
What I have tried so far is:
import requests
with open("the_logo.png", "rb") as file_obj:
data = file_obj.read()
requests.put(
"http://some.url",
files={"logo": ("the_logo.png", data, "image/png")},
headers={
"X-API-Key": "API_KEY",
"Accept": "application/json",
"Content-Type": "multipart/form-data"}
But for some reason the curl above works, while the Python code does not and the server replies with a 422.
How can I make Python replicate what curl does?
After some reading, it appears that the trick is to NOT set Content-Type in the headers when using requests and the files parameter.

Convert this curl command to Python 3

How can I send this curl out using Python?
I did find similar requests, but cannot adapt my code to suite the query
I have also tried using pycurl, following this example but without luck.
$ curl -v -X GET -H "Accept: text/csv" -H "Authorization: Basic YW5kcmVhLmJvdHRpQHdzcC5jb206OWY5N2E5YTY2ZWU1MTMxZjdmNjk4MDcwZTFkODEwMjU0M2I0NTg1ZA==" "https://epc.opendatacommunities.org/api/v1/domestic/search"
Thanks
If you are using the Python Requests package the following code snippet should work:
import requests
headers = {
'Accept': 'text/csv',
'Authorization': 'Basic YW5kcmVhLmJvdHRpQHdzcC5jb206OWY5N2E5YTY2ZWU1MTMxZjdmNjk4MDcwZTFkODEwMjU0M2I0NTg1ZA==',
}
response = requests.get('https://epc.opendatacommunities.org/api/v1/domestic/search', headers=headers)
response.status_code # 200
response.text # "lmk-key,address1,address2,address3,postcode,buildi ..."
(Note: I used the https://curl.trillworks.com/ website to automatically make the conversion)

How to convert "curl -X POST -T " to Python

How do I convert
curl -X POST -T 'sample_data.json' -H "Content-Type: application/json" https://sample_url.com
to Python using requests?
Specifically, how do I provide "-T" parameter to the request?
I believe you could do something like this:
import requests
import json
requests.post('https://sample_url.com',
headers = {'Content-type': 'application/json'},
data = json.loads(open('sample_data.json').read())
}
You can check out the requests page for more details.
Or, to show a fully self-contained example without having to load the json from a file, you could do:
import requests
requests.post('https://httpbin.org/post', data = {'key':'value'})
<Response [200]>
Note, from the requests docs:
Using the json parameter in the request will change the Content-Type in the header to application/json.
So, you could just do the following instead:
r = requests.post(url, json=payload)
curl -X POST -T 'sample_data.json' \
-H 'Content-Type: application/json' \
https://sample_url.com/
is effectively equivalent to
curl -X POST \
-H 'Content-Type: application/json' \
-d "$(cat sample_data.json)" \
https://sample_url.com/sample_data.json
so using requests, it would be
with open('sample_data.json') as fh:
response = requests.post(
"https://sample_url.com/sample_data.json",
data=fh.read(),
header={'Content-Type': 'application/json'}
)
There are a couple of ways that you could do it. But the best way is to use the requests library. It's not part of the standard library (yet), but makes HTTP requests super straight-forward.
$ pip install requests
or
$ conda install requests
Then
import json
import requests
url = r"https://sample_url.com"
with open("sample_data.json", "r") as fh:
data = json.load(fh)
requests.post(url=url, data=data)
The best way is to use the Python Requests library - https://2.python-requests.org/en/master/. To be able to post a JSON payload in the message is
import Requests
import json
result = requests.post(URL,json=json.loads(open('sample_data.json').read()))
The requests library natively understands how to send your JSON data
There are some more examples of how to post messages with Form encoded payloads on this part of the page as well - https://2.python-requests.org/en/master/user/quickstart/#more-complicated-post-requests
To be able to do other verbs you just need to change the function for requests -
for a GET, requests.get(url)
for a PUT, requests.put(url,data=DATA) or requests.put(url,json=JSON)
for a DELETE, requests.delete(url)
and so on.

Trouble converting curl commands to python requests

I'm trying to grab some data from a website using API, but I'm having trouble converting the example curl command to python requests.
example curl command
curl -X POST "some_url" \
-H "accept: application/json" \
-H "Authorization: <accesstoken>" \
-d #- <<BODY
{}
BODY
My python requests that didn't work
headers = {
'Authorization': "Bearer {0}".format(access_token)
}
response = requests.request('GET', "some_url",
headers=headers, allow_redirects=False)
I get error code 400, can anyone help me figure out what was wrong?
The equivalent requests code for your curl should be:
import requests
headers = {
'accept': 'application/json',
'Authorization': '<accesstoken>',
}
data = "{} "
response = requests.post('http://some_url', headers=headers, data=data)
You can use https://curl.trillworks.com/ to convert your actual curl invocation (note that it won't handle heredocs, as in your example).
If you see different behavior between curl and your python code, dump the HTTP requests and compare:
Python requests - print entire http request (raw)?
How can I see the request headers made by curl when sending a request to the server?

Categories