Convert cURL to Python - Upload A File - python

I can't seem to convert cURL to python. From the docs:
curl -i --upload-file ~/Desktop/Myimage.jpg -H 'Authorization: Bearer Redacted' "https://api.linkedin.com/mediaUpload/C5522AQHn46pwH96hxQ/feedshare-uploadedImage/0?ca=vector_feedshare&cn=uploads&m=AQLKRJOn_yNw6wAAAW2T0DWnRStny4dzsNVJjlF3aN4-H3ZR9Div77kKoQ&app=1983914&sync=0&v=beta&ut=1Dnjy796bpjEY1
I have tried using files instead of data to no avail.
The current code below creates the proper response 201, but it's blank (has no JSON details with an image to use for future API calls). Let me what changes I need to make to upload a file via a PUT request without using a multi-part form (ie "files=")
uploadUrl = data["value"]["uploadMechanism"]["com.linkedin.digitalmedia.uploading.MediaUploadHttpRequest"]["uploadUrl"]
filename = "ffadfads.jpeg"
media_url = "https://1000logos.net/wp-content/uploads/2017/03/LinkedIn-Logo.png"
request = requests.get(media_url, stream=True)
if request.status_code == 200:
with open(filename, 'wb') as image:
for chunk in request:
image.write(chunk)
#files = {'fileupload': open(filename)}
files = {"fileupload":(filename,open(filename,"rb"),'application-type')}
image_headers = {
'Accept': 'image/jpeg,image/png,image/gif',
'Authorization': 'Bearer ' + real_token
}
response = requests.request("PUT", uploadUrl, data=open(filename,"rb"), headers=image_headers)
print response
print response.text
print response.json()

Try not to confuse a request with a response.
response1 = requests.get(media_url, stream=True)
if response1.status_code == 200:
response2 = requests.request("PUT", uploadUrl,
data=response1.iter_content(),
headers=image_headers)

If you are not bound to use the requests library, you could try running the curl command directly from python, using subprocess.run() and shlex.split() for Python 3.
Using the example curl command from your question (adding a missing double quote at the end) the following code would run it and capture the response as text.
import shlex
import subprocess
curl_command_line = '''curl -i --upload-file ~/Desktop/Myimage.jpg \
-H 'Authorization: Bearer Redacted' \
"https://api.linkedin.com/mediaUpload/C5522AQHn46pwH96hxQ/feedshare-uploadedImage/0?ca=vector_feedshare&cn=uploads&m=AQLKRJOn_yNw6wAAAW2T0DWnRStny4dzsNVJjlF3aN4-H3ZR9Div77kKoQ&app=1983914&sync=0&v=beta&ut=1Dnjy796bpjEY1"'''
args = shlex.split(curl_command_line)
response = subprocess.run(args, capture_output=True, text=True).stdout
For Python 2.7, replace the last line with:
response = subprocess.call(args)

Related

CURL command in Python's requests

Can you please help me convert the following CURL command into a command for Python's requests library?
curl -F pdb_file[pathvar]=#/path/myfile.pdb -X POST https://proteins.plus/api/pdb_files_rest -H "Accept: application/json"
I've tried many things, like this:
import requests
file = open("3w32.pdb", "rb")
url = "https://proteins.plus/api/pdb_files_rest"
response = requests.post(url, data=file)
response.json()
or this:
import requests
file = open("3w32.pdb", "rb")
url = "https://proteins.plus/api/pdb_files_rest"
response = requests.post(url, data={"pdb_file[pathvar]": file}, json={"Accept": "application/json"})
response.json()
but I can't make it work. I either get an error from the server, or a JSONDecodeError in Python.
Try this answer https://stackoverflow.com/a/22567429/4252013
Instead of using "data" argument try with "file"
Ok, I managed to solve it at last.
The problem was that the 'pdb_file[pathvar]' part in the curl command should've been added to the request, like this:
import requests
file = open("3w32.pdb", "rb")
url = "https://proteins.plus/api/pdb_files_rest"
response = requests.post(url, files={'pdb_file[pathvar]':file})
response.json()
Now it works!
The problem in your code is that you have only opened the file and passed the pointer. you can pass the file contents by having file.read() in place.
Please refer this block of code:
import requests
file = open("3w32.pdb", "rb")
url = "https://proteins.plus/api/pdb_files_rest"
response = requests.post(url, data=file.read())
response.json()

Connecting to oauth2 API - it works with curl, doesn't with requests.get (Python)

I've been trying to connect to an oauth2 API. I've managed to write a code that delivers a token, so the token is not a problem.
I've checked that with curl. The following works:
curl -X GET \
https://api.website.pl/sale/delivery-methods \
-H 'Authorization: Bearer eyJhbGciOiJSUzBmF1BWKBjk3GiA' \
-H 'accept: application/vnd.website.public.v1+json'
<- This returns the data I need.
However, I simply can't make it work in python.
headers = {}
headers['Authorization'] = 'Bearer eyJhbGciOiJSUzBmF1BWKBjk3GiA'
headers['Accept'] = 'application/vnd.website.public.v1+json'
get_url = 'https://api.website.pl/sale/delivery-methods'
requests.get(get_url, headers)
The response is <Response [406]>, incorrect data, which I'm interpreting as a signal I didn't pass all the relevant authorization headers.
Any ideas how to fix that?
try this:
headers = {}
headers['Authorization'] = 'Bearer eyJhbGciOiJSUzBmF1BWKBjk3GiA'
headers['Accept'] = 'application/vnd.website.public.v1+json'
get_url = 'https://api.website.pl/sale/delivery-methods'
response = requests.get(get_url, headers=headers)

How to write python code for the below curl request to send a post request and uploading an image as binary

curl --request POST -H "Content-Type: application/octet-stream" --data-binary "#/C:\\Users\\U6068366\\Downloads\\Koala.jpg" https://c6y09pww43.execute-api.us-east-1.amazonaws.com/p
--
App_Url = "https://p7a0km3l6k.execute-api.us-east-1.amazonaws.com/preprod/v1/images/trademark/metadata/providerPartition/{providerPartition}/providerPartitionId/{providerPartitionId}"
# f = open('C://Users//UX016491//PycharmProjects//DSSApi//data1.json')
# requests_json = json.loads(f.read())
files = {'media' : open('C:\\Users\\UX016491\\Desktop\\images\\image123.jpg','rb') }
response = requests.request("POST", App_Url, files = files, headers={"content-type": 'application/octet-stream'})
print(response)
if __name__ == '__main__':
test_createimage_data()
EDIT: I added url from python example because url in curl was incomplete. But it still need two values providerPartition and providerPartitionId
On https://curl.trillworks.com/ you can convert curl to python code. And mostly it works.
Here code from this page. But I can't test it.
import requests
# incompletet url from curl
#url = 'https://c6y09pww43.execute-api.us-east-1.amazonaws.com/p'
providerPartition = '??'
providerPartitionId = '??'
url = f'https://p7a0km3l6k.execute-api.us-east-1.amazonaws.com/preprod/v1/images/trademark/metadata/providerPartition/{providerPartition}/providerPartitionId/{providerPartitionId}'
headers = {
'Content-Type': 'application/octet-stream',
}
data = open('C:\\Users\\U6068366\\Downloads\\Koala.jpg', 'rb').read()
response = requests.post(url, headers=headers, data=data)
print(response.text)
You can also test both with url https://httpbin.org/post and it will send back what it get from you. And you can compare results from both requests. I tested curl and python code and I go the same information so they should give the same effect.

Python post request returns 500

I am using requests to make a POST request to create a user. The request succeeds with 201 created when I use curl, however fails with a 500 response when I use requests. My curl command is
curl --user administrator:password -H "Content-Type: application/json" https://localhost:8080/midpoint/ws/rest/users -d #user.json -v
And my python script is:
import requests
import json
headers = {
'Content-Type': 'application/json',
}
with open('user.json') as j:
data = json.load(j)
response = requests.post('https://localhost:8080/midpoint/ws/rest/users', headers=headers, data=str(data), auth=('Administrator', 'password'))
print(response)
Can anyone see a reason why my python script would be failing? I am at a loss.
str(data) returns the Python representation of data, not its JSON representation. These two forms can differ in things like ' vs. ", True vs. true, and None vs. null. To properly JSONify data, call json.dumps() on it:
response = requests.post(..., data=json.dumps(data))
or let requests do the JSONification:
response = requests.post(..., json=data)
or use the JSON as it appears in user.json directly:
with open('user.json') as j:
data = j.read()
response = requests.post(..., data=data)

Why does this Translation of Curl into Python requests fail? [duplicate]

I'm trying to convert the following working request in curl to a python request (using Requests).
curl --data 'query={"tags":["test1","test2"]}' http://www.test.com/match
(I've used a fake url but the command does work with the real url)
The receiving end (ran in Flask) does this:
#app.route("/match", methods=['POST'])
def tagmatch():
query = json.loads(request.form['query'])
tags = query.get('tags')
# ... does stuff ...
return json.dump(stuff)
In curl (7.30), ran on Mac OS X (10.9) the command above properly returns a JSON list that's filtered using the tag query.
My Python script is as follows, it returns a 400 Bad Request error.
import requests
payload = {"tags":["test1", "test2"]}
# also tried payload = 'query={"tags":["test1","test2"]}'
url = 'http://www.test.com/match'
r = requests.post(url, data=payload)
if __name__=='__main__':
print(r.text)
There is an open source cURL to Python Requests conversion helper at https://curlconverter.com/. It isn't perfect, but helps out a lot of the time. Especially for converting Chrome "Copy as cURL" commands. There is also a node library if you need to do the conversions programmatically
Your server is expecting JSON, but you aren't sending it. Try this:
import requests
import json
payload = {'query': json.dumps({"tags":["test1", "test2"]})}
url = 'http://www.test.com/match'
r = requests.post(url, data=payload)
if __name__=='__main__':
print r.text
Save your life
A simpler approach would be:
Open POSTMAN
Click on the "import" tab on the upper left side.
Select the Raw Text option and paste your cURL command.
Hit import and you will have the command in your Postman builder!
Hope this helps!
credit: Onkaar Singh
Try to use uncurl library. It is pretty nice to do its job. I've tried it.
u = uncurl.parse(
"curl -X GET 'https://mytesturl.com/' -H 'accept: application/json' -H 'Authorization: 1234567890'")
print(u)
It prints,
requests.get("https://mytesturl.com/",
headers={
"Authorization": "1234567890",
"accept": "application/json"
},
cookies={},
)
try this:
https://github.com/spulec/uncurl
import uncurl
print uncurl.parse("curl 'https://pypi.python.org/pypi/uncurl' -H
'Accept-Encoding: gzip,deflate,sdch'")
I wrote an HTTP client plugin for Sublime Text called Requester, and one of its features is to convert calls to cURL to Requests, and vice versa.
If you're using Sublime Text this is probably your fastest, easiest option. If not, here's the code that actually handles the conversion from cURL to Requests. It's based uncurl, but with various improvements and bug fixes.
import argparse
import json
try:
from urllib.parse import urlencode, parse_qsl
except ImportError: # works for Python 2 and 3
from urllib import urlencode
from urlparse import parse_qsl
if __name__ == "__main__":
parser = argparse.ArgumentParser()
parser.add_argument('command')
parser.add_argument('url')
parser.add_argument('-X', '--request', default=None)
parser.add_argument('-d', '--data', default=None)
parser.add_argument('-G', '--get', action='store_true', default=False)
parser.add_argument('-b', '--cookie', default=None)
parser.add_argument('-H', '--header', action='append', default=[])
parser.add_argument('-A', '--user-agent', default=None)
parser.add_argument('--data-binary', default=None)
parser.add_argument('--compressed', action='store_true')
parsed_args = parser.parse_args()
method = 'get'
if parsed_args.request:
method = parsed_args.request
base_indent = ' ' * 4
post_data = parsed_args.data or parsed_args.data_binary or ''
if post_data:
if not parsed_args.request:
method = 'post'
try:
post_data = json.loads(post_data)
except ValueError:
try:
post_data = dict(parse_qsl(post_data))
except:
pass
cookies_dict = {}
if parsed_args.cookie:
cookies = parsed_args.cookie.split(';')
for cookie in cookies:
key, value = cookie.strip().split('=')
cookies_dict[key] = value
data_arg = 'data'
headers_dict = {}
for header in parsed_args.header:
key, value = header.split(':', 1)
if key.lower().strip() == 'content-type' and value.lower().strip() == 'application/json':
data_arg = 'json'
if key.lower() == 'cookie':
cookies = value.split(';')
for cookie in cookies:
key, value = cookie.strip().split('=')
cookies_dict[key] = value
else:
headers_dict[key] = value.strip()
if parsed_args.user_agent:
headers_dict['User-Agent'] = parsed_args.user_agent
qs = ''
if parsed_args.get:
method = 'get'
try:
qs = '?{}'.format(urlencode(post_data))
except:
qs = '?{}'.format(str(post_data))
print(post_data)
post_data = {}
result = """requests.{method}('{url}{qs}',{data}\n{headers},\n{cookies},\n)""".format(
method=method.lower(),
url=parsed_args.url,
qs=qs,
data='\n{}{}={},'.format(base_indent, data_arg, post_data) if post_data else '',
headers='{}headers={}'.format(base_indent, headers_dict),
cookies='{}cookies={}'.format(base_indent, cookies_dict),
)
print(result)
You could make a script with this code, e.g. curl_to_request.py, and call this script from the command line like so. It will work for both Python 2 and Python 3.
python curl_to_request.py curl -X POST -d 'key2=value2&key1=value1' 'http://httpbin.org/post'
python curl_to_request.py curl -X POST -H 'Content-Type: application/json' -d '{"key2": "value2", "key1": "value1"}' 'http://httpbin.org/post'
python curl_to_request.py curl -X POST -H 'Content-Type: application/json' -d '[1, 2, 3]' 'http://httpbin.org/post'
python curl_to_request.py curl -X POST -H 'Content-Type: application/json' -d '{"name": "Jimbo", "age": 35, "married": false, "hobbies": ["wiki", "pedia"]}' 'http://httpbin.org/post'
python curl_to_request.py curl -X GET 'http://httpbin.org/get?key2=value2&key1=value1'
python curl_to_request.py curl -X GET -H 'key1: value1' -H 'key2: value2' 'http://httpbin.org/headers'
python curl_to_request.py curl -X GET -b 'key1=value1;key2=value2' 'http://httpbin.org/cookies'
From your code using requests and in Flask, it seems like you don't post the right data format. The payload should be like this:
payload = {'query': {'tags': ['test1', 'test2']},}
This seems not normal as post data when using requests.post(). So if you have posted the html form here, it may have been more clear to solve the problem.
Here is another similar question: Using Python Requests to pass through a login/password

Categories

Resources