Add `TimeseriesNotFound` for fqme lookup failures
A common usage error is to run `piker anal mnq.cme.ib` where the CLI passed fqme is not actually fully-qualified (in this case missing an expiry token) and we get an underlying `FileNotFoundError` from the `StorageClient.read_ohlcv()` call. In such key misses, scan the existing `StorageClient._index` for possible matches and report in a `raise from` the new error. CHERRY into #486distribute_dis
parent
ebd1eb114e
commit
24a54a7085
|
@ -142,14 +142,21 @@ def anal(
|
||||||
period: int = 60,
|
period: int = 60,
|
||||||
|
|
||||||
) -> np.ndarray:
|
) -> np.ndarray:
|
||||||
|
'''
|
||||||
|
Anal-ysis is when you take the data do stuff to it, i think.
|
||||||
|
|
||||||
|
'''
|
||||||
async def main():
|
async def main():
|
||||||
async with (
|
async with (
|
||||||
open_piker_runtime(
|
open_piker_runtime(
|
||||||
|
# are you a bear or boi?
|
||||||
'tsdb_polars_anal',
|
'tsdb_polars_anal',
|
||||||
debug_mode=True,
|
debug_mode=True,
|
||||||
),
|
),
|
||||||
open_storage_client() as (mod, client),
|
open_storage_client() as (
|
||||||
|
mod,
|
||||||
|
client,
|
||||||
|
),
|
||||||
):
|
):
|
||||||
syms: list[str] = await client.list_keys()
|
syms: list[str] = await client.list_keys()
|
||||||
print(f'{len(syms)} FOUND for {mod.name}')
|
print(f'{len(syms)} FOUND for {mod.name}')
|
||||||
|
|
|
@ -72,6 +72,12 @@ from piker.log import get_logger
|
||||||
log = get_logger('storage.nativedb')
|
log = get_logger('storage.nativedb')
|
||||||
|
|
||||||
|
|
||||||
|
class TimeseriesNotFound(Exception):
|
||||||
|
'''
|
||||||
|
No timeseries entry can be found for this backend.
|
||||||
|
|
||||||
|
'''
|
||||||
|
|
||||||
# NOTE: thanks to this SO answer for the below conversion routines
|
# NOTE: thanks to this SO answer for the below conversion routines
|
||||||
# to go from numpy struct-arrays to polars dataframes and back:
|
# to go from numpy struct-arrays to polars dataframes and back:
|
||||||
# https://stackoverflow.com/a/72054819
|
# https://stackoverflow.com/a/72054819
|
||||||
|
@ -228,8 +234,21 @@ class NativeStorageClient:
|
||||||
fqme,
|
fqme,
|
||||||
timeframe,
|
timeframe,
|
||||||
)
|
)
|
||||||
except FileNotFoundError:
|
except FileNotFoundError as fnfe:
|
||||||
return None
|
|
||||||
|
bs_fqme, _, *_ = fqme.rpartition('.')
|
||||||
|
|
||||||
|
possible_matches: list[str] = []
|
||||||
|
for tskey in self._index:
|
||||||
|
if bs_fqme in tskey:
|
||||||
|
possible_matches.append(tskey)
|
||||||
|
|
||||||
|
match_str: str = '\n'.join(possible_matches)
|
||||||
|
raise TimeseriesNotFound(
|
||||||
|
f'No entry for `{fqme}`?\n'
|
||||||
|
f'Maybe you need a more specific fqme-key like:\n\n'
|
||||||
|
f'{match_str}'
|
||||||
|
) from fnfe
|
||||||
|
|
||||||
times = array['time']
|
times = array['time']
|
||||||
return (
|
return (
|
||||||
|
@ -376,6 +395,8 @@ class NativeStorageClient:
|
||||||
# ...
|
# ...
|
||||||
|
|
||||||
|
|
||||||
|
# TODO: does this need to be async on average?
|
||||||
|
# I guess for any IPC connected backend yes?
|
||||||
@acm
|
@acm
|
||||||
async def get_client(
|
async def get_client(
|
||||||
|
|
||||||
|
@ -393,7 +414,7 @@ async def get_client(
|
||||||
'''
|
'''
|
||||||
datadir: Path = config.get_conf_dir() / 'nativedb'
|
datadir: Path = config.get_conf_dir() / 'nativedb'
|
||||||
if not datadir.is_dir():
|
if not datadir.is_dir():
|
||||||
log.info(f'Creating `nativedb` director: {datadir}')
|
log.info(f'Creating `nativedb` dir: {datadir}')
|
||||||
datadir.mkdir()
|
datadir.mkdir()
|
||||||
|
|
||||||
client = NativeStorageClient(datadir)
|
client = NativeStorageClient(datadir)
|
||||||
|
|
Loading…
Reference in New Issue