From e180a589fccec51498e55881422bc1055284d4eb Mon Sep 17 00:00:00 2001 From: Nick Macholl Date: Tue, 16 Jan 2024 10:28:11 -0800 Subject: [PATCH 1/8] MOD: Streaming exceptions to BentoError --- databento/historical/api/batch.py | 17 ++++++++++++----- databento/historical/http.py | 15 +++++++++++---- 2 files changed, 23 insertions(+), 9 deletions(-) diff --git a/databento/historical/api/batch.py b/databento/historical/api/batch.py index b95aafc..dac53a4 100644 --- a/databento/historical/api/batch.py +++ b/databento/historical/api/batch.py @@ -20,6 +20,7 @@ from databento.common.enums import Delivery from databento.common.enums import Packaging from databento.common.enums import SplitDuration +from databento.common.error import BentoError from databento.common.parsing import datetime_to_string from databento.common.parsing import optional_datetime_to_string from databento.common.parsing import optional_symbols_list_to_list @@ -371,8 +372,11 @@ def _download_file( logger.debug("Starting download of file %s", output_path.name) with open(output_path, mode=mode) as f: - for chunk in response.iter_content(chunk_size=None): - f.write(chunk) + try: + for chunk in response.iter_content(chunk_size=None): + f.write(chunk) + except Exception as exc: + raise BentoError(f"Error downloading file: {exc}") logger.debug("Download of %s completed", output_path.name) async def download_async( @@ -512,9 +516,12 @@ async def _download_file_async( logger.debug("Starting async download of file %s", output_path.name) with open(output_path, mode=mode) as f: - async for chunk in response.content.iter_chunks(): - data: bytes = chunk[0] - f.write(data) + try: + async for chunk in response.content.iter_chunks(): + data: bytes = chunk[0] + f.write(data) + except Exception as exc: + raise BentoError(f"Error downloading file: {exc}") logger.debug("Download of %s completed", output_path.name) def _get_file_download_headers_and_mode( diff --git a/databento/historical/http.py b/databento/historical/http.py index be15024..a1d9597 100644 --- a/databento/historical/http.py +++ b/databento/historical/http.py @@ -18,6 +18,7 @@ from databento.common.dbnstore import DBNStore from databento.common.error import BentoClientError from databento.common.error import BentoDeprecationWarning +from databento.common.error import BentoError from databento.common.error import BentoServerError from databento.common.error import BentoWarning from databento.common.system import USER_AGENT @@ -132,8 +133,11 @@ def _stream( else: writer = open(path, "x+b") - for chunk in response.iter_content(chunk_size=None): - writer.write(chunk) + try: + for chunk in response.iter_content(chunk_size=None): + writer.write(chunk) + except Exception as exc: + raise BentoError(f"Error streaming response: {exc}") if path is None: writer.seek(0) @@ -169,8 +173,11 @@ async def _stream_async( else: writer = open(path, "x+b") - async for chunk in response.content.iter_chunks(): - writer.write(chunk[0]) + try: + async for chunk in response.content.iter_chunks(): + writer.write(chunk[0]) + except Exception as exc: + raise BentoError(f"Error streaming response: {exc}") if path is None: writer.seek(0) From 828a7fd13b4d12058b01fa51420f3ba4d01aa779 Mon Sep 17 00:00:00 2001 From: Nick Macholl Date: Thu, 18 Jan 2024 16:15:01 -0800 Subject: [PATCH 2/8] FIX: Live client error handling on connect --- CHANGELOG.md | 8 ++++++++ databento/live/protocol.py | 14 +++++++------- databento/live/session.py | 5 +++-- tests/test_live_protocol.py | 1 - 4 files changed, 18 insertions(+), 10 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index adb1629..985cb99 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,5 +1,13 @@ # Changelog +## 0.27.0 - TBD + +#### Breaking changes +- Renamed `DatatbentoLiveProtocol.started` to `DatatbentoLiveProtocol.is_started` which now returns a bool instead of an `asyncio.Event` + +#### Bug fixes +- Fixed an issue where an error message from the live gateway would not properly raise an exception if the connection closed before `Live.start` was called + ## 0.26.0 - 2024-01-16 This release adds support for transcoding DBN data into Apache parquet. diff --git a/databento/live/protocol.py b/databento/live/protocol.py index 3812164..7aa9107 100644 --- a/databento/live/protocol.py +++ b/databento/live/protocol.py @@ -82,7 +82,7 @@ def __init__( self._authenticated: asyncio.Future[int] = asyncio.Future() self._disconnected: asyncio.Future[None] = asyncio.Future() - self._started = asyncio.Event() + self._started: bool = False @property def authenticated(self) -> asyncio.Future[int]: @@ -118,14 +118,14 @@ def disconnected(self) -> asyncio.Future[None]: return self._disconnected @property - def started(self) -> asyncio.Event: + def is_started(self) -> bool: """ - Event that is set when the session has started streaming. This occurs - when the SessionStart message is sent to the gateway. + True if the session has started streaming. This occurs when the + SessionStart message is sent to the gateway. Returns ------- - asyncio.Event + bool """ return self._started @@ -219,7 +219,7 @@ def buffer_updated(self, nbytes: int) -> None: logger.debug("read %d bytes from remote gateway", nbytes) data = self.__buffer[:nbytes] - if self.started.is_set(): + if self.authenticated.done(): self._process_dbn(data) else: self._process_gateway(data) @@ -303,7 +303,7 @@ def start( """ logger.debug("sending start") message = SessionStart() - self.started.set() + self._started = True self.transport.write(bytes(message)) def _process_dbn(self, data: bytes) -> None: diff --git a/databento/live/session.py b/databento/live/session.py index 4d59129..d90f152 100644 --- a/databento/live/session.py +++ b/databento/live/session.py @@ -276,7 +276,8 @@ def is_reading(self) -> bool: def is_started(self) -> bool: """ - Return true if the session's connection has started streaming. + Return true if the session's connection has started streaming, false + otherwise. Returns ------- @@ -286,7 +287,7 @@ def is_started(self) -> bool: with self._lock: if self._protocol is None: return False - return self._protocol.started.is_set() + return self._protocol.is_started @property def metadata(self) -> databento_dbn.Metadata | None: diff --git a/tests/test_live_protocol.py b/tests/test_live_protocol.py index e6289ec..6b595fd 100644 --- a/tests/test_live_protocol.py +++ b/tests/test_live_protocol.py @@ -90,7 +90,6 @@ async def test_protocol_connection_streaming( ) protocol.start() - await asyncio.wait_for(protocol.started.wait(), timeout=1) await asyncio.wait_for(protocol.disconnected, timeout=1) # Assert From 657cdda80f6187e130c1b9f919bdbda5c645a871 Mon Sep 17 00:00:00 2001 From: Nick Macholl Date: Fri, 19 Jan 2024 13:29:30 -0800 Subject: [PATCH 3/8] MOD: Standardize Python client on os.PathLike --- databento/common/dbnstore.py | 22 ++++++------ databento/common/symbology.py | 48 ++++++++++++++------------ databento/common/validation.py | 4 +-- databento/historical/api/batch.py | 4 +-- databento/historical/api/timeseries.py | 4 +-- tests/mock_live_server.py | 12 +++---- 6 files changed, 48 insertions(+), 46 deletions(-) diff --git a/databento/common/dbnstore.py b/databento/common/dbnstore.py index dcdcaaf..6cba645 100644 --- a/databento/common/dbnstore.py +++ b/databento/common/dbnstore.py @@ -132,7 +132,7 @@ class FileDataSource(DataSource): The name of the file. nbytes : int The size of the data in bytes; equal to the file size. - path : PathLike or str + path : PathLike[str] or str The path of the file. reader : IO[bytes] A `BufferedReader` for this file-backed data. @@ -634,7 +634,7 @@ def from_file(cls, path: PathLike[str] | str) -> DBNStore: Parameters ---------- - path : Path or str + path : PathLike[str] or str The path to read from. Returns @@ -695,7 +695,7 @@ def replay(self, callback: Callable[[Any], None]) -> None: def request_full_definitions( self, client: Historical, - path: Path | str | None = None, + path: PathLike[str] | str | None = None, ) -> DBNStore: """ Request full instrument definitions based on the metadata properties. @@ -706,7 +706,7 @@ def request_full_definitions( ---------- client : Historical The historical client to use for the request (contains the API key). - path : Path or str, optional + path : PathLike[str] or str, optional The path to stream the data to on disk (will then return a `DBNStore`). Returns @@ -768,7 +768,7 @@ def request_symbology(self, client: Historical) -> dict[str, Any]: def to_csv( self, - path: Path | str, + path: PathLike[str] | str, pretty_px: bool = True, pretty_ts: bool = True, map_symbols: bool = True, @@ -780,7 +780,7 @@ def to_csv( Parameters ---------- - path : Path or str + path : PathLike[str] or str The file path to write to. pretty_px : bool, default True If all price columns should be converted from `int` to `float` at @@ -922,7 +922,7 @@ def to_df( def to_parquet( self, - path: Path | str, + path: PathLike[str] | str, price_type: Literal["fixed", "float"] = "float", pretty_ts: bool = True, map_symbols: bool = True, @@ -995,13 +995,13 @@ def to_parquet( if writer is not None: writer.close() - def to_file(self, path: Path | str) -> None: + def to_file(self, path: PathLike[str] | str) -> None: """ Write the data to a DBN file at the given path. Parameters ---------- - path : str + path : PathLike[str] or str The file path to write to. Raises @@ -1021,7 +1021,7 @@ def to_file(self, path: Path | str) -> None: def to_json( self, - path: Path | str, + path: PathLike[str] | str, pretty_px: bool = True, pretty_ts: bool = True, map_symbols: bool = True, @@ -1033,7 +1033,7 @@ def to_json( Parameters ---------- - path : Path or str + path : PathLike[str] or str The file path to write to. pretty_px : bool, default True If all price columns should be converted from `int` to `float` at diff --git a/databento/common/symbology.py b/databento/common/symbology.py index 1dceffb..0bb235e 100644 --- a/databento/common/symbology.py +++ b/databento/common/symbology.py @@ -43,8 +43,8 @@ class MappingInterval(NamedTuple): def _validate_path_pair( - in_file: Path | PathLike[str] | str, - out_file: Path | PathLike[str] | str | None, + in_file: PathLike[str] | str, + out_file: PathLike[str] | str | None, ) -> tuple[Path, Path]: in_file_valid = Path(in_file) @@ -74,9 +74,9 @@ def _validate_path_pair( def map_symbols_csv( - symbology_file: Path | PathLike[str] | str, - csv_file: Path | PathLike[str] | str, - out_file: Path | PathLike[str] | str | None = None, + symbology_file: PathLike[str] | str, + csv_file: PathLike[str] | str, + out_file: PathLike[str] | str | None = None, ) -> Path: """ Use a `symbology.json` file to map a symbols column onto an existing CSV @@ -84,12 +84,12 @@ def map_symbols_csv( Parameters ---------- - symbology_file: Path | PathLike[str] | str + symbology_file: PathLike[str] | str Path to a `symbology.json` file to use as a symbology source. - csv_file: Path | PathLike[str] | str + csv_file: PathLike[str] | str Path to a CSV file that contains encoded DBN data; must contain a `ts_recv` or `ts_event` and `instrument_id` column. - out_file: Path | PathLike[str] | str (optional) + out_file: PathLike[str] | str (optional) Path to a file to write results to. If unspecified, `_mapped` will be appended to the `csv_file` name. @@ -119,9 +119,9 @@ def map_symbols_csv( def map_symbols_json( - symbology_file: Path | PathLike[str] | str, - json_file: Path | PathLike[str] | str, - out_file: Path | PathLike[str] | str | None = None, + symbology_file: PathLike[str] | str, + json_file: PathLike[str] | str, + out_file: PathLike[str] | str | None = None, ) -> Path: """ Use a `symbology.json` file to insert a symbols key into records of an @@ -129,11 +129,11 @@ def map_symbols_json( Parameters ---------- - symbology_file: Path | PathLike[str] | str + symbology_file: PathLike[str] | str Path to a `symbology.json` file to use as a symbology source. - json_file: Path | PathLike[str] | str + json_file: PathLike[str] | str Path to a JSON file that contains encoded DBN data. - out_file: Path | PathLike[str] | str (optional) + out_file: PathLike[str] | str (optional) Path to a file to write results to. If unspecified, `_mapped` will be appended to the `json_file` name. @@ -243,7 +243,9 @@ def insert_metadata(self, metadata: Metadata) -> None: 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 + 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: @@ -395,8 +397,8 @@ def insert_json( def map_symbols_csv( self, - csv_file: Path | PathLike[str] | str, - out_file: Path | PathLike[str] | str | None = None, + csv_file: PathLike[str] | str, + out_file: PathLike[str] | str | None = None, ) -> Path: """ Use the loaded symbology data to map a symbols column onto an existing @@ -404,10 +406,10 @@ def map_symbols_csv( Parameters ---------- - csv_file: Path | PathLike[str] | str + csv_file: PathLike[str] | str Path to a CSV file that contains encoded DBN data; must contain a `ts_recv` or `ts_event` and `instrument_id` column. - out_file: Path | PathLike[str] | str (optional) + out_file: PathLike[str] | str (optional) Path to a file to write results to. If unspecified, `_mapped` will be appended to the `csv_file` name. @@ -474,8 +476,8 @@ def map_symbols_csv( def map_symbols_json( self, - json_file: Path | PathLike[str] | str, - out_file: Path | PathLike[str] | str | None = None, + json_file: PathLike[str] | str, + out_file: PathLike[str] | str | None = None, ) -> Path: """ Use the loaded symbology data to insert a symbols key into records of @@ -483,9 +485,9 @@ def map_symbols_json( Parameters ---------- - json_file: Path | PathLike[str] | str + json_file: PathLike[str] | str Path to a JSON file that contains encoded DBN data. - out_file: Path | PathLike[str] | str (optional) + out_file: PathLike[str] | str (optional) Path to a file to write results to. If unspecified, `_mapped` will be appended to the `json_file` name. diff --git a/databento/common/validation.py b/databento/common/validation.py index 5983f3e..4ff7037 100644 --- a/databento/common/validation.py +++ b/databento/common/validation.py @@ -18,7 +18,7 @@ def validate_path(value: PathLike[str] | str, param: str) -> Path: Parameters ---------- - value: PathLike or str + value: PathLike[str] or str The value to validate. param : str The name of the parameter being validated (for any error message). @@ -49,7 +49,7 @@ def validate_file_write_path(value: PathLike[str] | str, param: str) -> Path: Parameters ---------- - value: PathLike or str + value: PathLike[str] or str The value to validate. param : str The name of the parameter being validated (for any error message). diff --git a/databento/historical/api/batch.py b/databento/historical/api/batch.py index dac53a4..6c2c289 100644 --- a/databento/historical/api/batch.py +++ b/databento/historical/api/batch.py @@ -253,7 +253,7 @@ def download( Parameters ---------- - output_dir: PathLike or str + output_dir: PathLike[str] or str The directory to download the file(s) to. job_id : str The batch job identifier. @@ -397,7 +397,7 @@ async def download_async( Parameters ---------- - output_dir: PathLike or str + output_dir: PathLike[str] or str The directory to download the file(s) to. job_id : str The batch job identifier. diff --git a/databento/historical/api/timeseries.py b/databento/historical/api/timeseries.py index ca8eba1..6172154 100644 --- a/databento/historical/api/timeseries.py +++ b/databento/historical/api/timeseries.py @@ -80,7 +80,7 @@ def get_range( The output symbology type to resolve to. limit : int, optional The maximum number of records to return. If `None` then no limit. - path : PathLike or str, optional + path : PathLike[str] or str, optional The file path to stream the data to on disk (will then return a `DBNStore`). Returns @@ -177,7 +177,7 @@ async def get_range_async( The output symbology type to resolve to. limit : int, optional The maximum number of records to return. If `None` then no limit. - path : PathLike or str, optional + path : PathLike[str] or str, optional The file path to stream the data to on disk (will then return a `DBNStore`). Returns diff --git a/tests/mock_live_server.py b/tests/mock_live_server.py index f2ae54f..532cd10 100644 --- a/tests/mock_live_server.py +++ b/tests/mock_live_server.py @@ -15,6 +15,7 @@ from concurrent import futures from functools import singledispatchmethod from io import BytesIO +from os import PathLike from typing import Callable, NewType, TypeVar import zstandard @@ -80,7 +81,7 @@ def __init__( version: str, user_api_keys: dict[str, str], message_queue: MessageQueue, - dbn_path: pathlib.Path, + dbn_path: PathLike[str], mode: MockLiveMode = MockLiveMode.REPLAY, ) -> None: self.__transport: asyncio.Transport @@ -99,7 +100,7 @@ def __init__( self._is_streaming: bool = False self._repeater_tasks: set[asyncio.Task[None]] = set() - self._dbn_path = dbn_path + self._dbn_path = pathlib.Path(dbn_path) self._user_api_keys = user_api_keys @property @@ -392,7 +393,6 @@ def _(self, message: AuthenticationRequest) -> None: ) self.__transport.write(bytes(auth_success)) - @handle_client_message.register(SubscriptionRequest) def _(self, message: SubscriptionRequest) -> None: logger.info("received subscription request: %s", str(message).strip()) @@ -548,7 +548,7 @@ def _protocol_factory( user_api_keys: dict[str, str], message_queue: MessageQueue, version: str, - dbn_path: pathlib.Path, + dbn_path: PathLike[str], mode: MockLiveMode, ) -> Callable[[], MockLiveServerProtocol]: def factory() -> MockLiveServerProtocol: @@ -567,7 +567,7 @@ async def create( cls, host: str = "localhost", port: int = 0, - dbn_path: pathlib.Path = pathlib.Path.cwd(), + dbn_path: PathLike[str] = pathlib.Path.cwd(), mode: MockLiveMode = MockLiveMode.REPLAY, ) -> MockLiveServer: """ @@ -582,7 +582,7 @@ async def create( port : int The port to bind for the mock server. Defaults to 0 which will bind to an open port. - dbn_path : pathlib.Path (default: cwd) + dbn_path : PathLike[str] (default: cwd) A path to DBN files for streaming. The files must contain the schema name and end with `.dbn.zst`. From 4a4a99fff851de40bd1c68ebe104db760f027d6e Mon Sep 17 00:00:00 2001 From: Nick Macholl Date: Mon, 22 Jan 2024 11:22:38 -0800 Subject: [PATCH 4/8] MOD: Suppress exception chains for BentoError --- databento/common/dbnstore.py | 2 +- databento/historical/api/batch.py | 4 ++-- databento/historical/http.py | 4 ++-- databento/live/session.py | 4 ++-- 4 files changed, 7 insertions(+), 7 deletions(-) diff --git a/databento/common/dbnstore.py b/databento/common/dbnstore.py index 6cba645..3b75b83 100644 --- a/databento/common/dbnstore.py +++ b/databento/common/dbnstore.py @@ -1319,7 +1319,7 @@ def __next__(self) -> np.ndarray[Any, Any]: except ValueError: raise BentoError( "DBN file is truncated or contains an incomplete record", - ) + ) from None class DataFrameIterator: diff --git a/databento/historical/api/batch.py b/databento/historical/api/batch.py index 6c2c289..37d6801 100644 --- a/databento/historical/api/batch.py +++ b/databento/historical/api/batch.py @@ -376,7 +376,7 @@ def _download_file( for chunk in response.iter_content(chunk_size=None): f.write(chunk) except Exception as exc: - raise BentoError(f"Error downloading file: {exc}") + raise BentoError(f"Error downloading file: {exc}") from None logger.debug("Download of %s completed", output_path.name) async def download_async( @@ -521,7 +521,7 @@ async def _download_file_async( data: bytes = chunk[0] f.write(data) except Exception as exc: - raise BentoError(f"Error downloading file: {exc}") + raise BentoError(f"Error downloading file: {exc}") from None logger.debug("Download of %s completed", output_path.name) def _get_file_download_headers_and_mode( diff --git a/databento/historical/http.py b/databento/historical/http.py index a1d9597..788eab3 100644 --- a/databento/historical/http.py +++ b/databento/historical/http.py @@ -137,7 +137,7 @@ def _stream( for chunk in response.iter_content(chunk_size=None): writer.write(chunk) except Exception as exc: - raise BentoError(f"Error streaming response: {exc}") + raise BentoError(f"Error streaming response: {exc}") from None if path is None: writer.seek(0) @@ -177,7 +177,7 @@ async def _stream_async( async for chunk in response.content.iter_chunks(): writer.write(chunk[0]) except Exception as exc: - raise BentoError(f"Error streaming response: {exc}") + raise BentoError(f"Error streaming response: {exc}") from None if path is None: writer.seek(0) diff --git a/databento/live/session.py b/databento/live/session.py index d90f152..519d2e4 100644 --- a/databento/live/session.py +++ b/databento/live/session.py @@ -414,12 +414,12 @@ async def wait_for_close(self) -> None: try: self._protocol.authenticated.result() except Exception as exc: - raise BentoError(exc) + raise BentoError(exc) from None try: self._protocol.disconnected.result() except Exception as exc: - raise BentoError(exc) + raise BentoError(exc) from None self._protocol = self._transport = None From 552de8ca039ce28447d509a6345d02d16e48c98a Mon Sep 17 00:00:00 2001 From: Nick Macholl Date: Thu, 18 Jan 2024 16:32:29 -0800 Subject: [PATCH 5/8] ADD: Session.session_id property --- CHANGELOG.md | 3 +++ databento/live/session.py | 22 +++++++++++++++++----- tests/test_live_client.py | 23 +++++++++++++++++++++++ 3 files changed, 43 insertions(+), 5 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 985cb99..885be5b 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -2,6 +2,9 @@ ## 0.27.0 - TBD +#### Enhancements +- Added `Session.session_id` property which will contain the numerical session ID once a live session has been authenticated + #### Breaking changes - Renamed `DatatbentoLiveProtocol.started` to `DatatbentoLiveProtocol.is_started` which now returns a bool instead of an `asyncio.Event` diff --git a/databento/live/session.py b/databento/live/session.py index 519d2e4..bfd2a74 100644 --- a/databento/live/session.py +++ b/databento/live/session.py @@ -227,6 +227,20 @@ def __init__( self._user_gateway: str | None = user_gateway self._port = port + self._session_id: int = 0 + + @property + def session_id(self) -> int: + """ + Return the authenticated session ID. A zero value indicates no session + has started. + + Returns + ------- + int + + """ + return self._session_id def is_authenticated(self) -> bool: """ @@ -489,13 +503,11 @@ async def _connect_task( f"Authentication with {gateway}:{port} timed out after " f"{AUTH_TIMEOUT_SECONDS} second(s).", ) from None - except ValueError as exc: - raise BentoError(f"User authentication failed: {exc!s}") from None - else: - logger.info("assigned session id %s", session_id) + self._session_id = session_id logger.info( - "authentication with remote gateway completed", + "authenticated session %s", + self.session_id, ) return transport, protocol diff --git a/tests/test_live_client.py b/tests/test_live_client.py index 35a20df..47ffa89 100644 --- a/tests/test_live_client.py +++ b/tests/test_live_client.py @@ -405,6 +405,29 @@ def test_live_subscribe( assert message.start == start +@pytest.mark.usefixtures("mock_live_server") +async def test_live_subscribe_session_id( + live_client: client.Live, +) -> None: + """ + Test that a session ID is assigned after the connection is authenticated. + """ + # Arrange + old_session_id = live_client._session.session_id + + # Act + live_client.subscribe( + dataset=Dataset.GLBX_MDP3, + schema=Schema.MBO, + stype_in=SType.RAW_SYMBOL, + symbols=ALL_SYMBOLS, + ) + + # Assert + assert live_client._session.session_id != old_session_id + assert live_client._session.session_id != 0 + + @pytest.mark.skipif(platform.system() == "Windows", reason="timeout on windows") async def test_live_subscribe_large_symbol_list( live_client: client.Live, From 041ed4129497ac04b53c85d4b753526cfa45a650 Mon Sep 17 00:00:00 2001 From: Nick Macholl Date: Tue, 23 Jan 2024 10:21:35 -0800 Subject: [PATCH 6/8] MOD: Upgrade to databento-dbn v0.15.1 --- CHANGELOG.md | 1 + README.md | 2 +- pyproject.toml | 2 +- 3 files changed, 3 insertions(+), 2 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 885be5b..2f27df2 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -4,6 +4,7 @@ #### Enhancements - Added `Session.session_id` property which will contain the numerical session ID once a live session has been authenticated +- Upgraded `databento-dbn` to 0.15.1 #### Breaking changes - Renamed `DatatbentoLiveProtocol.started` to `DatatbentoLiveProtocol.is_started` which now returns a bool instead of an `asyncio.Event` diff --git a/README.md b/README.md index f2c453f..000cc2e 100644 --- a/README.md +++ b/README.md @@ -32,7 +32,7 @@ The library is fully compatible with the latest distribution of Anaconda 3.8 and The minimum dependencies as found in the `pyproject.toml` are also listed below: - python = "^3.8" - aiohttp = "^3.8.3" -- databento-dbn = "0.15.0" +- databento-dbn = "0.15.1" - numpy= ">=1.23.5" - pandas = ">=1.5.3" - pyarrow = ">=13.0.0" diff --git a/pyproject.toml b/pyproject.toml index a039a50..e21cecb 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.15.0" +databento-dbn = "0.15.1" numpy = [ {version = ">=1.23.5", python = "<3.12"}, {version = "^1.26.0", python = "^3.12"} From f20b9a815bd1d32c6e532ade4fab41b5cd40bab5 Mon Sep 17 00:00:00 2001 From: Nick Macholl Date: Tue, 23 Jan 2024 10:24:40 -0800 Subject: [PATCH 7/8] VER: Release 0.27.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 2f27df2..a125b1d 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,6 +1,6 @@ # Changelog -## 0.27.0 - TBD +## 0.27.0 - 2024-01-23 #### Enhancements - Added `Session.session_id` property which will contain the numerical session ID once a live session has been authenticated diff --git a/databento/version.py b/databento/version.py index 7c4a959..cde6d89 100644 --- a/databento/version.py +++ b/databento/version.py @@ -1 +1 @@ -__version__ = "0.26.0" +__version__ = "0.27.0" diff --git a/pyproject.toml b/pyproject.toml index e21cecb..fb63532 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -1,6 +1,6 @@ [tool.poetry] name = "databento" -version = "0.26.0" +version = "0.27.0" description = "Official Python client library for Databento" authors = [ "Databento ", From f5ddca85be391180ddfbf2f3a2c1a8cd56d2e960 Mon Sep 17 00:00:00 2001 From: Nick Macholl Date: Tue, 23 Jan 2024 13:26:23 -0800 Subject: [PATCH 8/8] FIX: Fix typo in Python change notes --- CHANGELOG.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index a125b1d..14183ea 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -7,7 +7,7 @@ - Upgraded `databento-dbn` to 0.15.1 #### Breaking changes -- Renamed `DatatbentoLiveProtocol.started` to `DatatbentoLiveProtocol.is_started` which now returns a bool instead of an `asyncio.Event` +- Renamed `DatabentoLiveProtocol.started` to `DatabentoLiveProtocol.is_started` which now returns a bool instead of an `asyncio.Event` #### Bug fixes - Fixed an issue where an error message from the live gateway would not properly raise an exception if the connection closed before `Live.start` was called @@ -258,7 +258,7 @@ This release includes updates to the fields in text encodings (CSV and JSON), yo ## 0.14.0 - 2023-06-14 #### Enhancements -- Added `DatatbentoLiveProtocol` class +- Added `DatabentoLiveProtocol` class - Added `metadata` property to `Live` - Added support for reusing a `Live` client to reconnect - Added support for emitting warnings in API response headers