Skip to content

Commit fa03a62

Browse files
committed
MOD: Batch large symbol subscriptions
1 parent 6d67bc0 commit fa03a62

File tree

11 files changed

+200
-122
lines changed

11 files changed

+200
-122
lines changed

CHANGELOG.md

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,14 +4,19 @@
44

55
#### Enhancements
66
- Added `symbology_map` property to `Live` client
7+
- Added `optional_symbols_list_to_list` parsing function
78
- Changed `Live.add_callback` and `Live.add_stream` to accept an exception callback
89
- Changed `Live.__iter__()` and `Live.__aiter__()` to send the session start message if the session is connected but not started
910
- Upgraded `databento-dbn` to 0.7.1
1011
- Removed `Encoding`, `Compression`, `Schema`, and `SType` enums as they are now exposed by `databento-dbn`
1112
- Removed exception chaining from exceptions emitted by the library
1213

14+
#### Bug fixes
15+
- Fixed issue where a large unreadable symbol subscription message could be sent
16+
1317
#### Breaking changes
1418
- Renamed `func` parameter to `record_callback` for `Live.add_callback` and `Live.add_stream`
19+
- Removed `optional_symbols_list_to_string` parsing function
1520

1621
## 0.14.1 - 2023-06-16
1722

databento/common/parsing.py

Lines changed: 36 additions & 37 deletions
Original file line numberDiff line numberDiff line change
@@ -58,12 +58,13 @@ def optional_values_list_to_string(
5858

5959

6060
@singledispatch
61-
def optional_symbols_list_to_string(
61+
def optional_symbols_list_to_list(
6262
symbols: Iterable[str] | Iterable[Number] | str | Number | None,
6363
stype_in: SType,
64-
) -> str:
64+
) -> list[str]:
6565
"""
66-
Concatenate a symbols string or iterable of symbol strings (if not None).
66+
Create a list from a symbols string or iterable of symbol strings (if not
67+
None).
6768
6869
Parameters
6970
----------
@@ -74,11 +75,11 @@ def optional_symbols_list_to_string(
7475
7576
Returns
7677
-------
77-
str
78+
list[str]
7879
7980
Notes
8081
-----
81-
If None is given, ALL_SYMBOLS is returned.
82+
If None is given, [ALL_SYMBOLS] is returned.
8283
8384
"""
8485
raise TypeError(
@@ -87,48 +88,48 @@ def optional_symbols_list_to_string(
8788
)
8889

8990

90-
@optional_symbols_list_to_string.register
91-
def _(_: None, __: SType) -> str:
91+
@optional_symbols_list_to_list.register
92+
def _(_: None, __: SType) -> list[str]:
9293
"""
93-
Dispatch method for optional_symbols_list_to_string. Handles None which
94-
defaults to ALL_SYMBOLS.
94+
Dispatch method for optional_symbols_list_to_list. Handles None which
95+
defaults to [ALL_SYMBOLS].
9596
9697
See Also
9798
--------
98-
optional_symbols_list_to_string
99+
optional_symbols_list_to_list
99100
100101
"""
101-
return ALL_SYMBOLS
102+
return [ALL_SYMBOLS]
102103

103104

104-
@optional_symbols_list_to_string.register
105-
def _(symbols: Number, stype_in: SType) -> str:
105+
@optional_symbols_list_to_list.register
106+
def _(symbols: Number, stype_in: SType) -> list[str]:
106107
"""
107-
Dispatch method for optional_symbols_list_to_string. Handles numerical
108-
types, alerting when an integer is given for STypes that expect strings.
108+
Dispatch method for optional_symbols_list_to_list. Handles numerical types,
109+
alerting when an integer is given for STypes that expect strings.
109110
110111
See Also
111112
--------
112-
optional_symbols_list_to_string
113+
optional_symbols_list_to_list
113114
114115
"""
115116
if stype_in == SType.INSTRUMENT_ID:
116-
return str(symbols)
117+
return [str(symbols)]
117118
raise ValueError(
118119
f"value `{symbols}` is not a valid symbol for stype {stype_in}; "
119120
"did you mean to use `instrument_id`?",
120121
)
121122

122123

123-
@optional_symbols_list_to_string.register
124-
def _(symbols: str, stype_in: SType) -> str:
124+
@optional_symbols_list_to_list.register
125+
def _(symbols: str, stype_in: SType) -> list[str]:
125126
"""
126-
Dispatch method for optional_symbols_list_to_string. Handles str, splitting
127+
Dispatch method for optional_symbols_list_to_list. Handles str, splitting
127128
on commas and validating smart symbology.
128129
129130
See Also
130131
--------
131-
optional_symbols_list_to_string
132+
optional_symbols_list_to_list
132133
133134
"""
134135
if not symbols:
@@ -137,35 +138,33 @@ def _(symbols: str, stype_in: SType) -> str:
137138
"an empty string is not allowed",
138139
)
139140

140-
if "," in symbols:
141-
symbol_to_string = partial(
142-
optional_symbols_list_to_string,
143-
stype_in=stype_in,
144-
)
145-
symbol_list = symbols.strip().strip(",").split(",")
146-
return ",".join(map(symbol_to_string, symbol_list))
141+
symbol_list = symbols.strip().strip(",").split(",")
147142

148143
if stype_in in (SType.PARENT, SType.CONTINUOUS):
149-
return validate_smart_symbol(symbols)
150-
return symbols.strip().upper()
144+
return list(map(str.strip, map(validate_smart_symbol, symbol_list)))
145+
146+
return list(map(str.upper, map(str.strip, symbol_list)))
151147

152148

153-
@optional_symbols_list_to_string.register(cls=Iterable)
154-
def _(symbols: Iterable[str] | Iterable[int], stype_in: SType) -> str:
149+
@optional_symbols_list_to_list.register(cls=Iterable)
150+
def _(symbols: Iterable[str] | Iterable[int], stype_in: SType) -> list[str]:
155151
"""
156-
Dispatch method for optional_symbols_list_to_string. Handles Iterables by
152+
Dispatch method for optional_symbols_list_to_list. Handles Iterables by
157153
dispatching the individual members.
158154
159155
See Also
160156
--------
161-
optional_symbols_list_to_string
157+
optional_symbols_list_to_list
162158
163159
"""
164-
symbol_to_string = partial(
165-
optional_symbols_list_to_string,
160+
symbol_to_list = partial(
161+
optional_symbols_list_to_list,
166162
stype_in=stype_in,
167163
)
168-
return ",".join(map(symbol_to_string, symbols))
164+
aggregated: list[str] = []
165+
for sym in map(symbol_to_list, symbols):
166+
aggregated.extend(sym)
167+
return aggregated
169168

170169

171170
def optional_date_to_string(value: date | str | None) -> str | None:

databento/historical/api/batch.py

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -22,7 +22,7 @@
2222
from databento.common.enums import SplitDuration
2323
from databento.common.parsing import datetime_to_string
2424
from databento.common.parsing import optional_datetime_to_string
25-
from databento.common.parsing import optional_symbols_list_to_string
25+
from databento.common.parsing import optional_symbols_list_to_list
2626
from databento.common.parsing import optional_values_list_to_string
2727
from databento.common.validation import validate_enum
2828
from databento.common.validation import validate_path
@@ -118,12 +118,12 @@ def submit_job(
118118
119119
"""
120120
stype_in_valid = validate_enum(stype_in, SType, "stype_in")
121-
symbols_list = optional_symbols_list_to_string(symbols, stype_in_valid)
121+
symbols_list = optional_symbols_list_to_list(symbols, stype_in_valid)
122122
data: dict[str, object | None] = {
123123
"dataset": validate_semantic_string(dataset, "dataset"),
124124
"start": datetime_to_string(start),
125125
"end": optional_datetime_to_string(end),
126-
"symbols": str(symbols_list),
126+
"symbols": ",".join(symbols_list),
127127
"schema": str(validate_enum(schema, Schema, "schema")),
128128
"stype_in": str(stype_in_valid),
129129
"stype_out": str(validate_enum(stype_out, SType, "stype_out")),

databento/historical/api/metadata.py

Lines changed: 7 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,7 @@
1414
from databento.common.parsing import datetime_to_string
1515
from databento.common.parsing import optional_date_to_string
1616
from databento.common.parsing import optional_datetime_to_string
17-
from databento.common.parsing import optional_symbols_list_to_string
17+
from databento.common.parsing import optional_symbols_list_to_list
1818
from databento.common.validation import validate_enum
1919
from databento.common.validation import validate_maybe_enum
2020
from databento.common.validation import validate_semantic_string
@@ -318,10 +318,10 @@ def get_record_count(
318318
319319
"""
320320
stype_in_valid = validate_enum(stype_in, SType, "stype_in")
321-
symbols_list = optional_symbols_list_to_string(symbols, stype_in_valid)
321+
symbols_list = optional_symbols_list_to_list(symbols, stype_in_valid)
322322
params: list[tuple[str, str | None]] = [
323323
("dataset", validate_semantic_string(dataset, "dataset")),
324-
("symbols", symbols_list),
324+
("symbols", ",".join(symbols_list)),
325325
("schema", str(validate_enum(schema, Schema, "schema"))),
326326
("start", optional_datetime_to_string(start)),
327327
("end", optional_datetime_to_string(end)),
@@ -387,12 +387,12 @@ def get_billable_size(
387387
388388
"""
389389
stype_in_valid = validate_enum(stype_in, SType, "stype_in")
390-
symbols_list = optional_symbols_list_to_string(symbols, stype_in_valid)
390+
symbols_list = optional_symbols_list_to_list(symbols, stype_in_valid)
391391
params: list[tuple[str, str | None]] = [
392392
("dataset", validate_semantic_string(dataset, "dataset")),
393393
("start", datetime_to_string(start)),
394394
("end", optional_datetime_to_string(end)),
395-
("symbols", symbols_list),
395+
("symbols", ",".join(symbols_list)),
396396
("schema", str(validate_enum(schema, Schema, "schema"))),
397397
("stype_in", str(stype_in_valid)),
398398
("stype_out", str(SType.INSTRUMENT_ID)),
@@ -459,12 +459,12 @@ def get_cost(
459459
460460
"""
461461
stype_in_valid = validate_enum(stype_in, SType, "stype_in")
462-
symbols_list = optional_symbols_list_to_string(symbols, stype_in_valid)
462+
symbols_list = optional_symbols_list_to_list(symbols, stype_in_valid)
463463
params: list[tuple[str, str | None]] = [
464464
("dataset", validate_semantic_string(dataset, "dataset")),
465465
("start", datetime_to_string(start)),
466466
("end", optional_datetime_to_string(end)),
467-
("symbols", symbols_list),
467+
("symbols", ",".join(symbols_list)),
468468
("schema", str(validate_enum(schema, Schema, "schema"))),
469469
("stype_in", str(stype_in_valid)),
470470
("stype_out", str(SType.INSTRUMENT_ID)),

databento/historical/api/symbology.py

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,7 @@
99
from databento.common.enums import Dataset
1010
from databento.common.parsing import datetime_to_date_string
1111
from databento.common.parsing import optional_date_to_string
12-
from databento.common.parsing import optional_symbols_list_to_string
12+
from databento.common.parsing import optional_symbols_list_to_list
1313
from databento.common.validation import validate_enum
1414
from databento.common.validation import validate_semantic_string
1515
from databento.historical.api import API_VERSION
@@ -65,10 +65,10 @@ def resolve(
6565
6666
"""
6767
stype_in_valid = validate_enum(stype_in, SType, "stype_in")
68-
symbols_list = optional_symbols_list_to_string(symbols, stype_in_valid)
68+
symbols_list = optional_symbols_list_to_list(symbols, stype_in_valid)
6969
data: dict[str, object | None] = {
7070
"dataset": validate_semantic_string(dataset, "dataset"),
71-
"symbols": symbols_list,
71+
"symbols": ",".join(symbols_list),
7272
"stype_in": str(stype_in_valid),
7373
"stype_out": str(validate_enum(stype_out, SType, "stype_out")),
7474
"start_date": datetime_to_date_string(start_date),

databento/historical/api/timeseries.py

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,7 @@
1313
from databento.common.enums import Dataset
1414
from databento.common.parsing import datetime_to_string
1515
from databento.common.parsing import optional_datetime_to_string
16-
from databento.common.parsing import optional_symbols_list_to_string
16+
from databento.common.parsing import optional_symbols_list_to_list
1717
from databento.common.validation import validate_enum
1818
from databento.common.validation import validate_semantic_string
1919
from databento.historical.api import API_VERSION
@@ -95,15 +95,15 @@ def get_range(
9595
9696
"""
9797
stype_in_valid = validate_enum(stype_in, SType, "stype_in")
98-
symbols_list = optional_symbols_list_to_string(symbols, stype_in_valid)
98+
symbols_list = optional_symbols_list_to_list(symbols, stype_in_valid)
9999
schema_valid = validate_enum(schema, Schema, "schema")
100100
start_valid = datetime_to_string(start)
101101
end_valid = optional_datetime_to_string(end)
102102
data: dict[str, object | None] = {
103103
"dataset": validate_semantic_string(dataset, "dataset"),
104104
"start": start_valid,
105105
"end": end_valid,
106-
"symbols": symbols_list,
106+
"symbols": ",".join(symbols_list),
107107
"schema": str(schema_valid),
108108
"stype_in": str(stype_in_valid),
109109
"stype_out": str(validate_enum(stype_out, SType, "stype_out")),
@@ -189,15 +189,15 @@ async def get_range_async(
189189
190190
"""
191191
stype_in_valid = validate_enum(stype_in, SType, "stype_in")
192-
symbols_list = optional_symbols_list_to_string(symbols, stype_in_valid)
192+
symbols_list = optional_symbols_list_to_list(symbols, stype_in_valid)
193193
schema_valid = validate_enum(schema, Schema, "schema")
194194
start_valid = datetime_to_string(start)
195195
end_valid = optional_datetime_to_string(end)
196196
data: dict[str, object | None] = {
197197
"dataset": validate_semantic_string(dataset, "dataset"),
198198
"start": start_valid,
199199
"end": end_valid,
200-
"symbols": symbols_list,
200+
"symbols": ",".join(symbols_list),
201201
"schema": str(schema_valid),
202202
"stype_in": str(stype_in_valid),
203203
"stype_out": str(validate_enum(stype_out, SType, "stype_out")),

databento/live/client.py

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -18,7 +18,6 @@
1818
from databento.common.enums import Dataset
1919
from databento.common.error import BentoError
2020
from databento.common.parsing import optional_datetime_to_unix_nanoseconds
21-
from databento.common.parsing import optional_symbols_list_to_string
2221
from databento.common.symbology import ALL_SYMBOLS
2322
from databento.common.validation import validate_enum
2423
from databento.common.validation import validate_semantic_string
@@ -453,7 +452,6 @@ def subscribe(
453452
dataset = validate_semantic_string(dataset, "dataset")
454453
schema = validate_enum(schema, Schema, "schema")
455454
stype_in = validate_enum(stype_in, SType, "stype_in")
456-
symbols = optional_symbols_list_to_string(symbols, stype_in)
457455
start = optional_datetime_to_unix_nanoseconds(start)
458456

459457
if not self.dataset:

databento/live/gateway.py

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -18,7 +18,6 @@
1818

1919
T = TypeVar("T", bound="GatewayControl")
2020

21-
2221
@dataclasses.dataclass
2322
class GatewayControl:
2423
"""

0 commit comments

Comments
 (0)