Skip to content

Commit 5ce951f

Browse files
authored
VER: Release 0.31.0
See release notes.
2 parents cab2937 + 89fb013 commit 5ce951f

35 files changed

+233
-158
lines changed

CHANGELOG.md

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,11 @@
11
# Changelog
22

3+
## 0.31.0 - 2024-03-05
4+
5+
#### Enhancements
6+
- Added `DBNStore.insert_symbology_json` convenience method for adding symbology data from a JSON dict or file path
7+
- Upgraded `databento-dbn` to 0.16.0
8+
39
## 0.30.0 - 2024-02-22
410

511
#### Enhancements

README.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -32,7 +32,7 @@ The library is fully compatible with the latest distribution of Anaconda 3.8 and
3232
The minimum dependencies as found in the `pyproject.toml` are also listed below:
3333
- python = "^3.8"
3434
- aiohttp = "^3.8.3"
35-
- databento-dbn = "0.15.1"
35+
- databento-dbn = "0.16.0"
3636
- numpy= ">=1.23.5"
3737
- pandas = ">=1.5.3"
3838
- pyarrow = ">=13.0.0"

databento/common/constants.py

Lines changed: 1 addition & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -21,9 +21,7 @@
2121

2222

2323
DEFINITION_TYPE_MAX_MAP: Final = {
24-
x[0]: np.iinfo(x[1]).max
25-
for x in InstrumentDefMsg._dtypes
26-
if not isinstance(x[1], str)
24+
x[0]: np.iinfo(x[1]).max for x in InstrumentDefMsg._dtypes if not isinstance(x[1], str)
2725
}
2826

2927
INT64_NULL: Final = 9223372036854775807

databento/common/cram.py

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
"""
22
Functions for handling challenge-response authentication.
33
"""
4+
45
import argparse
56
import hashlib
67
import os

databento/common/dbnstore.py

Lines changed: 53 additions & 39 deletions
Original file line numberDiff line numberDiff line change
@@ -6,20 +6,20 @@
66
import logging
77
from collections.abc import Generator
88
from collections.abc import Iterator
9+
from collections.abc import Mapping
910
from io import BytesIO
1011
from os import PathLike
1112
from pathlib import Path
12-
from typing import (
13-
IO,
14-
TYPE_CHECKING,
15-
Any,
16-
BinaryIO,
17-
Callable,
18-
Final,
19-
Literal,
20-
Protocol,
21-
overload,
22-
)
13+
from typing import IO
14+
from typing import TYPE_CHECKING
15+
from typing import Any
16+
from typing import BinaryIO
17+
from typing import Callable
18+
from typing import Final
19+
from typing import Literal
20+
from typing import Protocol
21+
from typing import TextIO
22+
from typing import overload
2323

2424
import databento_dbn
2525
import numpy as np
@@ -49,6 +49,7 @@
4949
from databento.common.symbology import InstrumentMap
5050
from databento.common.types import DBNRecord
5151
from databento.common.types import Default
52+
from databento.common.types import MappingIntervalDict
5253
from databento.common.validation import validate_enum
5354
from databento.common.validation import validate_file_write_path
5455
from databento.common.validation import validate_maybe_enum
@@ -108,20 +109,16 @@ class DataSource(abc.ABC):
108109
Abstract base class for backing DBNStore instances with data.
109110
"""
110111

111-
def __init__(self, source: object) -> None:
112-
...
112+
def __init__(self, source: object) -> None: ...
113113

114114
@property
115-
def name(self) -> str:
116-
...
115+
def name(self) -> str: ...
117116

118117
@property
119-
def nbytes(self) -> int:
120-
...
118+
def nbytes(self) -> int: ...
121119

122120
@property
123-
def reader(self) -> IO[bytes]:
124-
...
121+
def reader(self) -> IO[bytes]: ...
125122

126123

127124
class FileDataSource(DataSource):
@@ -371,6 +368,7 @@ def __init__(self, data_source: DataSource) -> None:
371368
# Read metadata
372369
self._metadata: Metadata = Metadata.decode(
373370
metadata_bytes.getvalue(),
371+
upgrade_policy=VersionUpgradePolicy.AS_IS,
374372
)
375373

376374
self._instrument_map = InstrumentMap()
@@ -384,10 +382,7 @@ def __iter__(self) -> Generator[DBNRecord, None, None]:
384382
raw = reader.read(DBNStore.DBN_READ_SIZE)
385383
if raw:
386384
decoder.write(raw)
387-
try:
388-
records = decoder.decode()
389-
except ValueError:
390-
continue
385+
records = decoder.decode()
391386
for record in records:
392387
if isinstance(record, databento_dbn.Metadata):
393388
continue
@@ -475,7 +470,7 @@ def nbytes(self) -> int:
475470
return self._data_source.nbytes
476471

477472
@property
478-
def mappings(self) -> dict[str, list[dict[str, Any]]]:
473+
def mappings(self) -> dict[str, list[MappingIntervalDict]]:
479474
"""
480475
Return the symbology mappings for the data.
481476
@@ -675,6 +670,27 @@ def from_bytes(cls, data: BytesIO | bytes | IO[bytes]) -> DBNStore:
675670
"""
676671
return cls(MemoryDataSource(data))
677672

673+
def insert_symbology_json(
674+
self,
675+
json_data: str | Mapping[str, Any] | TextIO,
676+
clear_existing: bool = True,
677+
) -> None:
678+
"""
679+
Insert the given JSON data obtained from the `symbology.resolve`
680+
endpoint or a `symbology.json` file.
681+
682+
Parameters
683+
----------
684+
json_data : str | Mapping[str, Any] | TextIO
685+
The JSON data to insert.
686+
clear_existing : bool, default True
687+
If existing symbology data should be cleared from the internal mappings.
688+
689+
"""
690+
if clear_existing:
691+
self._instrument_map.clear()
692+
self._instrument_map.insert_json(json_data)
693+
678694
def replay(self, callback: Callable[[Any], None]) -> None:
679695
"""
680696
Replay data by passing records sequentially to the given callback.
@@ -834,8 +850,7 @@ def to_df(
834850
schema: Schema | str | None = ...,
835851
tz: pytz.BaseTzInfo | str = ...,
836852
count: None = ...,
837-
) -> pd.DataFrame:
838-
...
853+
) -> pd.DataFrame: ...
839854

840855
@overload
841856
def to_df(
@@ -846,16 +861,17 @@ def to_df(
846861
schema: Schema | str | None = ...,
847862
tz: pytz.BaseTzInfo | str = ...,
848863
count: int = ...,
849-
) -> DataFrameIterator:
850-
...
864+
) -> DataFrameIterator: ...
851865

852866
def to_df(
853867
self,
854868
price_type: Literal["fixed", "float", "decimal"] = "float",
855869
pretty_ts: bool = True,
856870
map_symbols: bool = True,
857871
schema: Schema | str | None = None,
858-
tz: pytz.BaseTzInfo | str | Default[pytz.BaseTzInfo] = Default[pytz.BaseTzInfo](pytz.UTC),
872+
tz: pytz.BaseTzInfo | str | Default[pytz.BaseTzInfo] = Default[pytz.BaseTzInfo](
873+
pytz.UTC,
874+
),
859875
count: int | None = None,
860876
) -> pd.DataFrame | DataFrameIterator:
861877
"""
@@ -903,7 +919,9 @@ def to_df(
903919
if isinstance(tz, Default):
904920
tz = tz.value # consume default
905921
elif not pretty_ts:
906-
raise ValueError("A timezone was specified when `pretty_ts` is `False`. Did you mean to set `pretty_ts=True`?")
922+
raise ValueError(
923+
"A timezone was specified when `pretty_ts` is `False`. Did you mean to set `pretty_ts=True`?",
924+
)
907925

908926
if not isinstance(tz, pytz.BaseTzInfo):
909927
tz = pytz.timezone(tz)
@@ -1096,16 +1114,14 @@ def to_ndarray( # type: ignore [misc]
10961114
self,
10971115
schema: Schema | str | None = ...,
10981116
count: None = ...,
1099-
) -> np.ndarray[Any, Any]:
1100-
...
1117+
) -> np.ndarray[Any, Any]: ...
11011118

11021119
@overload
11031120
def to_ndarray(
11041121
self,
11051122
schema: Schema | str | None = ...,
11061123
count: int = ...,
1107-
) -> NDArrayIterator:
1108-
...
1124+
) -> NDArrayIterator: ...
11091125

11101126
def to_ndarray(
11111127
self,
@@ -1208,7 +1224,7 @@ def _transcode(
12081224
pretty_ts=pretty_ts,
12091225
has_metadata=True,
12101226
map_symbols=map_symbols,
1211-
symbol_interval_map=symbol_map,
1227+
symbol_interval_map=symbol_map, # type: ignore [arg-type]
12121228
schema=schema,
12131229
)
12141230

@@ -1242,12 +1258,10 @@ def _schema_struct_map(self) -> dict[Schema, type[DBNRecord]]:
12421258

12431259
class NDArrayIterator(Protocol):
12441260
@abc.abstractmethod
1245-
def __iter__(self) -> NDArrayIterator:
1246-
...
1261+
def __iter__(self) -> NDArrayIterator: ...
12471262

12481263
@abc.abstractmethod
1249-
def __next__(self) -> np.ndarray[Any, Any]:
1250-
...
1264+
def __next__(self) -> np.ndarray[Any, Any]: ...
12511265

12521266

12531267
class NDArrayStreamIterator(NDArrayIterator):

databento/common/enums.py

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,8 @@
44
from enum import Flag
55
from enum import IntFlag
66
from enum import unique
7-
from typing import Callable, TypeVar
7+
from typing import Callable
8+
from typing import TypeVar
89

910

1011
M = TypeVar("M", bound=Enum)

databento/common/error.py

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -30,8 +30,7 @@ def __init__(
3030
http_body = http_body.decode("utf-8")
3131
except UnicodeDecodeError:
3232
http_body = (
33-
"<Could not decode body as utf-8. "
34-
"Please report to support@databento.com>"
33+
"<Could not decode body as utf-8. Please report to support@databento.com>"
3534
)
3635

3736
self.http_status = http_status

databento/common/publishers.py

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,6 @@
1010
# ruff: noqa: C901
1111

1212

13-
1413
@unique
1514
@coercible
1615
class Venue(StringyMixin, str, Enum):
@@ -419,6 +418,7 @@ def description(self) -> str:
419418
return "Long-Term Stock Exchange, Inc."
420419
raise ValueError("Unexpected Venue value")
421420

421+
422422
@unique
423423
@coercible
424424
class Dataset(StringyMixin, str, Enum):
@@ -719,6 +719,7 @@ def description(self) -> str:
719719
return "Databento Equities Max"
720720
raise ValueError("Unexpected Dataset value")
721721

722+
722723
@unique
723724
@coercible
724725
class Publisher(StringyMixin, str, Enum):
@@ -1301,6 +1302,7 @@ def to_int(self) -> int:
13011302
if self == Publisher.DBEQ_MAX_LTSE:
13021303
return 80
13031304
raise ValueError("Invalid Publisher")
1305+
13041306
@property
13051307
def venue(self) -> Venue:
13061308
"""
@@ -1467,6 +1469,7 @@ def venue(self) -> Venue:
14671469
if self == Publisher.DBEQ_MAX_LTSE:
14681470
return Venue.LTSE
14691471
raise ValueError("Unexpected Publisher value")
1472+
14701473
@property
14711474
def dataset(self) -> Dataset:
14721475
"""

databento/common/symbology.py

Lines changed: 5 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,10 @@
1010
from io import TextIOWrapper
1111
from os import PathLike
1212
from pathlib import Path
13-
from typing import Any, ClassVar, NamedTuple, TextIO
13+
from typing import Any
14+
from typing import ClassVar
15+
from typing import NamedTuple
16+
from typing import TextIO
1417

1518
import pandas as pd
1619
from databento_dbn import UNDEF_TIMESTAMP
@@ -243,9 +246,7 @@ def insert_metadata(self, metadata: Metadata) -> None:
243246
return
244247

245248
stype_in = SType(metadata.stype_in) if metadata.stype_in is not None else None
246-
stype_out = (
247-
SType(metadata.stype_out) if metadata.stype_out is not None else None
248-
)
249+
stype_out = SType(metadata.stype_out) if metadata.stype_out is not None else None
249250

250251
for symbol_in, entries in metadata.mappings.items():
251252
for entry in entries:

databento/common/types.py

Lines changed: 30 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,9 @@
1-
from typing import Callable, Generic, TypeVar, Union
1+
import datetime as dt
2+
from typing import Callable
3+
from typing import Generic
4+
from typing import TypedDict
5+
from typing import TypeVar
6+
from typing import Union
27

38
import databento_dbn
49

@@ -16,13 +21,17 @@
1621
databento_dbn.SymbolMappingMsg,
1722
databento_dbn.SymbolMappingMsgV1,
1823
databento_dbn.SystemMsg,
24+
databento_dbn.SystemMsgV1,
1925
databento_dbn.ErrorMsg,
26+
databento_dbn.ErrorMsgV1,
2027
]
2128

2229
RecordCallback = Callable[[DBNRecord], None]
2330
ExceptionCallback = Callable[[Exception], None]
2431

2532
_T = TypeVar("_T")
33+
34+
2635
class Default(Generic[_T]):
2736
"""
2837
A container for a default value. This is to be used when a callable wants
@@ -52,3 +61,23 @@ def value(self) -> _T:
5261
5362
"""
5463
return self._value
64+
65+
66+
class MappingIntervalDict(TypedDict):
67+
"""
68+
Represents a symbol mapping over a start and end date range interval.
69+
70+
Parameters
71+
----------
72+
start_date : dt.date
73+
The start of the mapping period.
74+
end_date : dt.date
75+
The end of the mapping period.
76+
symbol : str
77+
The symbol value.
78+
79+
"""
80+
81+
start_date: dt.date
82+
end_date: dt.date
83+
symbol: str

0 commit comments

Comments
 (0)