Python requests.post, cant use a file as "data" variable - python

headers = {
"User-Agent": "Mozilla/5.0",
'accept': 'application/json',
'Content-Type': 'application/json',
}
with open("jsonattempt.txt","r") as f:
data = f.read()
json_data = "'" + data + "'"
response = requests.post('https://www.pathofexile.com/api/trade/search/Standard', headers=headers, data=json_data)
print(response)
Generally, there is a curl request like this:
curl -X 'POST' \
'https://www.pathofexile.com/api/trade/search/Standard' \
-H 'accept: application/json' \
-H 'Content-Type: application/json' \
-d '{
"query": {
"status": {
"option": "online"
},
"type": "Turquoise Amulet",
"stats": [
{
"type": "and",
"filters": [
{
"id": "pseudo.pseudo_total_mana",
"value": {
"min": 47,
"max": 49
},
"disabled": false
}
]
}
]
},
"sort": {
"price": "asc"
}
}'
Which returns a bunch of unnecessary things.
My json_data variable and jsonattempt.txt is the same as -d parameter, I add ' ' to start and to end:
{
"query": {
"status": {
"option": "online"
},
"type": "Turquoise Amulet",
"stats": [
{
"type": "and",
"filters": [
{
"id": "pseudo.pseudo_total_mana",
"value": {
"min": 47,
"max": 49
},
"disabled": false
}
]
}
]
},
"sort": {
"price": "asc"
}
}
I convert curl request to python which is the code on the top, I add the data as json_data and yeet the post request but keep getting 400 Bad Request.
Request 401 is Unauthorized AFAIK, so I dont need an OAuth2 key for this. How can I insert my json file appropiately to the request?
(Same exact json works on https://app.swaggerhub.com/apis-docs/Chuanhsing/poe/1.0.0#/Trade/get_api_trade_fetch__items_ I am just asking how to insert my json file to requests.post correctly.)

Why are you adding quotes around the JSON content? That doesn't make any sense. Those quotes aren't part of your curl request. If you just write...
import requests
headers = {
"User-Agent": "Mozilla/5.0",
"accept": "application/json",
"Content-Type": "application/json",
}
with open("jsonattempt.txt", "r") as f:
data = f.read()
response = requests.post(
"https://www.pathofexile.com/api/trade/search/Standard",
headers=headers,
data=data,
)
print(response)
...it works as expected.
And in fact you can further simplify that; you don't need to read in the file data yourself, you can let requests do that:
import requests
headers = {
"User-Agent": "Mozilla/5.0",
"accept": "application/json",
"Content-Type": "application/json",
}
with open("jsonattempt.txt", "r") as f:
response = requests.post(
"https://www.pathofexile.com/api/trade/search/Standard",
headers=headers,
data=f,
)
print(response)

import json
# some codes here
with open("jsonattempt.txt","r") as f:
data = f.read()
json_data = json.loads(data)
# rest of codes here
Your request requires json type data, while you are passing a string. The json.loads method converts string to json. Try it out.

Related

Convert curl send file to python request

For anonfiles, they only give the curl function to upload a file,
curl -F "file=#test.txt" https://api.anonfiles.com/upload
and I want to use python requests for this.
I tried
import requests
data = requests.put(url = "https://api.anonfiles.com/upload",data=open('file.txt','r').read() )
print(data.text)
Try:
import requests
with open('test.txt', 'rb') as fp:
r = requests.post('https://api.anonfiles.com/upload', files={'file': fp})
print(r.json())
Output:
{
"status": true,
"data": {
"file": {
"url": {
"full": "https://anonfiles.com/oa28JcS2ya/test_txt",
"short": "https://anonfiles.com/oa28JcS2ya"
},
"metadata": {
"id": "oa28JcS2ya",
"name": "test.txt",
"size": {
"bytes": 580,
"readable": "580 B"
}
}
}
}
}
More information here: POST a Multipart-Encoded File

Trying to place an order on Oanda using Python Requests. Getting JSON error

I am trying to place an Fx order using Python and the Oanda api.
from requests import post
headers = {
"Content-Type": "application/json",
"Authorization": "Bearer <auth code>"
}
data = {
"order": {
"units": "100",
"instrument": "EUR_USD",
"timeInForce": "FOK",
"type": "MARKET",
"positionFill": "DEFAULT"
}
}
#Practice Account
r = post(
"https://api-fxpractice.oanda.com/v3/accounts/<acct #>/orders",
headers=headers,
data=data
)
print(r.text)
I get the following error:
Invalid JSON, ParseErrorCode: 3, Message: Invalid value.
Does anyone know what the error means?
Here is the example CURL code from their website:
body=$(cat << EOF
{
"order": {
"units": "100",
"instrument": "EUR_USD",
"timeInForce": "FOK",
"type": "MARKET",
"positionFill": "DEFAULT"
}
}
EOF
)
curl \
-X POST \
-H "Content-Type: application/json" \
-H "Authorization: Bearer <AUTHENTICATION TOKEN>" \
-d "$body" \
"https://api-fxtrade.oanda.com/v3/accounts/<ACCOUNT>/orders"
You must encode the dictionary with json.dumps. I also removed the quotes from the value.
Here's the code:
from requests import post
import json
headers = {
"Content-Type": "application/json",
"Authorization": "Bearer <auth code>"
}
data = {
"order": {
"units": 10,
"instrument": "EUR_USD",
"timeInForce": "FOK",
"type": "MARKET",
"positionFill": "DEFAULT"
}
}
data = json.dumps(data)
#Practice Account
r = post(
"https://api-fxpractice.oanda.com/v3/accounts/<acct #>/orders",
headers=headers,
data=data
)
print(r.text)

Curl to Python using the Request library

I'm trying to translate Curl to Python, but I'm getting something wrong. Please help.
CURL:
body=$(cat << EOF
{
"order": {
"units": "-100",
"instrument": "EUR_USD",
"timeInForce": "FOK",
"type": "MARKET",
"positionFill": "DEFAULT"
}
}
EOF
)
curl \
-X POST \
-H "Content-Type: application/json" \
-H "Authorization: Bearer <AUTHENTICATION TOKEN>" \
-d "$body" \
"https://api-fxtrade.oanda.com/v3/accounts/<ACCOUNT>/orders"
PYTHON:
import requests
import json
def market_buy():
header = {"Accept": "application/json",
"Authorization": "Bearer <my auth code>"
}
data = {
"order": {
"units": "100",
"instrument": "EUR_USD",
"timeInForce": "FOK",
"type": "MARKET",
"positionFill": "DEFAULT"
}
}
url = "https://api-fxtrade.oanda.com/v3/accounts/<myaccount>/orders"
r = requests.post(url, data=data, headers=header)
print(r.text)
market_buy()
Error Message:
{"errorMessage":"Insufficient authorization to perform request."}
I've double-checked my credentials. I'm thinking something is wrong with the code.
A direct translation from cURL to Python requests would be this:
from requests import post
headers = {
"Content-Type": "application/json",
"Authorization": "Bearer <AUTHENTICATION TOKEN>",
}
data = {
"order": {
"units": "100",
"instrument": "EUR_USD",
"timeInForce": "FOK",
"type": "MARKET",
"positionFill": "DEFAULT",
}
}
post(
"https://api-fxtrade.oanda.com/v3/accounts/<myaccount>/orders",
headers=headers,
data=data,
)
I guess you are missing the SSL cert verification and basic authentication.
You can turn off SSL cert verification with the verify flag, and use basic authentication by specifying auth.
from requests.auth import HTTPBasicAuth
import requests
import json
def market_buy():
header = {"Accept": "application/json",
"Authorization": "Bearer <my auth code>"
}
data = {
"order": {
"units": "100",
"instrument": "EUR_USD",
"timeInForce": "FOK",
"type": "MARKET",
"positionFill": "DEFAULT"
}
}
url = "https://api-fxtrade.oanda.com/v3/accounts/<myaccount>/orders"
r = requests.post(url, data=data, headers=header, auth=HTTPBasicAuth('admin', 'admin'), verify=False)
print(r.text)
market_buy()
I guess the above should work.

Convert curl POST statement with JSON payload to Python request

I can run this curl statemtent with curl and works perfectly. I have read many post but nothing works.
curl -X POST "http://some.website.com" -H "accept: application/json" -H "authorization: Basic authcode" -H "Content-Type: application/json" -d "{ \"Fields\": [ \"string\" ], \"Filters\": [ { \"Field\": \"Item\", \"Operator\": \"=\", \"Value\": \"119001\" } ], \"PageSize\": 0, \"PageNumber\": 0}"
code tried so far
import requests
session = requests.Session()
url = 'http://some.website.com'
headers = {'accept': 'application/json', 'authorization': 'Basic authcode', 'Content-Type': 'application/json'}
data = {'Fields': 'string', 'Filters': { 'Field': 'Item', 'Operator': '=', 'Value': '119001' }, 'PageSize': 0, 'PageNumber': 0}
response = session.post(url, headers=headers, data=data)
print(response.status_code)
print(response.json())
Error = not valid JSON Value
I have also tried
import simplejson as json
# ...
# ...
response = session.post(url, headers=headers, data=json.dumps(data))
# ...
# ...
Failed = Error detecting JSON fields
I think it has something to do with the nested dict statement
Using https://httpbin.org/post I can see what data (headers and body) are received on server and I see the same result for curl
curl -X POST "http://httpbin.org/post" -H "accept: application/json" -H "authorization: Basic authcode" -H "Content-Type: application/json" -d "{\"Fields\": [\"string\"], \"Filters\": [{\"Field\": \"Item\", \"Operator\": \"=\", \"Value\": \"119001\"}], \"PageSize\": 0, \"PageNumber\": 0}"
# result
{
"args": {},
"data": "{\"Fields\": [\"string\"], \"Filters\": [{\"Field\": \"Item\", \"Operator\": \"=\", \"Value\": \"119001\"}], \"PageSize\": 0, \"PageNumber\": 0}",
"files": {},
"form": {},
"headers": {
"Accept": "application/json",
"Authorization": "Basic authcode",
"Content-Length": "122",
"Content-Type": "application/json",
"Host": "httpbin.org",
"User-Agent": "curl/7.58.0"
},
"json": {
"Fields": [
"string"
],
"Filters": [
{
"Field": "Item",
"Operator": "=",
"Value": "119001"
}
],
"PageNumber": 0,
"PageSize": 0
},
"origin": "83.23.32.69, 83.23.32.69",
"url": "https://httpbin.org/post"
}
and Python (using json=data or data=json.dumps(data) instead of data=data)
import requests
headers = {
'Accept': 'application/json',
'Authorization': 'Basic authcode',
# 'Content-Type': 'application/json',
# 'User-Agent': 'Mozilla/5.0',
}
data = {
"Fields": [ "string" ],
"Filters": [ { "Field": "Item", "Operator": "=", "Value": "119001" } ],
"PageSize": 0,
"PageNumber": 0
}
response = requests.post('https://httpbin.org/post', headers=headers, json=data)
print(response.text)
# result
{
"args": {},
"data": "{\"Fields\": [\"string\"], \"Filters\": [{\"Field\": \"Item\", \"Operator\": \"=\", \"Value\": \"119001\"}], \"PageSize\": 0, \"PageNumber\": 0}",
"files": {},
"form": {},
"headers": {
"Accept": "application/json",
"Accept-Encoding": "gzip, deflate",
"Authorization": "Basic authcode",
"Content-Length": "122",
"Content-Type": "application/json",
"Host": "httpbin.org",
"User-Agent": "python-requests/2.22.0"
},
"json": {
"Fields": [
"string"
],
"Filters": [
{
"Field": "Item",
"Operator": "=",
"Value": "119001"
}
],
"PageNumber": 0,
"PageSize": 0
},
"origin": "83.23.32.69, 83.23.32.69",
"url": "https://httpbin.org/post"
}
There are only differences in headers: "User-Agent": "curl/7.58.0" and "User-Agent": "python-requests/2.22.0". And Python uses "Accept-Encoding": "gzip, deflate".
BTW: you can use portal curl.trillworks.com to convert curl to Python code

Making a request to a RESTful API using Python

I have a RESTful API that I have exposed using an implementation of Elasticsearch on an EC2 instance to index a corpus of content. I can query the search by running the following from my terminal (MacOSX):
curl -XGET 'http://ES_search_demo.com/document/record/_search?pretty=true' -d '{
"query": {
"bool": {
"must": [
{
"text": {
"record.document": "SOME_JOURNAL"
}
},
{
"text": {
"record.articleTitle": "farmers"
}
}
],
"must_not": [],
"should": []
}
},
"from": 0,
"size": 50,
"sort": [],
"facets": {}
}'
How do I turn above into a API request using python/requests or python/urllib2 (not sure which one to go for - have been using urllib2, but hear that requests is better...)? Do I pass as a header or otherwise?
Using requests:
import requests
url = 'http://ES_search_demo.com/document/record/_search?pretty=true'
data = '''{
"query": {
"bool": {
"must": [
{
"text": {
"record.document": "SOME_JOURNAL"
}
},
{
"text": {
"record.articleTitle": "farmers"
}
}
],
"must_not": [],
"should": []
}
},
"from": 0,
"size": 50,
"sort": [],
"facets": {}
}'''
response = requests.post(url, data=data)
Depending on what kind of response your API returns, you will then probably want to look at response.text or response.json() (or possibly inspect response.status_code first). See the quickstart docs here, especially this section.
Using requests and json makes it simple.
Call the API
Assuming the API returns a JSON, parse the JSON object into a
Python dict using json.loads function
Loop through the dict to extract information.
Requests module provides you useful function to loop for success and failure.
if(Response.ok): will help help you determine if your API call is successful (Response code - 200)
Response.raise_for_status() will help you fetch the http code that is returned from the API.
Below is a sample code for making such API calls. Also can be found in github. The code assumes that the API makes use of digest authentication. You can either skip this or use other appropriate authentication modules to authenticate the client invoking the API.
#Python 2.7.6
#RestfulClient.py
import requests
from requests.auth import HTTPDigestAuth
import json
# Replace with the correct URL
url = "http://api_url"
# It is a good practice not to hardcode the credentials. So ask the user to enter credentials at runtime
myResponse = requests.get(url,auth=HTTPDigestAuth(raw_input("username: "), raw_input("Password: ")), verify=True)
#print (myResponse.status_code)
# For successful API call, response code will be 200 (OK)
if(myResponse.ok):
# Loading the response data into a dict variable
# json.loads takes in only binary or string variables so using content to fetch binary content
# Loads (Load String) takes a Json file and converts into python data structure (dict or list, depending on JSON)
jData = json.loads(myResponse.content)
print("The response contains {0} properties".format(len(jData)))
print("\n")
for key in jData:
print key + " : " + jData[key]
else:
# If response code is not ok (200), print the resulting http error code with description
myResponse.raise_for_status()
Below is the program to execute the rest api in python-
import requests
url = 'https://url'
data = '{ "platform": { "login": { "userName": "name", "password": "pwd" } } }'
response = requests.post(url, data=data,headers={"Content-Type": "application/json"})
print(response)
sid=response.json()['platform']['login']['sessionId'] //to extract the detail from response
print(response.text)
print(sid)
So you want to pass data in body of a GET request, better would be to do it in POST call. You can achieve this by using both Requests.
Raw Request
GET http://ES_search_demo.com/document/record/_search?pretty=true HTTP/1.1
Host: ES_search_demo.com
Content-Length: 183
User-Agent: python-requests/2.9.0
Connection: keep-alive
Accept: */*
Accept-Encoding: gzip, deflate
{
"query": {
"bool": {
"must": [
{
"text": {
"record.document": "SOME_JOURNAL"
}
},
{
"text": {
"record.articleTitle": "farmers"
}
}
],
"must_not": [],
"should": []
}
},
"from": 0,
"size": 50,
"sort": [],
"facets": {}
}
Sample call with Requests
import requests
def consumeGETRequestSync():
data = '{
"query": {
"bool": {
"must": [
{
"text": {
"record.document": "SOME_JOURNAL"
}
},
{
"text": {
"record.articleTitle": "farmers"
}
}
],
"must_not": [],
"should": []
}
},
"from": 0,
"size": 50,
"sort": [],
"facets": {}
}'
url = 'http://ES_search_demo.com/document/record/_search?pretty=true'
headers = {"Accept": "application/json"}
# call get service with headers and params
response = requests.get(url,data = data)
print "code:"+ str(response.status_code)
print "******************"
print "headers:"+ str(response.headers)
print "******************"
print "content:"+ str(response.text)
consumeGETRequestSync()

Categories

Resources