Hi I am using urrlib2 to send some data and custom headers to a link. Am getting 500 internal server error. I have contacted the service, and they are saying the data(json data) is correct but there is some error in my python code. What am I doing wrong ?
Following is the code.
import urllib2,urllib
import json
PREPAYMENT_URL = "https://services.gharpay.in/rest/GharpayService/"
PREPAYMENT_USERNAME = "somename"
PREPAYMENT_PASSWORD = "somepass"
data = {
"customerDetails":{
"address": "ads",
"contactNo": "9663924147",
"email": "a#c.com",
"firstName": "akash",
"lastName": "deshpande",
"prefix": "Mr."
},
"orderDetails" : {
"pincode": "411036",
"clientOrderID": "21234",
"deliveryDate": "13-10-2013",
"orderAmount": "123",
"clientComments": "please be carefull",
"paymentMode": "Cash",
"productDetails": {
"productID": "21334",
"productQuantity": "1",
"unitCost": "123",
"productDescription": "tshirt"
},
"templateID": ""
},
}
def create(request):
function = 'createOrder'
url = PREPAYMENT_URL
url = url+ function
headers= {'username':PREPAYMENT_USERNAME,'password':PREPAYMENT_PASSWORD,'Content-type':'application/json'}
data1 = urllib.urlencode(data)
req = urllib2.Request(url,data1,headers)
try:
contents = urllib2.urlopen(req).read()
except urllib2.HTTPError as e:
error_message = e.read()
print error_message # this error message is being printed. It is showing 500 error.
Your code is perfect except for one teensy-weensy detail:
The header should be Content-Type, not Content-type.
Maybe try changing this header and let me know if it works!
Related
I am trying to use the POST method of Amadeus flight availabilities API on Python, but is is still giving me error 400. Any suggestions? Many thanks.
from amadeus import Client, ResponseError, Location
import requests
amadeus = Client(
client_id='My ID',
client_secret='My Secret')
try:
flights = amadeus.get('/v2/shopping/flight-offers',originLocationCode = "GIG",destinationLocationCode = "ATL",departureDate = "2023-01-31",nonStop = "true",travelClass = "BUSINESS",adults = 1)
body = flights.data[0]
print(body)
except ResponseError as error:
print(error)
try:
availability = amadeus.post('/v1/shopping/availability/flight-availabilities', body)
print(availability.result)
except ResponseError as error:
print('headers: ', error.response.request.headers)
print('body: ', error.response.request.params)
As per their API documentation, the body of the second API call needs to be in the following format:
{
"originDestinations": [
{
"id": "1",
"originLocationCode": "BOS",
"destinationLocationCode": "MAD",
"departureDateTime": {
"date": "2021-11-14",
"time": "21:15:00"
}
}
],
"travelers": [
{
"id": "1",
"travelerType": "ADULT"
}
],
"sources": [
"GDS"
]
}
Right now you are just feeding the second call the return from the first, which doesn't seem to be what they're looking for.
You might also need to feed the proper headers, something like:
headers = {"Content-Type": "application/json; charset=utf-8"}
then you would do
response = requests.post(url, headers=headers, json=body)
import requests, json, time
url = 'https://api.kucoin.com/api/v1/orders'
headers = {
"KC-API-KEY": '',
"KC-API-PASSPHRASE": '',
"clientOid": "AAA",
"side": "sell",
"symbol": "BTC-USDT",
"type": "market",
"size": "0.001",
}
response = requests.post(url, headers=headers)
print(response.status_code)
print(response.json())
I am trying to place an order but it isn't working. Am I missing some parameters?
Error:
{'code': '400001', 'msg': 'Please check the header of your request for KC-API-KEY, KC-API-SIGN, KC-API-TIMESTAMP, KC-API-PASSPHRASE'}
According to the official docs, all private request must contain the following headers:
KC-API-KEY
KC-API-SIGN
KC-API-TIMESTAMP
KC-API-PASSPHRASE
KC-API-VERSION
Here is an example of the endpoint to place a order limit:
import base64, hmac, hashlib, json
# constants
API_KEY = "YOUR_API_KEY"
API_SECRET = "YOUR_API_SECRET"
API_PASSPHRASE = "YOUR_API_PASSPHRASE"
url = "https://api.kucoin.com/api/v1/orders"
now = int(time.time() * 1000)
data = {"clientOid": "AAA", "side": "sell", "symbol": "BTC-USDT", "type": "market", "size": "0.001"}
data_json = json.dumps(data)
str_to_sign = str(now) + 'POST' + '/api/v1/orders' + data_json
signature = base64.b64encode(hmac.new(API_SECRET.encode(
'utf-8'), str_to_sign.encode('utf-8'), hashlib.sha256).digest())
passphrase = base64.b64encode(hmac.new(API_SECRET.encode(
'utf-8'), API_PASSPHRASE.encode('utf-8'), hashlib.sha256).digest())
headers = {
"KC-API-SIGN": signature,
"KC-API-TIMESTAMP": str(now),
"KC-API-KEY": API_KEY,
"KC-API-PASSPHRASE": passphrase,
"KC-API-KEY-VERSION": "2",
"Content-Type": "application/json"
}
try:
res = requests.post(
url, headers=headers, data=data_json).json()
print(res)
except Exception as err:
print(err)
Hope it will help.
Did you consider using wrapped library like Python-kucoin ?
https://python-kucoin.readthedocs.io/en/stable/index.html
it is really great and will definitely help you. Have a look to the documentation
from kucoin.client import Client
api_key = '<api_key>'
api_secret = '<api_secret>'
api_passphrase = '<api_passphrase>'
client = Client(api_key, api_secret, api_passphrase)
# place a market buy order
order = client.create_market_order('BTC-USDT', Client.SIDE_BUY, size=0.001)
try removing the spaces from :
data = {"clientOid": "AAA", "side": "sell", "symbol": "BTC-USDT", "type": "market", "size": "0.001"}
This is my first time messing with APIs. I wrote some code to get data from USASpending's API using a 'GET' call and it works. I'm now trying to get data from another endpoint that only has 'post' capability. The code below returns the '400' response. I'm not sure what I need to change to get the output to be produced. I don't know if it matters but this endpoint produces a zip file.
import requests
payload = {"award_levels":["prime_awards"],"filters":{"award_types":["contracts","direct_payments","grants","idvs","loans","other_financial_assistance"],"agency":"United States Mint","date_type":"action_date","date_range":{"start_date":"2019-01-01","end_date":"2019-01-31"}},"columns":[],"file_format":"csv"}
response = requests.post('https://api.usaspending.gov/api/v2/bulk_download/awards/', params = payload).json()
Thanks in advance
Update:
This is what I finally used. I have the date as dynamic so I can automate this pull monthly using task scheduler. If you want to pull a specific date, remove the date variable reference in the header declaration and run.
pl_str1 = """{
"filters": {
"prime_award_types": [
"A",
"B",
"C",
"D",
"IDV_A",
"IDV_B",
"IDV_B_A",
"IDV_B_B",
"IDV_B_C",
"IDV_C",
"IDV_D",
"IDV_E",
"02",
"03",
"04",
"05",
"10",
"06",
"07",
"08",
"09",
"11"],
"agency": 54,
"date_type": "action_date","""
# Inserting date_range variable into API call
pl_str2 = '"date_range": {"start_date":' + date_3Months_prior +', "end_date":' + date_today + '}'
pl_str3 = """},
"columns": [],
"file_format": "csv"}"""
desired_payload = pl_str1 + pl_str2 + pl_str3
# $$$$$$$$$$$$$$$$$$$$$$$$$$$ REQUESTING DESIRED INFO FROM THE API HERE $$$$$$
url = 'https://api.usaspending.gov/api/v2/bulk_download/awards/'
headers = {'Content-Type': 'application/json'}
resp = requests.post(url, headers=headers, data=desired_payload)
if resp.status_code == 200:
print('success')
print(resp.content)
else:
print('fail')
# API returns a zip file; grabbing that
# This will turn the API response into a string I can use regex on
test = resp.content.decode('UTF-8')
# Extracting url for zip we want to retrieve
test2 = re.findall(r"file_url\S+\.zip", test)[0]
test3 = re.findall(r"https\S+\.zip", test2)[0]
import zipfile
import io
import time
r = requests.get(test3)
# add sleep in case it takes a while for the API to return stuff; not sure if
# but just in case
time.sleep(5)
z = zipfile.ZipFile(io.BytesIO(r.content))
z.extractall()
params are the query parameters in the URL.
e.g
www.stackoverflow.com?parameter=test
This can be expressed as
payload = {
"parameter": "test"
}
POST request has a body, This is the same data that would've been sent if you were posting from a form, You're sending a body, You have some parameters in requests module function .post that deal with the body, You can either use data=payload or json=payload, See the official documentation on this.
When you run this url (https://api.usaspending.gov/api/v2/bulk_download/awards/) in browser and fill form with your request. You will get respons like this
{
"detail": "Missing one or more required body parameters: prime_award_types or sub_award_types"
}
Add fliters, data_range, data_type , agency,prime_award_types
Your request should be like this:
{
"filters": {
"date_range": {
"start_date": "2019-01-01",
"end_date": "2019-12-31"
},
"date_type": "action_date",
"agency": 50,
"prime_award_types": [
"02",
"03",
"04",
"05",
"A",
"B",
"C",
"D"
],
"award_levels": [
"prime_awards"
],
"filters": {
"award_types": [
"contracts",
"direct_payments",
"grants",
"idvs",
"loans",
"other_financial_assistance"
],
"agency": "United States Mint",
"date_type": "action_date",
"date_range": {
"start_date": "2019-01-01",
"end_date": "2019-01-31"
}
},
"columns": [],
"file_format": "csv"
}
}
Get form data in function and send it an other function with request.
import requests
from flask import Flask, return , request,
#videos.route("/ajaxprocess", methods=["GET","POST"])
def ajaxprocess():
if request.method =="POST":
text = request.form.get('text_text')
font = request.form.get('font_text')
color = request.form.get('color_text')
start_text = request.form.get('start_text')
end_text = request.form.get('end_text')
video_id = request.form.get('vid')
all_data = {'status':'OK','text':text,'font':font,'color':color,'start_text':start_text,'end_text':end_text,'vid':video_id}
r = requests.post("http://127.0.0.1:5000/videos/test_text",json=all_data)
print(r)
return redirect(url_for("videos.show_videos"))
#videos.route("/test_text", methods = ['POST'])
def test_text():
data = request.get_json("")
print(data)
return "success!"
I'm using requests lib to fetch data from remote server and I'm saving the data in the model, but I need to handle pagination, currently I'm only loading one page from server.
I have a url for pagination like so
{
"status": "success",
"count": 32,
"total": 32,
"next": "https://pimber.ly/api/v2/products?sinceId=5c3ca8470985af0016229b5b",
"previous": "https://pimber.ly/api/v2/products?maxId=5c3ca8470985af0016229b04",
"sinceId": "5c3ca8470985af0016229b04",
"maxId": "5c3ca8470985af0016229b5b",
"data": [
{
"Primary ID": "API_DOCS_PROD1",
"Product Name": "Example Product 1",
"Product Reference": "Example Reference 1",
"Buyer": "Example Buyer 1",
"_id": "5c3ca8470985af0016229b04",
"primaryId": "API_DOCS_PROD1"
},
I've tried to use python generator to handle current situation but, that does not do anything
_plimber_data = response.json()
yield _plimber_data
_next = _plimber_data['next']
print(_next)
for page in _next:
_next_page = session.get(_plimber_data, params={'next': page}).json()
yield _next_page['next']
for _data in page:
Product.objects.create(
qr_id=_data['primaryId'],
ean_code=_data['EAN'],
description=_data['Description105'],
category=_data['Category'],
marketing_text=_data['Marketing Text'],
bullet=_data['Bullet 1'],
brand_image=_data['Brand Image'],
image=_data['Images']
)
logger.debug(f'Something went wrong {_data}')
print(f'This is the Data:{_data}')
Can someone please explain me how to handle this so I can load all the data into the database, thanks.
Ok so I've solved it, two thinks first generator function
def _get_product():
"""
TODO: Fetch data from server
"""
headers = {
'Accept': 'application/json',
'Content-Type': 'application/json',
'Authorization': settings.TOKEN
}
try:
response = requests.get(
url=f'{settings.API_DOMAIN}',
headers=headers
)
response.raise_for_status()
except HTTPError as http_err:
print(f'HTTP error occurred: {http_err}')
else:
_plimber_data = response.json()
while _plimber_data['next'] is not None:
response = requests.get(
_plimber_data['next'],
headers=headers
)
_plimber_data = response.json()
for _data in _plimber_data['data']:
yield _data
Then I iterate over generator function, and save the data:
def run(self):
_page_data = _get_product()
for _product in _page_data:
Product.objects.create(
qr_id=_product['primaryId'],
ean_code=_product['EAN'],
description=_product['Description105'],
category=_product['Category'],
marketing_text=_product['Marketing Text'],
bullet=_product['Bullet 1'],
brand_image='\n'.join(_product['Brand Image']),
image='\n'.join(_product['Images'])
)
logger.debug(f'Something went wrong {_product}')
print(f'This is the Data:{_product}')
I am facing this error while making request to fetch json from api.
I can get json data using the "/v1/articles' path.
conn = http.client.HTTPSConnection("api.xxxx.com.tr")
headers = {
'accept': "application/json",
'apikey': "cd6b6c96799847698d87dec9f9a731d6"
}
filter = "daily"
conn.request("GET", "/v1/articles", headers=headers)
reader = codecs.getreader("utf-8")
res = conn.getresponse()
data = json.load(reader(res))
json.dumps(data)
return data
But i am having JSONDecodeError if i set filter. Code:
conn = http.client.HTTPSConnection("api.xxxx.com.tr")
headers = {
'accept': "application/json",
'apikey': "cd6b6c96799847698d87dec9f9a731d6"
}
conn.request("GET", "/v1/articles?$filter=Path eq '/daily/'", headers=headers)
reader = codecs.getreader("utf-8")
res = conn.getresponse()
data = json.load(reader(res))
json.dumps(data)
return data
I tried same filter using Postman with no error and i can get Json data.
Returned Json data from Postman:
[
{
"Id": "40778196",
"ContentType": "Article",
"CreatedDate": "2018-03-20T08:28:05.385Z",
"Description": "İspanya'da 2016 yılında çalınan lüks otomobil, şasi numarası değiştirilerek Bulgaristan üzerinden getirildiği Türkiye'de bulundu.",
"Files": [
{
"FileUrl": "http://i.xxxx.com/i/xxxx/98/620x0/5ab0c6a9c9de3d18a866eb54.jpg",
"Metadata": {
"Title": "",
"Description": ""
}
}
],
"ModifiedDate": "2018-03-20T08:32:12.001Z",
"Path": "/gundem/",
"StartDate": "2018-03-20T08:32:12.001Z",
"Tags": [
"ispanya",
"Araç",
"Hırsız",
"Dolandırıcı"
],
"Title": "İspanya'da çalınan lüks araç Türkiye'de bulundu!",
"Url": "http://www.xxxx.com.tr/gundem/ispanyada-calinan-luks-arac-turkiyede-bulundu-40778196"
}
]
I can not figure out the problem. It would be great if anyone help me about this issue. Thank you.
I finally figured out the problem! Using the requests library have solved my problem now I can filter the api request.
data = requests.get('https://api.xxxxx.com.tr/v1/articles', headers =
headers, params={"$filter":"Path eq '/xxxxxx/'"}).json()
I am leaving this answer here for anyone else who can need this solution in the future.
Thanks for all your suggestions.
The problem is in the following line
data = json.load(reader(res))
when your response is not a json string, JSONDecodeError occurs. so, add an additional logic to see if the response is None or a json string. First thing, print the reader(res) and see what the return is