Trying to work through this signed request example script with no success.
I notice both "http_method" and "params" in "def send_signed_request" are both greyed out to indicate unused code.
I have tried to add the params to the request as below, but that's not going to solve the unused code issue, both are still showing as unused code.
response = send_signed_request('POST', '/sapi/v1/margin/loan', {"asset": "", "isIsolated": "TRUE", "symbol": "", "amount": ""} )
print(response)
I'm just learning Python and maybe missing some assumed knowledge I guess and have been reading a lot to no avail before posting.
I read somewhere that Binance are seeing lots of traders spending hours trying to solve signature authentication as I am, and maybe this will help others in the same situation.
thx in advance to anyone that takes a look.
Just to clarify the script didn't come from Binance and I would have to dig for the link if anyone wants it.
import hmac
import time
import hashlib
import requests
from urllib.parse import urlencode
KEY = ''
SECRET = ''
BASE_URL = 'https://sapi.binance.com' # production base url
#BASE_URL = 'https://testnet.binancefuture.com' # testnet base url
''' ====== begin of functions, you don't need to touch ====== '''
def hashing(query_string):
return hmac.new(SECRET.encode('utf-8'), query_string.encode('utf-8'), hashlib.sha256).hexdigest()
def get_timestamp():
return int(time.time() * 1000)
def dispatch_request(http_method):
session = requests.Session()
session.headers.update({
'Content-Type': 'application/json;charset=utf-8',
'X-MBX-APIKEY': KEY
})
return {
'GET': session.get,
'DELETE': session.delete,
'PUT': session.put,
'POST': session.post,
}.get(http_method, 'GET')
# used for sending request requires the signature
def send_signed_request(http_method, url_path, payload={}):
query_string = urlencode(payload)
url = BASE_URL + url_path + '?' + query_string + '&signature=' + hashing(query_string)
params = {'url': url, 'params': {}}
# used for sending public data request
# def send_public_request(url_path, payload={}):
# query_string = urlencode(payload, True)
# url = BASE_URL + url_path
# if query_string:
# url = url + '?' + query_string
# print("{}".format(url))
# response = dispatch_request('GET')(url=url)
# return response.json()
response = send_signed_request('POST', '/sapi/v1/margin/loan', params )
print(response)
Below is a working script if anyone has the same issue
import hmac
import time
import hashlib
import requests
from urllib.parse import urlencode
KEY = ''
SECRET= ''
BASE_URL = 'https://api.binance.com' # production base url
#BASE_URL = 'https://testnet.binancefuture.com' # testnet base url
''' ====== begin of functions, you don't need to touch ====== '''
def hashing(query_string):
return hmac.new(SECRET.encode('utf-8'), query_string.encode('utf-8'), hashlib.sha256).hexdigest()
def get_timestamp():
return int(time.time() * 1000)
def dispatch_request(http_method):
session = requests.Session()
session.headers.update({
'Content-Type': 'application/json;charset=utf-8',
'X-MBX-APIKEY': KEY
})
return {
'GET': session.get,
'DELETE': session.delete,
'PUT': session.put,
'POST': session.post,
}.get(http_method, 'GET')
# used for sending request requires the signature
def send_signed_request(http_method, url_path, payload={}):
query_string = urlencode(payload)
# replace single quote to double quote
query_string = query_string.replace('%27', '%22')
if query_string:
query_string = "{}×tamp={}".format(query_string, get_timestamp())
else:
query_string = 'timestamp={}'.format(get_timestamp())
url = BASE_URL + url_path + '?' + query_string + '&signature=' + hashing(query_string)
print("{} {}".format(http_method, url))
params = {'url': url, 'params': {}}
response = dispatch_request(http_method)(**params)
print(response)
return response.json()
# used for sending public data request
def send_public_request(url_path, payload={}):
query_string = urlencode(payload, True)
url = BASE_URL + url_path
if query_string:
url = url + '?' + query_string
print("{}".format(url))
response = dispatch_request('GET')(url=url)
return response.json()
#response = send_signed_request('GET', '/api/v3/time')
#print(response)
response = send_signed_request('POST', '/sapi/v1/margin/loan', {"asset": "SHIB", "isIsolated": "TRUE", "symbol": "SHIBUSDT", "amount": "1000.00"} )
print(response)
Related
I wanted to make a program where I can check the order details of my order at Bithumb Exchange.
So I looked at the docs(https://api.bithumb.com/info/orders) and made it, but the same error code kept coming out, so I don't know what to do.
import time
import math
import base64
import hmac, hashlib
import urllib.parse
import requests
class XCoinAPI:
api_url = "https://api.bithumb.com";
api_key = "";
api_secret = "";
def __init__(self, api_key, api_secret):
self.api_key = api_key;
self.api_secret = api_secret;
def body_callback(self, buf):
self.contents = buf;
def microtime(self, get_as_float = False):
if get_as_float:
return time.time()
else:
return '%f %d' % math.modf(time.time())
def usecTime(self) :
mt = self.microtime(False)
mt_array = mt.split(" ")[:2];
return mt_array[1] + mt_array[0][2:5];
def xcoinApiCall(self, endpoint, rgParams):
# 1. Api-Sign and Api-Nonce information generation.
# 2. Request related information from the Bithumb API server.
#
# - nonce: it is an arbitrary number that may only be used once.
# - api_sign: API signature information created in various combinations values.
endpoint_item_array = {
"endpoint" : endpoint
}
uri_array = dict(endpoint_item_array, **rgParams) # Concatenate the two arrays.
str_data = urllib.parse.urlencode(uri_array)
nonce = self.usecTime()
data = endpoint + chr(1) + str_data + chr(1) + nonce
utf8_data = data.encode('utf-8')
key = self.api_secret
utf8_key = key.encode('utf-8')
h = hmac.new(bytes(utf8_key), utf8_data, hashlib.sha512)
hex_output = h.hexdigest()
utf8_hex_output = hex_output.encode('utf-8')
api_sign = base64.b64encode(utf8_hex_output)
utf8_api_sign = api_sign.decode('utf-8')
headers = {
"Accept": "application/json",
"Content-Type": "application/x-www-form-urlencoded",
"Api-Key": self.api_key,
"Api-Nonce": nonce,
"Api-Sign": utf8_api_sign
}
url = self.api_url + endpoint
r = requests.post(url, headers=headers, data=uri_array)
return r.json()
a = XCoinAPI(api_key="MYKEY1c", api_secret="MYKEY2")
aa= a.xcoinApiCall("/info/orders",{"order_currency":"LN","payment_currency":"BTC"})
print(aa)
{'status': '5100', 'message': 'Bad Request.(Auth Data)'}
Process finished with exit code 0
The error code 5100, bad request keeps coming up(https://apidocs.bithumb.com/docs/api-%EC%A3%BC%EC%9A%94-%EC%97%90%EB%9F%AC-%EC%BD%94%EB%93%9C)
I really don't know which code to modify.
I think it's a parameter problem with XcoinApiCall, but I don't know.
I am programming an API in python to query a server if it has endpoint agents in it. The server and the endpoint belong to Apex central SaaS trend micro.
The error I get is that I'm putting the wrong parameters but I don't think the problem is there.
The code I have for the query is as follows:
import base64
import jwt
import hashlib
import requests
import time
import json
import urllib.parse
def create_checksum(http_method, raw_url, headers, request_body):
string_to_hash = http_method.upper() + '|' + raw_url.lower() + '|' + headers + '|' + request_body
base64_string = base64.b64encode(hashlib.sha256(str.encode(string_to_hash)).digest()).decode('utf-8')
return base64_string
def create_jwt_token(appication_id, api_key, http_method, raw_url, headers, request_body,
iat=time.time(), algorithm='HS256', version='V1'):
payload = {'appid': appication_id,
'iat': iat,
'version': version,
'checksum': create_checksum(http_method, raw_url, headers, request_body)}
token = jwt.encode(payload, api_key, algorithm=algorithm)
return token
# Use this region to setup the call info of the Apex Central server (server url, application id, api key)
# server info
use_url_base = 'https://arct3w.manage.trendmicro.com'
use_application_id = '52EB0005-B6DA-4249-9764-62AE3BFCDBB1'
use_api_key = 'B3FE1D91-5D05-490C-B45C-26A9EFF6C363'
productAgentAPIPath = '/WebApp/API/AgentResource/ProductAgents'
canonicalRequestHeaders = ''
useQueryString=''
payload = {
'computerId':'e34a13a1-1d0f-47bc-96e0-ae4db4288940'
}
useRequestBody = json.dumps(payload)
jwt_token = create_jwt_token(use_application_id, use_api_key, 'POST',
productAgentAPIPath + useQueryString,
canonicalRequestHeaders, useRequestBody, iat=time.time())
headers = {'Authorization': 'Bearer ' + jwt_token , 'Content-Type': 'application/json;charset=utf-8'}
#Choose by call type.
r = requests.post(use_url_base + productAgentAPIPath + useQueryString, data=useRequestBody, headers=headers, verify=False)
print(r.status_code)
if 'application/json' in r.headers.get('Content-Type', '') and len(r.content):
print(json.dumps(r.json(), indent=4))
else:
print(r.text)
I tried to do something similar to an api belonging to Vision One but it didn't work:
https://automation.trendmicro.com/xdr/api-v2#tag/Search/paths/~1v2.0~1xdr~1eiqs~1query~1endpointInfo/post
the original code of the query is :
https://automation.trendmicro.com/apex-central/api#tag/Security-Agents/operation/AgentResource_GetProductAgentsV2
i'm trying make http request from specified ip address, but it's doesen't work this way. The required IP address is not assigned during the request .Could someone please help me with this problem ? What i do incorrect ?
import random
import time
import json
import hmac
import hashlib
import requests
from urllib.parse import urljoin, urlencode
from binance import Client
import pandas as pd
import urllib3
def create_order(params): # Func for creating order
print('Creating order')
PATH = '/api/v3/order'
params['timestamp'] = int(time.time() * 1000)
query_string = urlencode(params)
print('Query to: ', query_string)
params['signature'] = hmac.new(secret_Key.encode('utf-8'), query_string.encode('utf-8'), hashlib.sha256).hexdigest()
url = urljoin(BASE_URL, PATH)
real_create_conn = urllib3.util.connection.create_connection
def set_src_addr(address, timeout, *args, **kw):
source_address = ('10.8.5.107', 0)
return real_create_conn(address, timeout=timeout, source_address=source_address)
urllib3.util.connection.create_connection = set_src_addr
r = requests.post(url, headers=headers, params=params)
def Get_Price(params, offset):
PATH = '/api/v3/ticker/price'
params['timestamp'] = int(time.time() * 1000)
params1 = {
'symbol': params['symbol']
}
url = urljoin(BASE_URL, PATH)
r = requests.get(url, headers=headers, params=params1)
if r.status_code == 200:
print(json.dumps(r.json(), indent=2))
else:
print(r)
print(r.status_code, r.json(), '\n')
price = round(float(r.json()['price']), 2)
print('Order Price : ', price + offset, '$')
params['price'] = price + offset
create_order(params)
return params
if __name__ == "__main__":
api_Key = input('Enter API Key:\n')
secret_Key = input('Enter Secret Key:\n')
time_to_sleep = int(input('Enter the frequency of order movement (in milliseconds):\n'))
tryes_limit = int(input('Enter the maximum number of times for a move order :\n'))
symbol = (input('Enter symbol:\n')).upper()
side = (input('Enter side (SELL / BUY):\n')).upper()
offset = float(input('Enter price offset in USD:\n'))
quantity = round(float(input('Enter quantity:\n')), 3)
client = Client(api_Key, secret_Key)
BASE_URL = 'https://api.binance.com'
headers = {
'X-MBX-APIKEY': api_Key
}
params = {
'symbol': symbol,
'side': side,
'type': 'LIMIT',
'timeInForce': 'GTC',
'quantity': quantity,
'price': '',
'recvWindow': 60000,
'timestamp': int()
}
Get_Price(params, offset)
Also i tryed do it by this way :
source = source.SourceAddressAdapter('10.8.5.107')
with requests.Session() as session:
a = session.mount('http://', source)
r = session.post(url, headers=headers, params=params)
print('dasasd', session.post(url, headers=headers, params=params))
I have a synchronous code with requests that I am trying to move to using aiohttp.ClientSession.
Indeed, I have a class in which I set a aiohttp.ClientSession with various headers, among those an API key. The above code works for requesting data: (I deleted the init.... everything works but this function)
class Client():
def __init__(self):
loop = asyncio.get_event_loop()
self.session = aiohttp.ClientSession(
loop=loop,
headers=self.get_headers()
)
def send_signed_request(self, url_path, payload={}):
session = requests.session()
session.headers.update(self._get_headers())
query_string = urlencode(payload)
url = url_path + '?' + query_string
params = {'url': url, 'params': {}}
response = session.post(**params)
return response.json()
client = Client()
results = client.send_signed_request(url, params)
From that, with the requests session, I obtain a valid response from the server.
for some reason, the code below, with aiohttp session does not work and I have no idea how to adapt it.
async def send_signed_request(self, url_path, payload={}):
query_string = urlencode(payload)
url = url_path + '?' + query_string
params = {'url': url, 'data': {}}
async with self.session.post(**params) as response:
return await response.json()
does anybody knows my error please?
I am writing a Flask application script and have encountered a function that accepts arguments and functions outside of the flask app in a standalone script but will not accept the the 'TFEVT_node_id'argument I pass to it inside of the Flask app. Here is the Flask code:
#################################################
# Flask Setup
#################################################
#app = Flask(__name__, static_url_path='')
app = Flask(__name__)
CORS(app)
#################################################
#global variables
TFEVT_node_id = ''
token = ''
#################################################
# CityIQ API calls
#################################################
def get_token():
print("Get Token")
url = 'https://auth.aa.cityiq.io/oauth/token'
querystring = {"grant_type":"client_credentials"}
response = requests.get(url, auth=HTTPBasicAuth(client,secret), params=querystring).json()
token = response['access_token']
print("Token Received")
return token
#given a specific subasset this function returns the CityIQ traffic events for a given period of time in minutes
def get_traffic(TFEVT_node_id, lookback_minutes):
url_string = '/events'
url = "https://sandiego.cityiq.io/api/v2/event/assets/"+TFEVT_node_id+url_string
ts = datetime.datetime.now().timestamp()
CityIQ_Current_TS = int(ts*1000)
CityIQ_TS_Calc_TS = datetime.datetime.now() - timedelta(minutes=lookback_minutes)
CityIQ_Starttime_TS = int((ts-(lookback_minutes*60))*1000)
querystring = {"eventType":"TFEVT","startTime":CityIQ_Starttime_TS,"endTime":CityIQ_Current_TS,"pageSize":"100"}
payload = ""
headers = {
'Authorization': "Bearer {}".format(token),
'Predix-Zone-Id': "SD-IE-TRAFFIC",
'cache-control': "no-cache",
}
response = requests.request("GET", url, headers=headers, params=querystring).json()
return(response)
#give it an CityIQ node ID and it will return the asset TFEVT child .
def get_asset_TFEVT(node_id):
url = "https://sandiego.cityiq.io/api/v2/metadata/assets/"+node_id+"/subAssets"
payload = ""
headers = {
'Authorization': "Bearer {}".format(token),
'Predix-Zone-Id': "SD-IE-ENVIRONMENTAL",
'cache-control': "no-cache",
}
response = requests.request("GET", url, data=payload, headers=headers).json()
for i in response['assets']:
if any('TFEVT' in i for i in [i][0]['eventTypes']):
global TFEVT_node_id
TFEVT_node_id = ([i][0]['assetUid'])
return(TFEVT_node_id)
#test def that should be removed in production
def test(TFEVT_node_id, lookback_minutes):
found_cars = get_traffic(TFEVT_node_id, lookback_minutes)
print(found_cars)
return(found_cars)
#################################################
# Flask Routes
#################################################
#app.route('/')
def hello_world():
global token
token = get_token()
return 'documentation comming soon!'
#app.route('/test/<string:node_id>')
def go(node_id):
global token
token = get_token()
global TFEVT_node_id
TFEVT_node_id = get_asset_TFEVT(node_id)
cars_list = []
lookback_minutes = 15
env_output = {}
ccars = test(TFEVT_node_id, lookback_minutes)
cars_list.append(ccars)
env_output.update({'Cars' : cars_list})
if __name__ == '__main__':
app.run()
Again, I am getting the desired result when these functions are run outside of a Flask app. Inside of the Flask app (running the code above) returns a TypeError: The view function did not return a valid response. I have traced that back to the 404 response in the gettraffic function where the lookback minutes variable is getting through but the TFEVT_node_id isn't.
I am new to Python.
Your go() function does not have a return. A response is expected. See: About responses.