simudyne-pulse 0.6.0.dev1__tar.gz → 0.6.0.dev2__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 (24) hide show
  1. {simudyne_pulse-0.6.0.dev1/src/simudyne_pulse.egg-info → simudyne_pulse-0.6.0.dev2}/PKG-INFO +1 -1
  2. {simudyne_pulse-0.6.0.dev1 → simudyne_pulse-0.6.0.dev2}/pyproject.toml +1 -1
  3. simudyne_pulse-0.6.0.dev2/src/simudyne/resources/data.py +45 -0
  4. simudyne_pulse-0.6.0.dev2/src/simudyne/resources/profile.py +30 -0
  5. {simudyne_pulse-0.6.0.dev1 → simudyne_pulse-0.6.0.dev2}/src/simudyne/resources/simulation.py +14 -7
  6. {simudyne_pulse-0.6.0.dev1 → simudyne_pulse-0.6.0.dev2/src/simudyne_pulse.egg-info}/PKG-INFO +1 -1
  7. simudyne_pulse-0.6.0.dev1/src/simudyne/resources/data.py +0 -9
  8. simudyne_pulse-0.6.0.dev1/src/simudyne/resources/profile.py +0 -25
  9. {simudyne_pulse-0.6.0.dev1 → simudyne_pulse-0.6.0.dev2}/LICENSE +0 -0
  10. {simudyne_pulse-0.6.0.dev1 → simudyne_pulse-0.6.0.dev2}/README.md +0 -0
  11. {simudyne_pulse-0.6.0.dev1 → simudyne_pulse-0.6.0.dev2}/setup.cfg +0 -0
  12. {simudyne_pulse-0.6.0.dev1 → simudyne_pulse-0.6.0.dev2}/src/simudyne/__init__.py +0 -0
  13. {simudyne_pulse-0.6.0.dev1 → simudyne_pulse-0.6.0.dev2}/src/simudyne/client.py +0 -0
  14. {simudyne_pulse-0.6.0.dev1 → simudyne_pulse-0.6.0.dev2}/src/simudyne/exceptions.py +0 -0
  15. {simudyne_pulse-0.6.0.dev1 → simudyne_pulse-0.6.0.dev2}/src/simudyne/resources/__init__.py +0 -0
  16. {simudyne_pulse-0.6.0.dev1 → simudyne_pulse-0.6.0.dev2}/src/simudyne/resources/api_keys.py +0 -0
  17. {simudyne_pulse-0.6.0.dev1 → simudyne_pulse-0.6.0.dev2}/src/simudyne/resources/historical.py +0 -0
  18. {simudyne_pulse-0.6.0.dev1 → simudyne_pulse-0.6.0.dev2}/src/simudyne/resources/simulator_gym.py +0 -0
  19. {simudyne_pulse-0.6.0.dev1 → simudyne_pulse-0.6.0.dev2}/src/simudyne/resources/validation.py +0 -0
  20. {simudyne_pulse-0.6.0.dev1 → simudyne_pulse-0.6.0.dev2}/src/simudyne_pulse.egg-info/SOURCES.txt +0 -0
  21. {simudyne_pulse-0.6.0.dev1 → simudyne_pulse-0.6.0.dev2}/src/simudyne_pulse.egg-info/dependency_links.txt +0 -0
  22. {simudyne_pulse-0.6.0.dev1 → simudyne_pulse-0.6.0.dev2}/src/simudyne_pulse.egg-info/requires.txt +0 -0
  23. {simudyne_pulse-0.6.0.dev1 → simudyne_pulse-0.6.0.dev2}/src/simudyne_pulse.egg-info/top_level.txt +0 -0
  24. {simudyne_pulse-0.6.0.dev1 → simudyne_pulse-0.6.0.dev2}/tests/test_simulator_gym.py +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: simudyne-pulse
3
- Version: 0.6.0.dev1
3
+ Version: 0.6.0.dev2
4
4
  Summary: Python SDK for the Simudyne Pulse synthetic market data API
5
5
  Author-email: Simudyne <support@simudyne.com>
6
6
  License-Expression: MIT
@@ -4,7 +4,7 @@ build-backend = "setuptools.build_meta"
4
4
 
5
5
  [project]
6
6
  name = "simudyne-pulse"
7
- version = "0.6.0-dev.1"
7
+ version = "0.6.0-dev.2"
8
8
  description = "Python SDK for the Simudyne Pulse synthetic market data API"
9
9
  readme = "README.md"
10
10
  license = "MIT"
@@ -0,0 +1,45 @@
1
+ AVAILABLE_SYMBOLS_PATH = "/data/available-symbols"
2
+
3
+
4
+ class DataResource:
5
+ def __init__(self, client):
6
+ self._client = client
7
+
8
+ def get_available_symbols(
9
+ self,
10
+ symbol: str | None = None,
11
+ exchange: str | None = None,
12
+ provider: str | None = None,
13
+ date: str | None = None,
14
+ limit: int | None = None,
15
+ offset: int | None = None,
16
+ ):
17
+ """List calibrated instruments and the dates available for each.
18
+
19
+ All arguments are optional filters; with none passed the whole catalog
20
+ comes back, as before.
21
+
22
+ Args:
23
+ symbol: Exact symbol, e.g. "700.HK".
24
+ exchange: Exchange protocol, e.g. "hkex_securities".
25
+ provider: Data provider, e.g. "omd" or "bmll".
26
+ date: Calibration date "YYYY-MM-DD". Keeps only instruments
27
+ calibrated on that date, and narrows each instrument's
28
+ available_dates to it.
29
+ limit: Max instruments to return.
30
+ offset: Instruments to skip (for paging alongside limit).
31
+
32
+ Returns:
33
+ list of instrument dicts, each with available_dates.
34
+ """
35
+ params = {
36
+ k: v for k, v in {
37
+ "symbol": symbol,
38
+ "exchange": exchange,
39
+ "provider": provider,
40
+ "date": date,
41
+ "limit": limit,
42
+ "offset": offset,
43
+ }.items() if v is not None
44
+ }
45
+ return self._client._request("GET", AVAILABLE_SYMBOLS_PATH, params=params or None)
@@ -0,0 +1,30 @@
1
+ class ProfileResource:
2
+ def __init__(self, client):
3
+ self._client = client
4
+
5
+ def get(self):
6
+ return self._client._request("GET", "/profile")
7
+
8
+ def usage(self):
9
+ return self._client._request("GET", "/profile/usage")
10
+
11
+ def downloads(self):
12
+ """Download quota usage for the current rolling 24-hour window.
13
+
14
+ Returns a dict with ``limit``, ``used``, ``remaining``,
15
+ ``window_hours`` and ``downloaded_groups``. ``limit`` and
16
+ ``remaining`` are ``None`` on the pro and demo tiers (unlimited); on
17
+ the free tier they reflect the account's daily download allowance.
18
+
19
+ A "download" is one simulation group (all Monte Carlo runs of one
20
+ scenario). ``used`` counts NEW groups added in the window;
21
+ ``downloaded_groups`` lists every group you have ever downloaded —
22
+ membership is permanent, so those are free to re-fetch forever in any
23
+ run or file format.
24
+
25
+ Example:
26
+ >>> quota = client.profile.downloads()
27
+ >>> print(f"{quota['used']}/{quota['limit']} used, {quota['remaining']} left")
28
+ >>> print(f"{len(quota['downloaded_groups'])} groups owned")
29
+ """
30
+ return self._client._request("GET", "/profile/downloads")
@@ -496,6 +496,13 @@ class SimulationResource:
496
496
  """
497
497
  Download simulation data as a Polars DataFrame.
498
498
 
499
+ Free-tier quota: downloading from a cached simulation group you haven't
500
+ downloaded before consumes one unit of the daily allowance (HTTP 429
501
+ once exhausted). Groups you've already downloaded — via this method,
502
+ the bulk ZIP, or the web explorer — stay free forever, any run or file
503
+ format. Your own job runs are never charged. See
504
+ ``client.profile.downloads()``.
505
+
499
506
  Args:
500
507
  sim_id: The simulation ID
501
508
  filename: File to download. Options:
@@ -656,13 +663,13 @@ class SimulationResource:
656
663
  Returns:
657
664
  bytes: ZIP file content containing requested parquet files
658
665
 
659
- Free-tier quota: bulk downloads are capped per rolling 24-hour window
660
- (default 3). One unit is consumed per distinct simulation group (all
661
- Monte Carlo runs of one scenario) — not per call, run, or file format,
662
- and re-fetching a group already counted in the window is free. The API
663
- returns HTTP 429 when a request would exceed the allowance. Check your
664
- remaining quota with ``client.profile.downloads()``. Pro and demo
665
- tiers are unlimited.
666
+ Free-tier quota: at most N NEW simulation groups per rolling 24-hour
667
+ window (default 3). One unit is consumed per distinct group (all Monte
668
+ Carlo runs of one scenario) — not per call, run, or file format — and
669
+ membership is permanent: a group you've downloaded before is free to
670
+ re-fetch forever. The API returns HTTP 429 (charging nothing) when a
671
+ request would exceed the allowance. Check your quota and owned groups
672
+ with ``client.profile.downloads()``. Pro and demo tiers are unlimited.
666
673
 
667
674
  Example - Download sim_data for multiple sims:
668
675
  >>> cached = client.simulation.list_cached(symbol="700.HK")
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: simudyne-pulse
3
- Version: 0.6.0.dev1
3
+ Version: 0.6.0.dev2
4
4
  Summary: Python SDK for the Simudyne Pulse synthetic market data API
5
5
  Author-email: Simudyne <support@simudyne.com>
6
6
  License-Expression: MIT
@@ -1,9 +0,0 @@
1
- AVAILABLE_SYMBOLS_PATH = "/data/available-symbols"
2
-
3
-
4
- class DataResource:
5
- def __init__(self, client):
6
- self._client = client
7
-
8
- def get_available_symbols(self):
9
- return self._client._request("GET", AVAILABLE_SYMBOLS_PATH)
@@ -1,25 +0,0 @@
1
- class ProfileResource:
2
- def __init__(self, client):
3
- self._client = client
4
-
5
- def get(self):
6
- return self._client._request("GET", "/profile")
7
-
8
- def usage(self):
9
- return self._client._request("GET", "/profile/usage")
10
-
11
- def downloads(self):
12
- """Bulk-download quota usage for the current rolling 24-hour window.
13
-
14
- Returns a dict with ``limit``, ``used``, ``remaining`` and
15
- ``window_hours``. ``limit`` and ``remaining`` are ``None`` on the
16
- pro and demo tiers (unlimited); on the free tier they reflect the
17
- account's daily download allowance. A "download" is one simulation
18
- group (all Monte Carlo runs of one scenario) — re-fetching a group
19
- already downloaded in the window, in any file format, is free.
20
-
21
- Example:
22
- >>> quota = client.profile.downloads()
23
- >>> print(f"{quota['used']}/{quota['limit']} used, {quota['remaining']} left")
24
- """
25
- return self._client._request("GET", "/profile/downloads")