Skip to content

Commit 4b53bc5

Browse files
committed
MOD: Update symbols parsing for smart symbology
1 parent fb5a7c1 commit 4b53bc5

File tree

7 files changed

+34
-20
lines changed

7 files changed

+34
-20
lines changed

databento/common/parsing.py

Lines changed: 19 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -178,6 +178,7 @@ def maybe_values_list_to_string(
178178

179179
def maybe_symbols_list_to_string(
180180
symbols: Optional[Union[Iterable[str], str]],
181+
stype_in: SType,
181182
) -> Optional[str]:
182183
"""
183184
Concatenate a symbols string or iterable of symbol strings (if not None).
@@ -186,21 +187,31 @@ def maybe_symbols_list_to_string(
186187
----------
187188
symbols : iterable of str or str, optional
188189
The symbols to concatenate.
190+
stype_in : SType
191+
The input symbology type for the request.
189192
190193
Returns
191194
-------
192195
str or ``None``
193196
194197
"""
195198
if symbols is None:
196-
return None # All symbols
197-
198-
if isinstance(symbols, str):
199-
return symbols.strip().rstrip(",").upper()
200-
elif isinstance(symbols, Iterable):
201-
return ",".join(symbols).strip().upper()
202-
else:
203-
raise TypeError(f"invalid symbols type, was {type(symbols)}")
199+
return None # Full universe
200+
201+
symbols_list = symbols.split(",") if isinstance(symbols, str) else list(symbols)
202+
cleaned_symbols: List[str] = []
203+
for symbol in symbols_list:
204+
if not symbol:
205+
continue
206+
symbol = symbol.strip().upper()
207+
if stype_in == SType.SMART:
208+
pieces: List[str] = symbol.split(".")
209+
if len(pieces) == 3:
210+
symbol = f"{pieces[0]}.{pieces[1].lower()}.{pieces[2]}"
211+
212+
cleaned_symbols.append(symbol)
213+
214+
return ",".join(cleaned_symbols)
204215

205216

206217
def maybe_date_to_string(value: Optional[Union[date, str]]) -> Optional[str]:

databento/historical/api/metadata.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -331,7 +331,7 @@ def get_record_count(
331331

332332
params: List[Tuple[str, Optional[str]]] = [
333333
("dataset", enum_or_str_uppercase(dataset, "dataset")),
334-
("symbols", maybe_symbols_list_to_string(symbols)),
334+
("symbols", maybe_symbols_list_to_string(symbols, SType(stype_in))),
335335
("schema", Schema(schema).value),
336336
("start", maybe_datetime_to_string(start)),
337337
("end", maybe_datetime_to_string(end)),

databento/historical/api/symbology.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -63,7 +63,7 @@ def resolve(
6363
"""
6464
params: List[Tuple[str, Optional[str]]] = [
6565
("dataset", enum_or_str_uppercase(dataset, "dataset")),
66-
("symbols", maybe_symbols_list_to_string(symbols)),
66+
("symbols", maybe_symbols_list_to_string(symbols, SType(stype_in))),
6767
("stype_in", enum_or_str_lowercase(stype_in, "stype_in")),
6868
("stype_out", enum_or_str_lowercase(stype_out, "stype_out")),
6969
("start_date", str(pd.to_datetime(start_date).date())),

databento/historical/api/timeseries.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -246,7 +246,7 @@ def _pre_check_data_size( # noqa (prefer not to make static)
246246

247247
def _is_large_number_of_symbols(symbols: Optional[Union[List[str], str]]) -> bool:
248248
if not symbols:
249-
return True # All symbols
249+
return True # Full universe
250250

251251
if isinstance(symbols, str):
252252
symbols = symbols.split(",")

databento/historical/http.py

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
import sys
22
from datetime import date
33
from json.decoder import JSONDecodeError
4-
from typing import Any, BinaryIO, List, Optional, Sequence, Tuple, Union
4+
from typing import Any, BinaryIO, List, Optional, Tuple, Union
55

66
import aiohttp
77
import pandas as pd
@@ -54,7 +54,7 @@ def _timeseries_params(
5454
("dataset", enum_or_str_uppercase(dataset, "dataset")),
5555
("start", datetime_to_string(start)),
5656
("end", datetime_to_string(end)),
57-
("symbols", maybe_symbols_list_to_string(symbols) or "*"),
57+
("symbols", maybe_symbols_list_to_string(symbols, SType(stype_in)) or "*"),
5858
("schema", schema.value),
5959
("stype_in", stype_in.value),
6060
("stype_out", stype_out.value),
@@ -179,7 +179,7 @@ def _stream(
179179
async def _stream_async(
180180
self,
181181
url: str,
182-
params: Sequence[Tuple[str, Optional[str]]],
182+
params: List[Tuple[str, Optional[str]]],
183183
basic_auth: bool,
184184
bento: Bento,
185185
) -> None:

tests/test_common_parsing.py

Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@
55
import numpy as np
66
import pandas as pd
77
import pytest
8-
from databento.common.enums import Dataset, Flags
8+
from databento.common.enums import Dataset, Flags, SType
99
from databento.common.parsing import (
1010
enum_or_str_lowercase,
1111
enum_or_str_uppercase,
@@ -159,17 +159,19 @@ def test_maybe_symbols_list_to_string_given_invalid_input_raises_type_error(
159159
) -> None:
160160
# Arrange, Act, Assert
161161
with pytest.raises(TypeError):
162-
maybe_symbols_list_to_string(INCORRECT_TYPE)
162+
maybe_symbols_list_to_string(INCORRECT_TYPE, SType.NATIVE)
163163

164164
@pytest.mark.parametrize(
165165
"symbols, expected",
166166
[
167167
[None, None],
168+
["ES.fut", "ES.FUT"],
168169
["ES,CL", "ES,CL"],
169170
["ES,CL,", "ES,CL"],
170171
["es,cl,", "ES,CL"],
171172
[["ES", "CL"], "ES,CL"],
172173
[["es", "cl"], "ES,CL"],
174+
[["ES.N.0", "CL.n.0"], "ES.n.0,CL.n.0"],
173175
],
174176
)
175177
def test_maybe_symbols_list_to_string_given_valid_inputs_returns_expected(
@@ -178,7 +180,7 @@ def test_maybe_symbols_list_to_string_given_valid_inputs_returns_expected(
178180
expected: str,
179181
) -> None:
180182
# Arrange, Act
181-
result: Optional[str] = maybe_symbols_list_to_string(symbols)
183+
result: Optional[str] = maybe_symbols_list_to_string(symbols, SType.SMART)
182184

183185
# Assert
184186
assert result == expected

tests/test_historical_timeseries.py

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -54,7 +54,8 @@ def test_stream_sends_expected_request(self, mocker: MockerFixture) -> None:
5454
# Act
5555
self.client.timeseries.stream(
5656
dataset="GLBX.MDP3",
57-
symbols="ESH1",
57+
symbols="ES.c.0",
58+
stype_in="smart",
5859
schema="trades",
5960
start="2020-12-28T12:00",
6061
end="2020-12-29",
@@ -75,9 +76,9 @@ def test_stream_sends_expected_request(self, mocker: MockerFixture) -> None:
7576
("dataset", "GLBX.MDP3"),
7677
("start", "2020-12-28T12:00:00"),
7778
("end", "2020-12-29T00:00:00"),
78-
("symbols", "ESH1"),
79+
("symbols", "ES.c.0"),
7980
("schema", "trades"),
80-
("stype_in", "native"),
81+
("stype_in", "smart"),
8182
("stype_out", "product_id"),
8283
("encoding", "dbz"),
8384
]

0 commit comments

Comments
 (0)