mirror of
https://github.com/c9s/bbgo.git
synced 2024-11-22 06:53:52 +00:00
Add grpc client
This commit is contained in:
parent
870a7a104e
commit
034a86ceb4
43
.github/workflows/python.yml
vendored
Normal file
43
.github/workflows/python.yml
vendored
Normal file
|
@ -0,0 +1,43 @@
|
|||
name: Python
|
||||
|
||||
on:
|
||||
push:
|
||||
branches: [ main ]
|
||||
pull_request:
|
||||
branches: [ main ]
|
||||
|
||||
jobs:
|
||||
|
||||
build:
|
||||
runs-on: ubuntu-latest
|
||||
|
||||
strategy:
|
||||
matrix:
|
||||
python-version: [3.8]
|
||||
|
||||
steps:
|
||||
- name: Checkout code
|
||||
uses: actions/checkout@v2
|
||||
|
||||
- name: Set up Python ${{ matrix.python-version }}
|
||||
uses: actions/setup-python@v2
|
||||
with:
|
||||
python-version: ${{ matrix.python-version }}
|
||||
|
||||
- name: Install poetry
|
||||
run: pip install poetry==1.1.13
|
||||
|
||||
- name: Install package
|
||||
run: |
|
||||
cd python
|
||||
poetry install
|
||||
|
||||
- name: Test
|
||||
run: |
|
||||
cd python
|
||||
poetry run pytest -v -s tests
|
||||
|
||||
- name: Lint
|
||||
run: |
|
||||
cd python
|
||||
poetry run flake8 .
|
3
Makefile
3
Makefile
|
@ -177,4 +177,5 @@ protobuf:
|
|||
protoc -I=$(PWD)/pkg/pb --go_out=$(PWD)/pkg/pb $(PWD)/pkg/pb/bbgo.proto
|
||||
|
||||
protobuf-py:
|
||||
python -m grpc_tools.protoc -I$(PWD)/pkg/pb --python_out=$(PWD)/python/pybbgo --grpc_python_out=$(PWD)/python/pybbgo $(PWD)/pkg/pb/bbgo.proto
|
||||
python -m grpc_tools.protoc -I$(PWD)/pkg/pb --python_out=$(PWD)/python/bbgo --grpc_python_out=$(PWD)/python/bbgo $(PWD)/pkg/pb/bbgo.proto
|
||||
|
||||
|
|
|
@ -18,6 +18,42 @@ service BBGO {
|
|||
rpc QueryKLines(QueryKLinesRequest) returns (QueryKLinesResponse) {}
|
||||
}
|
||||
|
||||
enum Event {
|
||||
ERROR = 0;
|
||||
SUBSCRIBED = 1;
|
||||
UNSUBSCRIBED = 2;
|
||||
SNAPSHOT = 3;
|
||||
UPDATE = 4;
|
||||
AUTHENTICATED = 5;
|
||||
ORDER_SNAPSHOT = 6;
|
||||
ORDER_UPDATE = 7;
|
||||
TRADE_SNAPSHOT = 8;
|
||||
TRADE_UPDATE = 9;
|
||||
ACCOUNT_SNAPSHOT = 10;
|
||||
ACCOUNT_UPDATE = 11;
|
||||
}
|
||||
|
||||
enum Channel {
|
||||
BOOK = 0;
|
||||
TRADE = 1;
|
||||
TICKER = 2;
|
||||
USER = 3;
|
||||
}
|
||||
|
||||
enum Side {
|
||||
BUY = 0;
|
||||
SELL = 1;
|
||||
}
|
||||
|
||||
enum OrderType {
|
||||
MARKET = 0;
|
||||
LIMIT = 1;
|
||||
STOP_MARKET = 2;
|
||||
STOP_LIMIT = 3;
|
||||
POST_ONLY = 4;
|
||||
IOC_LIMIT = 5;
|
||||
}
|
||||
|
||||
message Empty {}
|
||||
|
||||
message Error {
|
||||
|
@ -31,7 +67,7 @@ message SubscribeRequest {
|
|||
|
||||
message Subscription {
|
||||
string exchange = 1;
|
||||
string channel = 2; // book, trade, ticker
|
||||
Channel channel = 2; // book, trade, ticker
|
||||
string symbol = 3;
|
||||
int64 depth = 4;
|
||||
}
|
||||
|
@ -39,8 +75,8 @@ message Subscription {
|
|||
message SubscribeResponse {
|
||||
string exchange = 1;
|
||||
string symbol = 2;
|
||||
string channel = 3; // book, trade, ticker, user
|
||||
string event = 4; // snapshot, update, order_snapshot, ...
|
||||
Channel channel = 3; // book, trade, ticker, user
|
||||
Event event = 4; // snapshot, update, order_snapshot, ...
|
||||
Depth depth = 5;
|
||||
repeated Trade trades = 6;
|
||||
Ticker ticker = 7;
|
||||
|
@ -71,7 +107,7 @@ message Trade {
|
|||
double price = 4;
|
||||
double volume = 5;
|
||||
int64 created_at = 6;
|
||||
string side = 7;
|
||||
Side side = 7;
|
||||
double fee = 8;
|
||||
string fee_currency = 9;
|
||||
bool maker = 10;
|
||||
|
@ -94,8 +130,8 @@ message Order {
|
|||
string exchange = 1;
|
||||
string symbol = 2;
|
||||
string id = 3;
|
||||
string side = 4;
|
||||
string order_type = 5;
|
||||
Side side = 4;
|
||||
OrderType order_type = 5;
|
||||
double price = 6;
|
||||
double stop_price = 7;
|
||||
double avg_price = 8;
|
||||
|
@ -111,11 +147,11 @@ message Order {
|
|||
message SubmitOrder {
|
||||
string exchange = 1;
|
||||
string symbol = 2;
|
||||
string side = 3;
|
||||
Side side = 3;
|
||||
double quantity = 4;
|
||||
double price = 5;
|
||||
double stop_price = 6;
|
||||
string order_type = 7;
|
||||
OrderType order_type = 7;
|
||||
string client_order_id = 8;
|
||||
int64 group_id = 9;
|
||||
}
|
||||
|
|
29
python/README.md
Normal file
29
python/README.md
Normal file
|
@ -0,0 +1,29 @@
|
|||
# pybbgo
|
||||
|
||||
## Installation
|
||||
|
||||
```sh
|
||||
cd <path/to/bbgo/python>
|
||||
pip install .
|
||||
```
|
||||
|
||||
## Usage
|
||||
|
||||
### Stream
|
||||
|
||||
```python
|
||||
from bbgo import Stream
|
||||
from bbgo import bbgo_pb2
|
||||
|
||||
subscriptions = [
|
||||
bbgo_pb2.Subscription(exchange='max', channel=bbgo_pb2.Channel.BOOK, symbol='btcusdt', depth=2),
|
||||
bbgo_pb2.Subscription(exchange='max', channel=bbgo_pb2.Channel.BOOK, symbol='ethusdt', depth=2),
|
||||
...
|
||||
]
|
||||
|
||||
stream = Stream(host, port, subscriptions)
|
||||
stream.on_book_event(book_event_callback)
|
||||
stream.on_ticker_event(tocker_event_callback)
|
||||
...
|
||||
stream.start()
|
||||
```
|
2
python/bbgo/__init__.py
Normal file
2
python/bbgo/__init__.py
Normal file
|
@ -0,0 +1,2 @@
|
|||
from .bbgo import BBGO
|
||||
from .stream import Stream
|
104
python/bbgo/bbgo.py
Normal file
104
python/bbgo/bbgo.py
Normal file
|
@ -0,0 +1,104 @@
|
|||
from typing import List
|
||||
|
||||
from . import bbgo_pb2
|
||||
from .utils import create_stub
|
||||
|
||||
|
||||
class BBGO(object):
|
||||
|
||||
def __init__(self, host: str, port: int):
|
||||
self.stub = create_stub(host, port)
|
||||
|
||||
def submit_order(self,
|
||||
exchange: str,
|
||||
symbol: str,
|
||||
side: bbgo_pb2.Side,
|
||||
quantity: float,
|
||||
order_type: bbgo_pb2.OrderType,
|
||||
price: float = None,
|
||||
stop_price: float = None,
|
||||
client_order_id: float = None,
|
||||
group_id: float = None) -> bbgo_pb2.Order:
|
||||
submit_order = bbgo_pb2.SubmitOrder(exchange=exchange,
|
||||
symbol=symbol,
|
||||
side=side,
|
||||
quantity=quantity,
|
||||
order_type=order_type,
|
||||
price=price,
|
||||
stop_price=stop_price,
|
||||
client_order_id=client_order_id,
|
||||
group_id=group_id)
|
||||
request = bbgo_pb2.SubmitOrderRequest(submit_order=submit_order)
|
||||
response = self.stub.SubmitOrder(request)
|
||||
return response
|
||||
|
||||
def cancel_order(self, exchange: str, order_id: int, client_order_id: int = None) -> bbgo_pb2.CancelOrderResponse:
|
||||
request = bbgo_pb2.CancelOrderRequest(exchange=exchange, id=order_id, client_order_id=client_order_id)
|
||||
response = self.stub.CancelOrder(request)
|
||||
return response
|
||||
|
||||
def query_order(self, order_id: int = None, client_order_id: int = None) -> bbgo_pb2.QueryOrderResponse:
|
||||
request = bbgo_pb2.QueryOrderRequest(id=order_id, client_order_id=client_order_id)
|
||||
response = self.stub.QueryOrder(request)
|
||||
return response
|
||||
|
||||
def query_orders(self,
|
||||
exchange: str,
|
||||
symbol: str,
|
||||
states: List[str] = None,
|
||||
order_by: str = 'asc',
|
||||
group_id: int = None,
|
||||
pagination: bool = True,
|
||||
page: int = 0,
|
||||
limit: int = 100,
|
||||
offset: int = 0) -> bbgo_pb2.QueryOrdersResponse:
|
||||
# set default value to ['wait', 'convert']
|
||||
states = states or ['wait', 'convert']
|
||||
request = bbgo_pb2.QueryOrdersRequest(exchange=exchange,
|
||||
symbol=symbol,
|
||||
states=states,
|
||||
order_by=order_by,
|
||||
group_id=group_id,
|
||||
pagination=pagination,
|
||||
page=page,
|
||||
limit=limit,
|
||||
offset=offset)
|
||||
|
||||
reponse = self.stub.QueryOrders(request)
|
||||
return reponse
|
||||
|
||||
def query_trades(self,
|
||||
exchange: str,
|
||||
symbol: str,
|
||||
timestamp: int,
|
||||
order_by: str = 'asc',
|
||||
pagination: bool = True,
|
||||
page: int = 1,
|
||||
limit: int = 100,
|
||||
offset: int = 0) -> bbgo_pb2.QueryTradesResponse:
|
||||
|
||||
request = bbgo_pb2.QueryTradesRequest(exchange=exchange,
|
||||
symbol=symbol,
|
||||
timestamp=timestamp,
|
||||
order_by=order_by,
|
||||
pagination=pagination,
|
||||
page=page,
|
||||
limit=limit,
|
||||
offset=offset)
|
||||
response = self.stub.QueryTrades(request)
|
||||
return response
|
||||
|
||||
def query_klines(self,
|
||||
exchange: str,
|
||||
symbol: str,
|
||||
limit: int = 30,
|
||||
interval: int = 1,
|
||||
timestamp: int = None) -> bbgo_pb2.QueryKLinesResponse:
|
||||
request = bbgo_pb2.QueryKLinesRequest(exchange=exchange,
|
||||
symbol=symbol,
|
||||
limit=limit,
|
||||
interval=interval,
|
||||
timestamp=timestamp)
|
||||
|
||||
response = self.stub.QueryKLines(request)
|
||||
return response
|
319
python/bbgo/bbgo_pb2.py
Normal file
319
python/bbgo/bbgo_pb2.py
Normal file
File diff suppressed because one or more lines are too long
|
@ -2,7 +2,7 @@
|
|||
"""Client and server classes corresponding to protobuf-defined services."""
|
||||
import grpc
|
||||
|
||||
import bbgo_pb2 as bbgo__pb2
|
||||
from . import bbgo_pb2 as bbgo__pb2
|
||||
|
||||
|
||||
class BBGOStub(object):
|
141
python/bbgo/stream.py
Normal file
141
python/bbgo/stream.py
Normal file
|
@ -0,0 +1,141 @@
|
|||
import asyncio
|
||||
from typing import Callable
|
||||
from typing import List
|
||||
|
||||
import grpc
|
||||
|
||||
from . import bbgo_pb2
|
||||
from . import bbgo_pb2_grpc
|
||||
|
||||
|
||||
class Stream(object):
|
||||
|
||||
def __init__(self, host: str, port: int, subscriptions: List[bbgo_pb2.Subscription]):
|
||||
self.host = host
|
||||
self.port = port
|
||||
self.subscriptions = subscriptions
|
||||
|
||||
# callbacks for public channel
|
||||
self.book_event_callbacks = []
|
||||
self.trade_event_callbacks = []
|
||||
self.ticker_event_callbacks = []
|
||||
|
||||
# callbacks for private channel
|
||||
self.order_snapshot_event_callbacks = []
|
||||
self.order_update_event_callbacks = []
|
||||
self.trade_snapshot_event_callbacks = []
|
||||
self.trade_update_event_callbacks = []
|
||||
self.account_snapshot_event_callbacks = []
|
||||
self.account_update_event_callbacks = []
|
||||
|
||||
@property
|
||||
def address(self):
|
||||
return f'{self.host}:{self.port}'
|
||||
|
||||
async def subscribe(self):
|
||||
async with grpc.aio.insecure_channel(self.address) as channel:
|
||||
stub = bbgo_pb2_grpc.BBGOStub(channel)
|
||||
|
||||
request = bbgo_pb2.SubscribeRequest(subscriptions=self.subscriptions)
|
||||
async for response in stub.Subcribe(request):
|
||||
self.dispatch(response)
|
||||
|
||||
async def subscribe_user_data(self):
|
||||
async with grpc.aio.insecure_channel(self.address) as channel:
|
||||
stub = bbgo_pb2_grpc.BBGOStub(channel)
|
||||
|
||||
request = bbgo_pb2.Empty()
|
||||
async for response in stub.SubcribeUserData(request):
|
||||
self.dispatch_user_events(response)
|
||||
|
||||
def start(self):
|
||||
group = asyncio.gather(
|
||||
self.subscribe(),
|
||||
self.subscribe_user_data(),
|
||||
)
|
||||
loop = asyncio.get_event_loop()
|
||||
loop.run_until_complete(group)
|
||||
loop.close()
|
||||
|
||||
def dispatch(self, response: bbgo_pb2.SubscribeResponse):
|
||||
m = {
|
||||
bbgo_pb2.Channel.BOOK: self.emit_book_event_callbacks,
|
||||
bbgo_pb2.Channel.TRADE: self.emit_trade_event_callbacks,
|
||||
bbgo_pb2.Channel.TICKER: self.emit_ticker_event_callbacks,
|
||||
bbgo_pb2.Channel.USER: self.dispatch_user_events,
|
||||
}
|
||||
m[response.channel](response)
|
||||
|
||||
def dispatch_user_events(self, response: bbgo_pb2.SubscribeResponse):
|
||||
m = {
|
||||
bbgo_pb2.Event.ORDER_SNAPSHOT: self.emit_order_snapshot_event_callbacks,
|
||||
bbgo_pb2.Event.ORDER_UPDATE: self.emit_order_update_event_callbacks,
|
||||
bbgo_pb2.Event.TRADE_SNAPSHOT: self.emit_trade_snapshot_event_callbacks,
|
||||
bbgo_pb2.Event.TRADE_UPDATE: self.emit_trade_update_event_callbacks,
|
||||
bbgo_pb2.Event.ACCOUNT_SNAPSHOT: self.emit_account_snapshot_event_callbacks,
|
||||
bbgo_pb2.Event.ACCOUNT_UPDATE: self.emit_account_update_event_callbacks,
|
||||
}
|
||||
m[response.event](response)
|
||||
|
||||
def on_book_event(self, callback: Callable) -> None:
|
||||
self.book_event_callbacks.append(callback)
|
||||
|
||||
def emit_book_event_callbacks(self, event) -> None:
|
||||
for callback in self.book_event_callbacks:
|
||||
callback(event)
|
||||
|
||||
def on_trade_event(self, callback: Callable) -> None:
|
||||
self.trade_event_callbacks.append(callback)
|
||||
|
||||
def emit_trade_event_callbacks(self, event) -> None:
|
||||
for callback in self.trade_event_callbacks:
|
||||
callback(event)
|
||||
|
||||
def on_ticker_event(self, callback: Callable) -> None:
|
||||
self.ticker_event_callbacks.append(callback)
|
||||
|
||||
def emit_ticker_event_callbacks(self, event) -> None:
|
||||
for callback in self.ticker_event_callbacks:
|
||||
callback(event)
|
||||
|
||||
def on_order_snapshot_event(self, callback: Callable) -> None:
|
||||
self.order_snapshot_event_callbacks.append(callback)
|
||||
|
||||
def emit_order_snapshot_event_callbacks(self, event) -> None:
|
||||
for callback in self.order_snapshot_event_callbacks:
|
||||
callback(event)
|
||||
|
||||
def on_order_update_event(self, callback: Callable) -> None:
|
||||
self.order_update_event_callbacks.append(callback)
|
||||
|
||||
def emit_order_update_event_callbacks(self, event) -> None:
|
||||
for callback in self.order_update_event_callbacks:
|
||||
callback(event)
|
||||
|
||||
def on_trade_snapshot_event(self, callback: Callable) -> None:
|
||||
self.trade_snapshot_event_callbacks.append(callback)
|
||||
|
||||
def emit_trade_snapshot_event_callbacks(self, event) -> None:
|
||||
for callback in self.trade_snapshot_event_callbacks:
|
||||
callback(event)
|
||||
|
||||
def on_trade_update_event(self, callback: Callable) -> None:
|
||||
self.trade_update_event_callbacks.append(callback)
|
||||
|
||||
def emit_trade_update_event_callbacks(self, event) -> None:
|
||||
for callback in self.trade_update_event_callbacks:
|
||||
callback(event)
|
||||
|
||||
def on_account_snapshot_event(self, callback: Callable) -> None:
|
||||
self.account_snapshot_event_callbacks.append(callback)
|
||||
|
||||
def emit_account_snapshot_event_callbacks(self, event) -> None:
|
||||
for callback in self.account_snapshot_event_callbacks:
|
||||
callback(event)
|
||||
|
||||
def on_account_update_event(self, callback: Callable) -> None:
|
||||
self.account_update_event_callbacks.append(callback)
|
||||
|
||||
def emit_account_update_event_callbacks(self, event) -> None:
|
||||
for callback in self.account_update_event_callbacks:
|
||||
callback(event)
|
37
python/bbgo/utils.py
Normal file
37
python/bbgo/utils.py
Normal file
|
@ -0,0 +1,37 @@
|
|||
import os
|
||||
|
||||
import grpc
|
||||
|
||||
from . import bbgo_pb2_grpc
|
||||
|
||||
|
||||
def read_binary(f):
|
||||
with open(f, 'rb') as fp:
|
||||
return fp.read()
|
||||
|
||||
|
||||
def get_grpc_cert_file_from_env():
|
||||
cert_file = os.environ.get('BBGO_GRPC_CERT_FILE')
|
||||
return cert_file
|
||||
|
||||
|
||||
def get_grpc_key_file_from_env():
|
||||
key_file = os.environ.get('BBGO_GRPC_KEY_FILE')
|
||||
return key_file
|
||||
|
||||
|
||||
def get_credentials_from_env():
|
||||
key_file = get_grpc_key_file_from_env()
|
||||
private_key = read_binary(key_file)
|
||||
cert_file = get_grpc_cert_file_from_env()
|
||||
certificate_chain = read_binary(cert_file)
|
||||
|
||||
private_key_certificate_chain_pairs = [(private_key, certificate_chain)]
|
||||
server_credentials = grpc.ssl_server_credentials(private_key_certificate_chain_pairs)
|
||||
return server_credentials
|
||||
|
||||
|
||||
def create_stub(host, port):
|
||||
address = f'{host}:{port}'
|
||||
channel = grpc.insecure_channel(address)
|
||||
return bbgo_pb2_grpc.BBGOStub(channel)
|
423
python/poetry.lock
generated
Normal file
423
python/poetry.lock
generated
Normal file
|
@ -0,0 +1,423 @@
|
|||
[[package]]
|
||||
name = "atomicwrites"
|
||||
version = "1.4.0"
|
||||
description = "Atomic file writes."
|
||||
category = "dev"
|
||||
optional = false
|
||||
python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*"
|
||||
|
||||
[[package]]
|
||||
name = "attrs"
|
||||
version = "21.4.0"
|
||||
description = "Classes Without Boilerplate"
|
||||
category = "dev"
|
||||
optional = false
|
||||
python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*, !=3.4.*"
|
||||
|
||||
[package.extras]
|
||||
dev = ["coverage[toml] (>=5.0.2)", "hypothesis", "pympler", "pytest (>=4.3.0)", "six", "mypy", "pytest-mypy-plugins", "zope.interface", "furo", "sphinx", "sphinx-notfound-page", "pre-commit", "cloudpickle"]
|
||||
docs = ["furo", "sphinx", "zope.interface", "sphinx-notfound-page"]
|
||||
tests = ["coverage[toml] (>=5.0.2)", "hypothesis", "pympler", "pytest (>=4.3.0)", "six", "mypy", "pytest-mypy-plugins", "zope.interface", "cloudpickle"]
|
||||
tests_no_zope = ["coverage[toml] (>=5.0.2)", "hypothesis", "pympler", "pytest (>=4.3.0)", "six", "mypy", "pytest-mypy-plugins", "cloudpickle"]
|
||||
|
||||
[[package]]
|
||||
name = "click"
|
||||
version = "8.0.4"
|
||||
description = "Composable command line interface toolkit"
|
||||
category = "main"
|
||||
optional = false
|
||||
python-versions = ">=3.6"
|
||||
|
||||
[package.dependencies]
|
||||
colorama = {version = "*", markers = "platform_system == \"Windows\""}
|
||||
|
||||
[[package]]
|
||||
name = "colorama"
|
||||
version = "0.4.4"
|
||||
description = "Cross-platform colored terminal text."
|
||||
category = "main"
|
||||
optional = false
|
||||
python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*, !=3.4.*"
|
||||
|
||||
[[package]]
|
||||
name = "flake8"
|
||||
version = "4.0.1"
|
||||
description = "the modular source code checker: pep8 pyflakes and co"
|
||||
category = "main"
|
||||
optional = false
|
||||
python-versions = ">=3.6"
|
||||
|
||||
[package.dependencies]
|
||||
mccabe = ">=0.6.0,<0.7.0"
|
||||
pycodestyle = ">=2.8.0,<2.9.0"
|
||||
pyflakes = ">=2.4.0,<2.5.0"
|
||||
|
||||
[[package]]
|
||||
name = "grpcio"
|
||||
version = "1.44.0"
|
||||
description = "HTTP/2-based RPC framework"
|
||||
category = "main"
|
||||
optional = false
|
||||
python-versions = ">=3.6"
|
||||
|
||||
[package.dependencies]
|
||||
six = ">=1.5.2"
|
||||
|
||||
[package.extras]
|
||||
protobuf = ["grpcio-tools (>=1.44.0)"]
|
||||
|
||||
[[package]]
|
||||
name = "grpcio-tools"
|
||||
version = "1.44.0"
|
||||
description = "Protobuf code generator for gRPC"
|
||||
category = "main"
|
||||
optional = false
|
||||
python-versions = ">=3.6"
|
||||
|
||||
[package.dependencies]
|
||||
grpcio = ">=1.44.0"
|
||||
protobuf = ">=3.5.0.post1,<4.0dev"
|
||||
|
||||
[[package]]
|
||||
name = "iniconfig"
|
||||
version = "1.1.1"
|
||||
description = "iniconfig: brain-dead simple config-ini parsing"
|
||||
category = "dev"
|
||||
optional = false
|
||||
python-versions = "*"
|
||||
|
||||
[[package]]
|
||||
name = "loguru"
|
||||
version = "0.6.0"
|
||||
description = "Python logging made (stupidly) simple"
|
||||
category = "main"
|
||||
optional = false
|
||||
python-versions = ">=3.5"
|
||||
|
||||
[package.dependencies]
|
||||
colorama = {version = ">=0.3.4", markers = "sys_platform == \"win32\""}
|
||||
win32-setctime = {version = ">=1.0.0", markers = "sys_platform == \"win32\""}
|
||||
|
||||
[package.extras]
|
||||
dev = ["colorama (>=0.3.4)", "docutils (==0.16)", "flake8 (>=3.7.7)", "tox (>=3.9.0)", "pytest (>=4.6.2)", "pytest-cov (>=2.7.1)", "black (>=19.10b0)", "isort (>=5.1.1)", "Sphinx (>=4.1.1)", "sphinx-autobuild (>=0.7.1)", "sphinx-rtd-theme (>=0.4.3)"]
|
||||
|
||||
[[package]]
|
||||
name = "mccabe"
|
||||
version = "0.6.1"
|
||||
description = "McCabe checker, plugin for flake8"
|
||||
category = "main"
|
||||
optional = false
|
||||
python-versions = "*"
|
||||
|
||||
[[package]]
|
||||
name = "packaging"
|
||||
version = "21.3"
|
||||
description = "Core utilities for Python packages"
|
||||
category = "dev"
|
||||
optional = false
|
||||
python-versions = ">=3.6"
|
||||
|
||||
[package.dependencies]
|
||||
pyparsing = ">=2.0.2,<3.0.5 || >3.0.5"
|
||||
|
||||
[[package]]
|
||||
name = "pluggy"
|
||||
version = "1.0.0"
|
||||
description = "plugin and hook calling mechanisms for python"
|
||||
category = "dev"
|
||||
optional = false
|
||||
python-versions = ">=3.6"
|
||||
|
||||
[package.extras]
|
||||
dev = ["pre-commit", "tox"]
|
||||
testing = ["pytest", "pytest-benchmark"]
|
||||
|
||||
[[package]]
|
||||
name = "protobuf"
|
||||
version = "3.19.4"
|
||||
description = "Protocol Buffers"
|
||||
category = "main"
|
||||
optional = false
|
||||
python-versions = ">=3.5"
|
||||
|
||||
[[package]]
|
||||
name = "py"
|
||||
version = "1.11.0"
|
||||
description = "library with cross-python path, ini-parsing, io, code, log facilities"
|
||||
category = "dev"
|
||||
optional = false
|
||||
python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*, !=3.4.*"
|
||||
|
||||
[[package]]
|
||||
name = "pycodestyle"
|
||||
version = "2.8.0"
|
||||
description = "Python style guide checker"
|
||||
category = "main"
|
||||
optional = false
|
||||
python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*, !=3.4.*"
|
||||
|
||||
[[package]]
|
||||
name = "pyflakes"
|
||||
version = "2.4.0"
|
||||
description = "passive checker of Python programs"
|
||||
category = "main"
|
||||
optional = false
|
||||
python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*"
|
||||
|
||||
[[package]]
|
||||
name = "pyparsing"
|
||||
version = "3.0.7"
|
||||
description = "Python parsing module"
|
||||
category = "dev"
|
||||
optional = false
|
||||
python-versions = ">=3.6"
|
||||
|
||||
[package.extras]
|
||||
diagrams = ["jinja2", "railroad-diagrams"]
|
||||
|
||||
[[package]]
|
||||
name = "pytest"
|
||||
version = "7.0.1"
|
||||
description = "pytest: simple powerful testing with Python"
|
||||
category = "dev"
|
||||
optional = false
|
||||
python-versions = ">=3.6"
|
||||
|
||||
[package.dependencies]
|
||||
atomicwrites = {version = ">=1.0", markers = "sys_platform == \"win32\""}
|
||||
attrs = ">=19.2.0"
|
||||
colorama = {version = "*", markers = "sys_platform == \"win32\""}
|
||||
iniconfig = "*"
|
||||
packaging = "*"
|
||||
pluggy = ">=0.12,<2.0"
|
||||
py = ">=1.8.2"
|
||||
tomli = ">=1.0.0"
|
||||
|
||||
[package.extras]
|
||||
testing = ["argcomplete", "hypothesis (>=3.56)", "mock", "nose", "pygments (>=2.7.2)", "requests", "xmlschema"]
|
||||
|
||||
[[package]]
|
||||
name = "six"
|
||||
version = "1.16.0"
|
||||
description = "Python 2 and 3 compatibility utilities"
|
||||
category = "main"
|
||||
optional = false
|
||||
python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*"
|
||||
|
||||
[[package]]
|
||||
name = "tomli"
|
||||
version = "2.0.1"
|
||||
description = "A lil' TOML parser"
|
||||
category = "dev"
|
||||
optional = false
|
||||
python-versions = ">=3.7"
|
||||
|
||||
[[package]]
|
||||
name = "win32-setctime"
|
||||
version = "1.1.0"
|
||||
description = "A small Python utility to set file creation time on Windows"
|
||||
category = "main"
|
||||
optional = false
|
||||
python-versions = ">=3.5"
|
||||
|
||||
[package.extras]
|
||||
dev = ["pytest (>=4.6.2)", "black (>=19.3b0)"]
|
||||
|
||||
[metadata]
|
||||
lock-version = "1.1"
|
||||
python-versions = "^3.8"
|
||||
content-hash = "bfda359d4e023f07cd8df05859450215e9f560f50b4a77a8aa8436ac42a74fe3"
|
||||
|
||||
[metadata.files]
|
||||
atomicwrites = [
|
||||
{file = "atomicwrites-1.4.0-py2.py3-none-any.whl", hash = "sha256:6d1784dea7c0c8d4a5172b6c620f40b6e4cbfdf96d783691f2e1302a7b88e197"},
|
||||
{file = "atomicwrites-1.4.0.tar.gz", hash = "sha256:ae70396ad1a434f9c7046fd2dd196fc04b12f9e91ffb859164193be8b6168a7a"},
|
||||
]
|
||||
attrs = [
|
||||
{file = "attrs-21.4.0-py2.py3-none-any.whl", hash = "sha256:2d27e3784d7a565d36ab851fe94887c5eccd6a463168875832a1be79c82828b4"},
|
||||
{file = "attrs-21.4.0.tar.gz", hash = "sha256:626ba8234211db98e869df76230a137c4c40a12d72445c45d5f5b716f076e2fd"},
|
||||
]
|
||||
click = [
|
||||
{file = "click-8.0.4-py3-none-any.whl", hash = "sha256:6a7a62563bbfabfda3a38f3023a1db4a35978c0abd76f6c9605ecd6554d6d9b1"},
|
||||
{file = "click-8.0.4.tar.gz", hash = "sha256:8458d7b1287c5fb128c90e23381cf99dcde74beaf6c7ff6384ce84d6fe090adb"},
|
||||
]
|
||||
colorama = [
|
||||
{file = "colorama-0.4.4-py2.py3-none-any.whl", hash = "sha256:9f47eda37229f68eee03b24b9748937c7dc3868f906e8ba69fbcbdd3bc5dc3e2"},
|
||||
{file = "colorama-0.4.4.tar.gz", hash = "sha256:5941b2b48a20143d2267e95b1c2a7603ce057ee39fd88e7329b0c292aa16869b"},
|
||||
]
|
||||
flake8 = [
|
||||
{file = "flake8-4.0.1-py2.py3-none-any.whl", hash = "sha256:479b1304f72536a55948cb40a32dce8bb0ffe3501e26eaf292c7e60eb5e0428d"},
|
||||
{file = "flake8-4.0.1.tar.gz", hash = "sha256:806e034dda44114815e23c16ef92f95c91e4c71100ff52813adf7132a6ad870d"},
|
||||
]
|
||||
grpcio = [
|
||||
{file = "grpcio-1.44.0-cp310-cp310-linux_armv7l.whl", hash = "sha256:11f811c0fffd84fca747fbc742464575e5eb130fd4fb4d6012ccc34febd001db"},
|
||||
{file = "grpcio-1.44.0-cp310-cp310-macosx_10_10_universal2.whl", hash = "sha256:9a86a91201f8345502ea81dee0a55ae13add5fafadf109b17acd858fe8239651"},
|
||||
{file = "grpcio-1.44.0-cp310-cp310-manylinux_2_17_aarch64.whl", hash = "sha256:5f3c54ebb5d9633a557335c01d88d3d4928e9b1b131692283b6184da1edbec0b"},
|
||||
{file = "grpcio-1.44.0-cp310-cp310-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:3d47553b8e86ab1e59b0185ba6491a187f94a0239f414c8fc867a22b0405b798"},
|
||||
{file = "grpcio-1.44.0-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:d1e22d3a510438b7f3365c0071b810672d09febac6e8ca8a47eab657ae5f347b"},
|
||||
{file = "grpcio-1.44.0-cp310-cp310-win32.whl", hash = "sha256:41036a574cab3468f24d41d6ed2b52588fb85ed60f8feaa925d7e424a250740b"},
|
||||
{file = "grpcio-1.44.0-cp310-cp310-win_amd64.whl", hash = "sha256:4ee51964edfd0a1293a95bb0d72d134ecf889379d90d2612cbf663623ce832b4"},
|
||||
{file = "grpcio-1.44.0-cp36-cp36m-linux_armv7l.whl", hash = "sha256:e2149077d71e060678130644670389ddf1491200bcea16c5560d4ccdc65e3f2e"},
|
||||
{file = "grpcio-1.44.0-cp36-cp36m-macosx_10_10_x86_64.whl", hash = "sha256:0ac72d4b953b76924f8fa21436af060d7e6d8581e279863f30ee14f20751ac27"},
|
||||
{file = "grpcio-1.44.0-cp36-cp36m-manylinux2010_i686.whl", hash = "sha256:5c30a9a7d3a05920368a60b080cbbeaf06335303be23ac244034c71c03a0fd24"},
|
||||
{file = "grpcio-1.44.0-cp36-cp36m-manylinux2010_x86_64.whl", hash = "sha256:05467acd391e3fffb05991c76cb2ed2fa1309d0e3815ac379764bc5670b4b5d4"},
|
||||
{file = "grpcio-1.44.0-cp36-cp36m-manylinux_2_17_aarch64.whl", hash = "sha256:b81dc7894062ed2d25b74a2725aaa0a6895ce97ce854f432fe4e87cad5a07316"},
|
||||
{file = "grpcio-1.44.0-cp36-cp36m-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:46d4843192e7d36278884282e100b8f305cf37d1b3d8c6b4f736d4454640a069"},
|
||||
{file = "grpcio-1.44.0-cp36-cp36m-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:898c159148f27e23c08a337fb80d31ece6b76bb24f359d83929460d813665b74"},
|
||||
{file = "grpcio-1.44.0-cp36-cp36m-win32.whl", hash = "sha256:b8d852329336c584c636caa9c2db990f3a332b19bc86a80f4646b58d27c142db"},
|
||||
{file = "grpcio-1.44.0-cp36-cp36m-win_amd64.whl", hash = "sha256:790d7493337558ae168477d1be3178f4c9b8f91d8cd9b8b719d06fd9b2d48836"},
|
||||
{file = "grpcio-1.44.0-cp37-cp37m-linux_armv7l.whl", hash = "sha256:cd61b52d9cf8fcf8d9628c0b640b9e44fdc5e93d989cc268086a858540ed370c"},
|
||||
{file = "grpcio-1.44.0-cp37-cp37m-macosx_10_10_x86_64.whl", hash = "sha256:14eefcf623890f3f7dd7831decd2a2116652b5ce1e0f1d4b464b8f52110743b0"},
|
||||
{file = "grpcio-1.44.0-cp37-cp37m-manylinux2010_i686.whl", hash = "sha256:bebe90b8020b4248e5a2076b56154cc6ff45691bbbe980579fc9db26717ac968"},
|
||||
{file = "grpcio-1.44.0-cp37-cp37m-manylinux2010_x86_64.whl", hash = "sha256:89b390b1c0de909965280d175c53128ce2f0f4f5c0f011382243dd7f2f894060"},
|
||||
{file = "grpcio-1.44.0-cp37-cp37m-manylinux_2_17_aarch64.whl", hash = "sha256:c122dac5cb299b8ad7308d61bd9fe0413de13b0347cce465398436b3fdf1f609"},
|
||||
{file = "grpcio-1.44.0-cp37-cp37m-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:6641a28cc826a92ef717201cca9a035c34a0185e38b0c93f3ce5f01a01a1570a"},
|
||||
{file = "grpcio-1.44.0-cp37-cp37m-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:fdb0a3e0e64843441793923d9532a3a23907b07b2a1e0a7a31f186dc185bb772"},
|
||||
{file = "grpcio-1.44.0-cp37-cp37m-win32.whl", hash = "sha256:be857b7ec2ac43455156e6ba89262f7d7ae60227049427d01a3fecd218a3f88d"},
|
||||
{file = "grpcio-1.44.0-cp37-cp37m-win_amd64.whl", hash = "sha256:f6a9cf0e77f72f2ac30c9c6e086bc7446c984c51bebc6c7f50fbcd718037edba"},
|
||||
{file = "grpcio-1.44.0-cp38-cp38-linux_armv7l.whl", hash = "sha256:19e54f0c7083c8332b5a75a9081fc5127f1dbb67b6c1a32bd7fe896ef0934918"},
|
||||
{file = "grpcio-1.44.0-cp38-cp38-macosx_10_10_x86_64.whl", hash = "sha256:bfd36b959c3c4e945119387baed1414ea46f7116886aa23de0172302b49d7ff1"},
|
||||
{file = "grpcio-1.44.0-cp38-cp38-manylinux2010_i686.whl", hash = "sha256:ccd388b8f37b19d06e4152189726ce309e36dc03b53f2216a4ea49f09a7438e6"},
|
||||
{file = "grpcio-1.44.0-cp38-cp38-manylinux2010_x86_64.whl", hash = "sha256:9075c0c003c1ff14ebce8f0ba55cc692158cb55c68da09cf8b0f9fc5b749e343"},
|
||||
{file = "grpcio-1.44.0-cp38-cp38-manylinux_2_17_aarch64.whl", hash = "sha256:e898194f76212facbaeb6d7545debff29351afa23b53ff8f0834d66611af5139"},
|
||||
{file = "grpcio-1.44.0-cp38-cp38-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:8fa6584046a7cf281649975a363673fa5d9c6faf9dc923f261cc0e56713b5892"},
|
||||
{file = "grpcio-1.44.0-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:36a7bdd6ef9bca050c7ade8cba5f0e743343ea0756d5d3d520e915098a9dc503"},
|
||||
{file = "grpcio-1.44.0-cp38-cp38-win32.whl", hash = "sha256:dc3290d0411ddd2bd49adba5793223de8de8b01588d45e9376f1a9f7d25414f4"},
|
||||
{file = "grpcio-1.44.0-cp38-cp38-win_amd64.whl", hash = "sha256:13343e7b840c20f43b44f0e6d3bbdc037c964f0aec9735d7cb685c407731c9ff"},
|
||||
{file = "grpcio-1.44.0-cp39-cp39-linux_armv7l.whl", hash = "sha256:c5c2f8417d13386e18ccc8c61467cb6a6f9667a1ff7000a2d7d378e5d7df693f"},
|
||||
{file = "grpcio-1.44.0-cp39-cp39-macosx_10_10_x86_64.whl", hash = "sha256:cf220199b7b4992729ad4d55d5d3f652f4ccfe1a35b5eacdbecf189c245e1859"},
|
||||
{file = "grpcio-1.44.0-cp39-cp39-manylinux2010_i686.whl", hash = "sha256:4201c597e5057a9bfef9ea5777a6d83f6252cb78044db7d57d941ec2300734a5"},
|
||||
{file = "grpcio-1.44.0-cp39-cp39-manylinux2010_x86_64.whl", hash = "sha256:e2de61005118ae59d48d5d749283ebfd1ba4ca68cc1000f8a395cd2bdcff7ceb"},
|
||||
{file = "grpcio-1.44.0-cp39-cp39-manylinux_2_17_aarch64.whl", hash = "sha256:871078218fa9117e2a378678f327e32fda04e363ed6bc0477275444273255d4d"},
|
||||
{file = "grpcio-1.44.0-cp39-cp39-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:a8d610b7b557a7609fecee80b6dd793ecb7a9a3c3497fbdce63ce7d151cdd705"},
|
||||
{file = "grpcio-1.44.0-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:4fcb53e4eb8c271032c91b8981df5fc1bb974bc73e306ec2c27da41bd95c44b5"},
|
||||
{file = "grpcio-1.44.0-cp39-cp39-win32.whl", hash = "sha256:e50ddea6de76c09b656df4b5a55ae222e2a56e625c44250e501ff3c904113ec1"},
|
||||
{file = "grpcio-1.44.0-cp39-cp39-win_amd64.whl", hash = "sha256:d2ec124a986093e26420a5fb10fa3f02b2c232f924cdd7b844ddf7e846c020cd"},
|
||||
{file = "grpcio-1.44.0.tar.gz", hash = "sha256:4bae1c99896045d3062ab95478411c8d5a52cb84b91a1517312629fa6cfeb50e"},
|
||||
]
|
||||
grpcio-tools = [
|
||||
{file = "grpcio-tools-1.44.0.tar.gz", hash = "sha256:be37f458ea510c9a8f1caabbc2b258d12e55d189a567f5edcace90f27dc0efbf"},
|
||||
{file = "grpcio_tools-1.44.0-cp310-cp310-linux_armv7l.whl", hash = "sha256:9f58529e24f613019a85c258a274d441d89e0cad8cf7fca21ef3807ba5840c5d"},
|
||||
{file = "grpcio_tools-1.44.0-cp310-cp310-macosx_10_10_universal2.whl", hash = "sha256:1d120082236f8d2877f8a19366476b82c3562423b877b7c471a142432e31c2c4"},
|
||||
{file = "grpcio_tools-1.44.0-cp310-cp310-manylinux_2_17_aarch64.whl", hash = "sha256:65c2fe3cdc5425180f01dd303e28d4f363d38f4c2e3a7e1a87caedd5417e23bb"},
|
||||
{file = "grpcio_tools-1.44.0-cp310-cp310-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:5caef118deb8cdee1978fd3d8e388a9b256cd8d34e4a8895731ac0e86fa5e47c"},
|
||||
{file = "grpcio_tools-1.44.0-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:121c9765cee8636201cf0d4e80bc7b509813194919bccdb66e9671c4ece6dac3"},
|
||||
{file = "grpcio_tools-1.44.0-cp310-cp310-win32.whl", hash = "sha256:90d1fac188bac838c4169eb3b67197887fa0572ea8a90519a20cddb080800549"},
|
||||
{file = "grpcio_tools-1.44.0-cp310-cp310-win_amd64.whl", hash = "sha256:3e16260dfe6e997330473863e01466b0992369ae2337a0249b390b4651cff424"},
|
||||
{file = "grpcio_tools-1.44.0-cp36-cp36m-linux_armv7l.whl", hash = "sha256:608414cc1093e1e9e5980c97a6ee78e51dffff359e7a3f123d1fb9d95b8763a5"},
|
||||
{file = "grpcio_tools-1.44.0-cp36-cp36m-macosx_10_10_x86_64.whl", hash = "sha256:395609c06f69fbc79518b30a01931127088a3f9ef2cc2a35269c5f187eefd38c"},
|
||||
{file = "grpcio_tools-1.44.0-cp36-cp36m-manylinux2010_i686.whl", hash = "sha256:f7ce16766b24b88ec0e4355f5dd66c2eee6af210e889fcb7961c9c4634c687de"},
|
||||
{file = "grpcio_tools-1.44.0-cp36-cp36m-manylinux2010_x86_64.whl", hash = "sha256:3c9abc4a40c62f46d5e43e49c7afc567dedf12eeef95933ac9ea2986baa2420b"},
|
||||
{file = "grpcio_tools-1.44.0-cp36-cp36m-manylinux_2_17_aarch64.whl", hash = "sha256:b73fd87a44ba1b91866b0254193c37cdb001737759b77b637cebe0c816d38342"},
|
||||
{file = "grpcio_tools-1.44.0-cp36-cp36m-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:2b211f12e4cbc0fde8e0f982b0f581cce38874666a02ebfed93c23dcaeb8a4e0"},
|
||||
{file = "grpcio_tools-1.44.0-cp36-cp36m-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:9b421dc9b27bcaff4c73644cd3801e4893b11ba3eb39729246fd3de98d9f685b"},
|
||||
{file = "grpcio_tools-1.44.0-cp36-cp36m-win32.whl", hash = "sha256:33d93027840a873c7b59402fe6db8263b88c56e2f84aa0b6281c05cc8bd314a1"},
|
||||
{file = "grpcio_tools-1.44.0-cp36-cp36m-win_amd64.whl", hash = "sha256:71fb6e7e66b918803b1bebd0231560981ab86c2546a3318a45822ce94de5e83d"},
|
||||
{file = "grpcio_tools-1.44.0-cp37-cp37m-linux_armv7l.whl", hash = "sha256:614c427ff235d92f103e9189f0230197c8f2f817d0dd9fd078f5d2ea4d920d02"},
|
||||
{file = "grpcio_tools-1.44.0-cp37-cp37m-macosx_10_10_x86_64.whl", hash = "sha256:c13e0cb486cfa15320ddcd70452a4d736e6ce319c03d6b3c0c2513ec8d2748fb"},
|
||||
{file = "grpcio_tools-1.44.0-cp37-cp37m-manylinux2010_i686.whl", hash = "sha256:5ade6b13dc4e148f400c8f55a6ef0b14216a3371d7a9e559571d5981b6cec36b"},
|
||||
{file = "grpcio_tools-1.44.0-cp37-cp37m-manylinux2010_x86_64.whl", hash = "sha256:6138d2c7eec7ed57585bc58e2dbcb65635a2d574ac632abd29949d3e68936bab"},
|
||||
{file = "grpcio_tools-1.44.0-cp37-cp37m-manylinux_2_17_aarch64.whl", hash = "sha256:3d6c8548b199591757dbfe89ed14e23782d6079d6d201c6c314c72f4086883aa"},
|
||||
{file = "grpcio_tools-1.44.0-cp37-cp37m-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:b41c419829f01734d65958ba9b01b759061d8f7e0698f9612ba6b8837269f7a9"},
|
||||
{file = "grpcio_tools-1.44.0-cp37-cp37m-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:f9f0c5b4567631fec993826e694e83d86a972b3e2e9b05cb0c56839b0316d26c"},
|
||||
{file = "grpcio_tools-1.44.0-cp37-cp37m-win32.whl", hash = "sha256:3f0e1d1f3f5a6f0c9f8b5441819dbec831ce7e9ffe04768e4b0d965a95fbbe5e"},
|
||||
{file = "grpcio_tools-1.44.0-cp37-cp37m-win_amd64.whl", hash = "sha256:1f87fc86d0b4181b6b4da6ec6a29511dca000e6b5694fdd6bbf87d125128bc41"},
|
||||
{file = "grpcio_tools-1.44.0-cp38-cp38-linux_armv7l.whl", hash = "sha256:cb8baa1d4cea35ca662c24098377bdd9514c56f227da0e38b43cd9b8223bfcc6"},
|
||||
{file = "grpcio_tools-1.44.0-cp38-cp38-macosx_10_10_x86_64.whl", hash = "sha256:ea36a294f7c70fd2f2bfb5dcf08602006304aa65b055ebd4f7c709e2a89deba7"},
|
||||
{file = "grpcio_tools-1.44.0-cp38-cp38-manylinux2010_i686.whl", hash = "sha256:1972caf8f695b91edc6444134445798692fe71276f0cde7604d55e65179adf93"},
|
||||
{file = "grpcio_tools-1.44.0-cp38-cp38-manylinux2010_x86_64.whl", hash = "sha256:674fb8d9c0e2d75166c4385753962485b757897223fc92a19c9e513ab80b96f7"},
|
||||
{file = "grpcio_tools-1.44.0-cp38-cp38-manylinux_2_17_aarch64.whl", hash = "sha256:37045ba850d423cdacede77b266b127025818a5a36d80f1fd7a5a1614a6a0de5"},
|
||||
{file = "grpcio_tools-1.44.0-cp38-cp38-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:6cdf72947c6b0b03aa6dac06117a095947d02d43a5c6343051f4ce161fd0abcb"},
|
||||
{file = "grpcio_tools-1.44.0-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:69bfa6fc1515c202fe428ba9f99e2b2f947b01bafc15d868798235b2e2d36baa"},
|
||||
{file = "grpcio_tools-1.44.0-cp38-cp38-win32.whl", hash = "sha256:2c516124356476d9afa126acce10ce568733120afbd9ae17ee01d44b9da20a67"},
|
||||
{file = "grpcio_tools-1.44.0-cp38-cp38-win_amd64.whl", hash = "sha256:ceb6441c24176705c5ab056e65a8b330e107107c5a492ba094d1b862a136d15d"},
|
||||
{file = "grpcio_tools-1.44.0-cp39-cp39-linux_armv7l.whl", hash = "sha256:398eda759194d355eb09f7beabae6e4fb45b3877cf7efe505b49095fa4889cef"},
|
||||
{file = "grpcio_tools-1.44.0-cp39-cp39-macosx_10_10_x86_64.whl", hash = "sha256:a169bfd7a1fe8cc11472eeeeab3088b3c5d56caac12b2192a920b73adcbc974c"},
|
||||
{file = "grpcio_tools-1.44.0-cp39-cp39-manylinux2010_i686.whl", hash = "sha256:a58aaaec0d846d142edd8e794ebb80aa429abfd581f4493a60a603aac0c50ac8"},
|
||||
{file = "grpcio_tools-1.44.0-cp39-cp39-manylinux2010_x86_64.whl", hash = "sha256:c3253bee8b68fe422754faf0f286aa068861c926a7b11e4daeb44b9af767c7f1"},
|
||||
{file = "grpcio_tools-1.44.0-cp39-cp39-manylinux_2_17_aarch64.whl", hash = "sha256:3c0be60721ae1ba09c4f29572a145f412e561b9201e19428758893709827f472"},
|
||||
{file = "grpcio_tools-1.44.0-cp39-cp39-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:e44b9572c2226b85976e0d6054e22d7c59ebd6c9425ee71e5bc8910434aee3e1"},
|
||||
{file = "grpcio_tools-1.44.0-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:7c04ec47905c4f6d6dad34d29f6ace652cc1ddc986f55aaa5559b72104c3f5cf"},
|
||||
{file = "grpcio_tools-1.44.0-cp39-cp39-win32.whl", hash = "sha256:fb8c7b9d24e2c4dc77e7800e83b68081729ac6094b781b2afdabf08af18c3b28"},
|
||||
{file = "grpcio_tools-1.44.0-cp39-cp39-win_amd64.whl", hash = "sha256:4eb93619c8cb3773fb899504e3e30a0dc79d3904fd7a84091d15552178e1e920"},
|
||||
]
|
||||
iniconfig = [
|
||||
{file = "iniconfig-1.1.1-py2.py3-none-any.whl", hash = "sha256:011e24c64b7f47f6ebd835bb12a743f2fbe9a26d4cecaa7f53bc4f35ee9da8b3"},
|
||||
{file = "iniconfig-1.1.1.tar.gz", hash = "sha256:bc3af051d7d14b2ee5ef9969666def0cd1a000e121eaea580d4a313df4b37f32"},
|
||||
]
|
||||
loguru = [
|
||||
{file = "loguru-0.6.0-py3-none-any.whl", hash = "sha256:4e2414d534a2ab57573365b3e6d0234dfb1d84b68b7f3b948e6fb743860a77c3"},
|
||||
{file = "loguru-0.6.0.tar.gz", hash = "sha256:066bd06758d0a513e9836fd9c6b5a75bfb3fd36841f4b996bc60b547a309d41c"},
|
||||
]
|
||||
mccabe = [
|
||||
{file = "mccabe-0.6.1-py2.py3-none-any.whl", hash = "sha256:ab8a6258860da4b6677da4bd2fe5dc2c659cff31b3ee4f7f5d64e79735b80d42"},
|
||||
{file = "mccabe-0.6.1.tar.gz", hash = "sha256:dd8d182285a0fe56bace7f45b5e7d1a6ebcbf524e8f3bd87eb0f125271b8831f"},
|
||||
]
|
||||
packaging = [
|
||||
{file = "packaging-21.3-py3-none-any.whl", hash = "sha256:ef103e05f519cdc783ae24ea4e2e0f508a9c99b2d4969652eed6a2e1ea5bd522"},
|
||||
{file = "packaging-21.3.tar.gz", hash = "sha256:dd47c42927d89ab911e606518907cc2d3a1f38bbd026385970643f9c5b8ecfeb"},
|
||||
]
|
||||
pluggy = [
|
||||
{file = "pluggy-1.0.0-py2.py3-none-any.whl", hash = "sha256:74134bbf457f031a36d68416e1509f34bd5ccc019f0bcc952c7b909d06b37bd3"},
|
||||
{file = "pluggy-1.0.0.tar.gz", hash = "sha256:4224373bacce55f955a878bf9cfa763c1e360858e330072059e10bad68531159"},
|
||||
]
|
||||
protobuf = [
|
||||
{file = "protobuf-3.19.4-cp310-cp310-macosx_10_9_universal2.whl", hash = "sha256:f51d5a9f137f7a2cec2d326a74b6e3fc79d635d69ffe1b036d39fc7d75430d37"},
|
||||
{file = "protobuf-3.19.4-cp310-cp310-manylinux2014_aarch64.whl", hash = "sha256:09297b7972da685ce269ec52af761743714996b4381c085205914c41fcab59fb"},
|
||||
{file = "protobuf-3.19.4-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:072fbc78d705d3edc7ccac58a62c4c8e0cec856987da7df8aca86e647be4e35c"},
|
||||
{file = "protobuf-3.19.4-cp310-cp310-win32.whl", hash = "sha256:7bb03bc2873a2842e5ebb4801f5c7ff1bfbdf426f85d0172f7644fcda0671ae0"},
|
||||
{file = "protobuf-3.19.4-cp310-cp310-win_amd64.whl", hash = "sha256:f358aa33e03b7a84e0d91270a4d4d8f5df6921abe99a377828839e8ed0c04e07"},
|
||||
{file = "protobuf-3.19.4-cp36-cp36m-macosx_10_9_x86_64.whl", hash = "sha256:1c91ef4110fdd2c590effb5dca8fdbdcb3bf563eece99287019c4204f53d81a4"},
|
||||
{file = "protobuf-3.19.4-cp36-cp36m-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:c438268eebb8cf039552897d78f402d734a404f1360592fef55297285f7f953f"},
|
||||
{file = "protobuf-3.19.4-cp36-cp36m-win32.whl", hash = "sha256:835a9c949dc193953c319603b2961c5c8f4327957fe23d914ca80d982665e8ee"},
|
||||
{file = "protobuf-3.19.4-cp36-cp36m-win_amd64.whl", hash = "sha256:4276cdec4447bd5015453e41bdc0c0c1234eda08420b7c9a18b8d647add51e4b"},
|
||||
{file = "protobuf-3.19.4-cp37-cp37m-macosx_10_9_x86_64.whl", hash = "sha256:6cbc312be5e71869d9d5ea25147cdf652a6781cf4d906497ca7690b7b9b5df13"},
|
||||
{file = "protobuf-3.19.4-cp37-cp37m-manylinux2014_aarch64.whl", hash = "sha256:54a1473077f3b616779ce31f477351a45b4fef8c9fd7892d6d87e287a38df368"},
|
||||
{file = "protobuf-3.19.4-cp37-cp37m-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:435bb78b37fc386f9275a7035fe4fb1364484e38980d0dd91bc834a02c5ec909"},
|
||||
{file = "protobuf-3.19.4-cp37-cp37m-win32.whl", hash = "sha256:16f519de1313f1b7139ad70772e7db515b1420d208cb16c6d7858ea989fc64a9"},
|
||||
{file = "protobuf-3.19.4-cp37-cp37m-win_amd64.whl", hash = "sha256:cdc076c03381f5c1d9bb1abdcc5503d9ca8b53cf0a9d31a9f6754ec9e6c8af0f"},
|
||||
{file = "protobuf-3.19.4-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:69da7d39e39942bd52848438462674c463e23963a1fdaa84d88df7fbd7e749b2"},
|
||||
{file = "protobuf-3.19.4-cp38-cp38-manylinux2014_aarch64.whl", hash = "sha256:48ed3877fa43e22bcacc852ca76d4775741f9709dd9575881a373bd3e85e54b2"},
|
||||
{file = "protobuf-3.19.4-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:bd95d1dfb9c4f4563e6093a9aa19d9c186bf98fa54da5252531cc0d3a07977e7"},
|
||||
{file = "protobuf-3.19.4-cp38-cp38-win32.whl", hash = "sha256:b38057450a0c566cbd04890a40edf916db890f2818e8682221611d78dc32ae26"},
|
||||
{file = "protobuf-3.19.4-cp38-cp38-win_amd64.whl", hash = "sha256:7ca7da9c339ca8890d66958f5462beabd611eca6c958691a8fe6eccbd1eb0c6e"},
|
||||
{file = "protobuf-3.19.4-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:36cecbabbda242915529b8ff364f2263cd4de7c46bbe361418b5ed859677ba58"},
|
||||
{file = "protobuf-3.19.4-cp39-cp39-manylinux2014_aarch64.whl", hash = "sha256:c1068287025f8ea025103e37d62ffd63fec8e9e636246b89c341aeda8a67c934"},
|
||||
{file = "protobuf-3.19.4-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:96bd766831596d6014ca88d86dc8fe0fb2e428c0b02432fd9db3943202bf8c5e"},
|
||||
{file = "protobuf-3.19.4-cp39-cp39-win32.whl", hash = "sha256:84123274d982b9e248a143dadd1b9815049f4477dc783bf84efe6250eb4b836a"},
|
||||
{file = "protobuf-3.19.4-cp39-cp39-win_amd64.whl", hash = "sha256:3112b58aac3bac9c8be2b60a9daf6b558ca3f7681c130dcdd788ade7c9ffbdca"},
|
||||
{file = "protobuf-3.19.4-py2.py3-none-any.whl", hash = "sha256:8961c3a78ebfcd000920c9060a262f082f29838682b1f7201889300c1fbe0616"},
|
||||
{file = "protobuf-3.19.4.tar.gz", hash = "sha256:9df0c10adf3e83015ced42a9a7bd64e13d06c4cf45c340d2c63020ea04499d0a"},
|
||||
]
|
||||
py = [
|
||||
{file = "py-1.11.0-py2.py3-none-any.whl", hash = "sha256:607c53218732647dff4acdfcd50cb62615cedf612e72d1724fb1a0cc6405b378"},
|
||||
{file = "py-1.11.0.tar.gz", hash = "sha256:51c75c4126074b472f746a24399ad32f6053d1b34b68d2fa41e558e6f4a98719"},
|
||||
]
|
||||
pycodestyle = [
|
||||
{file = "pycodestyle-2.8.0-py2.py3-none-any.whl", hash = "sha256:720f8b39dde8b293825e7ff02c475f3077124006db4f440dcbc9a20b76548a20"},
|
||||
{file = "pycodestyle-2.8.0.tar.gz", hash = "sha256:eddd5847ef438ea1c7870ca7eb78a9d47ce0cdb4851a5523949f2601d0cbbe7f"},
|
||||
]
|
||||
pyflakes = [
|
||||
{file = "pyflakes-2.4.0-py2.py3-none-any.whl", hash = "sha256:3bb3a3f256f4b7968c9c788781e4ff07dce46bdf12339dcda61053375426ee2e"},
|
||||
{file = "pyflakes-2.4.0.tar.gz", hash = "sha256:05a85c2872edf37a4ed30b0cce2f6093e1d0581f8c19d7393122da7e25b2b24c"},
|
||||
]
|
||||
pyparsing = [
|
||||
{file = "pyparsing-3.0.7-py3-none-any.whl", hash = "sha256:a6c06a88f252e6c322f65faf8f418b16213b51bdfaece0524c1c1bc30c63c484"},
|
||||
{file = "pyparsing-3.0.7.tar.gz", hash = "sha256:18ee9022775d270c55187733956460083db60b37d0d0fb357445f3094eed3eea"},
|
||||
]
|
||||
pytest = [
|
||||
{file = "pytest-7.0.1-py3-none-any.whl", hash = "sha256:9ce3ff477af913ecf6321fe337b93a2c0dcf2a0a1439c43f5452112c1e4280db"},
|
||||
{file = "pytest-7.0.1.tar.gz", hash = "sha256:e30905a0c131d3d94b89624a1cc5afec3e0ba2fbdb151867d8e0ebd49850f171"},
|
||||
]
|
||||
six = [
|
||||
{file = "six-1.16.0-py2.py3-none-any.whl", hash = "sha256:8abb2f1d86890a2dfb989f9a77cfcfd3e47c2a354b01111771326f8aa26e0254"},
|
||||
{file = "six-1.16.0.tar.gz", hash = "sha256:1e61c37477a1626458e36f7b1d82aa5c9b094fa4802892072e49de9c60c4c926"},
|
||||
]
|
||||
tomli = [
|
||||
{file = "tomli-2.0.1-py3-none-any.whl", hash = "sha256:939de3e7a6161af0c887ef91b7d41a53e7c5a1ca976325f429cb46ea9bc30ecc"},
|
||||
{file = "tomli-2.0.1.tar.gz", hash = "sha256:de526c12914f0c550d15924c62d72abc48d6fe7364aa87328337a31007fe8a4f"},
|
||||
]
|
||||
win32-setctime = [
|
||||
{file = "win32_setctime-1.1.0-py3-none-any.whl", hash = "sha256:231db239e959c2fe7eb1d7dc129f11172354f98361c4fa2d6d2d7e278baa8aad"},
|
||||
{file = "win32_setctime-1.1.0.tar.gz", hash = "sha256:15cf5750465118d6929ae4de4eb46e8edae9a5634350c01ba582df868e932cb2"},
|
||||
]
|
File diff suppressed because one or more lines are too long
|
@ -1,8 +1,8 @@
|
|||
[tool.poetry]
|
||||
name = "pybbgo"
|
||||
name = "bbgo"
|
||||
version = "0.1.0"
|
||||
description = ""
|
||||
authors = ["なるみ <narumi@maicoin.com>"]
|
||||
authors = ["なるみ <weaper@gmail.com>"]
|
||||
|
||||
[tool.poetry.dependencies]
|
||||
python = "^3.8"
|
||||
|
@ -10,8 +10,10 @@ click = "^8.0.4"
|
|||
loguru = "^0.6.0"
|
||||
grpcio = "^1.44.0"
|
||||
grpcio-tools = "^1.44.0"
|
||||
flake8 = "^4.0.1"
|
||||
|
||||
[tool.poetry.dev-dependencies]
|
||||
pytest = "^7.0.1"
|
||||
|
||||
[build-system]
|
||||
requires = ["poetry-core>=1.0.0"]
|
||||
|
|
|
@ -1,6 +1,8 @@
|
|||
[flake8]
|
||||
max-line-length = 120
|
||||
per-file-ignores = __init__.py: F401
|
||||
# ignore =
|
||||
exclude = bbgo_pb2.py, bbgo_pb2_grpc.py
|
||||
|
||||
[yapf]
|
||||
based_on_style = google
|
||||
|
|
67
python/tests/servicer.py
Normal file
67
python/tests/servicer.py
Normal file
|
@ -0,0 +1,67 @@
|
|||
import random
|
||||
import time
|
||||
|
||||
from bbgo import bbgo_pb2
|
||||
from bbgo import bbgo_pb2_grpc
|
||||
|
||||
|
||||
class TestServicer(bbgo_pb2_grpc.BBGOServicer):
|
||||
|
||||
def Subcribe(self, request, context):
|
||||
i = 0
|
||||
while True:
|
||||
for subscription in request.subscriptions:
|
||||
yield bbgo_pb2.SubscribeResponse(
|
||||
channel=subscription.channel,
|
||||
event=bbgo_pb2.Event.UPDATE,
|
||||
exchange=subscription.exchange,
|
||||
symbol=subscription.symbol + f'_{i}',
|
||||
)
|
||||
i += 1
|
||||
time.sleep(random.random())
|
||||
|
||||
def SubcribeUserData(self, request, context):
|
||||
i = 0
|
||||
while True:
|
||||
yield bbgo_pb2.SubscribeResponse(
|
||||
channel=bbgo_pb2.Channel.USER,
|
||||
event=bbgo_pb2.Event.ORDER_UPDATE,
|
||||
exchange='max',
|
||||
symbol=f'user_{i}',
|
||||
)
|
||||
i += 1
|
||||
time.sleep(random.random())
|
||||
|
||||
def SubmitOrder(self, request, context):
|
||||
submit_order = request.submit_order
|
||||
|
||||
order = bbgo_pb2.Order(
|
||||
exchange=submit_order.exchange,
|
||||
symbol=submit_order.symbol,
|
||||
side=submit_order.side,
|
||||
quantity=submit_order.quantity,
|
||||
price=submit_order.price,
|
||||
stop_price=submit_order.stop_price,
|
||||
order_type=submit_order.order_type,
|
||||
client_order_id=submit_order.client_order_id,
|
||||
group_id=submit_order.group_id,
|
||||
)
|
||||
|
||||
error = bbgo_pb2.Error(error_code=0, error_message='')
|
||||
|
||||
return bbgo_pb2.SubmitOrderResponse(order=order, error=error)
|
||||
|
||||
def CancelOrder(self, request, context):
|
||||
pass
|
||||
|
||||
def QueryOrder(self, request, context):
|
||||
pass
|
||||
|
||||
def QueryOrders(self, request, context):
|
||||
pass
|
||||
|
||||
def QueryTrades(self, request, context):
|
||||
pass
|
||||
|
||||
def QueryKLines(self, request, context):
|
||||
pass
|
58
python/tests/test_grpc.py
Normal file
58
python/tests/test_grpc.py
Normal file
|
@ -0,0 +1,58 @@
|
|||
from concurrent import futures
|
||||
|
||||
import grpc
|
||||
import pytest
|
||||
|
||||
from bbgo import BBGO
|
||||
from bbgo import bbgo_pb2
|
||||
from bbgo import bbgo_pb2_grpc
|
||||
from tests.servicer import TestServicer
|
||||
|
||||
|
||||
@pytest.fixture
|
||||
def grpc_address(host='[::]', port=50051):
|
||||
return f'{host}:{port}'
|
||||
|
||||
|
||||
@pytest.fixture
|
||||
def bbgo(host='[::]', port=50051):
|
||||
return BBGO(host, port)
|
||||
|
||||
|
||||
@pytest.fixture
|
||||
def grpc_channel(grpc_address):
|
||||
return grpc.insecure_channel(grpc_address)
|
||||
|
||||
|
||||
@pytest.fixture
|
||||
def grpc_server(grpc_address, max_workers=1):
|
||||
server = grpc.server(futures.ThreadPoolExecutor(max_workers))
|
||||
servicer = TestServicer()
|
||||
bbgo_pb2_grpc.add_BBGOServicer_to_server(servicer, server)
|
||||
server.add_insecure_port(grpc_address)
|
||||
server.start()
|
||||
yield server
|
||||
server.stop(grace=None)
|
||||
|
||||
|
||||
def test_submit_order(bbgo, grpc_server):
|
||||
exchange = 'max'
|
||||
symbol = 'BTCUSDT'
|
||||
side = bbgo_pb2.Side.BUY
|
||||
quantity = 0.01
|
||||
order_type = bbgo_pb2.OrderType.LIMIT
|
||||
|
||||
response = bbgo.submit_order(
|
||||
exchange=exchange,
|
||||
symbol=symbol,
|
||||
side=side,
|
||||
quantity=quantity,
|
||||
order_type=order_type,
|
||||
)
|
||||
|
||||
order = response.order
|
||||
|
||||
assert order.exchange == exchange
|
||||
assert order.symbol == symbol
|
||||
assert order.side == side
|
||||
assert order.quantity == quantity
|
Loading…
Reference in New Issue
Block a user