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.
Files changed (58) hide show
  1. {gnomepy-2.3.2 → gnomepy-2.3.3}/PKG-INFO +1 -1
  2. {gnomepy-2.3.2 → gnomepy-2.3.3}/gnomepy/registry/api.py +22 -5
  3. {gnomepy-2.3.2 → gnomepy-2.3.3}/pyproject.toml +1 -1
  4. {gnomepy-2.3.2 → gnomepy-2.3.3}/README.md +0 -0
  5. {gnomepy-2.3.2 → gnomepy-2.3.3}/gnomepy/__init__.py +0 -0
  6. {gnomepy-2.3.2 → gnomepy-2.3.3}/gnomepy/_fs.py +0 -0
  7. {gnomepy-2.3.2 → gnomepy-2.3.3}/gnomepy/auth.py +0 -0
  8. {gnomepy-2.3.2 → gnomepy-2.3.3}/gnomepy/cli.py +0 -0
  9. {gnomepy-2.3.2 → gnomepy-2.3.3}/gnomepy/config.py +0 -0
  10. {gnomepy-2.3.2 → gnomepy-2.3.3}/gnomepy/explorer/__init__.py +0 -0
  11. {gnomepy-2.3.2 → gnomepy-2.3.3}/gnomepy/explorer/app.py +0 -0
  12. {gnomepy-2.3.2 → gnomepy-2.3.3}/gnomepy/explorer/data.py +0 -0
  13. {gnomepy-2.3.2 → gnomepy-2.3.3}/gnomepy/explorer/panels/__init__.py +0 -0
  14. {gnomepy-2.3.2 → gnomepy-2.3.3}/gnomepy/explorer/panels/event_log.py +0 -0
  15. {gnomepy-2.3.2 → gnomepy-2.3.3}/gnomepy/explorer/panels/pnl.py +0 -0
  16. {gnomepy-2.3.2 → gnomepy-2.3.3}/gnomepy/explorer/panels/price.py +0 -0
  17. {gnomepy-2.3.2 → gnomepy-2.3.3}/gnomepy/explorer/panels/signals.py +0 -0
  18. {gnomepy-2.3.2 → gnomepy-2.3.3}/gnomepy/explorer/styles.py +0 -0
  19. {gnomepy-2.3.2 → gnomepy-2.3.3}/gnomepy/importer/__init__.py +0 -0
  20. {gnomepy-2.3.2 → gnomepy-2.3.3}/gnomepy/importer/chunker.py +0 -0
  21. {gnomepy-2.3.2 → gnomepy-2.3.3}/gnomepy/importer/encoder.py +0 -0
  22. {gnomepy-2.3.2 → gnomepy-2.3.3}/gnomepy/importer/import_job.py +0 -0
  23. {gnomepy-2.3.2 → gnomepy-2.3.3}/gnomepy/importer/mapping.py +0 -0
  24. {gnomepy-2.3.2 → gnomepy-2.3.3}/gnomepy/importer/scaling.py +0 -0
  25. {gnomepy-2.3.2 → gnomepy-2.3.3}/gnomepy/importer/tardis/__init__.py +0 -0
  26. {gnomepy-2.3.2 → gnomepy-2.3.3}/gnomepy/importer/tardis/book.py +0 -0
  27. {gnomepy-2.3.2 → gnomepy-2.3.3}/gnomepy/importer/tardis/client.py +0 -0
  28. {gnomepy-2.3.2 → gnomepy-2.3.3}/gnomepy/importer/tardis/importer.py +0 -0
  29. {gnomepy-2.3.2 → gnomepy-2.3.3}/gnomepy/importer/tardis/mappings.py +0 -0
  30. {gnomepy-2.3.2 → gnomepy-2.3.3}/gnomepy/importer/uploader.py +0 -0
  31. {gnomepy-2.3.2 → gnomepy-2.3.3}/gnomepy/importer/validators.py +0 -0
  32. {gnomepy-2.3.2 → gnomepy-2.3.3}/gnomepy/java/__init__.py +0 -0
  33. {gnomepy-2.3.2 → gnomepy-2.3.3}/gnomepy/java/_classpath.py +0 -0
  34. {gnomepy-2.3.2 → gnomepy-2.3.3}/gnomepy/java/_jvm.py +0 -0
  35. {gnomepy-2.3.2 → gnomepy-2.3.3}/gnomepy/java/backtest/__init__.py +0 -0
  36. {gnomepy-2.3.2 → gnomepy-2.3.3}/gnomepy/java/backtest/config.py +0 -0
  37. {gnomepy-2.3.2 → gnomepy-2.3.3}/gnomepy/java/backtest/orders.py +0 -0
  38. {gnomepy-2.3.2 → gnomepy-2.3.3}/gnomepy/java/backtest/runner.py +0 -0
  39. {gnomepy-2.3.2 → gnomepy-2.3.3}/gnomepy/java/backtest/strategy.py +0 -0
  40. {gnomepy-2.3.2 → gnomepy-2.3.3}/gnomepy/java/cache.py +0 -0
  41. {gnomepy-2.3.2 → gnomepy-2.3.3}/gnomepy/java/datastore.py +0 -0
  42. {gnomepy-2.3.2 → gnomepy-2.3.3}/gnomepy/java/enums.py +0 -0
  43. {gnomepy-2.3.2 → gnomepy-2.3.3}/gnomepy/java/market_data.py +0 -0
  44. {gnomepy-2.3.2 → gnomepy-2.3.3}/gnomepy/java/oms.py +0 -0
  45. {gnomepy-2.3.2 → gnomepy-2.3.3}/gnomepy/java/recorder.py +0 -0
  46. {gnomepy-2.3.2 → gnomepy-2.3.3}/gnomepy/java/sbe.py +0 -0
  47. {gnomepy-2.3.2 → gnomepy-2.3.3}/gnomepy/java/schemas.py +0 -0
  48. {gnomepy-2.3.2 → gnomepy-2.3.3}/gnomepy/java/statics.py +0 -0
  49. {gnomepy-2.3.2 → gnomepy-2.3.3}/gnomepy/metadata.py +0 -0
  50. {gnomepy-2.3.2 → gnomepy-2.3.3}/gnomepy/registry/__init__.py +0 -0
  51. {gnomepy-2.3.2 → gnomepy-2.3.3}/gnomepy/registry/types.py +0 -0
  52. {gnomepy-2.3.2 → gnomepy-2.3.3}/gnomepy/remote.py +0 -0
  53. {gnomepy-2.3.2 → gnomepy-2.3.3}/gnomepy/reporting/__init__.py +0 -0
  54. {gnomepy-2.3.2 → gnomepy-2.3.3}/gnomepy/reporting/metrics.py +0 -0
  55. {gnomepy-2.3.2 → gnomepy-2.3.3}/gnomepy/reporting/plots.py +0 -0
  56. {gnomepy-2.3.2 → gnomepy-2.3.3}/gnomepy/reporting/report.py +0 -0
  57. {gnomepy-2.3.2 → gnomepy-2.3.3}/gnomepy/sweep.py +0 -0
  58. {gnomepy-2.3.2 → gnomepy-2.3.3}/gnomepy/utils.py +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: gnomepy
3
- Version: 2.3.2
3
+ Version: 2.3.3
4
4
  Summary:
5
5
  Author: mprey
6
6
  Author-email: masonprey7@gmail.com
@@ -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._PAGE_SIZE, "offset": offset}
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._PAGE_SIZE:
178
+ if len(page) < self._page_size:
167
179
  break
168
- offset += self._PAGE_SIZE
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,
@@ -1,6 +1,6 @@
1
1
  [project]
2
2
  name = "gnomepy"
3
- version = "2.3.2"
3
+ version = "2.3.3"
4
4
  description = ""
5
5
  authors = [
6
6
  {name = "mprey",email = "masonprey7@gmail.com"}
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