diff --git a/.github/workflows/test.yml b/.github/workflows/test.yml index 8c142aa..9b6423e 100644 --- a/.github/workflows/test.yml +++ b/.github/workflows/test.yml @@ -10,7 +10,7 @@ jobs: fail-fast: false matrix: os: [ubuntu-latest, macos-latest, windows-latest] - python-version: ["3.9", "3.10", "3.11", "3.12"] + python-version: ["3.9", "3.10", "3.11", "3.12", "3.13"] name: build - Python ${{ matrix.python-version }} (${{ matrix.os }}) runs-on: ${{ matrix.os }} diff --git a/CHANGELOG.md b/CHANGELOG.md index df8dcf5..d333595 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,5 +1,19 @@ # Changelog +## 0.45.0 - 2024-11-12 + +This release adds support for Python v3.13. + +#### Enhancements +- Added support for Python 3.13 +- Added new IntelligentCross venues `ASPN`, `ASMT`, and `ASPI` +- Upgraded `databento-dbn` to 0.23.1 + - Fixed `pretty_activation` getter in `databento_dbn` returning `expiration` instead + - Fixed some `pretty_` getters in `databento_dbn` didn't correctly handle `UNDEF_PRICE` + +#### Deprecations +- Deprecated `packaging` parameter for `Historical.batch.submit_job` which will be removed in a future release + ## 0.44.1 - 2024-10-29 #### Enhancements diff --git a/README.md b/README.md index 8e80808..e99d2ac 100644 --- a/README.md +++ b/README.md @@ -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.23.0" +- databento-dbn = "0.23.1" - numpy= ">=1.23.5" - pandas = ">=1.5.3" - pip-system-certs = ">=4.0" (Windows only) diff --git a/databento/common/publishers.py b/databento/common/publishers.py index 813019b..8112fbe 100644 --- a/databento/common/publishers.py +++ b/databento/common/publishers.py @@ -102,6 +102,12 @@ class Venue(StringyMixin, str, Enum): Long-Term Stock Exchange, Inc.. XOFF Off-Exchange Transactions - Listed Instruments. + ASPN + IntelligentCross ASPEN Intelligent Bid/Offer. + ASMT + IntelligentCross ASPEN Maker/Taker. + ASPI + IntelligentCross ASPEN Inverted. """ @@ -148,6 +154,9 @@ class Venue(StringyMixin, str, Enum): SPHR = "SPHR" LTSE = "LTSE" XOFF = "XOFF" + ASPN = "ASPN" + ASMT = "ASMT" + ASPI = "ASPI" @classmethod def from_int(cls, value: int) -> Venue: @@ -240,6 +249,12 @@ def from_int(cls, value: int) -> Venue: return Venue.LTSE if value == 43: return Venue.XOFF + if value == 44: + return Venue.ASPN + if value == 45: + return Venue.ASMT + if value == 46: + return Venue.ASPI raise ValueError(f"Integer value {value} does not correspond with any Venue variant") def to_int(self) -> int: @@ -332,6 +347,12 @@ def to_int(self) -> int: return 42 if self == Venue.XOFF: return 43 + if self == Venue.ASPN: + return 44 + if self == Venue.ASMT: + return 45 + if self == Venue.ASPI: + return 46 raise ValueError("Invalid Venue") @property @@ -425,6 +446,12 @@ def description(self) -> str: return "Long-Term Stock Exchange, Inc." if self == Venue.XOFF: return "Off-Exchange Transactions - Listed Instruments" + if self == Venue.ASPN: + return "IntelligentCross ASPEN Intelligent Bid/Offer" + if self == Venue.ASMT: + return "IntelligentCross ASPEN Maker/Taker" + if self == Venue.ASPI: + return "IntelligentCross ASPEN Inverted" raise ValueError("Unexpected Venue value") diff --git a/databento/historical/api/batch.py b/databento/historical/api/batch.py index 223520c..e75ece8 100644 --- a/databento/historical/api/batch.py +++ b/databento/historical/api/batch.py @@ -29,6 +29,7 @@ from databento.common.enums import Delivery from databento.common.enums import Packaging from databento.common.enums import SplitDuration +from databento.common.error import BentoDeprecationWarning from databento.common.error import BentoError from databento.common.error import BentoHttpError from databento.common.error import BentoWarning @@ -39,6 +40,7 @@ from databento.common.parsing import optional_values_list_to_string from databento.common.parsing import symbols_list_to_list from databento.common.publishers import Dataset +from databento.common.types import Default from databento.common.validation import validate_enum from databento.common.validation import validate_path from databento.common.validation import validate_semantic_string @@ -73,7 +75,7 @@ def submit_job( split_symbols: bool = False, split_duration: SplitDuration | str = "day", split_size: int | None = None, - packaging: Packaging | str | None = None, + packaging: Packaging | str | None = Default(None), # type: ignore [assignment] delivery: Delivery | str = "download", stype_in: SType | str = "raw_symbol", stype_out: SType | str = "instrument_id", @@ -148,6 +150,15 @@ def submit_job( """ stype_in_valid = validate_enum(stype_in, SType, "stype_in") symbols_list = symbols_list_to_list(symbols, stype_in_valid) + + if isinstance(packaging, Default): + packaging = packaging.value + else: + warnings.warn( + message="The `packaging` parameter is deprecated and will be removed in a future release.", + category=BentoDeprecationWarning, + ) + data: dict[str, object | None] = { "dataset": validate_semantic_string(dataset, "dataset"), "start": datetime_to_string(start), diff --git a/databento/version.py b/databento/version.py index 7f532dc..4d8afa5 100644 --- a/databento/version.py +++ b/databento/version.py @@ -1 +1 @@ -__version__ = "0.44.1" +__version__ = "0.45.0" diff --git a/pyproject.toml b/pyproject.toml index c795057..bb6f54e 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -1,6 +1,6 @@ [tool.poetry] name = "databento" -version = "0.44.1" +version = "0.45.0" description = "Official Python client library for Databento" authors = [ "Databento ", @@ -27,12 +27,12 @@ repository = "https://github.com/databento/databento-python" "Bug Tracker" = "https://github.com/databento/databento-python/issues" [tool.poetry.dependencies] -python = ">=3.9,<3.13" +python = ">=3.9,<3.14" aiohttp = [ {version = "^3.8.3", python = "<3.12"}, {version = "^3.9.0", python = "^3.12"} ] -databento-dbn = "0.23.0" +databento-dbn = "0.23.1" numpy = [ {version = ">=1.23.5", python = "<3.12"}, {version = ">=1.26.0", python = "^3.12"} diff --git a/tests/conftest.py b/tests/conftest.py index 5f60434..8c01b4e 100644 --- a/tests/conftest.py +++ b/tests/conftest.py @@ -297,4 +297,6 @@ async def fixture_live_client( with mock_live_server.test_context(): yield test_client - test_client.stop() + if test_client.is_connected(): + test_client.stop() + await test_client.wait_for_close() diff --git a/tests/mockliveserver/controller.py b/tests/mockliveserver/controller.py index 0781f2c..437c3f6 100644 --- a/tests/mockliveserver/controller.py +++ b/tests/mockliveserver/controller.py @@ -94,7 +94,12 @@ def _command_active_count(self, *_: str) -> None: """ Log the number of active connections. """ - count = self._server._active_count # type: ignore [attr-defined] + # _active_count was removed in Python 3.13 + if hasattr(self._server, "_active_count"): + count = self._server._active_count + else: + count = len(self._server._clients) # type: ignore [attr-defined] + logger.info("active connections: %d", count) def _command_add_key(self, key: str) -> None: diff --git a/tests/test_historical_batch.py b/tests/test_historical_batch.py index efbe35c..4bb2584 100644 --- a/tests/test_historical_batch.py +++ b/tests/test_historical_batch.py @@ -5,6 +5,7 @@ import databento as db import pytest import requests +from databento.common.error import BentoDeprecationWarning from databento.historical.client import Historical @@ -63,19 +64,20 @@ def test_batch_submit_job_sends_expected_request( monkeypatch.setattr(requests, "post", mocked_post := MagicMock()) # Act - historical_client.batch.submit_job( - dataset="GLBX.MDP3", - symbols="ESH1", - schema="trades", - start="2020-12-28T12:00", - end="2020-12-29", - encoding="csv", - split_duration="day", - split_size=10000000000, - packaging="none", - delivery="download", - compression="zstd", - ) + with pytest.warns(BentoDeprecationWarning): + historical_client.batch.submit_job( + dataset="GLBX.MDP3", + symbols="ESH1", + schema="trades", + start="2020-12-28T12:00", + end="2020-12-29", + encoding="csv", + split_duration="day", + split_size=10000000000, + packaging="none", + delivery="download", + compression="zstd", + ) # Assert call = mocked_post.call_args.kwargs