gnomepy 2.3.2__tar.gz → 2.3.3__tar.gz
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- {gnomepy-2.3.2 → gnomepy-2.3.3}/PKG-INFO +1 -1
- {gnomepy-2.3.2 → gnomepy-2.3.3}/gnomepy/registry/api.py +22 -5
- {gnomepy-2.3.2 → gnomepy-2.3.3}/pyproject.toml +1 -1
- {gnomepy-2.3.2 → gnomepy-2.3.3}/README.md +0 -0
- {gnomepy-2.3.2 → gnomepy-2.3.3}/gnomepy/__init__.py +0 -0
- {gnomepy-2.3.2 → gnomepy-2.3.3}/gnomepy/_fs.py +0 -0
- {gnomepy-2.3.2 → gnomepy-2.3.3}/gnomepy/auth.py +0 -0
- {gnomepy-2.3.2 → gnomepy-2.3.3}/gnomepy/cli.py +0 -0
- {gnomepy-2.3.2 → gnomepy-2.3.3}/gnomepy/config.py +0 -0
- {gnomepy-2.3.2 → gnomepy-2.3.3}/gnomepy/explorer/__init__.py +0 -0
- {gnomepy-2.3.2 → gnomepy-2.3.3}/gnomepy/explorer/app.py +0 -0
- {gnomepy-2.3.2 → gnomepy-2.3.3}/gnomepy/explorer/data.py +0 -0
- {gnomepy-2.3.2 → gnomepy-2.3.3}/gnomepy/explorer/panels/__init__.py +0 -0
- {gnomepy-2.3.2 → gnomepy-2.3.3}/gnomepy/explorer/panels/event_log.py +0 -0
- {gnomepy-2.3.2 → gnomepy-2.3.3}/gnomepy/explorer/panels/pnl.py +0 -0
- {gnomepy-2.3.2 → gnomepy-2.3.3}/gnomepy/explorer/panels/price.py +0 -0
- {gnomepy-2.3.2 → gnomepy-2.3.3}/gnomepy/explorer/panels/signals.py +0 -0
- {gnomepy-2.3.2 → gnomepy-2.3.3}/gnomepy/explorer/styles.py +0 -0
- {gnomepy-2.3.2 → gnomepy-2.3.3}/gnomepy/importer/__init__.py +0 -0
- {gnomepy-2.3.2 → gnomepy-2.3.3}/gnomepy/importer/chunker.py +0 -0
- {gnomepy-2.3.2 → gnomepy-2.3.3}/gnomepy/importer/encoder.py +0 -0
- {gnomepy-2.3.2 → gnomepy-2.3.3}/gnomepy/importer/import_job.py +0 -0
- {gnomepy-2.3.2 → gnomepy-2.3.3}/gnomepy/importer/mapping.py +0 -0
- {gnomepy-2.3.2 → gnomepy-2.3.3}/gnomepy/importer/scaling.py +0 -0
- {gnomepy-2.3.2 → gnomepy-2.3.3}/gnomepy/importer/tardis/__init__.py +0 -0
- {gnomepy-2.3.2 → gnomepy-2.3.3}/gnomepy/importer/tardis/book.py +0 -0
- {gnomepy-2.3.2 → gnomepy-2.3.3}/gnomepy/importer/tardis/client.py +0 -0
- {gnomepy-2.3.2 → gnomepy-2.3.3}/gnomepy/importer/tardis/importer.py +0 -0
- {gnomepy-2.3.2 → gnomepy-2.3.3}/gnomepy/importer/tardis/mappings.py +0 -0
- {gnomepy-2.3.2 → gnomepy-2.3.3}/gnomepy/importer/uploader.py +0 -0
- {gnomepy-2.3.2 → gnomepy-2.3.3}/gnomepy/importer/validators.py +0 -0
- {gnomepy-2.3.2 → gnomepy-2.3.3}/gnomepy/java/__init__.py +0 -0
- {gnomepy-2.3.2 → gnomepy-2.3.3}/gnomepy/java/_classpath.py +0 -0
- {gnomepy-2.3.2 → gnomepy-2.3.3}/gnomepy/java/_jvm.py +0 -0
- {gnomepy-2.3.2 → gnomepy-2.3.3}/gnomepy/java/backtest/__init__.py +0 -0
- {gnomepy-2.3.2 → gnomepy-2.3.3}/gnomepy/java/backtest/config.py +0 -0
- {gnomepy-2.3.2 → gnomepy-2.3.3}/gnomepy/java/backtest/orders.py +0 -0
- {gnomepy-2.3.2 → gnomepy-2.3.3}/gnomepy/java/backtest/runner.py +0 -0
- {gnomepy-2.3.2 → gnomepy-2.3.3}/gnomepy/java/backtest/strategy.py +0 -0
- {gnomepy-2.3.2 → gnomepy-2.3.3}/gnomepy/java/cache.py +0 -0
- {gnomepy-2.3.2 → gnomepy-2.3.3}/gnomepy/java/datastore.py +0 -0
- {gnomepy-2.3.2 → gnomepy-2.3.3}/gnomepy/java/enums.py +0 -0
- {gnomepy-2.3.2 → gnomepy-2.3.3}/gnomepy/java/market_data.py +0 -0
- {gnomepy-2.3.2 → gnomepy-2.3.3}/gnomepy/java/oms.py +0 -0
- {gnomepy-2.3.2 → gnomepy-2.3.3}/gnomepy/java/recorder.py +0 -0
- {gnomepy-2.3.2 → gnomepy-2.3.3}/gnomepy/java/sbe.py +0 -0
- {gnomepy-2.3.2 → gnomepy-2.3.3}/gnomepy/java/schemas.py +0 -0
- {gnomepy-2.3.2 → gnomepy-2.3.3}/gnomepy/java/statics.py +0 -0
- {gnomepy-2.3.2 → gnomepy-2.3.3}/gnomepy/metadata.py +0 -0
- {gnomepy-2.3.2 → gnomepy-2.3.3}/gnomepy/registry/__init__.py +0 -0
- {gnomepy-2.3.2 → gnomepy-2.3.3}/gnomepy/registry/types.py +0 -0
- {gnomepy-2.3.2 → gnomepy-2.3.3}/gnomepy/remote.py +0 -0
- {gnomepy-2.3.2 → gnomepy-2.3.3}/gnomepy/reporting/__init__.py +0 -0
- {gnomepy-2.3.2 → gnomepy-2.3.3}/gnomepy/reporting/metrics.py +0 -0
- {gnomepy-2.3.2 → gnomepy-2.3.3}/gnomepy/reporting/plots.py +0 -0
- {gnomepy-2.3.2 → gnomepy-2.3.3}/gnomepy/reporting/report.py +0 -0
- {gnomepy-2.3.2 → gnomepy-2.3.3}/gnomepy/sweep.py +0 -0
- {gnomepy-2.3.2 → gnomepy-2.3.3}/gnomepy/utils.py +0 -0
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
__all__ = ["RegistryClient"]
|
|
2
2
|
|
|
3
3
|
import dataclasses
|
|
4
|
+
import logging
|
|
4
5
|
import os
|
|
5
6
|
from typing import Optional
|
|
6
7
|
|
|
@@ -19,6 +20,8 @@ from gnomepy.registry.types import (
|
|
|
19
20
|
Security,
|
|
20
21
|
)
|
|
21
22
|
|
|
23
|
+
logger = logging.getLogger(__name__)
|
|
24
|
+
|
|
22
25
|
|
|
23
26
|
def _to_camel_case(snake_str: str) -> str:
|
|
24
27
|
camel = "".join(x.capitalize() for x in snake_str.lower().split("_"))
|
|
@@ -37,6 +40,7 @@ class RegistryClient:
|
|
|
37
40
|
base_url: Optional[str] = None,
|
|
38
41
|
api_key: Optional[str] = None,
|
|
39
42
|
api_key_environ_key: str = "GNOME_REGISTRY_API_KEY",
|
|
43
|
+
page_size: int = 1000,
|
|
40
44
|
):
|
|
41
45
|
if base_url:
|
|
42
46
|
self.base_url = base_url.rstrip("/") + "/api"
|
|
@@ -49,6 +53,7 @@ class RegistryClient:
|
|
|
49
53
|
if api_key is None or not isinstance(api_key, str) or api_key.isspace():
|
|
50
54
|
raise ValueError(f"Invalid API key: {api_key}")
|
|
51
55
|
self.api_key = api_key
|
|
56
|
+
self._page_size = page_size
|
|
52
57
|
|
|
53
58
|
def get_exchange(self, *, exchange_id: Optional[int] = None, exchange_name: Optional[str] = None) -> list[Exchange]:
|
|
54
59
|
return self._get("/exchanges", _parse_kwarg_params(locals()), Exchange)
|
|
@@ -105,6 +110,9 @@ class RegistryClient:
|
|
|
105
110
|
def get_exchange_events(self, *, exchange_id: Optional[int] = None, event_id: Optional[int] = None) -> list[ExchangeEvent]:
|
|
106
111
|
return self._get("/exchange-events", _parse_kwarg_params(locals()), ExchangeEvent)
|
|
107
112
|
|
|
113
|
+
def create_currency(self, **kwargs) -> dict:
|
|
114
|
+
return self._post("/currencies", {_to_camel_case(k): v for k, v in kwargs.items()})
|
|
115
|
+
|
|
108
116
|
def create_security(self, **kwargs) -> dict:
|
|
109
117
|
return self._post("/securities", {_to_camel_case(k): v for k, v in kwargs.items()})
|
|
110
118
|
|
|
@@ -126,6 +134,9 @@ class RegistryClient:
|
|
|
126
134
|
def bulk_create_securities(self, items: list[dict]) -> list[dict]:
|
|
127
135
|
return self._post_bulk("/securities", items)
|
|
128
136
|
|
|
137
|
+
def bulk_create_currencies(self, items: list[dict]) -> list[dict]:
|
|
138
|
+
return self._post_bulk("/currencies", items)
|
|
139
|
+
|
|
129
140
|
def bulk_create_listings(self, items: list[dict]) -> list[dict]:
|
|
130
141
|
return self._post_bulk("/listings", items)
|
|
131
142
|
|
|
@@ -148,30 +159,36 @@ class RegistryClient:
|
|
|
148
159
|
body = {_to_camel_case(k): v for k, v in kwargs.items()}
|
|
149
160
|
return self._patch("/event-contracts", {"eventContractId": str(event_contract_id)}, body)
|
|
150
161
|
|
|
151
|
-
_PAGE_SIZE = 5000
|
|
152
|
-
|
|
153
162
|
def _get(self, path: str, params: dict, output_type) -> list:
|
|
154
163
|
all_items = []
|
|
155
164
|
offset = 0
|
|
165
|
+
page_num = 0
|
|
166
|
+
logger.debug("GET %s params=%s page_size=%d", path, params, self._page_size)
|
|
156
167
|
while True:
|
|
157
|
-
page_params = {**params, "limit": self.
|
|
168
|
+
page_params = {**params, "limit": self._page_size, "offset": offset}
|
|
158
169
|
res = requests.get(self.base_url + path, params=page_params, headers={"x-api-key": self.api_key})
|
|
159
170
|
res.raise_for_status()
|
|
160
171
|
page = res.json()
|
|
172
|
+
logger.debug("GET %s page=%d offset=%d got=%d total=%d", path, page_num, offset, len(page), len(all_items) + len(page))
|
|
161
173
|
if dataclasses.is_dataclass(output_type):
|
|
162
174
|
known = {f.name for f in dataclasses.fields(output_type)}
|
|
163
175
|
all_items.extend(output_type(**{k: v for k, v in item.items() if k in known}) for item in page)
|
|
164
176
|
else:
|
|
165
177
|
all_items.extend(output_type(**item) for item in page)
|
|
166
|
-
if len(page) < self.
|
|
178
|
+
if len(page) < self._page_size:
|
|
167
179
|
break
|
|
168
|
-
offset += self.
|
|
180
|
+
offset += self._page_size
|
|
181
|
+
page_num += 1
|
|
182
|
+
logger.debug("GET %s done total=%d pages=%d", path, len(all_items), page_num + 1)
|
|
169
183
|
return all_items
|
|
170
184
|
|
|
171
185
|
def _post_bulk(self, path: str, items: list[dict], batch_size: int = 500) -> list[dict]:
|
|
186
|
+
n_batches = (len(items) + batch_size - 1) // batch_size
|
|
187
|
+
logger.debug("POST bulk %s total=%d batch_size=%d n_batches=%d", path, len(items), batch_size, n_batches)
|
|
172
188
|
results: list[dict] = []
|
|
173
189
|
for i in range(0, len(items), batch_size):
|
|
174
190
|
batch = [{_to_camel_case(k): v for k, v in item.items()} for item in items[i : i + batch_size]]
|
|
191
|
+
logger.debug("POST bulk %s batch=%d/%d items=%d", path, i // batch_size + 1, n_batches, len(batch))
|
|
175
192
|
res = requests.post(
|
|
176
193
|
self.base_url + path,
|
|
177
194
|
json=batch,
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|