Python: conversion from requests library to urllib3 - python

I need to convert the following CURL command into an http request in Python:
curl -X POST https://some/url
-H 'api-key: {api_key}'
-H 'Content-Type: application/json'
-H 'Accept: application/json'
-d '{ "data": { "dirname": "{dirname}", "basename": "{filename}", "contentType": "application/octet-stream" } }'
I initially successfully implemented the request using Python's requests library.
import requests
url = 'https://some/url'
api_key = ...
dirname = ...
filename = ...
headers = {
'api-key': f'{api_key}',
'Content-Type': 'application/json',
'Accept': 'application/json',
}
payload = json.dumps({
'data': {
'dirname': f'{dirname}',
'basename': f'{filename}',
'contentType': 'application/octet-stream'
}
})
response = requests.post(url, headers=headers, data=payload)
The customer later asked not to use pip to install the requests library. For this I am trying to use the urllib3 library as follows:
import urllib3
url = 'https://some/url'
api_key = ...
dirname = ...
filename = ...
headers = {
'api-key': f'{api_key}',
'Content-Type': 'application/json',
'Accept': 'application/json',
}
payload = json.dumps({
'data': {
'dirname': f'{dirname}',
'basename': f'{filename}',
'contentType': 'application/octet-stream'
}
})
http = urllib3.PoolManager()
response = http.request('POST', url, headers=headers, body=payload)
The problem is that now the request returns me an error 400 and I don't understand why.

Try calling .encode('utf-8') on payload before passing as a parameter.
Alternatively, try to pass payload as fields without manually converting it to JSON:
payload = {
'data': {
'dirname': f'{dirname}',
'basename': f'{filename}',
'contentType': 'application/octet-stream'
}
}
http = urllib3.PoolManager()
response = http.request('POST', url, headers=headers, fields=payload)

Related

Curl Requests Params inside url

I have an API, where all important Parameter like ID, category is in the Request's URL and not as payload. What would be the smartest and recommended way to solve this?
curl --request GET \
--url 'https://api.otto.market/v2/products?sku=SOME_STRING_VALUE&productReference=SOME_STRING_VALUE&category=SOME_STRING_VALUE&brand=SOME_STRING_VALUE&page=SOME_INTEGER_VALUE&limit=SOME_INTEGER_VALUE' \
--header 'Authorization: Bearer REPLACE_BEARER_TOKEN'
What I did till now
def example(content_type: str, cache_control: str, grand_type:str, client_id:str):
endpoint = website.BASE_URL
header_content = {
'Content-Type': (f'{content_type}'),
'Cache-Control': (f'{cache_control}')
}
data_content = {
'grant_type': (f'{grand_type}'),
'client_id': (f'{client_id}')
}
response = requests.get(url= endpoint, headers=header_content, data=data_content, verify=False)
return response
requests.get has optional parameter params where you might deliver dict, consider following simple example
import requests
parameters = {"client":"123","product":"abc","category":"a"}
r = requests.get("https://www.example.com",params=parameters)
print(r.url) # https://www.example.com/?client=123&product=abc&category=a
For further discussion read Passing Parameters In URLs
The curl request that you posted in python would be:
import requests
headers = {
'Authorization': 'Bearer REPLACE_BEARER_TOKEN',
}
params = {
'sku': 'SOME_STRING_VALUE',
'productReference': 'SOME_STRING_VALUE',
'category': 'SOME_STRING_VALUE',
'brand': 'SOME_STRING_VALUE',
'page': 'SOME_INTEGER_VALUE',
'limit': 'SOME_INTEGER_VALUE',
}
response = requests.get('https://api.otto.market/v2/products', params=params, headers=headers)
Insert your variables as required.

Curl To Python Request (-d parameter)

Havin error to convert the below curl into python request.
curl -G "https://thethings.example.com/api/v3/as/applications//packages/storage/uplink_message"
-H "Authorization: Bearer $API_KEY"
-H "Accept: text/event-stream"
-d "limit=10"
-d "after=2020-08-20T00:00:00Z"
-d "field_mask=up.uplink_message.decoded_payload"
Python Request
headers = {
'Authorization': f'Bearer {apiKey}',
'Accept': 'text/event-stream',
'Content-Type': 'application/json;charset=utf-8'}
data = {
"order": {
'field_mask=up.uplink_message.decoded_payload'
}
}
response = requests.get(url, headers=headers)
print(response.status_code)
print(response.text)
you can try use this tool - https://curlconverter.com/
import os
import requests
API_KEY = os.getenv('API_KEY')
headers = {
'Authorization': f"Bearer {API_KEY}",
'Accept': 'text/event-stream',
}
params = (
('limit', '10'),
('after', '2020-08-20T00:00:00Z'),
('field_mask', 'up.uplink_message.decoded_payload'),
)
response = requests.get('https://thethings.example.com/api/v3/as/applications//packages/storage/uplink_message', headers=headers, params=params)

convert curl command to a Python request command

I am trying to convert the following curl command to Python request command:
curl 'https://api.test.com/v1/data/?type=name&status=active' -H 'Authorization: apikey username:api_key_value'
I have tried a lot of possible solutions like the one below but nothing is working and I am getting a'401' code:
url = "https://api.test.com/v1/data/?type=name&status=active"
headers = {"content-type": "application/json", "Accept-Charset": "UTF-8"}
params = (
(username, api_key_value),
)
data = requests.get(url, headers=headers, params=params).json
print(data)
Params specifies the URL parameters. The Authorization thing is just another header. And response.json is a function.
url = "https://api.test.com/v1/data/"
headers = {
"content-type": "application/json",
"Accept-Charset": "UTF-8",
"Authorization": "apikey {0}:{1}".format(username, api_key_value)
}
params = { 'type': 'name', 'status': 'active' }
data = requests.get(url, headers=headers, params=params).json()
print(data)

How to verify outgoing HTTP request from python's module?

I need to write Python equivalent code for below mentioned working curl(I have replaced the credentials for obvious reason, but it gives back 200 status.).
curl -X POST \
'https://api.lever.co/v1/candidates?dedupe=true&perform_as=user_123' \
-H 'Authorization: Basic token_123' \
-H 'Cache-Control: no-cache' \
-H 'Content-Type: multipart/form-data' \
-H 'Postman-Token: 58cafa90-7ae4-47db-a144-4e9d430ffc94' \
-H 'content-type: multipart/form-data; boundary=----WebKitFormBoundary7MA4YWxkTrZu0gW' \
-F 'files[]=#/Users/gaurav/lever_resume.pdf' \
-F 'emails[]=a#b.com'
So, I ended up in writing this snippet.
user_email = 'user#domain.com'
admin_id = '20f3975a-543f-4ca8-b215-2f851232a0ad'
client_id = '893728937298'
client_secret = '32032'
file_path = '/Users/ttn/Desktop/a.txt'
file_name = 'a.txt'
logging.basicConfig(level=logging.DEBUG)
url = "https://api.lever.co/v1/candidates"
files = {
'files[]': (file_name, open(file_path,'rb')),
}
auth = HTTPBasicAuth(client_id, client_secret)
querystring = {
"perform_as": admin_id,
"dedupe": 'true'
}
payload = {
'emails[]': user_email
}
headers = {
'Content-Type': "multipart/form-data",
"Cache-Control": "no-cache",
"content-type": "multipart/form-data; boundary=----WebKitFormBoundary7MA4YWxkTrZu0gW"
}
response = requests.post(url,
headers=headers,
params=querystring,
data=payload,
auth=auth,
files=files)
req = response.request
# print(curlify.to_curl(req))
print('\n==== Headers', req.headers)
print('\n==== Body', req.body)
print('\n==== form-data', str(req))
print(response.text)
Question
Since Python version of Curl is not working(giving 502 error instead of 200), so How can I compare the two? Can I generate the Curl out of Python's request`?
Can someone spot mistake in my Python version? I am suspecting some problem at form-data being passed (to collect evidence, I need answer to above question)
Edit
There seems to be a curlify package. But It looks like it does not support distinction between -d and -F parameters.
Try this:
import requests
headers = {
'Authorization': 'Basic token_123',
'Cache-Control': 'no-cache',
'Content-Type': 'multipart/form-data',
'Postman-Token': '58cafa90-7ae4-47db-a144-4e9d430ffc94',
'content-type': 'multipart/form-data; boundary=----WebKitFormBoundary7MA4YWxkTrZu0gW',
}
params = (
('dedupe', 'true'),
('perform_as', 'user_123'),
)
files = {
'files[]': ('/Users/gaurav/lever_resume.pdf', open('/Users/gaurav/lever_resume.pdf', 'rb')),
'emails[]': (None, 'a#b.com'),
}
response = requests.post('https://api.lever.co/v1/candidates', headers=headers, params=params, files=files)
#NB. Original query string below. It seems impossible to parse and
#reproduce query strings 100% accurately so the one below is given
#in case the reproduced version is not "correct".
# response = requests.post('https://api.lever.co/v1/candidates?dedupe=true&perform_as=user_123', headers=headers, files=files)oduced version is not "correct".
# response = requests.post('https://api.lever.co/v1/candidates?dedupe=true&perform_as=user_123', headers=headers, files=files)
Reference: https://curl.trillworks.com/#python

How to format a python" requests" that has a parameter

I am writing a python script to using an API to pull down JSON data using requests.
A cleaned up snippet from the CURL that works is (with altered key and URL):
curl -G -H 'key: wwwxxxx' -H 'Content-Type: application/json' --data-urlencode 'from=2017-01-01 12:00:00' https://sampleurl/target1
How do I handle the "--data-urlencode 'from=2017-01-01 12:00:00'" ?
I think the code would be:
import requests
headers = {
'key': 'wwwxxxx',
'Content-Type': 'application/json',
}
url = 'https://sampleurl/target1'
data = requests.get(url, headers=headers)
Thanks in advance for any help!
UPDATE
I tried the DATA suggested by zwer, but that threw a 404 error.
They i just tried to add the parameter as a header pair and it worked!!!
So the code that works is:
import requests
headers = {
'key': 'wwwxxxx',
'Content-Type': 'application/json',
'from' : '2017-01-01 12:00:00'
}
url = 'https://sampleurl/target1'
data = requests.get(url, headers=headers)
Just use the data parameter:
import requests
headers = {
'key': 'wwwxxxx',
'Content-Type': 'application/json',
}
url = 'https://sampleurl/target1'
data = requests.get(url, headers=headers, data={"from": "2017-01-01 12:00:00"})

Categories

Resources