为啥我的 websocket 请求只有在用 OOP 编写时才“未经授权”,而在仅使用函数编写时同样可以完美运行?
Posted
技术标签:
【中文标题】为啥我的 websocket 请求只有在用 OOP 编写时才“未经授权”,而在仅使用函数编写时同样可以完美运行?【英文标题】:Why is my websocket request "unauthorized" only when written in OOP, when the same works perfectly when written with just functions?为什么我的 websocket 请求只有在用 OOP 编写时才“未经授权”,而在仅使用函数编写时同样可以完美运行? 【发布时间】:2019-11-14 19:17:37 【问题描述】:我正在编写一个 Python 程序来实现一些交易自动化。我使用的 API 来自 Deribit,它的首选传输机制是 Websocket。我是 Python 的 websockets
和 asyncio
模块的新手。
这是我首先编写的代码,用于验证我的客户,然后发送单独的私人消息以从帐户获取订单头寸,仅使用函数编写,没有类:
import asyncio
import websockets
import json
CL_ID = 'qxv0EeAu'
CL_SECRET = 't24F49ocH1_qFawiKnEyqlWF5D-haABb31O8xCQhySg'
REQ_URL = 'wss://test.deribit.com/ws/api/v2'
acc_token = ''
msg =
"jsonrpc": "2.0",
"id": 1,
"params":
async def auth_api():
global msg
global acc_token
msg["method"] = "public/auth"
msg["params"] =
"grant_type": "client_credentials",
"client_id": CL_ID,
"client_secret": CL_SECRET,
"scope": "session:test"
async with websockets.connect(REQ_URL) as websocket:
await websocket.send(json.dumps(msg))
while websocket.open:
response = await websocket.recv()
response_json = json.loads(response)
acc_token = response_json["result"]["access_token"]
return
async def get_position(websocket, instrument):
global msg
global acc_token
msg["id"] += 1
msg["method"] = "private/get_position"
msg["params"] =
"access_token": acc_token,
"instrument_name": instrument
await websocket.send(json.dumps(msg))
while websocket.open:
response = await websocket.recv()
return response
async def main():
global msg
await auth_api()
async with websockets.connect(REQ_URL) as websocket:
response = await get_position(websocket, "BTC-PERPETUAL")
print(response)
asyncio.get_event_loop().run_until_complete(main())
它工作得很好。这是我的结果:
"jsonrpc":"2.0","id":2,"result":"total_profit_loss":0.000209124,"size_currency":-0.017402402,"size":-150.0,"settlement_price":8649.9,"realized_profit_loss":2.67e-7,"open_orders_margin":0.0,"mark_price":8619.5,"maintenance_margin":0.000100079,"leverage":100,"kind":"future","instrument_name":"BTC-PERPETUAL","initial_margin":0.000174039,"index_price":8619.45,"floating_profit_loss":0.000061161,"estimated_liquidation_price":-14.95,"direction":"sell","delta":-0.017402402,"average_price":8724.34,"usIn":1573756522511975,"usOut":1573756522512240,"usDiff":265,"testnet":true
我决定用OOP的方式重写它,这是我创建的类(文件名为“Call_Deribit
”):
import asyncio, websockets, json
class WSClient():
def __init__(self, key=None, secret=None, url=None):
self.api_key = key
self.api_secret = secret
self.msg =
"jsonrpc": "2.0",
"id": 0
if url:
self.host = url
else:
self.host = 'wss://test.deribit.com/ws/api/v2'
async def call_api(self, msg):
async with websockets.connect(self.host) as websocket:
print("Connected to URL:", self.host)
try:
await websocket.send(msg)
while websocket.open:
response = await websocket.recv()
response_json = json.loads(response)
return response_json
except Exception as e:
return e
def request(self, method, params, session=None):
msg = self.msg
msg["id"] += 1
msg["method"] = method
msg["params"] = params
if session != None:
msg["params"]["scope": "session:".format(session)]
return asyncio.get_event_loop().run_until_complete(self.call_api(json.dumps(msg)))
def get_order_book(self, instrument):
method = "public/get_order_book"
params =
"instrument_name": instrument
return self.request(method, params)
这是我访问该类的主文件以及我发出所有请求的位置:
import json, asyncio, websockets
from Call_Deribit import WSClient
CL_ID = 'qxv0EeAu'
CL_SECRET = 't24F49ocH1_qFawiKnEyqlWF5D-haABb31O8xCQhySg'
REQ_URL = 'wss://test.deribit.com/ws/api/v2'
method_auth = "public/auth"
params_auth =
"grant_type": "client_credentials",
"client_id": CL_ID,
"client_secret": CL_SECRET
main_client = WSClient(key=CL_ID, secret=CL_SECRET, url=REQ_URL)
auth_response = main_client.request(method_auth, params_auth)
acc_token = auth_response["result"]["access_token"]
method_pos = "private/get_position"
params_pos =
"access_token": acc_token,
"instrument_name": "BTC-PERPETUAL"
position = main_client.request(method_pos, params_pos)
print(position)
这次第一个身份验证请求正在运行,我也能够提取访问令牌,但第二个 private/get_position
消息无论出于何种原因返回一个 unauthorized
错误。
'jsonrpc': '2.0', 'id': 1, 'error': 'message': 'unauthorized', 'code': 13009, 'testnet': True, 'usIn': 1573756936534405, 'usOut': 1573756936534629, 'usDiff': 224
我已经花费了几个小时,而且我在 OOP 版本中所做的事情似乎与我在原始版本中所做的完全一样。我对 OOP 及其概念(例如继承)的熟悉程度有限,所以我想知道我在这里缺少什么,以及为什么我的代码在 OOP 版本中不起作用,尽管遵循与中相同的确切工作流程原版。
这里是 Deribit API 的文档:https://docs.deribit.com/v2/?python#json-rpc
任何帮助将不胜感激。
【问题讨论】:
【参考方案1】:在主文件中添加params_auth
下的范围有效:
params_auth =
"grant_type": "client_credentials",
"client_id": CL_ID,
"client_secret": CL_SECRET,
"scope": "session:test"
【讨论】:
以上是关于为啥我的 websocket 请求只有在用 OOP 编写时才“未经授权”,而在仅使用函数编写时同样可以完美运行?的主要内容,如果未能解决你的问题,请参考以下文章