I am having trouble with the code in that every time I go to run it, it receive an error as follows:
File "/Users/richard/Desktop/Python/gdaxauth.py", line 27
request.headers.update({ ^
SyntaxError: invalid syntax
So it seems to relate to something in the request.headers.update section. I have tried researching this but have hit a total brick wall. Can anyone advise as to what the correct syntax should be? I am using Python 3.7.
import json
import hmac
import hashlib
import time
import requests
import base64
import urllib
from requests.auth import AuthBase
# Tracking execution time
start = time.time()
# Create custom authentication for Exchange
class CoinbaseExchangeAuth(AuthBase):
def __init__(self, api_key, secret_key, passphrase):
self.api_key = api_key
self.secret_key = secret_key
self.passphrase = passphrase
def __call__(self, request):
timestamp = str(time.time())
message = timestamp + request.method + request.path_url + (request.body or '')
hmac_key = base64.b64decode(self.secret_key)
signature = hmac.new(hmac_key, message.encode('utf-8'), hashlib.sha256)
signature_b64 = base64.b64encode(signature.digest().rstrip('\n')
request.headers.update({
'CB-ACCESS-SIGN': signature_b64,
'CB-ACCESS-TIMESTAMP': timestamp,
'CB-ACCESS-KEY': self.api_key,
'CB-ACCESS-PASSPHRASE': self.passphrase,
'Content-type': 'application/json'
})
return request
# Credentials - ADD YOUR API KEY CREDS IN THIS SECTION
API_KEY = "xxxxxxxxx"
SECRET_KEY = "xxxxxxxxxx"
API_PASSPHRASE = "xxxxxxxxxx"
# Get accounts
api_url = 'https://api.gdax.com/' #'https://api.pro.coinbase.com'
auth = CoinbaseExchangeAuth(API_KEY,SECRET_KEY,API_PASSPHRASE)
r = requests.get(api_url + 'accounts', auth=auth)
# Output account data and code execution time
print(json.dumps(r.json(),indent=4))
Related
I’ve quite recently found this feature on Bitget which enables users to essentially copy other ranked traders. This feature comes with a corresponding api documentation. But after going through it im more confused than ever. Firstly, im trying to obtain the historical data trading data of specific traders which are available data on their “orders tab” from the website (shown in excerpt above). I reckon this is possible from the following get request from the documentation: “GET /api/mix/v1/trace/waitProfitDateList”.
Based on the above http request from i have produced the following python code below. The request response is 403. Help a fellow novice
import requests
import hmac
import base64
import hashlib
import json
import time
def sign(message, secret_key):
mac = hmac.new(bytes(secret_key, encoding='utf8'), bytes(message, encoding='utf-8'), digestmod='sha256')
d = mac.digest()
return base64.b64encode(d).decode('utf-8')
def pre_hash(timestamp, method, request_path, query_string, body):
return str(timestamp) + str.upper(method) + request_path + query_string + body
if __name__ == '__main__':
params = {
"pageSize": 10,
"pageNo": 1
}
rest_url = "https://api.bitget.com"
secret_key = ""
api_key = ""
passphrase = ""
timestamp = int(time.time_ns() / 1000000);
query_string = '&'.join([f'{k}={v}' for k, v in params.items()])
message = pre_hash(timestamp, 'GET', '/api/mix/v1/trace/waitProfitDateList', "?"+query_string,"")
sign = sign(message, secret_key)
headers = {
"ACCESS-KEY":api_key,
"ACCESS-SIGN":sign,
"ACCESS-TIMESTAMP":str(timestamp),
"ACCESS-PASSPHRASE":passphrase,
"Content-Type":"application/json",
"locale":"en-US"
}
response = requests.get(rest_url, headers=headers, params=params)
if response.status_code == 200:
result = response.json()
print(result)
else:
print(response.status_code)
I'm trying to retrieve the information within the non_public_metrics field in twitter API (i.e, "impression_count", "url_link_clicks", "user_profile_clicks"). I was able to access the public_metrics field using only the Bearer Token. But, when I include the non_public_metrics in my query params I got the error Field Authorization Error. Here is my code:
import requests
import collections
import os
from dotenv import load_dotenv
load_dotenv()
def auth():
return os.getenv('TWITTER_TOKEN')
def create_headers(bearer_token):
headers = {"Authorization": "Bearer {}".format(bearer_token)}
return headers
def create_url(keyword, start_date, end_date, max_results = 10):
ttid = 1184334528837574656
search_url = f"https://api.twitter.com/2/users/{ttid}/tweets" #Change to the endpoint you want to collect data from
#change params based on the endpoint you are using
query_params = {'start_time': start_date,
'end_time': end_date,
'max_results': max_results,
'tweet.fields': 'public_metrics,created_at,non_public_metric',#remove non_public_metric and the code will work
'next_token': {}}
return (search_url, query_params)
def connect_to_endpoint(url, headers, params, next_token = None):
params['next_token'] = next_token #params object received from create_url function
response = requests.request("GET", url, headers = headers, params = params)
print("Endpoint Response Code: " + str(response.status_code))
if response.status_code != 200:
raise Exception(response.status_code, response.text)
return response.json()
def flatten(d, parent_key='', sep='_'):
items = []
for k, v in d.items():
new_key = parent_key + sep + k if parent_key else k
if isinstance(v, collections.MutableMapping):
items.extend(flatten(v, new_key, sep=sep).items())
else:
items.append((new_key, v))
return dict(items)
#Inputs for the request
bearer_token = auth()
headers = create_headers(bearer_token)
keyword = "xbox lang:en"
start_time = "2021-12-01T00:00:00.000Z"
end_time = "2021-12-22T00:00:00.000Z"
max_results = 100
url = create_url(keyword, start_time,end_time, max_results)
json_response = connect_to_endpoint(url[0], headers, url[1])
print(json_response['data']) #if non_public_metrics is included, this throws a error
Then I read in Twitter Docs that I need to use OAuth1.0 authorization in order to access the field non_public_metrics. I tried to use one of the sample codes available in twitter-dev GH'page that uses OAuth1.0 authentication. Here is the snippet I used:
from requests_oauthlib import OAuth1Session
import os
import json
from dotenv import load_dotenv
load_dotenv()
consumer_key = os.getenv("CONSUMER_KEY")
consumer_secret = os.getenv("CONSUMER_SECRET")
#I actually used an ID associate to my account, not this one
params = {"ids": "1184334528837574656", "tweet.fields": "public_metrics,created_at,non_public_metrics"}
request_token_url = "https://api.twitter.com/oauth/request_token"
oauth = OAuth1Session(consumer_key, client_secret=consumer_secret)
try:
fetch_response = oauth.fetch_request_token(request_token_url)
except ValueError:
print(
"There may have been an issue with the consumer_key or consumer_secret you entered."
)
resource_owner_key = fetch_response.get("oauth_token")
resource_owner_secret = fetch_response.get("oauth_token_secret")
print("Got OAuth token: %s" % resource_owner_key)
# Get authorization
base_authorization_url = "https://api.twitter.com/oauth/authorize"
authorization_url = oauth.authorization_url(base_authorization_url)
print("Please go here and authorize: %s" % authorization_url)
verifier = input("Paste the PIN here: ")
# Get the access token
access_token_url = "https://api.twitter.com/oauth/access_token"
oauth = OAuth1Session(
consumer_key,
client_secret=consumer_secret,
resource_owner_key=resource_owner_key,
resource_owner_secret=resource_owner_secret,
verifier=verifier,
)
oauth_tokens = oauth.fetch_access_token(access_token_url)
access_token = oauth_tokens["oauth_token"]
access_token_secret = oauth_tokens["oauth_token_secret"]
# Make the request
oauth = OAuth1Session(
consumer_key,
client_secret=consumer_secret,
resource_owner_key=access_token,
resource_owner_secret=access_token_secret,
)
response = oauth.get(
"https://api.twitter.com/2/tweets", params=params
)
if response.status_code != 200:
raise Exception(
"Request returned an error: {} {}".format(response.status_code, response.text)
)
print("Response code: {}".format(response.status_code))
json_response = response.json()
print(json.dumps(json_response, indent=4, sort_keys=True))
This snippet, however, leads me to a similar error "Sorry, you are not authorized to access 'non_public_metrics.impression_count' on the Tweet with ids. Besides, this snippet has the huge incovenient of ask me to click a link and generate a PIN every time I need to request information for a particular tweet.
How can I properly request information on non_public_metrics field for my tweets?
One can retrieve the information within the non_public_metrics field using the url https://api.twitter.com/2/tweets/[YOU_TWEET_ID]?tweet.fields=non_public_metrics in Postman. To do the same in python just use the following snippet:
import os
from requests_oauthlib import OAuth1
import requests
from dotenv import load_dotenv
load_dotenv()
YOUR_TWEET_ID = ''
url = f'https://api.twitter.com/2/tweets/{YOUR_TWEET_ID}?tweet.fields=public_metrics,non_public_metrics'
CONSUMER_KEY=os.getenv('CONSUMER_KEY')
CONSUMER_SECRET=os.getenv('CONSUMER_SECRET')
ACCESS_TOKEN=os.getenv('ACCESS_TOKEN')
ACCESS_SECRET=os.getenv('ACCESS_SECRET')
headeroauth = OAuth1(CONSUMER_KEY, CONSUMER_SECRET,ACCESS_TOKEN, ACCESS_SECRET, signature_type='auth_header')
r = requests.get(url, auth=headeroauth)
print(r.json())
this is my first time asking in stackoverflow. I want to fetch data using Shopee API. I follow the documentation in Shopee but it always return "error_auth". How can I fix this ? Here is the code below :
import hmac
import time
import requests
import hashlib
timest = int(time.time())
host = "https://partner.shopeemobile.com"
path = "/api/v2/shop/auth_partner"
redirect_url = "http://localhost:3000"
partner_id =
partner_key = ""
base_string = "%s%s%s"%(partner_id, path, timest)
signature = hmac.new(bytes( partner_key, 'utf-8'), msg = bytes(base_string , 'utf-8'), digestmod = hashlib.sha256).hexdigest()
url = host + path + "?partner_id=%s×tamp=%s&sign=%s&redirect=%s"%(partner_id, timest, signature, redirect_url)
And here is the respond :
{
"request_id": "5e82043c27318f70007e4aca894f1365",
"error": "error_auth"
}
I'm use this configuration for base_string and sign:
base_string = ("%s%s%s"%(partner_id, path, timest)).encode('utf_8')
sign = hmac.new(partner_key, base_string, hashlib.sha256).hexdigest()
I'm having trouble generating the authorization token for cosmos db for a simple get databases request. Here is my python code:
import requests
import hmac
import hashlib
import base64
from datetime import datetime
key = 'AG . . .EZPcZBKz7gvrKiXKsuaPA=='
now = datetime.utcnow().strftime('%a, %d %b %Y %H:%M:00 GMT')
payload = ('get\ndbs\n\n' + now + '\n\n').lower()
signature = base64.b64encode(hmac.new(key, msg = payload, digestmod = hashlib.sha256).digest()).decode()
url = 'https://myacct.documents.azure.com/dbs'
headers = {
'Authorization': "type=master&ver=1.0&sig=" + signature,
"x-ms-date": now,
"x-ms-version": "2017-02-22"
}
res = requests.get(url, headers = headers)
print res.content
Which produces this error:
{"code":"Unauthorized","message":"The input authorization token can't serve the request. Please check that the expected payload is built as per the protocol, and check the key being used. Server used the following payload to sign: 'get\ndbs\n\nsun, 08 apr 2018 02:39:00 gmt\n\n'\r\nActivityId: 5abe59d8-f44e-42c1-9380-5cf4e63425ec, Microsoft.Azure.Documents.Common/1.21.0.0"}
Greg. Per my observe, the miss of your code is url encode. You could find the sample code here.
Please refer to my code which was made a slight adjustment to your code.
import requests
import hmac
import hashlib
import base64
from datetime import datetime
import urllib
key = '***'
now = datetime.utcnow().strftime('%a, %d %b %Y %H:%M:00 GMT')
print now
payload = ('get\ndbs\n\n' + now + '\n\n').lower()
payload = bytes(payload).encode('utf-8')
key = base64.b64decode(key.encode('utf-8'))
signature = base64.b64encode(hmac.new(key, msg = payload, digestmod = hashlib.sha256).digest()).decode()
print signature
authStr = urllib.quote('type=master&ver=1.0&sig={}'.format(signature))
print authStr
headers = {
'Authorization': authStr,
"x-ms-date": now,
"x-ms-version": "2017-02-22"
}
url = 'https://***.documents.azure.com/dbs'
res = requests.get(url, headers = headers)
print res.content
Execute result:
Hope it helps you.
I am trying to make a basic authenticated api call to their new v2 api and getting an invalid api key error returned.
I reissued the api key just to verify, same error.
from time import time
import urllib.request
import urllib.parse
import hashlib
import hmac
APIkey = b'myapikeyyouarenotsupposedtosee'
secret = b'myceeeeecretkeyyyy'
url = 'https://api.bitfinex.com/v2/auth/r/wallets'
payload = {
#'request':'/auth/r/wallets',
'nonce': int(time() * 1000),
}
paybytes = urllib.parse.urlencode(payload).encode('utf8')
print(paybytes)
sign = hmac.new(secret, paybytes, hashlib.sha512).hexdigest()
print(sign)
headers = {
'Key': APIkey,
'Sign': sign
}
req = urllib.request.Request(url, headers=headers, data=paybytes)
with urllib.request.urlopen(req) as response:
the_page = response.read()
print(the_page)
How do I make an authenticated api call to the new v2 API for bitfinex?
Your headers are wrong. I was also trying to do this and tried using the example code from the bitfinex v2 api docs, however their example contained a bug in that they needed to encode the strings into UTF-8 byte arrays first. So I've fixed it and posting the entire example below.
#
# Example Bitfinex API v2 Auth Python Code
#
import requests # pip install requests
import json
import base64
import hashlib
import hmac
import os
import time #for nonce
class BitfinexClient(object):
BASE_URL = "https://api.bitfinex.com/"
KEY = "API_KEY_HERE"
SECRET = "API_SECRET_HERE"
def _nonce(self):
# Returns a nonce
# Used in authentication
return str(int(round(time.time() * 10000)))
def _headers(self, path, nonce, body):
secbytes = self.SECRET.encode(encoding='UTF-8')
signature = "/api/" + path + nonce + body
sigbytes = signature.encode(encoding='UTF-8')
h = hmac.new(secbytes, sigbytes, hashlib.sha384)
hexstring = h.hexdigest()
return {
"bfx-nonce": nonce,
"bfx-apikey": self.KEY,
"bfx-signature": hexstring,
"content-type": "application/json"
}
def req(self, path, params = {}):
nonce = self._nonce()
body = params
rawBody = json.dumps(body)
headers = self._headers(path, nonce, rawBody)
url = self.BASE_URL + path
resp = requests.post(url, headers=headers, data=rawBody, verify=True)
return resp
def active_orders(self):
# Fetch active orders
response = self.req("v2/auth/r/orders")
if response.status_code == 200:
return response.json()
else:
print('error, status_code = ', response.status_code)
return ''
# fetch all your orders and print out
client = BitfinexClient()
result = client.active_orders()
print(result)
Why not use one of the open source api clients out there ? and you can compare to your work .
https://github.com/scottjbarr/bitfinex
https://github.com/tuberculo/bitfinex