.data.validate: add missing endpoint warnings

master
Tyler Goodlet 2023-05-25 16:01:21 -04:00
parent da4d344e63
commit 9c80969fd5
2 changed files with 46 additions and 2 deletions

View File

@ -25,6 +25,7 @@ __brokers__ = [
'ib', 'ib',
'kraken', 'kraken',
'kucoin' 'kucoin'
# broken but used to work # broken but used to work
# 'questrade', # 'questrade',
# 'robinhood', # 'robinhood',

View File

@ -23,6 +23,7 @@ from pprint import pformat
from types import ModuleType from types import ModuleType
from typing import ( from typing import (
Any, Any,
Callable,
) )
from msgspec import field from msgspec import field
@ -60,6 +61,31 @@ class FeedInit(Struct, frozen=True):
'sum_tick_vlm': True, 'sum_tick_vlm': True,
}) })
# XXX: we group backend endpoints into 3
# groups to determine "degrees" of functionality.
_eps: dict[str, list[str]] = {
# basic API `Client` layer
'middleware': [
'get_client',
],
# (live) data streaming / loading / search
'datad': [
'get_mkt_info',
'open_history_client',
'open_symbol_search',
'stream_quotes',
],
# live order control and trading
'brokerd': [
'trades_dialogue',
# TODO: ledger normalizer helper?
# norm_trades(records: dict[str, Any]) -> TransactionLedger)
],
}
def validate_backend( def validate_backend(
mod: ModuleType, mod: ModuleType,
@ -77,6 +103,20 @@ def validate_backend(
that haven't been implemented by this backend yet. that haven't been implemented by this backend yet.
''' '''
for daemon_name, eps in _eps.items():
for name in eps:
ep: Callable = getattr(
mod,
name,
None,
)
if ep is None:
log.warning(
f'Provider backend {mod.name} is missing '
f'{daemon_name} support :(\n'
f'The following endpoint is missing: {name}'
)
inits: list[ inits: list[
FeedInit | dict[str, Any] FeedInit | dict[str, Any]
] = init_msgs ] = init_msgs
@ -128,6 +168,8 @@ def validate_backend(
mkt: MktPair mkt: MktPair
match init: match init:
# backend is using old dict msg delivery
case { case {
'symbol_info': dict(symbol_info), 'symbol_info': dict(symbol_info),
'fqsn': bs_fqme, 'fqsn': bs_fqme,
@ -164,6 +206,7 @@ def validate_backend(
_atype=symbol_info['asset_type'] _atype=symbol_info['asset_type']
) )
# backend is using new `MktPair` but not entirely
case { case {
'mkt_info': MktPair( 'mkt_info': MktPair(
dst=Asset(), dst=Asset(),
@ -182,7 +225,6 @@ def validate_backend(
) as init: ) as init:
name: str = mod.name name: str = mod.name
log.info( log.info(
f'NICE JOB {name} BACKEND being fully up to API spec B)\n'
f"{name}'s `MktPair` info:\n" f"{name}'s `MktPair` info:\n"
f'{pformat(mkt.to_dict())}\n' f'{pformat(mkt.to_dict())}\n'
f'shm conf: {pformat(shm_opts)}\n' f'shm conf: {pformat(shm_opts)}\n'
@ -203,7 +245,8 @@ def validate_backend(
mkt = init.mkt_info mkt = init.mkt_info
assert mkt.type_key assert mkt.type_key
# `MktPair` wish list # backend is using new `MktPair` but not embedded `Asset` types
# for the .src/.dst..
if not isinstance(mkt.src, Asset): if not isinstance(mkt.src, Asset):
warn_msg += ( warn_msg += (
f'ALSO, {mod.name.upper()} should try to deliver\n' f'ALSO, {mod.name.upper()} should try to deliver\n'