I'm finding the Kraken Futures API confusing compared to other providers. Using a demo account I'm trying to make basic private requests and not working so far with authentication error. The code mainly comes from Kraken docs (non-futures)
Futures auth doc: https://support.kraken.com/hc/en-us/articles/360022635592-Generate-authentication-strings-REST-API-
api_sec = "MxA2FwIQxCxsfy2XDa4R8PwTjwLKjzT8GSOw+qOVuWGh3Lx6PtyW0f94J5XXKz9mP8bztRJSDQJVKBsHFicrDr/N"
api_url = "https://futures.kraken.com/derivatives/api/v3"
api_key = 'Y7kVv/hW0JWRRAhJtA8BuJkUX+E0gWmTL5NWf4lRPN8f+iYoJp9AoYwW'
def get_kraken_signature(urlpath, data, secret):
postdata = urllib.parse.urlencode(data)
encoded = (str(data['nonce']) + postdata).encode()
message = urlpath.encode() + hashlib.sha256(encoded).digest()
mac = hmac.new(base64.b64decode(secret), message, hashlib.sha256)
sigdigest = base64.b64encode(mac.digest())
return sigdigest.decode()
# Attaches auth headers and returns results of a get request
def kraken_request(uri_path, data, api_key, api_sec):
headers = {}
headers['API-Key'] = api_key
# get_kraken_signature() as defined in the 'Authentication' section
headers['API-Sign'] = get_kraken_signature(uri_path, data, api_sec)
req = requests.get((api_url + uri_path), headers=headers, data=data)
return req
# Construct the request and print the result
resp = kraken_request('/accounts', {
"nonce": str(int(1000*time.time()))
}, api_key, api_sec)
Output
{"result":"error","error":"authenticationError","serverTime":"2022-05-13T10:14:50.838Z"}
Related
I need to use a socket stream API or any tools you know to get historical and live prices from my broker(Deriv) to my system server were the program will be hosted. Thank you in advance
I use huobi api to build my bot.. below are some working codes:
import requests
import json
import hmac
import hashlib
import base64
from urllib.parse import urlencode
import time
base_uri = 'api.huobi.pro'
AccessKeyId = 'xxxxxx'
SecretKey = 'xxxxxx'
account_id = '11111111'
def get_url(method, endpoint):
timestamp = str(datetime.utcnow().isoformat())[0:19]
params = urlencode({'AccessKeyId': AccessKeyId, 'SignatureMethod': 'HmacSHA256', 'SignatureVersion': '2', 'Timestamp': timestamp})
pre_signed_text = method + '\n' + base_uri + '\n' + endpoint + '\n' + params
hash_code = hmac.new(SecretKey.encode(), pre_signed_text.encode(), hashlib.sha256).digest()
signature = urlencode({'Signature': base64.b64encode(hash_code).decode()})
return 'https://' + base_uri + endpoint + '?' + params + '&' + signature
def get_all_open_orders():
url = get_url('GET', '/v1/order/openOrders')
response = requests.request('GET', url, headers={}, data={})
return json.loads(response.text)['data']
def place_new_order(data): #for both buy/sell
url = get_url('POST', '/v1/order/orders/place')
response = requests.request('POST', url, headers={'Content-Type': 'application/json'}, data=data)
return json.loads(response.text)
def cancel_order(order_id):
url = get_url('POST', '/v1/order/orders/{}/submitcancel'.format(order_id))
response = requests.request('POST', url, headers={}, data={})
return json.loads(response.text)
To get current price
SYMBOL = 'xrphusd'
url = 'https://api.huobi.pro/market/history/kline?period=1min&size=1&symbol=' + SYMBOL
response = requests.request('GET', url, headers={}, data={})
print(json.loads(response.text)['data'][0])
To place an order (can be 'buy-limit' or 'sell-limit')
price = "1.25"
quantity = "100"
payload = {"account-id": str(account_id), "amount": quantity, "price": price, "source": "api", "symbol": SYMBOL, "type": "buy-limit"}
status = place_new_order(json.dumps(payload))
print(status)
Documentation available here https://huobiapi.github.io/docs/spot/v1/en
I'm a beginner with Python and trying to build a service that takes information from api.ai, passes it to an API, then returns a confirmation message from the JSON it returns.
app.py:
#!/usr/bin/env python
from __future__ import print_function
from future.standard_library import install_aliases
install_aliases()
from urllib.parse import urlparse, urlencode
from urllib.request import urlopen, Request
from urllib.error import HTTPError
import json
import os
import sys
import logging
from flask import Flask, render_template
from flask import request
from flask import make_response
# Flask app should start in global layout
app = Flask(__name__)
app.logger.addHandler(logging.StreamHandler(sys.stdout))
app.logger.setLevel(logging.ERROR)
#app.route('/webhook', methods=['POST'])
def webhook():
req = request.get_json(silent=True, force=True)
print("Request:")
print(json.dumps(req, indent=4))
res = processRequest(req)
res = json.dumps(res, indent=4)
# print(res)
r = make_response(res)
r.headers['Content-Type'] = 'application/json'
return r
def processRequest(req):
if req.get("result").get("action") != "bookMyConference":
return {}
#oauth
orequest = req.get("originalRequest") # work down the tree
odata = orequest.get("data") # work down the tree
user = odata.get("user") # work down the tree
access_token = user.get("access_token")
#data
result = req.get("result") # work down the tree
parameters = result.get("parameters") # work down the tree
startdate = parameters.get("start-date")
meetingname = parameters.get("meeting-name")
payload = {
"start-date": startdate,
"end-date": startdate,
"meeting-name": meetingname
}
# POST info to join.me
baseurl = "https://api.join.me/v1/meetings"
p = Request(baseurl)
p.add_header('Content-Type', 'application/json; charset=utf-8')
p.add_header('Authorization', 'Bearer ' + access_token) #from oauth
jsondata = json.dumps(payload)
jsondataasbytes = jsondata.encode('utf-8') # needs to be bytes
jresult = urlopen(p, jsondataasbytes).read()
data = json.loads(jresult)
res = makeWebhookResult(data)
return res
def makeWebhookResult(data):
speech = "Appointment scheduled!"
print("Response:")
print(speech)
return {
"speech": speech,
"displayText": speech,
# "data": data,
"source": "heroku-bookmyconference"
}
if __name__ == '__main__':
port = int(os.getenv('PORT', 5000))
print("Starting app on port %d" % port)
app.run(debug=False, port=port, host='0.0.0.0')
Edit 4: Here's the error I'm getting in my Heroku logs:
2017-03-21T19:06:09.383612+00:00 app[web.1]: HTTPError: HTTP Error
400: Bad Request
Borrowing from here, using urlib modules inside processRequest() you could add your payload to urlopen like this:
req = Request(yql_url)
req.add_header('Content-Type', 'application/json; charset=utf-8')
jsondata = json.dumps(payload)
jsondataasbytes = jsondata.encode('utf-8') # needs to be bytes
result = urlopen(req, jsondataasbytes).read()
data = json.loads(result)
Things get more succinct if using the requests module:
headers = {'content-type': 'application/json'}
result = requests.post(yql_url, data=json.dumps(payload), headers=headers)
data = result.json()
EDIT: Adding some details specific to the join.me api
Looking at the join.me docs you'll need to obtain an access token to add to your header. But you also need an app auth code before you can get an access token. You can get the app auth code manually, or by chaining some redirects.
To get started, try this url in your browser and get the code from the callback params. Using your join.me creds:
auth_url = 'https://secure.join.me/api/public/v1/auth/oauth2' \
+ '?client_id=' + client_id \
+ '&scope=scheduler%20start_meeting' \
+ '&redirect_uri=' + callback_url \
+ '&state=ABCD' \
+ '&response_type=code'
print(auth_url) # try in browser
To get an access token:
token_url = 'https://secure.join.me/api/public/v1/auth/token'
headers = {'content-type': 'application/json'}
token_params = {
'client_id': client_id,
'client_secret': client_secret,
'code': auth_code,
'redirect_uri': callback_url,
'grant_type': 'authorization_code'
}
result = requests.post(token_url, data=json.dumps(token_params), headers=headers)
access_token = result.json().get('access_token')
Then your header for the post to /meetings would need to look like:
headers = {
'content-type': 'application/json',
'Authorization': 'Bearer ' + access_token
}
Netsuite's documentation is not forthcoming. Does anyone have code they've written that will help me generate a valid signature.
There is some sample code in the NetSuite Suite answers site, but you'll have to log in to access it.
https://netsuite.custhelp.com/app/answers/detail/a_id/42165/kw/42165
Here is the code from the answer that I was able to make work. The only difference is that their code broke by trying to encode the timestamp as an int. I typecasted it to a str and the encoding worked fine. The keys/tokens/realm are from their demo code. Insert your own and you should be good to go.
import oauth2 as oauth
import requests
import time
url = "https://rest.netsuite.com/app/site/hosting/restlet.nl?script=992&deploy=1"
token = oauth.Token(key="080eefeb395df81902e18305540a97b5b3524b251772adf769f06e6f0d9dfde5", secret="451f28d17127a3dd427898c6b75546d30b5bd8c8d7e73e23028c497221196ae2")
consumer = oauth.Consumer(key="504ee7703e1871f22180441563ad9f01f3f18d67ecda580b0fae764ed7c4fd38", secret="b36d202caf62f889fbd8c306e633a5a1105c3767ba8fc15f2c8246c5f11e500c")
http_method = "GET"
realm="ACCT123456"
params = {
'oauth_version': "1.0",
'oauth_nonce': oauth.generate_nonce(),
'oauth_timestamp': str(int(time.time())),
'oauth_token': token.key,
'oauth_consumer_key': consumer.key
}
req = oauth.Request(method=http_method, url=url, parameters=params)
signature_method = oauth.SignatureMethod_HMAC_SHA1()
req.sign_request(signature_method, consumer, token)
header = req.to_header(realm)
headery = header['Authorization'].encode('ascii', 'ignore')
headerx = {"Authorization": headery, "Content-Type":"application/json"}
print(headerx)
conn = requests.get("https://rest.netsuite.com/app/site/hosting/restlet.nl?script=992&deploy=1",headers=headerx)
print(conn.text)
Just for reference, I recently did this in Python3 using requests_oauthlib and it worked with standard use of the library:
from requests_oauthlib import OAuth1Session
import json
url = 'https://xxx.restlets.api.netsuite.com/app/site/hosting/restlet.nl?script=xxx&deploy=xxx'
oauth = OAuth1Session(
client_key='xxx',
client_secret='xxx',
resource_owner_key='xxx',
resource_owner_secret='xxx',
realm='xxx')
payload = dict(...)
resp = oauth.post(
url,
headers={'Content-Type': 'application/json'},
data=json.dumps(payload),
)
print(resp)
Building off NetSuite's original sample code I was able to get the below working with SHA256, I think you could do a similar thing for SHA512.
import binascii
import hmac
import time
from hashlib import sha256
import oauth2 as oauth
import requests
url = "https://<account>.restlets.api.netsuite.com/app/site/hosting/restlet.nl?script=<scriptId>&deploy=1"
token = oauth.Token(key="080eefeb395df81902e18305540a97b5b3524b251772adf769f06e6f0d9dfde5",
secret="451f28d17127a3dd427898c6b75546d30b5bd8c8d7e73e23028c497221196ae2")
consumer = oauth.Consumer(key="504ee7703e1871f22180441563ad9f01f3f18d67ecda580b0fae764ed7c4fd38",
secret="b36d202caf62f889fbd8c306e633a5a1105c3767ba8fc15f2c8246c5f11e500c")
http_method = "POST"
realm = "CCT123456"
params = {
'oauth_version': "1.0",
'oauth_nonce': oauth.generate_nonce(),
'oauth_timestamp': str(int(time.time())),
'oauth_token': token.key,
'oauth_consumer_key': consumer.key
}
class SignatureMethod_HMAC_SHA256(oauth.SignatureMethod):
name = 'HMAC-SHA256'
def signing_base(self, request, consumer, token):
if (not hasattr(request, 'normalized_url') or request.normalized_url is None):
raise ValueError("Base URL for request is not set.")
sig = (
oauth.escape(request.method),
oauth.escape(request.normalized_url),
oauth.escape(request.get_normalized_parameters()),
)
key = '%s&' % oauth.escape(consumer.secret)
if token:
key += oauth.escape(token.secret)
raw = '&'.join(sig)
return key.encode('ascii'), raw.encode('ascii')
def sign(self, request, consumer, token):
"""Builds the base signature string."""
key, raw = self.signing_base(request, consumer, token)
hashed = hmac.new(key, raw, sha256)
# Calculate the digest base 64.
return binascii.b2a_base64(hashed.digest())[:-1]
req = oauth.Request(method=http_method, url=url, parameters=params)
oauth.SignatureMethod_HMAC_SHA256 = SignatureMethod_HMAC_SHA256
signature_method = oauth.SignatureMethod_HMAC_SHA256()
req.sign_request(signature_method, consumer, token)
header = req.to_header(realm)
header_y = header['Authorization'].encode('ascii', 'ignore')
header_x = {"Authorization": header_y, "Content-Type": "application/json"}
print(header_x)
response = requests.request("POST", url, data={}, headers=header_x)
# conn = requests.post(url, headers=headerx)
print(response.text)
I am trying to make a Python Wrapper for an API. I have been able to create scripts that work fine but don't use classes. I want to make a real wrapper of that API using classes. I am new to OOP in Python.
Following was my attempt but I am stuck at how to convert it to an OO type.
import urllib2
from urllib import urlencode
import json
class apiclient:
def __init__(self,
request_url,
hmh_api_key,
client_id,
grant_type="password",
username="username",
password="password"):
values = {
"client_id": client_id,
"grant_type": grant_type,
"username": username,
"password": password
}
data = urlencode(values)
req = urllib2.Request(request_url, data)
req.add_header("Api-Key", api_key)
response = urllib2.urlopen(req)
response_header = response.info().dict
response_body = response.read()
json_acceptable_string = response_body.replace("'", "\"")
response_body_dict = json.loads(json_acceptable_string)
return response_body_dict ## this is the response
if __name__ == "__main__":
API_KEY = "75b5cc58a5cdc0a583f91301cefedf0c"
CLIENT_ID = "ef5f7a03-58e8-48d7-a38a-abbd2696bdb6.hmhco.com"
REQUEST_URL = "http://some.url"
client = apiclient(request_url=REQUEST_URL,
api_key=API_KEY,
client_id=CLIENT_ID)
print client
Without classes, I get the response JSON as response_body_dict but with classes I get TypeError: __init__() should return None. How should I start designing my program.
I have shown only a part of the whole program, there are a lot many similar scripts that send requests to URLs and get JSON responses.
Thanks!
You should not return something from __init__ function.
EDIT:
If you need that value you should use the response_body_dict as a class member and get him from other method:
import urllib2
from urllib import urlencode
import json
class apiclient:
def __init__(self,
request_url,
api_key,
client_id,
grant_type="password",
username="username",
password="password"):
values = {
"client_id": client_id,
"grant_type": grant_type,
"username": username,
"password": password
}
data = urlencode(values)
req = urllib2.Request(request_url, data)
req.add_header("Api-Key", api_key)
response = urllib2.urlopen(req)
response_header = response.info().dict
response_body = response.read()
json_acceptable_string = response_body.replace("'", "\"")
self.response_body_dict = json.loads(json_acceptable_string)
def get_response_body(self):
return self.response_body_dict
if __name__ == "__main__":
API_KEY = "75b5cc58a5cdc0a583f91301cefedf0c"
CLIENT_ID = "ef5f7a03-58e8-48d7-a38a-abbd2696bdb6.hmhco.com"
REQUEST_URL = "http://some.url"
client = apiclient(request_url=REQUEST_URL,
api_key=API_KEY,
client_id=CLIENT_ID)
response = client.get_response_body()
print client
I am trying to get an authentication token from the Sabre Dev Studio. I am following the generic directions given here https://developer.sabre.com/docs/read/rest_basics/authentication(need to login to view) but I cannot figure out how to obtain a token using Python - specifically using the python-oauth2 library as it seems to be recommended to simplify the process.
Here's a sample of my code:
config = ConfigParser.ConfigParser()
config.read("conf.ini")
clientID = config.get('DEV', 'Key').strip()
clientSecret = config.get('DEV', 'SharedSecret').strip()
consumer = oauth.Consumer(key=base64.b64encode(clientID),
secret=base64.b64encode(clientSecret))
# Request token URL for Sabre.
request_token_url = "https://api.sabre.com/v1/auth/token"
# Create our client.
client = oauth.Client(consumer)
# create headers as per Sabre Dev Guidelines https://developer.sabre.com/docs/read/rest_basics/authentication
headers = {'Content-Type':'application/x-www-form-urlencoded'}
params = {'grant_type':'client_credentials'}
# The OAuth Client request works just like httplib2 for the most part.
resp, content = client.request(request_token_url, "POST", headers=headers)
print resp
print content
The response is a type 401. Where the credentials are incomplete or misformed.
Any suggestions appreciated.
I could not with oauth2, but I did with requests package I think you can get it from here
My code is:
import requests
import base64
import json
def encodeBase64(stringToEncode):
retorno = ""
retorno = base64.b64encode(stringToEncode)
return retorno
parameters = {"user": "YOUR_USER", "group": "YOUR_GROUP", "domain": "YOUR_DOMAIN", "password": "YOUR_PASSWORD"}
endpoint = "https://api.test.sabre.com/v1"
urlByService = "/auth/token?="
url = endpoint + urlByService
user = parameters["user"]
group = parameters["group"]
domain = parameters["domain"]
password = parameters["password"]
encodedUserInfo = encodeBase64("V1:" + user + ":" + group + ":" + domain)
encodedPassword = encodeBase64(password)
encodedSecurityInfo = encodeBase64(encodedUserInfo + ":" + encodedPassword)
data = {'grant_type':'client_credentials'}
headers = {'content-type': 'application/x-www-form-urlencoded ','Authorization': 'Basic ' + encodedSecurityInfo}
response = requests.post(url, headers=headers,data=data)
print "Post Request to: " + url
print response
print "Response Message: " + response.text
Regards,
First get your credentials:
Register in https://developer.sabre.com/member/register
Sign in into https://developer.sabre.com
Go to https://developer.sabre.com/apps/mykeys and get your credentials. They should look like this (where spam and eggs will look like garbage):
client_id = 'V1:spam:DEVCENTER:EXT'
client_secret = 'eggs'
Then call the /v2/auth/token endpoint in order to get an access token:
import requests
credentials = ":".join([part.encode('base64').strip()
for part in (client_id, client_secret)]
).encode('base64').strip()
url = 'https://api.test.sabre.com/v2/auth/token'
headers = {'Authorization': 'Basic ' + credentials}
params = {'grant_type': 'client_credentials'}
r = requests.post(url, headers=headers, data=params)
assert r.status_code is 200, 'Oops...'
token = r.json()
print(token)
You should get something like this:
{u'access_token': u'T1RLAQJwPBoAuz...x8zEJg**',
u'token_type': u'bearer',
u'expires_in': 604800}
Now you can call others endpoints using an Authorization header containing your access token. For example, if you want the list of supported countries:
headers = {'Authorization': 'Bearer ' + token[u'access_token']}
endpoint = 'https://api.test.sabre.com/v1/lists/supported/countries'
r = requests.get(endpoint, headers=headers)
assert r.status_code is 200, 'Oops...'
print (r.json())
If everything went well, you should receive the list of supported countries:
{u'DestinationCountries': [
{u'CountryName': u'Antigua And Barbuda', u'CountryCode': u'AG'},
{u'CountryName': u'Argentina', u'CountryCode': u'AR'},
{u'CountryName': u'Armenia', u'CountryCode': u'AM'},
{u'CountryName': u'Aruba', u'CountryCode': u'AW'},
...
}
I'm pretty sure you're using this oauth library: https://pypi.python.org/pypi/oauth2 Despite being named "oauth2" it does not implement the OAuth 2 specification. Here is the best library I could find that provides OAuth 2 support and has documentation: http://requests-oauthlib.readthedocs.org/en/latest/oauth2_workflow.html