simudyne-pulse 0.7.0.dev7__tar.gz → 0.7.0.dev8__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 (26) hide show
  1. {simudyne_pulse-0.7.0.dev7/src/simudyne_pulse.egg-info → simudyne_pulse-0.7.0.dev8}/PKG-INFO +50 -1
  2. {simudyne_pulse-0.7.0.dev7 → simudyne_pulse-0.7.0.dev8}/README.md +49 -0
  3. {simudyne_pulse-0.7.0.dev7 → simudyne_pulse-0.7.0.dev8}/pyproject.toml +1 -1
  4. {simudyne_pulse-0.7.0.dev7 → simudyne_pulse-0.7.0.dev8}/src/simudyne/resources/validation.py +3 -1
  5. {simudyne_pulse-0.7.0.dev7 → simudyne_pulse-0.7.0.dev8/src/simudyne_pulse.egg-info}/PKG-INFO +50 -1
  6. {simudyne_pulse-0.7.0.dev7 → simudyne_pulse-0.7.0.dev8}/tests/test_new_resources.py +11 -11
  7. {simudyne_pulse-0.7.0.dev7 → simudyne_pulse-0.7.0.dev8}/tests/test_validation.py +4 -2
  8. {simudyne_pulse-0.7.0.dev7 → simudyne_pulse-0.7.0.dev8}/LICENSE +0 -0
  9. {simudyne_pulse-0.7.0.dev7 → simudyne_pulse-0.7.0.dev8}/setup.cfg +0 -0
  10. {simudyne_pulse-0.7.0.dev7 → simudyne_pulse-0.7.0.dev8}/src/simudyne/__init__.py +0 -0
  11. {simudyne_pulse-0.7.0.dev7 → simudyne_pulse-0.7.0.dev8}/src/simudyne/client.py +0 -0
  12. {simudyne_pulse-0.7.0.dev7 → simudyne_pulse-0.7.0.dev8}/src/simudyne/exceptions.py +0 -0
  13. {simudyne_pulse-0.7.0.dev7 → simudyne_pulse-0.7.0.dev8}/src/simudyne/resources/__init__.py +0 -0
  14. {simudyne_pulse-0.7.0.dev7 → simudyne_pulse-0.7.0.dev8}/src/simudyne/resources/api_keys.py +0 -0
  15. {simudyne_pulse-0.7.0.dev7 → simudyne_pulse-0.7.0.dev8}/src/simudyne/resources/data.py +0 -0
  16. {simudyne_pulse-0.7.0.dev7 → simudyne_pulse-0.7.0.dev8}/src/simudyne/resources/fix.py +0 -0
  17. {simudyne_pulse-0.7.0.dev7 → simudyne_pulse-0.7.0.dev8}/src/simudyne/resources/fm.py +0 -0
  18. {simudyne_pulse-0.7.0.dev7 → simudyne_pulse-0.7.0.dev8}/src/simudyne/resources/historical.py +0 -0
  19. {simudyne_pulse-0.7.0.dev7 → simudyne_pulse-0.7.0.dev8}/src/simudyne/resources/profile.py +0 -0
  20. {simudyne_pulse-0.7.0.dev7 → simudyne_pulse-0.7.0.dev8}/src/simudyne/resources/simulation.py +0 -0
  21. {simudyne_pulse-0.7.0.dev7 → simudyne_pulse-0.7.0.dev8}/src/simudyne/resources/simulator_gym.py +0 -0
  22. {simudyne_pulse-0.7.0.dev7 → simudyne_pulse-0.7.0.dev8}/src/simudyne_pulse.egg-info/SOURCES.txt +0 -0
  23. {simudyne_pulse-0.7.0.dev7 → simudyne_pulse-0.7.0.dev8}/src/simudyne_pulse.egg-info/dependency_links.txt +0 -0
  24. {simudyne_pulse-0.7.0.dev7 → simudyne_pulse-0.7.0.dev8}/src/simudyne_pulse.egg-info/requires.txt +0 -0
  25. {simudyne_pulse-0.7.0.dev7 → simudyne_pulse-0.7.0.dev8}/src/simudyne_pulse.egg-info/top_level.txt +0 -0
  26. {simudyne_pulse-0.7.0.dev7 → simudyne_pulse-0.7.0.dev8}/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.7.0.dev7
3
+ Version: 0.7.0.dev8
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
@@ -59,6 +59,55 @@ pip install --pre simudyne-pulse
59
59
  Only use dev builds for testing unreleased changes; they are not guaranteed
60
60
  stable. Merge `dev` into `prod` to promote those changes to a stable release.
61
61
 
62
+ ### Working from a checkout
63
+
64
+ To run the SDK from source — editing it, or using unreleased changes — install
65
+ it editable **into the interpreter you will actually import from**. A notebook
66
+ kernel is frequently not the python on your `$PATH`:
67
+
68
+ ```bash
69
+ # in a notebook, find the right interpreter first
70
+ import sys; print(sys.executable)
71
+
72
+ # then, with that path
73
+ <that python> -m pip install -e /path/to/pulse-sdk
74
+ ```
75
+
76
+ Check which copy you loaded — this is worth doing whenever an attribute seems
77
+ to be missing:
78
+
79
+ ```python
80
+ import simudyne
81
+ from importlib.metadata import version
82
+
83
+ print(simudyne.__file__) # should be .../pulse-sdk/src/simudyne/...
84
+ print(version("simudyne-pulse"))
85
+ ```
86
+
87
+ #### If an older install shadows it
88
+
89
+ The SDK was once published under the distribution name **`simudyne`**; it is
90
+ now **`simudyne-pulse`**. Both ship a module called `simudyne`, and the older
91
+ one installs a real directory while the editable install only adds a path
92
+ entry — so the old copy wins and you get errors like
93
+ `'PulseABM' object has no attribute 'validation'` from a version that predates
94
+ the feature. `pip list` shows both. Remove the obsolete one:
95
+
96
+ ```bash
97
+ <that python> -m pip uninstall simudyne # the old distribution
98
+ <that python> -m pip install -e /path/to/pulse-sdk
99
+ ```
100
+
101
+ ### Running the tests
102
+
103
+ ```bash
104
+ uv run --with pytest --with requests --with pandas --with pyarrow \
105
+ python -m pytest tests/ -q
106
+ ```
107
+
108
+ No network: the client's `_request` is replaced with a recorder, so the tests
109
+ assert the exact payload the API would receive.
110
+
62
111
  ## Quick start
63
112
 
64
113
  ```python
@@ -33,6 +33,55 @@ pip install --pre simudyne-pulse
33
33
  Only use dev builds for testing unreleased changes; they are not guaranteed
34
34
  stable. Merge `dev` into `prod` to promote those changes to a stable release.
35
35
 
36
+ ### Working from a checkout
37
+
38
+ To run the SDK from source — editing it, or using unreleased changes — install
39
+ it editable **into the interpreter you will actually import from**. A notebook
40
+ kernel is frequently not the python on your `$PATH`:
41
+
42
+ ```bash
43
+ # in a notebook, find the right interpreter first
44
+ import sys; print(sys.executable)
45
+
46
+ # then, with that path
47
+ <that python> -m pip install -e /path/to/pulse-sdk
48
+ ```
49
+
50
+ Check which copy you loaded — this is worth doing whenever an attribute seems
51
+ to be missing:
52
+
53
+ ```python
54
+ import simudyne
55
+ from importlib.metadata import version
56
+
57
+ print(simudyne.__file__) # should be .../pulse-sdk/src/simudyne/...
58
+ print(version("simudyne-pulse"))
59
+ ```
60
+
61
+ #### If an older install shadows it
62
+
63
+ The SDK was once published under the distribution name **`simudyne`**; it is
64
+ now **`simudyne-pulse`**. Both ship a module called `simudyne`, and the older
65
+ one installs a real directory while the editable install only adds a path
66
+ entry — so the old copy wins and you get errors like
67
+ `'PulseABM' object has no attribute 'validation'` from a version that predates
68
+ the feature. `pip list` shows both. Remove the obsolete one:
69
+
70
+ ```bash
71
+ <that python> -m pip uninstall simudyne # the old distribution
72
+ <that python> -m pip install -e /path/to/pulse-sdk
73
+ ```
74
+
75
+ ### Running the tests
76
+
77
+ ```bash
78
+ uv run --with pytest --with requests --with pandas --with pyarrow \
79
+ python -m pytest tests/ -q
80
+ ```
81
+
82
+ No network: the client's `_request` is replaced with a recorder, so the tests
83
+ assert the exact payload the API would receive.
84
+
36
85
  ## Quick start
37
86
 
38
87
  ```python
@@ -4,7 +4,7 @@ build-backend = "setuptools.build_meta"
4
4
 
5
5
  [project]
6
6
  name = "simudyne-pulse"
7
- version = "0.7.0-dev.7"
7
+ version = "0.7.0-dev.8"
8
8
  description = "Python SDK for the Simudyne Pulse synthetic market data API"
9
9
  readme = "README.md"
10
10
  license = "MIT"
@@ -276,8 +276,10 @@ class ValidationResource:
276
276
  },
277
277
  )
278
278
  else:
279
+ # Three-tuple parts: the content type matters to the server's
280
+ # multipart parser, so it is sent explicitly.
279
281
  files = [
280
- ("sim_files", _frame_to_parquet(entry, i))
282
+ ("sim_files", (*_frame_to_parquet(entry, i), "application/octet-stream"))
281
283
  for i, entry in enumerate(sim_files)
282
284
  ]
283
285
  submitted = self._client._request(
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: simudyne-pulse
3
- Version: 0.7.0.dev7
3
+ Version: 0.7.0.dev8
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
@@ -59,6 +59,55 @@ pip install --pre simudyne-pulse
59
59
  Only use dev builds for testing unreleased changes; they are not guaranteed
60
60
  stable. Merge `dev` into `prod` to promote those changes to a stable release.
61
61
 
62
+ ### Working from a checkout
63
+
64
+ To run the SDK from source — editing it, or using unreleased changes — install
65
+ it editable **into the interpreter you will actually import from**. A notebook
66
+ kernel is frequently not the python on your `$PATH`:
67
+
68
+ ```bash
69
+ # in a notebook, find the right interpreter first
70
+ import sys; print(sys.executable)
71
+
72
+ # then, with that path
73
+ <that python> -m pip install -e /path/to/pulse-sdk
74
+ ```
75
+
76
+ Check which copy you loaded — this is worth doing whenever an attribute seems
77
+ to be missing:
78
+
79
+ ```python
80
+ import simudyne
81
+ from importlib.metadata import version
82
+
83
+ print(simudyne.__file__) # should be .../pulse-sdk/src/simudyne/...
84
+ print(version("simudyne-pulse"))
85
+ ```
86
+
87
+ #### If an older install shadows it
88
+
89
+ The SDK was once published under the distribution name **`simudyne`**; it is
90
+ now **`simudyne-pulse`**. Both ship a module called `simudyne`, and the older
91
+ one installs a real directory while the editable install only adds a path
92
+ entry — so the old copy wins and you get errors like
93
+ `'PulseABM' object has no attribute 'validation'` from a version that predates
94
+ the feature. `pip list` shows both. Remove the obsolete one:
95
+
96
+ ```bash
97
+ <that python> -m pip uninstall simudyne # the old distribution
98
+ <that python> -m pip install -e /path/to/pulse-sdk
99
+ ```
100
+
101
+ ### Running the tests
102
+
103
+ ```bash
104
+ uv run --with pytest --with requests --with pandas --with pyarrow \
105
+ python -m pytest tests/ -q
106
+ ```
107
+
108
+ No network: the client's `_request` is replaced with a recorder, so the tests
109
+ assert the exact payload the API would receive.
110
+
62
111
  ## Quick start
63
112
 
64
113
  ```python
@@ -1,4 +1,4 @@
1
- """Payload tests for the 0.8.0 surface: validation.run_upload, the fm and fix
1
+ """Payload tests for the 0.8.0 surface: validation.run, the fm and fix
2
2
  resources, and simulation.get_job_logs / run_lrm.
3
3
 
4
4
  No network — same recorder pattern as test_validation.py. These pin the wire
@@ -30,7 +30,7 @@ class TestRunUpload:
30
30
  def test_rejects_empty_before_any_request(self):
31
31
  client = FakeClient()
32
32
  with pytest.raises(ValueError, match="empty"):
33
- ValidationResource(client).run_upload(
33
+ ValidationResource(client).run(
34
34
  "700.HK", "2025-09-01", "omd", "hkex_securities", sim_files=[]
35
35
  )
36
36
  assert client.calls == []
@@ -39,18 +39,18 @@ class TestRunUpload:
39
39
  client = FakeClient()
40
40
  files = [(f"sim_{i}.parquet", b"x") for i in range(26)]
41
41
  with pytest.raises(ValueError, match="25"):
42
- ValidationResource(client).run_upload(
42
+ ValidationResource(client).run(
43
43
  "700.HK", "2025-09-01", "omd", "hkex_securities", sim_files=files
44
44
  )
45
45
  assert client.calls == []
46
46
 
47
47
  def test_multipart_payload_shape(self):
48
48
  client = FakeClient([{"job_id": "v1", "status": "pending"}])
49
- ValidationResource(client).run_upload(
49
+ ValidationResource(client).run(
50
50
  "700.HK", "2025-09-01", "omd", "hkex_securities",
51
51
  sim_files=[("sim_0000.parquet", b"PARQ")],
52
52
  ticksize=0.5,
53
- run_metrics=False,
53
+ statistical=False,
54
54
  )
55
55
  method, path, kwargs = client.calls[0]
56
56
  assert (method, path) == ("POST", "/validation/run/upload")
@@ -58,11 +58,11 @@ class TestRunUpload:
58
58
  assert data["provider"] == "omd" and data["exchange"] == "hkex_securities"
59
59
  assert data["ticksize"] == "0.5"
60
60
  config = json.loads(data["config"])
61
- # explicit False sent; unset tri-state flags omitted (tier default)
62
- assert config["run_metrics"] is False
63
- for flag in ("run_impact", "run_stylised_facts", "plot_data"):
61
+ # explicit False sent; unset area flags omitted (tier default)
62
+ assert config["statistical"] is False
63
+ for flag in ("impact", "stylised_facts", "fid", "mind",
64
+ "run_metrics", "plot_data"):
64
65
  assert flag not in config
65
- assert config["run_fid"] is True
66
66
  [(field, (filename, content, mime))] = kwargs["files"]
67
67
  assert field == "sim_files" and filename == "sim_0000.parquet"
68
68
  assert content == b"PARQ" and mime == "application/octet-stream"
@@ -70,8 +70,8 @@ class TestRunUpload:
70
70
  def test_reads_paths_from_disk(self, tmp_path):
71
71
  p = tmp_path / "sim_0001.parquet"
72
72
  p.write_bytes(b"BYTES")
73
- client = FakeClient([{}])
74
- ValidationResource(client).run_upload(
73
+ client = FakeClient([{"job_id": "v1"}])
74
+ ValidationResource(client).run(
75
75
  "700.HK", "2025-09-01", "omd", "hkex_securities", sim_files=[p]
76
76
  )
77
77
  [(_, (filename, content, _))] = client.calls[0][2]["files"]
@@ -216,12 +216,14 @@ class TestSimulatedFrameShapes:
216
216
  return client.calls[0][2]["files"]
217
217
 
218
218
  def test_pair(self):
219
- assert self._files_sent([("a.parquet", b"x")])[0][1] == ("a.parquet", b"x")
219
+ part = self._files_sent([("a.parquet", b"x")])[0][1]
220
+ assert part == ("a.parquet", b"x", "application/octet-stream")
220
221
 
221
222
  def test_path(self, tmp_path):
222
223
  p = tmp_path / "sim.parquet"
223
224
  p.write_bytes(b"data")
224
- assert self._files_sent([str(p)])[0][1] == ("sim.parquet", b"data")
225
+ part = self._files_sent([str(p)])[0][1]
226
+ assert part == ("sim.parquet", b"data", "application/octet-stream")
225
227
 
226
228
  def test_each_frame_gets_its_own_name(self):
227
229
  pd = pytest.importorskip("pandas")