Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 2 additions & 2 deletions .github/workflows/test.yml
Original file line number Diff line number Diff line change
Expand Up @@ -30,13 +30,13 @@ jobs:
shell: bash

- name: Test (release)
timeout-minutes: 3
timeout-minutes: 5
if: ${{ github.ref == 'refs/heads/main' }}
run: scripts/test.sh -vvv --release
shell: bash

- name: Test
timeout-minutes: 3
timeout-minutes: 5
if: ${{ github.ref != 'refs/heads/main' }}
run: scripts/test.sh -vvv
shell: bash
13 changes: 13 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,5 +1,18 @@
# Changelog

## 0.55.0 - 2025-05-29

#### Enhancements
- Added `exchanges` parameter to `Reference.corporate_actions.get_range(...)`
- Added `is_last` field to live subscription requests which will be used to improve
the handling of split subscription requests
- Upgraded `databento-dbn` to 0.35.0
- This version delivers DBN version 3 (DBNv3), which is the new default
- Improved the performance of the Python `DBNDecoder`

#### Bug fixes
- Fixed an issue where `JSONDecodeError` would not be caught when using `simplejson` with `requests` (credit: @xuanqing94)

## 0.54.0 - 2025-05-13

#### Enhancements
Expand Down
2 changes: 1 addition & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -32,7 +32,7 @@ The library is fully compatible with the latest distribution of Anaconda 3.9 and
The minimum dependencies as found in the `pyproject.toml` are also listed below:
- python = "^3.9"
- aiohttp = "^3.8.3"
- databento-dbn = "0.34.0"
- databento-dbn = "0.35.0"
- numpy= ">=1.23.5"
- pandas = ">=1.5.3"
- pip-system-certs = ">=4.0" (Windows only)
Expand Down
5 changes: 4 additions & 1 deletion databento/common/dbnstore.py
Original file line number Diff line number Diff line change
Expand Up @@ -380,7 +380,7 @@ def __init__(self, data_source: DataSource) -> None:
def __iter__(self) -> Generator[DBNRecord, None, None]:
reader = self.reader
decoder = DBNDecoder(
upgrade_policy=VersionUpgradePolicy.UPGRADE_TO_V2,
upgrade_policy=VersionUpgradePolicy.UPGRADE_TO_V3,
)
while True:
raw = reader.read(DBNStore.DBN_READ_SIZE)
Expand All @@ -394,6 +394,9 @@ def __iter__(self) -> Generator[DBNRecord, None, None]:
self._instrument_map.insert_symbol_mapping_msg(record)
yield record
else:
# This call to decode is required to seek past the decoded records
# This behavior will be fixed in the next version of databento_dbn
_ = decoder.decode()
if len(decoder.buffer()) > 0:
warnings.warn(
BentoWarning("DBN file is truncated or contains an incomplete record"),
Expand Down
2 changes: 1 addition & 1 deletion databento/common/http.py
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,6 @@
from collections.abc import Iterable
from collections.abc import Mapping
from io import BytesIO
from json.decoder import JSONDecodeError
from os import PathLike
from typing import IO
from typing import Any
Expand All @@ -15,6 +14,7 @@
import requests
from aiohttp import ClientResponse
from aiohttp import ContentTypeError
from requests import JSONDecodeError
from requests import Response
from requests.auth import HTTPBasicAuth

Expand Down
3 changes: 2 additions & 1 deletion databento/common/types.py
Original file line number Diff line number Diff line change
Expand Up @@ -21,8 +21,9 @@
databento_dbn.ImbalanceMsg,
databento_dbn.InstrumentDefMsg,
databento_dbn.InstrumentDefMsgV1,
databento_dbn.InstrumentDefMsgV3,
databento_dbn.InstrumentDefMsgV2,
databento_dbn.StatMsg,
databento_dbn.StatMsgV1,
databento_dbn.StatusMsg,
databento_dbn.SymbolMappingMsg,
databento_dbn.SymbolMappingMsgV1,
Expand Down
3 changes: 2 additions & 1 deletion databento/historical/api/metadata.py
Original file line number Diff line number Diff line change
Expand Up @@ -407,7 +407,8 @@ def get_cost(
) -> float:
"""
Request the cost in US dollars for historical streaming or batched
files from Databento.
files from Databento. This cost respects any discounts provided by flat
rate plans.

Makes a `GET /metadata.get_cost` HTTP request.

Expand Down
1 change: 1 addition & 0 deletions databento/live/gateway.py
Original file line number Diff line number Diff line change
Expand Up @@ -133,6 +133,7 @@ class SubscriptionRequest(GatewayControl):
start: int | None = None
snapshot: int = 0
id: int | None = None
is_last: int = 1


@dataclasses.dataclass
Expand Down
16 changes: 9 additions & 7 deletions databento/live/protocol.py
Original file line number Diff line number Diff line change
Expand Up @@ -82,7 +82,7 @@ def __init__(
self._heartbeat_interval_s = heartbeat_interval_s

self._dbn_decoder = databento_dbn.DBNDecoder(
upgrade_policy=VersionUpgradePolicy.UPGRADE_TO_V2,
upgrade_policy=VersionUpgradePolicy.UPGRADE_TO_V3,
)
self._gateway_decoder = GatewayDecoder()

Expand Down Expand Up @@ -175,7 +175,7 @@ def connection_made(self, transport: asyncio.BaseTransport) -> None:

See Also
--------
asycnio.BufferedProtocol.connection_made
asyncio.BufferedProtocol.connection_made

"""
logger.debug("established connection to gateway")
Expand All @@ -190,7 +190,7 @@ def connection_lost(self, exc: Exception | None) -> None:

See Also
--------
asycnio.BufferedProtocol.connection_lost
asyncio.BufferedProtocol.connection_lost

"""
super().connection_lost(exc)
Expand All @@ -216,7 +216,7 @@ def eof_received(self) -> bool | None:

See Also
--------
asycnio.BufferedProtocol.eof_received
asyncio.BufferedProtocol.eof_received

"""
logger.info("received EOF from remote")
Expand All @@ -228,7 +228,7 @@ def get_buffer(self, sizehint: int) -> bytearray:

See Also
--------
asycnio.BufferedProtocol.get_buffer
asyncio.BufferedProtocol.get_buffer

"""
if len(self.__buffer) < sizehint:
Expand All @@ -241,7 +241,7 @@ def buffer_updated(self, nbytes: int) -> None:

See Also
--------
asycnio.BufferedProtocol.buffer_updated
asyncio.BufferedProtocol.buffer_updated

"""
logger.debug("read %d bytes from remote gateway", nbytes)
Expand Down Expand Up @@ -325,7 +325,8 @@ def subscribe(

subscriptions: list[SubscriptionRequest] = []
chunked_symbols = list(chunk(symbols_list, SYMBOL_LIST_BATCH_SIZE))
for batch in chunked_symbols:
last_chunk_idx = len(chunked_symbols) - 1
for i, batch in enumerate(chunked_symbols):
batch_str = ",".join(batch)
message = SubscriptionRequest(
schema=validate_enum(schema, Schema, "schema"),
Expand All @@ -334,6 +335,7 @@ def subscribe(
start=optional_datetime_to_unix_nanoseconds(start),
snapshot=int(snapshot),
id=subscription_id,
is_last=int(i == last_chunk_idx),
)
subscriptions.append(message)

Expand Down
11 changes: 11 additions & 0 deletions databento/reference/api/corporate.py
Original file line number Diff line number Diff line change
Expand Up @@ -39,6 +39,7 @@ def get_range(
stype_in: SType | str = "raw_symbol",
events: Iterable[str] | str | None = None,
countries: Iterable[str] | str | None = None,
exchanges: Iterable[str] | str | None = None,
security_types: Iterable[str] | str | None = None,
flatten: bool = True,
pit: bool = False,
Expand Down Expand Up @@ -84,6 +85,11 @@ def get_range(
Takes any number of two letter ISO 3166-1 alpha-2 country codes per request.
If not specified then will select **all** listing countries by default.
See [CNTRY](https://databento.com/docs/standards-and-conventions/reference-data-enums#cntry) enum.
exchanges : Iterable[str] or str, optional
The (listing) exchanges to filter for.
Takes any number of exchanges per request.
If not specified then will select **all** exchanges by default.
See [EXCHANGE](https://databento.com/docs/standards-and-conventions/reference-data-enums#exchange) enum.
security_types : Iterable[str] or str, optional
The security types to filter for.
Takes any number of security types per request.
Expand All @@ -108,6 +114,7 @@ def get_range(
symbols_list = optional_symbols_list_to_list(symbols, SType.RAW_SYMBOL)
events = optional_string_to_list(events)
countries = optional_string_to_list(countries)
exchanges = optional_string_to_list(exchanges)
security_types = optional_string_to_list(security_types)

data: dict[str, object | None] = {
Expand All @@ -122,6 +129,10 @@ def get_range(
"compression": str(Compression.ZSTD), # Always request zstd
}

# Only add the `exchanges` param if it is supplied, for compatibility
if exchanges:
data["exchanges"] = ",".join(exchanges)

response = self._post(
url=self._base_url + ".get_range",
data=data,
Expand Down
2 changes: 1 addition & 1 deletion databento/version.py
Original file line number Diff line number Diff line change
@@ -1 +1 @@
__version__ = "0.54.0"
__version__ = "0.55.0"
4 changes: 2 additions & 2 deletions pyproject.toml
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
[tool.poetry]
name = "databento"
version = "0.54.0"
version = "0.55.0"
description = "Official Python client library for Databento"
authors = [
"Databento <support@databento.com>",
Expand Down Expand Up @@ -32,7 +32,7 @@ aiohttp = [
{version = "^3.8.3", python = "<3.12"},
{version = "^3.9.0", python = "^3.12"}
]
databento-dbn = "0.34.0"
databento-dbn = "0.35.0"
numpy = [
{version = ">=1.23.5", python = "<3.12"},
{version = ">=1.26.0", python = "^3.12"}
Expand Down
Binary file modified tests/data/EQUS.MINI/test_data.bbo-1m.dbn.zst
Binary file not shown.
Binary file modified tests/data/EQUS.MINI/test_data.bbo-1s.dbn.zst
Binary file not shown.
Binary file modified tests/data/EQUS.MINI/test_data.definition.dbn.zst
Binary file not shown.
Binary file modified tests/data/EQUS.MINI/test_data.mbp-1.dbn.zst
Binary file not shown.
Binary file modified tests/data/EQUS.MINI/test_data.ohlcv-1d.dbn.zst
Binary file not shown.
Binary file modified tests/data/EQUS.MINI/test_data.ohlcv-1h.dbn.zst
Binary file not shown.
Binary file modified tests/data/EQUS.MINI/test_data.ohlcv-1m.dbn.zst
Binary file not shown.
Binary file modified tests/data/EQUS.MINI/test_data.ohlcv-1s.dbn.zst
Binary file not shown.
Binary file modified tests/data/EQUS.MINI/test_data.tbbo.dbn.zst
Binary file not shown.
Binary file modified tests/data/EQUS.MINI/test_data.trades.dbn.zst
Binary file not shown.
Binary file modified tests/data/GLBX.MDP3/test_data.bbo-1m.dbn.zst
Binary file not shown.
Binary file modified tests/data/GLBX.MDP3/test_data.bbo-1s.dbn.zst
Binary file not shown.
Binary file modified tests/data/GLBX.MDP3/test_data.definition.dbn.zst
Binary file not shown.
Binary file modified tests/data/GLBX.MDP3/test_data.mbo.dbn.zst
Binary file not shown.
Binary file modified tests/data/GLBX.MDP3/test_data.mbp-1.dbn.zst
Binary file not shown.
Binary file modified tests/data/GLBX.MDP3/test_data.mbp-10.dbn.zst
Binary file not shown.
Binary file modified tests/data/GLBX.MDP3/test_data.ohlcv-1d.dbn.zst
Binary file not shown.
Binary file modified tests/data/GLBX.MDP3/test_data.ohlcv-1h.dbn.zst
Binary file not shown.
Binary file modified tests/data/GLBX.MDP3/test_data.ohlcv-1m.dbn.zst
Binary file not shown.
Binary file modified tests/data/GLBX.MDP3/test_data.ohlcv-1s.dbn.zst
Binary file not shown.
Binary file modified tests/data/GLBX.MDP3/test_data.statistics.dbn.zst
Binary file not shown.
Binary file modified tests/data/GLBX.MDP3/test_data.status.dbn.zst
Binary file not shown.
Binary file modified tests/data/GLBX.MDP3/test_data.tbbo.dbn.zst
Binary file not shown.
Binary file modified tests/data/GLBX.MDP3/test_data.trades.dbn.zst
Binary file not shown.
Binary file modified tests/data/IFEU.IMPACT/test_data.bbo-1m.dbn.zst
Binary file not shown.
Binary file modified tests/data/IFEU.IMPACT/test_data.bbo-1s.dbn.zst
Binary file not shown.
Binary file modified tests/data/IFEU.IMPACT/test_data.definition.dbn.zst
Binary file not shown.
Binary file modified tests/data/IFEU.IMPACT/test_data.mbo.dbn.zst
Binary file not shown.
Binary file modified tests/data/IFEU.IMPACT/test_data.mbp-1.dbn.zst
Binary file not shown.
Binary file modified tests/data/IFEU.IMPACT/test_data.mbp-10.dbn.zst
Binary file not shown.
Binary file modified tests/data/IFEU.IMPACT/test_data.ohlcv-1d.dbn.zst
Binary file not shown.
Binary file modified tests/data/IFEU.IMPACT/test_data.ohlcv-1h.dbn.zst
Binary file not shown.
Binary file modified tests/data/IFEU.IMPACT/test_data.ohlcv-1m.dbn.zst
Binary file not shown.
Binary file modified tests/data/IFEU.IMPACT/test_data.ohlcv-1s.dbn.zst
Binary file not shown.
Binary file modified tests/data/IFEU.IMPACT/test_data.statistics.dbn.zst
Binary file not shown.
Binary file modified tests/data/IFEU.IMPACT/test_data.tbbo.dbn.zst
Binary file not shown.
Binary file modified tests/data/IFEU.IMPACT/test_data.trades.dbn.zst
Binary file not shown.
Binary file modified tests/data/LIVE/test_data.live.dbn.zst
Binary file not shown.
Binary file modified tests/data/NDEX.IMPACT/test_data.bbo-1m.dbn.zst
Binary file not shown.
Binary file modified tests/data/NDEX.IMPACT/test_data.bbo-1s.dbn.zst
Binary file not shown.
Binary file modified tests/data/NDEX.IMPACT/test_data.definition.dbn.zst
Binary file not shown.
Binary file modified tests/data/NDEX.IMPACT/test_data.mbo.dbn.zst
Binary file not shown.
Binary file modified tests/data/NDEX.IMPACT/test_data.mbp-1.dbn.zst
Binary file not shown.
Binary file modified tests/data/NDEX.IMPACT/test_data.mbp-10.dbn.zst
Binary file not shown.
Binary file modified tests/data/NDEX.IMPACT/test_data.ohlcv-1d.dbn.zst
Binary file not shown.
Binary file modified tests/data/NDEX.IMPACT/test_data.ohlcv-1h.dbn.zst
Binary file not shown.
Binary file modified tests/data/NDEX.IMPACT/test_data.ohlcv-1m.dbn.zst
Binary file not shown.
Binary file modified tests/data/NDEX.IMPACT/test_data.ohlcv-1s.dbn.zst
Binary file not shown.
Binary file modified tests/data/NDEX.IMPACT/test_data.statistics.dbn.zst
Binary file not shown.
Binary file modified tests/data/NDEX.IMPACT/test_data.tbbo.dbn.zst
Binary file not shown.
Binary file modified tests/data/NDEX.IMPACT/test_data.trades.dbn.zst
Binary file not shown.
Binary file modified tests/data/OPRA.PILLAR/test_data.cbbo-1m.dbn.zst
Binary file not shown.
Binary file modified tests/data/OPRA.PILLAR/test_data.cbbo-1s.dbn.zst
Binary file not shown.
Binary file modified tests/data/OPRA.PILLAR/test_data.definition.dbn.zst
Binary file not shown.
Binary file modified tests/data/OPRA.PILLAR/test_data.mbp-1.dbn.zst
Binary file not shown.
Binary file modified tests/data/OPRA.PILLAR/test_data.ohlcv-1d.dbn.zst
Binary file not shown.
Binary file modified tests/data/OPRA.PILLAR/test_data.ohlcv-1h.dbn.zst
Binary file not shown.
Binary file modified tests/data/OPRA.PILLAR/test_data.ohlcv-1m.dbn.zst
Binary file not shown.
Binary file modified tests/data/OPRA.PILLAR/test_data.ohlcv-1s.dbn.zst
Binary file not shown.
Binary file modified tests/data/OPRA.PILLAR/test_data.statistics.dbn.zst
Binary file not shown.
Binary file modified tests/data/OPRA.PILLAR/test_data.tbbo.dbn.zst
Binary file not shown.
Binary file modified tests/data/OPRA.PILLAR/test_data.trades.dbn.zst
Binary file not shown.
Binary file modified tests/data/XNAS.ITCH/test_data.definition.dbn.zst
Binary file not shown.
Binary file modified tests/data/XNAS.ITCH/test_data.imbalance.dbn.zst
Binary file not shown.
Binary file modified tests/data/XNAS.ITCH/test_data.mbo.dbn.zst
Binary file not shown.
Binary file modified tests/data/XNAS.ITCH/test_data.mbp-1.dbn.zst
Binary file not shown.
Binary file modified tests/data/XNAS.ITCH/test_data.mbp-10.dbn.zst
Binary file not shown.
Binary file modified tests/data/XNAS.ITCH/test_data.ohlcv-1d.dbn.zst
Binary file not shown.
Binary file modified tests/data/XNAS.ITCH/test_data.ohlcv-1h.dbn.zst
Binary file not shown.
Binary file modified tests/data/XNAS.ITCH/test_data.ohlcv-1m.dbn.zst
Binary file not shown.
Binary file modified tests/data/XNAS.ITCH/test_data.ohlcv-1s.dbn.zst
Binary file not shown.
Binary file modified tests/data/XNAS.ITCH/test_data.tbbo.dbn.zst
Binary file not shown.
Binary file modified tests/data/XNAS.ITCH/test_data.trades.dbn.zst
Binary file not shown.
14 changes: 7 additions & 7 deletions tests/test_historical_bento.py
Original file line number Diff line number Diff line change
Expand Up @@ -90,7 +90,7 @@ def test_sources_metadata_returns_expected_json_as_dict(
dbnstore = DBNStore.from_bytes(data=stub_data)

# Assert
assert dbnstore.metadata.version == 2
assert dbnstore.metadata.version == 3
assert dbnstore.metadata.dataset == "GLBX.MDP3"
assert dbnstore.metadata.schema == Schema.MBO
assert dbnstore.metadata.stype_in == SType.RAW_SYMBOL
Expand Down Expand Up @@ -123,7 +123,7 @@ def test_dbnstore_given_initial_nbytes_returns_expected_metadata(
dbnstore = DBNStore.from_bytes(data=stub_data)

# Assert
assert dbnstore.nbytes == 189
assert dbnstore.nbytes == 191
assert dbnstore.dataset == "GLBX.MDP3"
assert dbnstore.schema == Schema.MBO
assert dbnstore.symbols == ["ESH1"]
Expand Down Expand Up @@ -171,14 +171,14 @@ def test_file_dbnstore_given_valid_path_initialized_expected_data(

# Assert
assert dbnstore.dataset == "GLBX.MDP3"
assert dbnstore.nbytes == 189
assert dbnstore.nbytes == 191


@pytest.mark.parametrize(
"schema,expected_size",
[
(Schema.MBO, 189),
(Schema.DEFINITION, 290),
(Schema.MBO, 191),
(Schema.DEFINITION, 288),
],
)
def test_to_file_persists_to_disk(
Expand Down Expand Up @@ -215,14 +215,14 @@ def test_to_file_overwrite(
dbnstore = DBNStore.from_bytes(data=stub_data)
dbn_path = tmp_path / "my_test.dbn"
dbnstore.to_file(path=dbn_path)
assert dbn_path.stat().st_size == 189
assert dbn_path.stat().st_size == 191

# Act
dbnstore.to_file(path=dbn_path)

# Assert
assert dbn_path.exists()
assert dbn_path.stat().st_size == 189
assert dbn_path.stat().st_size == 191


def test_to_file_exclusive(
Expand Down
Loading