Skip to content

Commit 0cdcda9

Browse files
committed
MOD: Deprecate Python 3.7 in the client library
1 parent 5159808 commit 0cdcda9

File tree

12 files changed

+27
-65
lines changed

12 files changed

+27
-65
lines changed

.github/workflows/test.yml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,7 @@ jobs:
1010
fail-fast: false
1111
matrix:
1212
os: [ubuntu-latest, macos-latest, windows-latest]
13-
python-version: ["3.7", "3.8", "3.9", "3.10", "3.11"]
13+
python-version: ["3.8", "3.9", "3.10", "3.11"]
1414
name: build - Python ${{ matrix.python-version }} (${{ matrix.os }})
1515
runs-on: ${{ matrix.os }}
1616

CHANGELOG.md

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

3+
## 0.14.0 - TBD
4+
- Upgraded `aiohttp` to 3.8.3
5+
- Upgraded `numpy` to to 1.23.5
6+
- Upgraded `pandas` to to 1.5.3
7+
- Upgraded `requests` to to 2.28.1
8+
- Upgraded `zstandard` to to 0.21.0
9+
- Removed support for Python 3.7
10+
311
## 0.13.0 - 2023-06-02
412
- Added support for `statistics` schema
513
- Added batch download support data files (`condition.json` and `symbology.json`)

README.md

Lines changed: 8 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
# databento-python
22

33
[![test](https://github.com/databento/databento-python/actions/workflows/test.yml/badge.svg?branch=dev)](https://github.com/databento/databento-python/actions/workflows/test.yml)
4-
![python](https://img.shields.io/badge/python-3.7+-blue.svg)
4+
![python](https://img.shields.io/badge/python-3.8+-blue.svg)
55
[![pypi-version](https://img.shields.io/pypi/v/databento)](https://pypi.org/project/databento)
66
[![license](https://img.shields.io/github/license/databento/databento-python?color=blue)](./LICENSE)
77
[![code-style: black](https://img.shields.io/badge/code%20style-black-000000.svg)](https://github.com/psf/black)
@@ -27,15 +27,15 @@ You can find our full client API reference on the [Historical Reference](https:/
2727
[Examples](https://docs.databento.com/examples?historical=python&live=python) section for various tutorials and code samples.
2828

2929
## Requirements
30-
The library is fully compatible with the latest distribution of Anaconda 3.7 and above.
30+
The library is fully compatible with the latest distribution of Anaconda 3.8 and above.
3131
The minimum dependencies as found in the `pyproject.toml` are also listed below:
32-
- python = "^3.7"
33-
- aiohttp = "^3.7.2"
32+
- python = "^3.8"
33+
- aiohttp = "^3.8.3"
3434
- databento-dbn = "0.6.1"
35-
- numpy= ">=1.17.0"
36-
- pandas = ">=1.1.3"
37-
- requests = ">=2.24.0"
38-
- zstandard = ">=0.20.0"
35+
- numpy= ">=1.23.5"
36+
- pandas = ">=1.5.3"
37+
- requests = ">=2.28.1"
38+
- zstandard = ">=0.21.0"
3939

4040
## Installation
4141
To install the latest stable version of the package from PyPI:

databento/live/gateway.py

Lines changed: 2 additions & 28 deletions
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,9 @@
11
import asyncio
22
import dataclasses
33
import logging
4-
from functools import partial, singledispatch, update_wrapper
4+
from functools import partial, singledispatchmethod
55
from io import BytesIO
6-
from typing import Any, Callable, Optional, Type, TypeVar, Union
6+
from typing import Optional, Type, TypeVar, Union
77

88
from databento.common import cram
99
from databento.common.enums import Compression, Dataset, Encoding, Schema, SType
@@ -16,32 +16,6 @@
1616
MIN_BUFFER_SIZE = 16 * 1024 # 16kB
1717

1818

19-
def singledispatchmethod(
20-
func: Callable[..., Any],
21-
) -> Any:
22-
"""
23-
Decorate a function to dispatch arguments by type.
24-
This is a custom implementation of functools.singledispatchmethod.
25-
26-
See Also
27-
--------
28-
functools.singledispatch
29-
30-
Notes
31-
-----
32-
This should be removed when python 3.7 is no longer supported.
33-
34-
"""
35-
dispatcher: Any = singledispatch(func)
36-
37-
def _wrapper(*args: object, **kw: object) -> Any:
38-
return dispatcher.dispatch(args[1].__class__)(*args, **kw)
39-
40-
setattr(_wrapper, "register", getattr(dispatcher, "register"))
41-
update_wrapper(_wrapper, func)
42-
return _wrapper
43-
44-
4519
@dataclasses.dataclass
4620
class GatewayControl:
4721
"""

databento/version.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1 +1 @@
1-
__version__ = "0.13.0"
1+
__version__ = "0.14.0"

pyproject.toml

Lines changed: 7 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
[tool.poetry]
22
name = "databento"
3-
version = "0.13.0"
3+
version = "0.14.0"
44
description = "Official Python client library for Databento"
55
authors = [
66
"Databento <[email protected]>",
@@ -24,13 +24,13 @@ repository = "https://github.com/databento/databento-python"
2424
"Bug Tracker" = "https://github.com/databento/databento-python/issues"
2525

2626
[tool.poetry.dependencies]
27-
python = "^3.7"
28-
aiohttp = "^3.7.2"
27+
python = "^3.8"
28+
aiohttp = "^3.8.3"
2929
databento-dbn = "0.6.1"
30-
numpy= ">=1.17.0"
31-
pandas = ">=1.1.3"
30+
numpy= ">=1.23.5"
31+
pandas = ">=1.5.3"
3232
requests = ">=2.24.0"
33-
zstandard = ">=0.20.0"
33+
zstandard = ">=0.21.0"
3434

3535
[tool.poetry.group.dev.dependencies]
3636
mypy = "1.2.0"
@@ -44,7 +44,7 @@ requires = ["poetry-core"]
4444
build-backend = "poetry.core.masonry.api"
4545

4646
[tool.mypy]
47-
python_version = 3.7
47+
python_version = 3.8
4848
disallow_untyped_defs = true
4949
disallow_any_generics = true
5050
disallow_subclassing_any = true

tests/test_historical_batch.py

Lines changed: 0 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -49,7 +49,6 @@ def test_batch_submit_job_given_invalid_stype_in_raises_error(self) -> None:
4949
stype_in="zzz", # <--- invalid
5050
)
5151

52-
@pytest.mark.skipif(sys.version_info < (3, 8), reason="incompatible mocking")
5352
def test_batch_submit_job_sends_expected_request(
5453
self,
5554
mocker: MockerFixture,
@@ -101,7 +100,6 @@ def test_batch_submit_job_sends_expected_request(
101100
assert call["timeout"] == (100, 100)
102101
assert isinstance(call["auth"], requests.auth.HTTPBasicAuth)
103102

104-
@pytest.mark.skipif(sys.version_info < (3, 8), reason="incompatible mocking")
105103
def test_batch_list_jobs_sends_expected_request(
106104
self,
107105
mocker: MockerFixture,
@@ -130,7 +128,6 @@ def test_batch_list_jobs_sends_expected_request(
130128
assert call["timeout"] == (100, 100)
131129
assert isinstance(call["auth"], requests.auth.HTTPBasicAuth)
132130

133-
@pytest.mark.skipif(sys.version_info < (3, 8), reason="incompatible mocking")
134131
def test_batch_list_files_sends_expected_request(
135132
self,
136133
mocker: MockerFixture,
@@ -159,7 +156,6 @@ def test_batch_list_files_sends_expected_request(
159156
assert call["timeout"] == (100, 100)
160157
assert isinstance(call["auth"], requests.auth.HTTPBasicAuth)
161158

162-
@pytest.mark.skipif(sys.version_info < (3, 8), reason="incompatible mocking")
163159
def test_batch_download_single_file_sends_expected_request(
164160
self,
165161
mocker: MockerFixture,

tests/test_historical_client.py

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -96,7 +96,6 @@ def test_custom_gateway_force_https(
9696
# Assert
9797
assert client.gateway == expected
9898

99-
@pytest.mark.skipif(sys.version_info < (3, 8), reason="incompatible mocking")
10099
def test_re_request_symbology_makes_expected_request(
101100
self,
102101
test_data_path: Callable[[Schema], pathlib.Path],
@@ -135,7 +134,6 @@ def test_re_request_symbology_makes_expected_request(
135134
assert call["timeout"] == (100, 100)
136135
assert isinstance(call["auth"], requests.auth.HTTPBasicAuth)
137136

138-
@pytest.mark.skipif(sys.version_info < (3, 8), reason="incompatible mocking")
139137
def test_request_full_definitions_expected_request(
140138
self,
141139
test_data: Callable[[Schema], bytes],

tests/test_historical_error.py

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -35,7 +35,6 @@ def test_check_http_status(
3535

3636

3737
@pytest.mark.asyncio
38-
@pytest.mark.skipif(sys.version_info < (3, 8), reason="no async support for MagicMock")
3938
@pytest.mark.parametrize(
4039
"status_code, expected_exception, message",
4140
[

tests/test_historical_metadata.py

Lines changed: 0 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,6 @@ def setup_method(self) -> None:
1313
key = "DUMMY_API_KEY"
1414
self.client = db.Historical(key=key)
1515

16-
@pytest.mark.skipif(sys.version_info < (3, 8), reason="incompatible mocking")
1716
def test_list_publishers_sends_expected_request(
1817
self,
1918
mocker: MockerFixture,
@@ -38,7 +37,6 @@ def test_list_publishers_sends_expected_request(
3837
assert call["timeout"] == (100, 100)
3938
assert isinstance(call["auth"], requests.auth.HTTPBasicAuth)
4039

41-
@pytest.mark.skipif(sys.version_info < (3, 8), reason="incompatible mocking")
4240
def test_list_datasets_sends_expected_request(self, mocker: MockerFixture) -> None:
4341
# Arrange
4442
mocked_get = mocker.patch("requests.get")
@@ -65,7 +63,6 @@ def test_list_datasets_sends_expected_request(self, mocker: MockerFixture) -> No
6563
assert call["timeout"] == (100, 100)
6664
assert isinstance(call["auth"], requests.auth.HTTPBasicAuth)
6765

68-
@pytest.mark.skipif(sys.version_info < (3, 8), reason="incompatible mocking")
6966
def test_list_schemas_sends_expected_request(self, mocker: MockerFixture) -> None:
7067
# Arrange
7168
mocked_get = mocker.patch("requests.get")
@@ -88,7 +85,6 @@ def test_list_schemas_sends_expected_request(self, mocker: MockerFixture) -> Non
8885
assert call["timeout"] == (100, 100)
8986
assert isinstance(call["auth"], requests.auth.HTTPBasicAuth)
9087

91-
@pytest.mark.skipif(sys.version_info < (3, 8), reason="incompatible mocking")
9288
def test_list_fields_sends_expected_request(self, mocker: MockerFixture) -> None:
9389
# Arrange
9490
mocked_get = mocker.patch("requests.get")
@@ -117,7 +113,6 @@ def test_list_fields_sends_expected_request(self, mocker: MockerFixture) -> None
117113
assert call["timeout"] == (100, 100)
118114
assert isinstance(call["auth"], requests.auth.HTTPBasicAuth)
119115

120-
@pytest.mark.skipif(sys.version_info < (3, 8), reason="incompatible mocking")
121116
@pytest.mark.parametrize(
122117
"dataset, schema, mode",
123118
[
@@ -161,7 +156,6 @@ def test_list_unit_price_sends_expected_request(
161156
assert call["timeout"] == (100, 100)
162157
assert isinstance(call["auth"], requests.auth.HTTPBasicAuth)
163158

164-
@pytest.mark.skipif(sys.version_info < (3, 8), reason="incompatible mocking")
165159
def test_get_dataset_condition_sends_expected_request(
166160
self,
167161
mocker: MockerFixture,
@@ -193,7 +187,6 @@ def test_get_dataset_condition_sends_expected_request(
193187
assert call["timeout"] == (100, 100)
194188
assert isinstance(call["auth"], requests.auth.HTTPBasicAuth)
195189

196-
@pytest.mark.skipif(sys.version_info < (3, 8), reason="incompatible mocking")
197190
def test_get_dataset_range_sends_expected_request(
198191
self,
199192
mocker: MockerFixture,
@@ -221,7 +214,6 @@ def test_get_dataset_range_sends_expected_request(
221214
assert call["timeout"] == (100, 100)
222215
assert isinstance(call["auth"], requests.auth.HTTPBasicAuth)
223216

224-
@pytest.mark.skipif(sys.version_info < (3, 8), reason="incompatible mocking")
225217
def test_get_record_count_sends_expected_request(
226218
self,
227219
mocker: MockerFixture,
@@ -262,7 +254,6 @@ def test_get_record_count_sends_expected_request(
262254
assert call["timeout"] == (100, 100)
263255
assert isinstance(call["auth"], requests.auth.HTTPBasicAuth)
264256

265-
@pytest.mark.skipif(sys.version_info < (3, 8), reason="incompatible mocking")
266257
def test_get_billable_size_sends_expected_request(
267258
self,
268259
mocker: MockerFixture,
@@ -304,7 +295,6 @@ def test_get_billable_size_sends_expected_request(
304295
assert call["timeout"] == (100, 100)
305296
assert isinstance(call["auth"], requests.auth.HTTPBasicAuth)
306297

307-
@pytest.mark.skipif(sys.version_info < (3, 8), reason="incompatible mocking")
308298
def test_get_cost_sends_expected_request(self, mocker: MockerFixture) -> None:
309299
# Arrange
310300
mocked_get = mocker.patch("requests.get")

0 commit comments

Comments
 (0)