Skip to content

Commit 0005a27

Browse files
author
Zach Banks
committed
ADD: Add User-Agent Python client library requests
1 parent 0d87a34 commit 0005a27

File tree

11 files changed

+94
-26
lines changed

11 files changed

+94
-26
lines changed

MANIFEST.in

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1 +1 @@
1-
include setup.cfg CHANGELOG.md LICENSE README.md VERSION
1+
include setup.cfg CHANGELOG.md LICENSE README.md

VERSION

Lines changed: 0 additions & 1 deletion
This file was deleted.

databento/__init__.py

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -3,14 +3,15 @@
33
from databento.common.bento import Bento, FileBento, MemoryBento
44
from databento.historical.api import API_VERSION
55
from databento.historical.client import Historical
6+
from databento.version import __version__ # noqa
67

78

89
__all__ = [
10+
"API_VERSION",
911
"Bento",
1012
"FileBento",
11-
"MemoryBento",
1213
"Historical",
13-
"API_VERSION",
14+
"MemoryBento",
1415
]
1516

1617
# Set to either 'DEBUG' or 'INFO', controls console logging

databento/historical/http.py

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,4 @@
1+
import sys
12
from datetime import date
23
from json.decoder import JSONDecodeError
34
from typing import Any, BinaryIO, List, Optional, Tuple, Union
@@ -15,6 +16,7 @@
1516
maybe_symbols_list_to_string,
1617
)
1718
from databento.historical.error import BentoClientError, BentoServerError
19+
from databento.version import __version__
1820
from requests import Response
1921
from requests.auth import HTTPBasicAuth
2022

@@ -29,9 +31,12 @@ class BentoHttpAPI:
2931
TIMEOUT = 100
3032

3133
def __init__(self, key: str, gateway: str):
34+
python_version = f"{sys.version_info.major}.{sys.version_info.minor}"
35+
user_agent = f"Databento/{__version__} Python/{python_version}"
36+
3237
self._key = key
3338
self._gateway = gateway
34-
self._headers = {"accept": "application/json"}
39+
self._headers = {"accept": "application/json", "user-agent": user_agent}
3540

3641
@staticmethod
3742
def _timeseries_params(

databento/version.py

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
__version__ = "0.2.0"

setup.cfg

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@ universal = 1
33

44
[metadata]
55
license_file = LICENSE
6-
version_file = VERSION
6+
version = attr: databento.version.__version__
77

88
[flake8]
99
max-line-length = 88

setup.py

Lines changed: 2 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,16 +1,14 @@
11
#!/usr/bin/env python3
22
import os
33

4+
from databento.version import __version__
45
from setuptools import find_packages, setup
56

67

78
here = os.path.abspath(os.path.dirname(__file__))
89
os.chdir(here)
910

1011

11-
with open("VERSION") as f:
12-
version = f.read()
13-
1412
with open("README.md") as f:
1513
readme = f.read()
1614

@@ -23,7 +21,7 @@
2321

2422
setup(
2523
name="databento",
26-
version=version,
24+
version=__version__,
2725
description="Official Python client library for Databento",
2826
long_description=readme,
2927
long_description_content_type="text/x-rst",

tests/test_historical_batch.py

Lines changed: 10 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -74,7 +74,11 @@ def test_batch_timeseries_submit_sends_expected_request(self, mocker) -> None:
7474
call["url"]
7575
== f"https://hist.databento.com/v{db.API_VERSION}/batch.timeseries_submit"
7676
)
77-
assert call["headers"] == {"accept": "application/json"}
77+
assert sorted(call["headers"].keys()) == ["accept", "user-agent"]
78+
assert call["headers"]["accept"] == "application/json"
79+
assert all(
80+
v in call["headers"]["user-agent"] for v in ("Databento/", "Python/")
81+
)
7882
assert call["params"] == [
7983
("dataset", "glbx.mdp3"),
8084
("symbols", "ESH1"),
@@ -107,7 +111,11 @@ def test_batch_list_jobs_sends_expected_request(self, mocker) -> None:
107111
call["url"]
108112
== f"https://hist.databento.com/v{db.API_VERSION}/batch.list_jobs"
109113
)
110-
assert call["headers"] == {"accept": "application/json"}
114+
assert sorted(call["headers"].keys()) == ["accept", "user-agent"]
115+
assert call["headers"]["accept"] == "application/json"
116+
assert all(
117+
v in call["headers"]["user-agent"] for v in ("Databento/", "Python/")
118+
)
111119
assert call["params"] == [
112120
("states", "received,queued,processing,done"),
113121
("since", "2022-01-01T00:00:00"),

tests/test_historical_client.py

Lines changed: 10 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -84,7 +84,11 @@ def test_re_request_symbology_makes_expected_request(self, mocker) -> None:
8484
("end_date", "2020-12-29"),
8585
("default_value", ""),
8686
]
87-
assert call["headers"] == {"accept": "application/json"}
87+
assert sorted(call["headers"].keys()) == ["accept", "user-agent"]
88+
assert call["headers"]["accept"] == "application/json"
89+
assert all(
90+
v in call["headers"]["user-agent"] for v in ("Databento/", "Python/")
91+
)
8892
assert call["timeout"] == (100, 100)
8993
assert isinstance(call["auth"], requests.auth.HTTPBasicAuth)
9094

@@ -118,6 +122,10 @@ def test_request_full_definitions_expected_request(self, mocker) -> None:
118122
("encoding", "dbz"),
119123
("compression", "zstd"),
120124
]
121-
assert call["headers"] == {"accept": "application/json"}
125+
assert sorted(call["headers"].keys()) == ["accept", "user-agent"]
126+
assert call["headers"]["accept"] == "application/json"
127+
assert all(
128+
v in call["headers"]["user-agent"] for v in ("Databento/", "Python/")
129+
)
122130
assert call["timeout"] == (100, 100)
123131
assert isinstance(call["auth"], requests.auth.HTTPBasicAuth)

tests/test_historical_metadata.py

Lines changed: 50 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -30,7 +30,11 @@ def test_list_datasets_sends_expected_request(self, mocker) -> None:
3030
)
3131
assert ("start_date", "2018-01-01") in call["params"]
3232
assert ("end_date", "2020-01-01") in call["params"]
33-
assert call["headers"] == {"accept": "application/json"}
33+
assert sorted(call["headers"].keys()) == ["accept", "user-agent"]
34+
assert call["headers"]["accept"] == "application/json"
35+
assert all(
36+
v in call["headers"]["user-agent"] for v in ("Databento/", "Python/")
37+
)
3438
assert call["timeout"] == (100, 100)
3539
assert isinstance(call["auth"], requests.auth.HTTPBasicAuth)
3640

@@ -54,7 +58,11 @@ def test_list_schemas_sends_expected_request(self, mocker) -> None:
5458
)
5559
assert ("start_date", "2018-01-01") in call["params"]
5660
assert ("end_date", "2021-01-01") in call["params"]
57-
assert call["headers"] == {"accept": "application/json"}
61+
assert sorted(call["headers"].keys()) == ["accept", "user-agent"]
62+
assert call["headers"]["accept"] == "application/json"
63+
assert all(
64+
v in call["headers"]["user-agent"] for v in ("Databento/", "Python/")
65+
)
5866
assert call["timeout"] == (100, 100)
5967
assert isinstance(call["auth"], requests.auth.HTTPBasicAuth)
6068

@@ -78,7 +86,11 @@ def test_list_fields_sends_expected_request(self, mocker) -> None:
7886
)
7987
assert ("schema", "mbo") in call["params"]
8088
assert ("encoding", "dbz") in call["params"]
81-
assert call["headers"] == {"accept": "application/json"}
89+
assert sorted(call["headers"].keys()) == ["accept", "user-agent"]
90+
assert call["headers"]["accept"] == "application/json"
91+
assert all(
92+
v in call["headers"]["user-agent"] for v in ("Databento/", "Python/")
93+
)
8294
assert call["timeout"] == (100, 100)
8395
assert isinstance(call["auth"], requests.auth.HTTPBasicAuth)
8496

@@ -96,7 +108,11 @@ def test_list_encodings_sends_expected_request(self, mocker) -> None:
96108
call["url"]
97109
== f"https://hist.databento.com/v{db.API_VERSION}/metadata.list_encodings"
98110
)
99-
assert call["headers"] == {"accept": "application/json"}
111+
assert sorted(call["headers"].keys()) == ["accept", "user-agent"]
112+
assert call["headers"]["accept"] == "application/json"
113+
assert all(
114+
v in call["headers"]["user-agent"] for v in ("Databento/", "Python/")
115+
)
100116
assert call["timeout"] == (100, 100)
101117
assert isinstance(call["auth"], requests.auth.HTTPBasicAuth)
102118

@@ -114,7 +130,11 @@ def test_list_compressions_sends_expected_request(self, mocker) -> None:
114130
call["url"]
115131
== f"https://hist.databento.com/v{db.API_VERSION}/metadata.list_compressions" # noqa
116132
)
117-
assert call["headers"] == {"accept": "application/json"}
133+
assert sorted(call["headers"].keys()) == ["accept", "user-agent"]
134+
assert call["headers"]["accept"] == "application/json"
135+
assert all(
136+
v in call["headers"]["user-agent"] for v in ("Databento/", "Python/")
137+
)
118138
assert call["timeout"] == (100, 100)
119139
assert isinstance(call["auth"], requests.auth.HTTPBasicAuth)
120140

@@ -145,7 +165,11 @@ def test_list_unit_price_sends_expected_request(
145165
call["url"]
146166
== f"https://hist.databento.com/v{db.API_VERSION}/metadata.list_unit_prices"
147167
)
148-
assert call["headers"] == {"accept": "application/json"}
168+
assert sorted(call["headers"].keys()) == ["accept", "user-agent"]
169+
assert call["headers"]["accept"] == "application/json"
170+
assert all(
171+
v in call["headers"]["user-agent"] for v in ("Databento/", "Python/")
172+
)
149173
assert call["params"] == [
150174
("dataset", "glbx.mdp3"),
151175
("mode", "live"),
@@ -175,7 +199,11 @@ def test_get_shape_sends_expected_request(self, mocker) -> None:
175199
call["url"]
176200
== f"https://hist.databento.com/v{db.API_VERSION}/metadata.get_shape"
177201
)
178-
assert call["headers"] == {"accept": "application/json"}
202+
assert sorted(call["headers"].keys()) == ["accept", "user-agent"]
203+
assert call["headers"]["accept"] == "application/json"
204+
assert all(
205+
v in call["headers"]["user-agent"] for v in ("Databento/", "Python/")
206+
)
179207
assert call["params"] == [
180208
("dataset", "glbx.mdp3"),
181209
("symbols", "ESH1"),
@@ -210,7 +238,11 @@ def test_get_billable_size_sends_expected_request(self, mocker) -> None:
210238
call["url"]
211239
== f"https://hist.databento.com/v{db.API_VERSION}/metadata.get_billable_size" # noqa
212240
)
213-
assert call["headers"] == {"accept": "application/json"}
241+
assert sorted(call["headers"].keys()) == ["accept", "user-agent"]
242+
assert call["headers"]["accept"] == "application/json"
243+
assert all(
244+
v in call["headers"]["user-agent"] for v in ("Databento/", "Python/")
245+
)
214246
assert call["params"] == [
215247
("dataset", "glbx.mdp3"),
216248
("symbols", "ESH1"),
@@ -245,7 +277,11 @@ def test_get_cost_sends_expected_request(self, mocker) -> None:
245277
call["url"]
246278
== f"https://hist.databento.com/v{db.API_VERSION}/metadata.get_cost"
247279
)
248-
assert call["headers"] == {"accept": "application/json"}
280+
assert sorted(call["headers"].keys()) == ["accept", "user-agent"]
281+
assert call["headers"]["accept"] == "application/json"
282+
assert all(
283+
v in call["headers"]["user-agent"] for v in ("Databento/", "Python/")
284+
)
249285
assert call["params"] == [
250286
("dataset", "glbx.mdp3"),
251287
("symbols", "ESH1"),
@@ -277,7 +313,11 @@ def test_get_license_fee_sends_expected_request(self, mocker) -> None:
277313
call["url"]
278314
== f"https://hist.databento.com/v{db.API_VERSION}/metadata.get_license_fee"
279315
)
280-
assert call["headers"] == {"accept": "application/json"}
316+
assert sorted(call["headers"].keys()) == ["accept", "user-agent"]
317+
assert call["headers"]["accept"] == "application/json"
318+
assert all(
319+
v in call["headers"]["user-agent"] for v in ("Databento/", "Python/")
320+
)
281321
assert call["params"] == [
282322
("dataset", "glbx.mdp3"),
283323
("purposes", "professional trading"),

0 commit comments

Comments
 (0)