From 33f02830e5cc018a88ce64fcabf61cd79da21729 Mon Sep 17 00:00:00 2001 From: Rob Maierle Date: Fri, 18 Jul 2025 11:29:57 -0400 Subject: [PATCH 1/4] DEL: Remove bill_id from client libraries --- CHANGELOG.md | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index 2d1e7a9..9d430ee 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,5 +1,10 @@ # Changelog +## 0.62.0 - TBD + +#### Breaking changes +- Removed `bill_id` from the response of `batch.list_jobs()` and `batch.submit_job()` + ## 0.61.0 - 2025-08-12 #### Breaking changes From 58a8b8cd62a14d3ba0789d5fa02adf2e6464489b Mon Sep 17 00:00:00 2001 From: Carter Green Date: Thu, 14 Aug 2025 15:33:36 -0500 Subject: [PATCH 2/4] ADD: Add `EndOfInterval` variant to `SystemCode` --- CHANGELOG.md | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 9d430ee..44b16bf 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -2,6 +2,9 @@ ## 0.62.0 - TBD +#### Enhancements +- Added `END_OF_INTERVAL` variant to `SystemCode` enum + #### Breaking changes - Removed `bill_id` from the response of `batch.list_jobs()` and `batch.submit_job()` @@ -24,7 +27,7 @@ - Added `parquet_schema` option to `DBNStore.to_parquet()` for overriding the pyarrow schema. - Upgraded `databento-dbn` to 0.39.0 - Added `side()` and `unpaired_side()` methods to `ImbalanceMsg` that convert the fields -of the same name to the `Side` enum + of the same name to the `Side` enum - Added `pretty_auction_time` property in Python for `ImbalanceMsg` - Added `action` and `ts_in_delta` getters to `BboMsg` - Added `ts_recv` getter to `StatusMsg` From 02dc2744422bf462291ee6cbf3ef8a23f72d4a61 Mon Sep 17 00:00:00 2001 From: Nick Macholl Date: Tue, 19 Aug 2025 12:01:51 -0700 Subject: [PATCH 3/4] MOD: Upgrade databento_dbn to version 0.40.0 --- CHANGELOG.md | 28 ++++++++++++++++++++++++++-- databento/common/dbnstore.py | 7 ++----- databento/common/symbology.py | 9 +++------ pyproject.toml | 2 +- tests/mockliveserver/server.py | 6 +++++- tests/test_historical_bento.py | 33 +++++++++++++++------------------ tests/test_historical_data.py | 7 ------- 7 files changed, 52 insertions(+), 40 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 44b16bf..65dfe47 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -2,11 +2,35 @@ ## 0.62.0 - TBD -#### Enhancements -- Added `END_OF_INTERVAL` variant to `SystemCode` enum +This release delivers a number of breaking changes to the Python interface for DBN records to provide a cleaner and more consistent API. #### Breaking changes - Removed `bill_id` from the response of `batch.list_jobs()` and `batch.submit_job()` +- Upgraded `databento-dbn` to 0.40.0 + - Removed `hd` property from records in Python. Header fields are accessible + directly from the record + - Removed ability to directly instantiate most enums from an `int` in Python and coercion + from `int` in `__eq__`. They can still be instantitated with the `from_int` class method. + Write `Side.from_int(66)` instead of `Side(66)` and `Side.BID == Side.from_int(66)` + instead of `Side.BID == 66`. Affected enums: + - `Side` + - `Action` + - `InstrumentClass` + - `MatchAlgorithm` + - `UserDefinedInstrument` + - `SecurityUpdateAction` + - `SType` + - `Schema` + - `Encoding` + - `Compression` + - `TriState` + - Removed string coercion in `__init__` and `__eq__` for `RType`, `SystemCode`, and + `ErrorCode` enums in Python. It can still be instantiated from a `str` with the + `from_str` class method. Write `RType.from_str("mbo")` instead of `RType("mbo")` + and `RType.TRADES == RType.from_str("trades")` instead of `RType.TRADES == "trades"` + +#### Enhancements +- Added `END_OF_INTERVAL` variant to `SystemCode` enum ## 0.61.0 - 2025-08-12 diff --git a/databento/common/dbnstore.py b/databento/common/dbnstore.py index 22d435a..edb2e52 100644 --- a/databento/common/dbnstore.py +++ b/databento/common/dbnstore.py @@ -584,10 +584,7 @@ def stype_in(self) -> SType | None: SType or None """ - stype = self._metadata.stype_in - if stype: - return SType(self._metadata.stype_in) - return None + return self._metadata.stype_in @property def stype_out(self) -> SType: @@ -599,7 +596,7 @@ def stype_out(self) -> SType: SType """ - return SType(self._metadata.stype_out) + return self._metadata.stype_out @property def symbology(self) -> dict[str, Any]: diff --git a/databento/common/symbology.py b/databento/common/symbology.py index a0e331b..0549ba2 100644 --- a/databento/common/symbology.py +++ b/databento/common/symbology.py @@ -245,9 +245,6 @@ def insert_metadata(self, metadata: Metadata) -> None: # Nothing to do return - stype_in = SType(metadata.stype_in) if metadata.stype_in is not None else None - stype_out = SType(metadata.stype_out) if metadata.stype_out is not None else None - for symbol_in, entries in metadata.mappings.items(): for entry in entries: if not entry["symbol"]: @@ -263,9 +260,9 @@ def insert_metadata(self, metadata: Metadata) -> None: symbol, instrument_id = _resolve_mapping_tuple( symbol_in=symbol_in, - stype_in=stype_in, + stype_in=metadata.stype_in, symbol_out=entry["symbol"], - stype_out=stype_out, + stype_out=metadata.stype_out, ) self._insert_interval( @@ -313,7 +310,7 @@ def insert_symbol_mapping_msg( symbol = msg.stype_out_symbol self._insert_interval( - msg.hd.instrument_id, + msg.instrument_id, MappingInterval( start_date=start_ts.date(), end_date=end_ts.date(), diff --git a/pyproject.toml b/pyproject.toml index 1443d76..52c56fd 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -32,7 +32,7 @@ aiohttp = [ {version = "^3.8.3", python = "<3.12"}, {version = "^3.9.0", python = "^3.12"} ] -databento-dbn = "~=0.39.0" +databento-dbn = "~=0.40.0" numpy = [ {version = ">=1.23.5", python = "<3.12"}, {version = ">=1.26.0", python = "^3.12"} diff --git a/tests/mockliveserver/server.py b/tests/mockliveserver/server.py index a8b3dee..36a31de 100644 --- a/tests/mockliveserver/server.py +++ b/tests/mockliveserver/server.py @@ -297,7 +297,11 @@ def _replay_done_callback(self, task: asyncio.Task[Any]) -> None: async def _file_replay_task(self) -> None: for subscription in self._subscriptions: - schema = Schema(subscription.schema) + schema = ( + Schema.from_str(subscription.schema) + if isinstance(subscription.schema, str) + else subscription.schema + ) replay = self._file_replay_table[(self.dataset, schema)] logger.info("starting replay %s for %s", replay.name, self.peer) for chunk in replay: diff --git a/tests/test_historical_bento.py b/tests/test_historical_bento.py index e4c4e5a..5194a5a 100644 --- a/tests/test_historical_bento.py +++ b/tests/test_historical_bento.py @@ -444,12 +444,11 @@ def test_replay_with_stub_data_record_passes_to_callback( # Assert assert isinstance(record, MBOMsg) - assert record.hd.length == 14 - assert record.hd.rtype == 160 - assert record.hd.rtype == 160 - assert record.hd.publisher_id == 1 - assert record.hd.instrument_id == 5482 - assert record.hd.ts_event == 1609099225061045683 + assert record.rtype == 160 + assert record.rtype == 160 + assert record.publisher_id == 1 + assert record.instrument_id == 5482 + assert record.ts_event == 1609099225061045683 assert record.order_id == 647784248135 assert record.price == 3675750000000 assert record.size == 2 @@ -1036,12 +1035,11 @@ def test_dbnstore_iterable( second: MBOMsg = record_list[1] # type: ignore [assignment] # Assert - assert first.hd.length == 14 - assert first.hd.rtype == 160 - assert first.hd.rtype == 160 - assert first.hd.publisher_id == 1 - assert first.hd.instrument_id == 5482 - assert first.hd.ts_event == 1609099225061045683 + assert first.rtype == 160 + assert first.rtype == 160 + assert first.publisher_id == 1 + assert first.instrument_id == 5482 + assert first.ts_event == 1609099225061045683 assert first.order_id == 647784248135 assert first.price == 3675750000000 assert first.size == 2 @@ -1053,12 +1051,11 @@ def test_dbnstore_iterable( assert first.ts_in_delta == 0 assert first.sequence == 1180 - assert second.hd.length == 14 - assert second.hd.rtype == 160 - assert second.hd.rtype == 160 - assert second.hd.publisher_id == 1 - assert second.hd.instrument_id == 5482 - assert second.hd.ts_event == 1609099225061045683 + assert second.rtype == 160 + assert second.rtype == 160 + assert second.publisher_id == 1 + assert second.instrument_id == 5482 + assert second.ts_event == 1609099225061045683 assert second.order_id == 647782686353 assert second.price == 3675500000000 assert second.size == 1 diff --git a/tests/test_historical_data.py b/tests/test_historical_data.py index 4179677..8e45df5 100644 --- a/tests/test_historical_data.py +++ b/tests/test_historical_data.py @@ -11,7 +11,6 @@ def test_mbo_fields() -> None: struct = SCHEMA_STRUCT_MAP[databento.Schema.MBO] fields = set(f for f in dir(struct) if not f.startswith(("_", "pretty_"))) - fields.remove("hd") fields.remove("record_size") fields.remove("size_hint") @@ -41,7 +40,6 @@ def test_mbp_fields( struct = SCHEMA_STRUCT_MAP[schema] fields = set(f for f in dir(struct) if not f.startswith(("_", "pretty_"))) - fields.remove("hd") fields.remove("record_size") fields.remove("size_hint") @@ -74,7 +72,6 @@ def test_ohlcv_fields( struct = SCHEMA_STRUCT_MAP[schema] fields = set(f for f in dir(struct) if not f.startswith(("_", "pretty_"))) - fields.remove("hd") fields.remove("record_size") fields.remove("size_hint") @@ -93,7 +90,6 @@ def test_trades_struct() -> None: struct = SCHEMA_STRUCT_MAP[databento.Schema.TRADES] fields = set(f for f in dir(struct) if not f.startswith(("_", "pretty_"))) - fields.remove("hd") fields.remove("record_size") fields.remove("size_hint") @@ -112,7 +108,6 @@ def test_definition_struct() -> None: struct = SCHEMA_STRUCT_MAP[databento.Schema.DEFINITION] fields = set(f for f in dir(struct) if not f.startswith(("_", "pretty_"))) - fields.remove("hd") fields.remove("record_size") fields.remove("size_hint") @@ -131,7 +126,6 @@ def test_imbalance_struct() -> None: struct = SCHEMA_STRUCT_MAP[databento.Schema.IMBALANCE] fields = set(f for f in dir(struct) if not f.startswith(("_", "pretty_"))) - fields.remove("hd") fields.remove("record_size") fields.remove("size_hint") @@ -150,7 +144,6 @@ def test_statistics_struct() -> None: struct = SCHEMA_STRUCT_MAP[databento.Schema.STATISTICS] fields = set(f for f in dir(struct) if not f.startswith(("_", "pretty_"))) - fields.remove("hd") fields.remove("record_size") fields.remove("size_hint") From 68076491499bd56fbe4c0c42accf87bdecc3be5d Mon Sep 17 00:00:00 2001 From: Nick Macholl Date: Tue, 19 Aug 2025 12:15:46 -0700 Subject: [PATCH 4/4] VER: Release 0.62.0 --- CHANGELOG.md | 2 +- databento/version.py | 2 +- pyproject.toml | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 65dfe47..48bccf1 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,6 +1,6 @@ # Changelog -## 0.62.0 - TBD +## 0.62.0 - 2025-08-19 This release delivers a number of breaking changes to the Python interface for DBN records to provide a cleaner and more consistent API. diff --git a/databento/version.py b/databento/version.py index a076e5d..647040d 100644 --- a/databento/version.py +++ b/databento/version.py @@ -1 +1 @@ -__version__ = "0.61.0" +__version__ = "0.62.0" diff --git a/pyproject.toml b/pyproject.toml index 52c56fd..d51bb5b 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -1,6 +1,6 @@ [tool.poetry] name = "databento" -version = "0.61.0" +version = "0.62.0" description = "Official Python client library for Databento" authors = [ "Databento ",