Skip to content

Commit 2897008

Browse files
committed
ADD: Add get_license_fee to Python client library
1 parent 6254b3d commit 2897008

File tree

8 files changed

+184
-36
lines changed

8 files changed

+184
-36
lines changed

databento/common/parsing.py

Lines changed: 53 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -68,15 +68,61 @@ def maybe_enum_or_str_lowercase(
6868
return enum_or_str_lowercase(value, param)
6969

7070

71+
def values_list_to_string(
72+
values: Union[Iterable[str], str],
73+
) -> str:
74+
"""
75+
Concatenate a values string or iterable of string values.
76+
77+
Parameters
78+
----------
79+
values : iterable of str or str
80+
The values to concatenate.
81+
82+
Returns
83+
-------
84+
str
85+
86+
"""
87+
if isinstance(values, str):
88+
return values.strip().rstrip(",").lower()
89+
elif isinstance(values, Iterable):
90+
return ",".join(values).strip().lower()
91+
else:
92+
raise TypeError(f"invalid values type, was {type(values)}")
93+
94+
95+
def maybe_values_list_to_string(
96+
values: Optional[Union[Iterable[str], str]],
97+
) -> Optional[str]:
98+
"""
99+
Concatenate a values string or iterable of string values (if not None).
100+
101+
Parameters
102+
----------
103+
values : iterable of str or str, optional
104+
The values to concatenate.
105+
106+
Returns
107+
-------
108+
str or ``None``
109+
110+
"""
111+
if values is None:
112+
return None
113+
114+
return values_list_to_string(values)
115+
116+
71117
def maybe_symbols_list_to_string(
72-
symbols: Optional[Iterable[str]],
118+
symbols: Optional[Union[Iterable[str], str]],
73119
) -> Optional[str]:
74120
"""
75-
Concatenate a symbols string (if not None).
121+
Concatenate a symbols string or iterable of symbol strings (if not None).
76122
77123
Parameters
78124
----------
79-
symbols : iterable of str, optional
125+
symbols : iterable of str or str, optional
80126
The symbols to concatenate.
81127
82128
Returns
@@ -85,12 +131,12 @@ def maybe_symbols_list_to_string(
85131
86132
"""
87133
if symbols is None:
88-
return None # ALL
134+
return None # All symbols
89135

90136
if isinstance(symbols, str):
91-
return symbols.rstrip(",").upper()
92-
if isinstance(symbols, (tuple, list)):
93-
return ",".join(symbols).upper()
137+
return symbols.strip().rstrip(",").upper()
138+
elif isinstance(symbols, Iterable):
139+
return ",".join(symbols).strip().upper()
94140
else:
95141
raise TypeError(f"invalid symbols type, was {type(symbols)}")
96142

databento/historical/api/batch.py

Lines changed: 18 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,10 @@
1212
Schema,
1313
SType,
1414
)
15-
from databento.common.parsing import maybe_datetime_to_string
15+
from databento.common.parsing import (
16+
maybe_datetime_to_string,
17+
maybe_values_list_to_string,
18+
)
1619
from databento.common.validation import validate_enum
1720
from databento.historical.api import API_VERSION
1821
from databento.historical.http import BentoHttpAPI
@@ -47,7 +50,7 @@ def timeseries_submit(
4750
"""
4851
Submit a time series batch data job to the Databento backend.
4952
50-
`POST /v0/batch.timeseries_submit` HTTP API endpoint.
53+
Makes a `POST /batch.timeseries_submit` HTTP request.
5154
5255
Parameters
5356
----------
@@ -139,32 +142,35 @@ def timeseries_submit(
139142

140143
def list_jobs(
141144
self,
142-
states: Optional[str] = "received,queued,processing,done",
145+
states: Optional[Union[List[str], str]] = "received,queued,processing,done",
143146
since: Optional[Union[pd.Timestamp, date, str, int]] = None,
144147
) -> List[Dict[str, Any]]:
145148
"""
146-
Request all batch data jobs associated with the client access key with
147-
the optional query filters.
149+
List batch job details for the user account.
150+
151+
The job details will be sorted in order of `ts_received`.
148152
149-
Makes a `GET /v0/batch.list_jobs` HTTP request.
153+
Makes a `GET /batch.list_jobs` HTTP request.
150154
151155
Parameters
152156
----------
153-
states : str, optional {'received', 'queued', 'processing', 'done', 'expired'}
154-
The comma separated job states to include in the response. If ``None``
155-
will default to 'queued,processing,done' (may contain whitespace).
157+
states : List[str] or str, optional {'received', 'queued', 'processing', 'done', 'expired'} # noqa
158+
The filter for jobs states as a list of comma separated values.
156159
since : pd.Timestamp or date or str or int, optional
157-
The datetime to filter from.
160+
The filter for timestamp submitted (will not include jobs prior to this).
158161
159162
Returns
160163
-------
161164
List[Dict[str, Any]]
162-
The matching jobs sorted in order of timestamp received.
165+
The batch job details.
163166
164167
"""
168+
states = maybe_values_list_to_string(states)
169+
since = maybe_datetime_to_string(since)
170+
165171
params: List[Tuple[str, str]] = [
166172
("states", states),
167-
("since", maybe_datetime_to_string(since)),
173+
("since", since),
168174
]
169175

170176
return self._get(

databento/historical/api/metadata.py

Lines changed: 49 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,7 @@
99
maybe_datetime_to_string,
1010
maybe_enum_or_str_lowercase,
1111
maybe_symbols_list_to_string,
12+
values_list_to_string,
1213
)
1314
from databento.common.validation import validate_enum, validate_maybe_enum
1415
from databento.historical.api import API_VERSION
@@ -33,7 +34,7 @@ def list_datasets(
3334
"""
3435
List all available datasets from Databento.
3536
36-
Makes a `GET /v0/metadata.list_datasets` HTTP request.
37+
Makes a `GET /metadata.list_datasets` HTTP request.
3738
3839
Parameters
3940
----------
@@ -82,7 +83,7 @@ def list_schemas(
8283
"""
8384
List all available data schemas from Databento.
8485
85-
Makes a `GET /v0/metadata.list_schemas` HTTP request.
86+
Makes a `GET /metadata.list_schemas` HTTP request.
8687
8788
Parameters
8889
----------
@@ -124,7 +125,7 @@ def list_fields(
124125
"""
125126
List all fields for a dataset, schema and encoding from Databento.
126127
127-
Makes a `GET /v0/metadata.list_fields` HTTP request.
128+
Makes a `GET /metadata.list_fields` HTTP request.
128129
129130
The `schema` and `encoding` parameters act as optional filters. All
130131
metadata for that parameter is returned if they are not specified.
@@ -168,7 +169,7 @@ def list_encodings(self) -> List[str]:
168169
"""
169170
List all available data encodings from Databento.
170171
171-
Makes a `GET /v0/metadata.list_encodings` HTTP request.
172+
Makes a `GET /metadata.list_encodings` HTTP request.
172173
173174
Returns
174175
-------
@@ -185,7 +186,7 @@ def list_compressions(self) -> List[str]:
185186
"""
186187
List all available data compression modes from Databento.
187188
188-
Makes a `GET /v0/metadata.list_compressions` HTTP request.
189+
Makes a `GET /metadata.list_compressions` HTTP request.
189190
190191
Returns
191192
-------
@@ -207,7 +208,7 @@ def list_unit_prices(
207208
"""
208209
List data schema prices per GB unit from Databento.
209210
210-
Makes a `GET /v0/metadata.list_unit_prices` HTTP request.
211+
Makes a `GET /metadata.list_unit_prices` HTTP request.
211212
212213
Parameters
213214
----------
@@ -258,7 +259,7 @@ def get_shape(
258259
"""
259260
Get the shape of the time series data query.
260261
261-
Makes a GET `/v0/metadata.get_shape` HTTP request.
262+
Makes a GET `/metadata.get_shape` HTTP request.
262263
263264
Parameters
264265
----------
@@ -337,7 +338,7 @@ def get_billable_size(
337338
Get the raw uncompressed binary size of a historical streaming or batch
338339
data request, which would be used for billing.
339340
340-
Makes a GET `/v0/metadata.get_billable_size` HTTP request.
341+
Makes a GET `/metadata.get_billable_size` HTTP request.
341342
342343
Parameters
343344
----------
@@ -405,7 +406,7 @@ def get_cost(
405406
"""
406407
Get cost in US Dollars for a historical streaming or batch data request.
407408
408-
Makes a `GET /v0/metadata.get_cost` HTTP request.
409+
Makes a `GET /metadata.get_cost` HTTP request.
409410
410411
Parameters
411412
----------
@@ -464,3 +465,42 @@ def get_cost(
464465
)
465466

466467
return response.json()
468+
469+
def get_license_fee(
470+
self,
471+
dataset: Union[Dataset, str],
472+
purposes: Union[List[str], str],
473+
) -> int:
474+
"""
475+
Get the license fee in US Dollars for a dataset and access purposes.
476+
477+
Makes a `GET /metadata.get_license_fee` HTTP request.
478+
479+
Parameters
480+
----------
481+
dataset : Dataset or str
482+
The dataset name for the request.
483+
purposes : List[str] or str, {'professional trading', 'display usage', 'non-display usage', 'external redistribution', 'internal redistribution'} # noqa
484+
The licensing purposes.
485+
486+
Returns
487+
-------
488+
int
489+
The license fee in US Dollars.
490+
491+
"""
492+
dataset = enum_or_str_lowercase(dataset, "dataset")
493+
purposes = values_list_to_string(purposes)
494+
495+
params: List[Tuple[str, str]] = [
496+
("dataset", dataset),
497+
("purposes", purposes),
498+
]
499+
500+
response: Response = self._get(
501+
url=self._base_url + ".get_license_fee",
502+
params=params,
503+
basic_auth=True,
504+
)
505+
506+
return response.json()

databento/historical/api/symbology.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -31,7 +31,7 @@ def resolve(
3131
"""
3232
Request symbology resolution.
3333
34-
Makes a `GET /v0/symbology.resolve` HTTP request.
34+
Makes a `GET /symbology.resolve` HTTP request.
3535
3636
Parameters
3737
----------

databento/historical/api/timeseries.py

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -39,7 +39,7 @@ def stream(
3939
"""
4040
Request a historical time series stream from the Databento API servers.
4141
42-
Makes a `GET /v0/timeseries.stream` HTTP request.
42+
Makes a `GET /timeseries.stream` HTTP request.
4343
4444
Parameters
4545
----------
@@ -133,7 +133,7 @@ async def stream_async(
133133
Request a historical time series stream from the Databento API servers
134134
asynchronously.
135135
136-
Makes a `GET /v0/timeseries.stream` HTTP request.
136+
Makes a `GET /timeseries.stream` HTTP request.
137137
138138
Parameters
139139
----------
@@ -236,7 +236,7 @@ def _pre_check_data_size(
236236
"request...",
237237
)
238238
response: Response = self._get(
239-
url=self._gateway + "/v0/metadata.get_size_estimation",
239+
url=self._gateway + f"/v{API_VERSION}/metadata.get_size_estimation",
240240
params=params,
241241
basic_auth=True,
242242
)
@@ -260,7 +260,7 @@ def _pre_check_data_size(
260260

261261
def _is_large_number_of_symbols(symbols: Optional[Union[List[str], str]]):
262262
if not symbols:
263-
return True # ALL
263+
return True # All symbols
264264

265265
if isinstance(symbols, str):
266266
symbols = symbols.split(",")

databento/historical/client.py

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -85,7 +85,7 @@ def request_symbology(self, data: Bento) -> Dict[str, Dict[str, Any]]:
8585
"""
8686
Request symbology resolution based on the metadata properties.
8787
88-
Makes a `GET /v0/symbology.resolve` HTTP request.
88+
Makes a `GET /symbology.resolve` HTTP request.
8989
9090
Current symbology mappings from the metadata are also available by
9191
calling the `.symbology` or `.mappings` properties.
@@ -118,7 +118,7 @@ def request_full_definitions(
118118
"""
119119
Request full instrument definitions based on the metadata properties.
120120
121-
Makes a `GET /v0/timeseries.stream` HTTP request.
121+
Makes a `GET /timeseries.stream` HTTP request.
122122
123123
Parameters
124124
----------

tests/test_common_parsing.py

Lines changed: 31 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
from datetime import date
22

3+
import numpy as np
34
import pandas as pd
45
import pytest
56
from databento.common.enums import Dataset, Flags
@@ -9,6 +10,7 @@
910
maybe_datetime_to_string,
1011
maybe_enum_or_str_lowercase,
1112
maybe_symbols_list_to_string,
13+
maybe_values_list_to_string,
1214
parse_flags,
1315
)
1416

@@ -60,6 +62,35 @@ def test_maybe_enum_or_str_lowercase_returns_expected_outputs(
6062
# Arrange, Act, Assert
6163
assert maybe_enum_or_str_lowercase(value, "param") == expected
6264

65+
def test_maybe_values_list_to_string_given_invalid_input_raises_type_error(
66+
self,
67+
) -> None:
68+
# Arrange, Act, Assert
69+
with pytest.raises(TypeError):
70+
maybe_values_list_to_string(type)
71+
72+
@pytest.mark.parametrize(
73+
"values, expected",
74+
[
75+
[None, None],
76+
["ABC,DEF", "abc,def"],
77+
[" ABC, DEF ", "abc, def"],
78+
[[" ABC", "DEF "], "abc,def"],
79+
[np.asarray([" ABC", "DEF "]), "abc,def"],
80+
[("1", "2"), "1,2"],
81+
],
82+
)
83+
def test_maybe_values_list_to_string_given_valid_inputs_returns_expected(
84+
self,
85+
values,
86+
expected,
87+
) -> None:
88+
# Arrange, Act
89+
result = maybe_values_list_to_string(values)
90+
91+
# Assert
92+
assert result == expected
93+
6394
def test_maybe_symbols_list_to_string_given_invalid_input_raises_type_error(
6495
self,
6596
) -> None:

0 commit comments

Comments
 (0)