Translating curl to python requests - python

Making a multipart/form-data request to an api endpoint: https://api-reference.smartling.com/#tag/Files%2Fpaths%2F~1files-api~1v2~1projects~1%7BprojectId%7D~1file%2Fpost
I'm using python requests module with this syntax:
headers = {
'Authorization': 'Bearer ...',
'Content-Type': 'multipart/form-data'
}
files = {'file': open('myfile.xliff', 'rb')}
data = {
'fileUri': '...',
'fileType': 'xliff',
...
}
requests.request('POST', endpoint, headers=headers, files=files, data=data)
I am receiving an error from the endpoint unfortunately it just gives me a general http 500 error.
This does work fine if I manually do it via curl:
curl -XPOST -H 'Authorization: Bearer ...' -F "file=#myfile.xliff' -F "fileUri=..." ...
So I don't believe its the endpoint not accepting a proper request.
Does this curl statement and this python call seem equivalent? Been stuck on this problem, I have tried the following resources:
https://github.com/spulec/uncurl
https://curl.trillworks.com/
To try and get a curl to python equivalent for verification.
Unfortunately uncurl cannot parse my curl statement at all despite it working and curl.trillworks gives me a malformed 'files' dictionary and no 'data':
files = {
'file': ('myfile.xliff.;type', open('myfile.xliff;type', 'rb')),
'fileUri': (None, 'myfile.xliff'),
'fileType': (None, 'xliff'),
}
which is incorrect. (I tried it anyways as I was stuck)

try remove Content-Type from headers it will created automatically

Related

PiXhost's API- upload images

I'm trying to use PiXhost's api to upload images. Every time I request something from https://api.pixhost.to/images it always returns 400 Bad request. Their API documentation uses python unirest package, but I can't install it as it seems to use too old code.
Am I doing something wrong here?
Link to documentation
my code:
import requests
headers = {
"Content-Type": "multipart/form-data; charset=utf-8",
"Accept": "application/json"
}
params = {
"content_type": "0",
"max_th_size": "420"
}
files = {
"img": open("image.jpg", mode="rb")
}
response = requests.post("https://api.pixhost.to/images", headers=headers, params=params, files=files)```
import requests
url = "https://api.pixhost.to/images"
payload={'content_type': '0',
'max_th_size': '420'}
files={
'img': ('1.JPG', open('C:/Users/prave/Desktop/1.JPG', 'rb')),
'content_type': '0',
'max_th_size': '420'
}
headers = {
}
response = requests.request("POST", url, data=payload, files=files)
print(response)
Here you go
output :
Response 200
Issue with your code:
THe endpoint expects formdata , you are passing query parameter
So how did i figure it out
goto documentation and click curl tab to get curl equalent code:
Now goto postman and click import>Raw text > paste the curl , and click continue and then import
This creates the request for you
Now goto body and select img type as file and upload the file:
Now click code and generate equalent curl and python request code:
THe generated python code had few isseus one was to remove header completely and then to remove one slash from the file name.
Just a quick test, I managed to get it done via cURL
curl -X POST --include "https://api.pixhost.to/images" \
-H 'Content-Type: multipart/form-data; charset=utf-8' \
-H 'Accept: application/json' \
-F 'img=#test1.jpg' \
-F 'content_type=0' \
-F 'max_th_size=420'
https://pixhost.to/show/39/178828640_test1.jpg
Note: the test1 image is in the same folder when I running the script
I also receive 400 status code without a body when removing the # before the URL (so check you URL again)
HTTP/1.1 400 Bad Request
Server: nginx/1.10.3 (Ubuntu)

Why does this curl command work but not my post request via python?

I'm trying to make a POST request to https://accounts.spotify.com/api/token via python and the request, library but can't get it to work. I'm able to execute the request via curl command:
note - params enclosed in * * are correct and work in the curl request
curl -H "Authorization: Basic *base 64 encoded client ID and secret*"
-d grant_type=authorization_code -d code=*auth code* -d
redirect_uri=https%3A%2F%2Fopen.spotify.com%2F
https://accounts.spotify.com/api/token
and the request works just fine, however when I try to make what I think is the exact same request in python, I always get the same bad request error
headers = {
"Authorization": "Basic *base64 encoded client ID and secret*"
}
params = {
"grant_type": "authorization_code",
"code": code,
"redirect_uri": "https://open.spotify.com/"
}
response = requests.post(
url,
params=params,
headers=headers
)
If you can help me figure out how the two requests differ and why the python one never seems to work that would be amazing.
see section 2. of https://developer.spotify.com/documentation/general/guides/authorization-guide/ for the params
You use -d flag in your curl request which stands for data.
So you should pass your params as data also in your Python POST request:
headers = {
"Authorization": "Basic *base64 encoded client ID and secret*"
}
params = {
"grant_type": "authorization_code",
"code": code,
"redirect_uri": "https://open.spotify.com/"
}
response = requests.post(
url,
data=params,
headers=headers
)
seems like you put payload under wrong argument, try to change params into json or data (depends on what type of requests that API accept):
response = requests.post(
url,
json=params,
headers=headers
)

Translating a curl to python requests

I'm trying to create a python script to interact with an API for a system called Xibo. My problem is that I don't know python very well and the documentation for this system is what could generously be described as poor. Parts of their documentation use the format of the requests but their official API manual suggested the following curl command to update a media file on the system. I understand that requests are the best format to interact with APIs over and above curl so obviously I'd rather do it in requests if the general idea is that it's better.
curl -X POST "http://129.12.19.62/api/library" -H "accept: application/json" -H "Content-Type: multipart/form-data" -F "files=#47.htz" -F "name=47" -F "oldMediaId=47" -F "updateInLayouts=1" -F "deleteOldRevisions=1"
That is the command. Could anyone give me assistance by helping me translate it to the format of a request? I have tried using curl.trillworks but for some reason, it says that there was an "Error parsing curl command.". I understand if this is not possible or if you need some more information, I'll do my best to provide what anyone needs to help me.
Thank you.
Try something like this:
import requests
entry_point = 'http://129.12.19.62/api/library'
headers = {
'Accept': 'application/json',
'Content-Type': 'multipart/form-data'
}
data = {
'files': '#47.htz',
'name': '47',
'oldMediaId': '47',
'updateInLayouts': '1',
'deleteOldRevisions': '1'
}
r = requests.post(entry_point, headers=headers, data=data)
If you try pasting your curl command into curlconverter.com again, it now generates correct requests code:
import requests
headers = {
'accept': 'application/json',
# requests won't add a boundary if this header is set when you pass files=
# 'Content-Type': 'multipart/form-data',
}
files = {
'files': open('47.htz', 'rb'),
'name': (None, '47'),
'oldMediaId': (None, '47'),
'updateInLayouts': (None, '1'),
'deleteOldRevisions': (None, '1'),
}
response = requests.post('http://129.12.19.62/api/library', headers=headers, files=files)

Converting a cURL command to a python request

I am new to cURL; I wanted to convert a curl command of this structure:
curl -X POST "http://127.0.0.1:8881/models/faewrfaw/v1/predict" -H "Content-Type:multipart/form-data" -F "data={\"key\": \"Path\"};type=application/json" -F "Path=#C:\Users\rtam\Music\1 2 3\TEST123.jpg"
to a python request. I used https://curl.trillworks.com/ to assist me and got this as the output:
import requests
headers = {
'Content-Type': 'multipart/form-data',
}
files = {
'data': (None, '{"key": "Path"};type'),
'Path': ('C:\\Users\\rtam\\Music\\1 2 3\\TEST123.jpg', open('C:\\Users\\rtam\\Music\\1 2 3\\TEST123.jpg', 'rb')),
}
response = requests.post('http://127.0.0.1:8881/models/faewrfaw/v1/predict', headers=headers, files=files)
However, when testing the response in python I got a bad request/request the server did not understand. I noticed the trillworks website did not account for the type (application/json) in its formatting, does it need to be in the python script?
This answer might help you: How to send JSON as part of multipart POST-request
In your case it would be
files = {
'Path': (
'C:\\Users\\rtam\\Music\\1 2 3\\TEST123.jpg',
open('C:\\Users\\rtam\\Music\\1 2 3\\TEST123.jpg', 'rb'),
'application/octet-stream'
)
'data': (None, '{"key": "Path"}', 'application/json'),
}
response = requests.post(
'http://127.0.0.1:8881/models/faewrfaw/v1/predict',
files=files
)

Trigger GitLab Build with Python Requests

I'm trying to trigger a GitLab build using Python Requests. Normally one can kick off a build with a curl command.
Example curl command:
curl -X POST \
-F token=TOKEN \
-F ref=master \
-F "variables[UPLOAD_TO_S3]=true" \
https://gitlab.example.com/api/v4/projects/9/trigger/pipeline
I can get this working using the sh module but I'd prefer using requests. I've tried variations with the following:
data = {
'token': token,
'ref': master,
'variables[UPLOAD_TO_S3]': str(uploadS3),
}
headers = {'Content-Type': 'application/json'}
result = requests.post(_trigger_url, headers=headers, json=data)
I tried with and without the headers param. I've also tried passing the data dict using params, json, files, and data. All keep coming back with 400 or 404 errors. Any suggestions?
The above answer is incomplete as it does not deal with the part that makes this complex that is passing trough variables.
To pass variables around with requests using json data one needs to pass the data in the following structure
data = {
'token': token,
'ref': master,
'variables': [{"key": "UPLOAD_TO_S3", "value": True}, {"key": "S3_SERVER", "value": "https://mys3.example.com"}],
}
result = requests.post(_trigger_url, json=data)
You shouldn't send the Content-Type: "application/json" header as part of your request, and you should only need form encoding, so just pass your data dict as the data argument.
Here's a request to my Gitlab instance that succeeds and triggers a build of my project's master branch.
rsp = requests.post('https://gitlab.instance/api/v4/projects/PROJECT_ID/trigger/pipeline',
data={'token': '125fdsfdf1ab3631d2423434347643', 'ref': 'master'})
Here's the output if I inspect my rsp object in `ipython:
In [3]: rsp
Out[3]: <Response [201]>
You should also be able to trigger the pipeline by sending a POST and including the token and ref in the URL itself.
rsp = requests.post('https://gitlab.instance/api/v4/projects/PROJECT_ID/trigger/pipeline?token=TOKEN&ref=master')
If I pass the Content-Type: "application/json" header, Gitlab responds with an HTTP/400 error.
The first answer doesn't address the "variables" part. The second answer didn't work for me. Here's what I ended up with working:
variables = {
"UPLOAD_TO_S3": True,
"S3_SERVER": "https://mys3.example.com"
}
data = {
"token": token,
"ref": ref_name,
"variables": variables
}
res = requests.post(pipeline_trigger, json=data)

Categories

Resources