simulo-interfaces 0.16.0__tar.gz → 0.17.0__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. {simulo_interfaces-0.16.0/src/simulo_interfaces.egg-info → simulo_interfaces-0.17.0}/PKG-INFO +1 -1
  2. {simulo_interfaces-0.16.0 → simulo_interfaces-0.17.0}/pyproject.toml +1 -1
  3. {simulo_interfaces-0.16.0 → simulo_interfaces-0.17.0}/src/simulo/interfaces/platform/__init__.py +14 -0
  4. {simulo_interfaces-0.16.0 → simulo_interfaces-0.17.0}/src/simulo/interfaces/platform/runs.py +78 -0
  5. {simulo_interfaces-0.16.0 → simulo_interfaces-0.17.0/src/simulo_interfaces.egg-info}/PKG-INFO +1 -1
  6. {simulo_interfaces-0.16.0 → simulo_interfaces-0.17.0}/MANIFEST.in +0 -0
  7. {simulo_interfaces-0.16.0 → simulo_interfaces-0.17.0}/PYPI.md +0 -0
  8. {simulo_interfaces-0.16.0 → simulo_interfaces-0.17.0}/setup.cfg +0 -0
  9. {simulo_interfaces-0.16.0 → simulo_interfaces-0.17.0}/src/simulo/interfaces/__init__.py +0 -0
  10. {simulo_interfaces-0.16.0 → simulo_interfaces-0.17.0}/src/simulo/interfaces/authoring/__init__.py +0 -0
  11. {simulo_interfaces-0.16.0 → simulo_interfaces-0.17.0}/src/simulo/interfaces/authoring/actuator.py +0 -0
  12. {simulo_interfaces-0.16.0 → simulo_interfaces-0.17.0}/src/simulo/interfaces/authoring/asset.py +0 -0
  13. {simulo_interfaces-0.16.0 → simulo_interfaces-0.17.0}/src/simulo/interfaces/authoring/entity.py +0 -0
  14. {simulo_interfaces-0.16.0 → simulo_interfaces-0.17.0}/src/simulo/interfaces/authoring/light.py +0 -0
  15. {simulo_interfaces-0.16.0 → simulo_interfaces-0.17.0}/src/simulo/interfaces/authoring/materials.py +0 -0
  16. {simulo_interfaces-0.16.0 → simulo_interfaces-0.17.0}/src/simulo/interfaces/authoring/physics.py +0 -0
  17. {simulo_interfaces-0.16.0 → simulo_interfaces-0.17.0}/src/simulo/interfaces/authoring/pose.py +0 -0
  18. {simulo_interfaces-0.16.0 → simulo_interfaces-0.17.0}/src/simulo/interfaces/authoring/primitives.py +0 -0
  19. {simulo_interfaces-0.16.0 → simulo_interfaces-0.17.0}/src/simulo/interfaces/authoring/prop.py +0 -0
  20. {simulo_interfaces-0.16.0 → simulo_interfaces-0.17.0}/src/simulo/interfaces/authoring/record.py +0 -0
  21. {simulo_interfaces-0.16.0 → simulo_interfaces-0.17.0}/src/simulo/interfaces/authoring/robot.py +0 -0
  22. {simulo_interfaces-0.16.0 → simulo_interfaces-0.17.0}/src/simulo/interfaces/authoring/scene.py +0 -0
  23. {simulo_interfaces-0.16.0 → simulo_interfaces-0.17.0}/src/simulo/interfaces/authoring/sensor.py +0 -0
  24. {simulo_interfaces-0.16.0 → simulo_interfaces-0.17.0}/src/simulo/interfaces/authoring/terrain.py +0 -0
  25. {simulo_interfaces-0.16.0 → simulo_interfaces-0.17.0}/src/simulo/interfaces/authoring/visual.py +0 -0
  26. {simulo_interfaces-0.16.0 → simulo_interfaces-0.17.0}/src/simulo/interfaces/authoring/world.py +0 -0
  27. {simulo_interfaces-0.16.0 → simulo_interfaces-0.17.0}/src/simulo/interfaces/exceptions.py +0 -0
  28. {simulo_interfaces-0.16.0 → simulo_interfaces-0.17.0}/src/simulo/interfaces/ids.py +0 -0
  29. {simulo_interfaces-0.16.0 → simulo_interfaces-0.17.0}/src/simulo/interfaces/platform/_payload.py +0 -0
  30. {simulo_interfaces-0.16.0 → simulo_interfaces-0.17.0}/src/simulo/interfaces/platform/app.py +0 -0
  31. {simulo_interfaces-0.16.0 → simulo_interfaces-0.17.0}/src/simulo/interfaces/platform/asset.py +0 -0
  32. {simulo_interfaces-0.16.0 → simulo_interfaces-0.17.0}/src/simulo/interfaces/platform/asset_catalog.py +0 -0
  33. {simulo_interfaces-0.16.0 → simulo_interfaces-0.17.0}/src/simulo/interfaces/platform/callbacks.py +0 -0
  34. {simulo_interfaces-0.16.0 → simulo_interfaces-0.17.0}/src/simulo/interfaces/platform/debug.py +0 -0
  35. {simulo_interfaces-0.16.0 → simulo_interfaces-0.17.0}/src/simulo/interfaces/platform/domain.py +0 -0
  36. {simulo_interfaces-0.16.0 → simulo_interfaces-0.17.0}/src/simulo/interfaces/platform/enums.py +0 -0
  37. {simulo_interfaces-0.16.0 → simulo_interfaces-0.17.0}/src/simulo/interfaces/platform/job_events.py +0 -0
  38. {simulo_interfaces-0.16.0 → simulo_interfaces-0.17.0}/src/simulo/interfaces/platform/manifest.py +0 -0
  39. {simulo_interfaces-0.16.0 → simulo_interfaces-0.17.0}/src/simulo/interfaces/platform/outputs.py +0 -0
  40. {simulo_interfaces-0.16.0 → simulo_interfaces-0.17.0}/src/simulo/interfaces/platform/policy_bundle.py +0 -0
  41. {simulo_interfaces-0.16.0 → simulo_interfaces-0.17.0}/src/simulo/interfaces/platform/runtime.py +0 -0
  42. {simulo_interfaces-0.16.0 → simulo_interfaces-0.17.0}/src/simulo/interfaces/platform/submit.py +0 -0
  43. {simulo_interfaces-0.16.0 → simulo_interfaces-0.17.0}/src/simulo/interfaces/platform/volume.py +0 -0
  44. {simulo_interfaces-0.16.0 → simulo_interfaces-0.17.0}/src/simulo/interfaces/py.typed +0 -0
  45. {simulo_interfaces-0.16.0 → simulo_interfaces-0.17.0}/src/simulo/interfaces/runtime/__init__.py +0 -0
  46. {simulo_interfaces-0.16.0 → simulo_interfaces-0.17.0}/src/simulo/interfaces/runtime/anomaly.py +0 -0
  47. {simulo_interfaces-0.16.0 → simulo_interfaces-0.17.0}/src/simulo/interfaces/runtime/components.py +0 -0
  48. {simulo_interfaces-0.16.0 → simulo_interfaces-0.17.0}/src/simulo/interfaces/runtime/env.py +0 -0
  49. {simulo_interfaces-0.16.0 → simulo_interfaces-0.17.0}/src/simulo/interfaces/runtime/player.py +0 -0
  50. {simulo_interfaces-0.16.0 → simulo_interfaces-0.17.0}/src/simulo/interfaces/runtime/policy.py +0 -0
  51. {simulo_interfaces-0.16.0 → simulo_interfaces-0.17.0}/src/simulo/interfaces/runtime/scenario.py +0 -0
  52. {simulo_interfaces-0.16.0 → simulo_interfaces-0.17.0}/src/simulo/interfaces/runtime/task.py +0 -0
  53. {simulo_interfaces-0.16.0 → simulo_interfaces-0.17.0}/src/simulo/interfaces/runtime/tensors.py +0 -0
  54. {simulo_interfaces-0.16.0 → simulo_interfaces-0.17.0}/src/simulo/interfaces/runtime/trainer.py +0 -0
  55. {simulo_interfaces-0.16.0 → simulo_interfaces-0.17.0}/src/simulo_interfaces.egg-info/SOURCES.txt +0 -0
  56. {simulo_interfaces-0.16.0 → simulo_interfaces-0.17.0}/src/simulo_interfaces.egg-info/dependency_links.txt +0 -0
  57. {simulo_interfaces-0.16.0 → simulo_interfaces-0.17.0}/src/simulo_interfaces.egg-info/requires.txt +0 -0
  58. {simulo_interfaces-0.16.0 → simulo_interfaces-0.17.0}/src/simulo_interfaces.egg-info/top_level.txt +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: simulo-interfaces
3
- Version: 0.16.0
3
+ Version: 0.17.0
4
4
  Summary: Type contracts for the Simulo SDK. Installed automatically as a dependency of the simulo package.
5
5
  Author-email: Simulo Team <team@simulo.ai>
6
6
  License: BSD-3-Clause
@@ -4,7 +4,7 @@ build-backend = "setuptools.build_meta"
4
4
 
5
5
  [project]
6
6
  name = "simulo-interfaces"
7
- version = "0.16.0"
7
+ version = "0.17.0"
8
8
  description = "Type contracts for the Simulo SDK. Installed automatically as a dependency of the simulo package."
9
9
  readme = "PYPI.md"
10
10
  requires-python = ">=3.11"
@@ -205,6 +205,10 @@ from simulo.interfaces.platform.runs import (
205
205
  JOB_SCOPE_QUERY_PARAM,
206
206
  JOBS_API_DEFAULT_PORT,
207
207
  JOBS_ROUTE,
208
+ LOG_ARCHIVE_EXPIRED_CODE,
209
+ LOG_ARCHIVE_LOST_CODE,
210
+ LOG_ARCHIVE_READ_FAILED_CODE,
211
+ LOG_ARCHIVE_UNAVAILABLE_CODES,
208
212
  LOG_CHUNK_MAX_BYTES,
209
213
  LOG_TAIL_MAX_BYTES,
210
214
  TERMINAL_JOB_STATUSES,
@@ -327,6 +331,16 @@ __all__ = [
327
331
  "JOB_RESULT_ROUTE_TEMPLATE",
328
332
  "LOG_CHUNK_MAX_BYTES",
329
333
  "LOG_TAIL_MAX_BYTES",
334
+ # unavailable-log contract (issue #1052) — 410 Gone, TERMINAL: the bytes
335
+ # are gone and retrying cannot succeed
336
+ "LOG_ARCHIVE_EXPIRED_CODE",
337
+ "LOG_ARCHIVE_LOST_CODE",
338
+ "LOG_ARCHIVE_UNAVAILABLE_CODES",
339
+ # ...and its RETRYABLE counterpart, deliberately NOT one of the above:
340
+ # 503, the stored log could not be read right now. A client that folds it
341
+ # into the terminal set tells the user their logs are gone because S3 was
342
+ # briefly slow.
343
+ "LOG_ARCHIVE_READ_FAILED_CODE",
330
344
  # user scoping (issue #651)
331
345
  "JOB_SCOPE_QUERY_PARAM",
332
346
  "JOB_SCOPE_MINE",
@@ -74,6 +74,44 @@ HTTP API shape (all responses JSON; all timestamps ISO 8601 UTC, e.g.
74
74
  sequence; a line-oriented client trims its first partial line client-side
75
75
  (``simulo logs --follow`` requests a generous byte window for its line
76
76
  count and does exactly that).
77
+
78
+ **Log retention, and the ``410 Gone`` outcome it produces.** A job's logs
79
+ live in the platform's live-tail store while the job runs, and are archived
80
+ to object storage once it reaches a terminal status. That archive is kept
81
+ for a BOUNDED time, and once it is gone the log is gone — there is no
82
+ second copy and no retry brings it back.
83
+
84
+ **The window's LENGTH is deliberately not stated here.** It is a
85
+ per-environment deployment value — an object-store lifecycle rule, mirrored
86
+ by the platform's own retention ceiling — and it differs between production,
87
+ staging, and a local development stack, which a client cannot reliably tell
88
+ apart. Restating a number in this module would publish a copy to PyPI that
89
+ no guard covers and that nobody would update the first time the window
90
+ moved, so a released client would go on stating a figure that had stopped
91
+ being true. Simulo's product documentation (docs.simulo.ai) carries the
92
+ single user-facing statement of the current windows, and the ``simulo``
93
+ CLI's own message names the behaviour rather than the number for exactly
94
+ this reason.
95
+
96
+ What IS contractual here, and does not vary by environment: reading a job's
97
+ logs after that point answers **410 Gone** in the usual
98
+ error envelope, with a machine-readable code naming WHICH of the two
99
+ terminal conditions occurred:
100
+
101
+ * :data:`LOG_ARCHIVE_EXPIRED_CODE` — the archive aged out under the
102
+ retention policy above;
103
+ * :data:`LOG_ARCHIVE_LOST_CODE` — the platform could not archive the bytes
104
+ and, rather than retain them indefinitely, accounted for the loss and
105
+ released them.
106
+
107
+ Both are TERMINAL: retrying the same request cannot succeed, so a client
108
+ must present them as "these logs are no longer available" rather than as an
109
+ empty log or a generic failure. Neither is ``404`` — ``404 job_not_found``
110
+ is this API's deliberately indistinguishable answer for a job the caller
111
+ may not see, so reusing it here could not tell "no such job" apart from
112
+ "your logs expired". A transient storage failure is a separate, RETRYABLE
113
+ ``503`` carrying :data:`LOG_ARCHIVE_READ_FAILED_CODE`, and is never one of
114
+ these codes.
77
115
  * ``GET /v1/jobs/{job_id}/result`` — the job's result JSON object. 404 (code
78
116
  ``result_not_available``) until the run stores one. A run stores its result
79
117
  when it completes successfully, and in ONE failure case: a run reported
@@ -222,6 +260,46 @@ LOG_CHUNK_MAX_BYTES = 256 * 1024
222
260
  #: server's tail scan bounded. Values above this cap answer 422.
223
261
  LOG_TAIL_MAX_BYTES = 4 * LOG_CHUNK_MAX_BYTES
224
262
 
263
+ #: ``410 Gone`` — the job's archived log aged out under the platform's log
264
+ #: retention policy. TERMINAL: the bytes are gone, there is no second copy,
265
+ #: and retrying cannot succeed. The window's length is a per-environment
266
+ #: deployment value and is deliberately not restated here — see the module
267
+ #: docstring's retention section for why a copy in this package would be a
268
+ #: published number nobody maintains.
269
+ LOG_ARCHIVE_EXPIRED_CODE = "log_archive_expired"
270
+ #: ``410 Gone`` — the platform could not archive this job's terminal log
271
+ #: bytes and, rather than retain them indefinitely, accounted for the loss
272
+ #: and released them. Also TERMINAL, and deliberately DISTINCT from
273
+ #: :data:`LOG_ARCHIVE_EXPIRED_CODE`: "your logs aged out under the documented
274
+ #: policy" and "we could not keep your logs" are different statements, and a
275
+ #: client that collapses them makes the retention guarantee above
276
+ #: unverifiable from the outside.
277
+ LOG_ARCHIVE_LOST_CODE = "log_archive_lost"
278
+ #: Both unavailable-log codes. A client that treats "the logs are no longer
279
+ #: available" as ONE user-facing outcome branches on this set; one that
280
+ #: reports which condition occurred uses the two codes individually. Either
281
+ #: way the outcome is terminal — never an empty log, and never a retry loop.
282
+ LOG_ARCHIVE_UNAVAILABLE_CODES = frozenset({LOG_ARCHIVE_EXPIRED_CODE, LOG_ARCHIVE_LOST_CODE})
283
+
284
+ #: ``503 Service Unavailable`` — the stored log could not be READ right now.
285
+ #: The RETRYABLE counterpart of the two codes above, and deliberately a
286
+ #: different status as well as a different code: a throttle, a credential
287
+ #: problem, or a connection reset says nothing about whether the bytes still
288
+ #: exist, so presenting it as "your logs are gone" would be wrong twice — it
289
+ #: tells the user something false and it invites them to stop retrying.
290
+ #:
291
+ #: NOT a member of :data:`LOG_ARCHIVE_UNAVAILABLE_CODES`, and a client MUST
292
+ #: NOT fold it in. It carries the same ``{"error": {"code", "message",
293
+ #: "request_id"}}`` envelope as every other error; a client that recognizes it
294
+ #: should say the logs are temporarily unreadable and suggest retrying.
295
+ #:
296
+ #: THE WIRE VALUE SAYS ``read_failed``, NOT ``unavailable``, on purpose. An
297
+ #: earlier draft of this contract spelled it ``log_archive_unavailable`` —
298
+ #: the one code deliberately EXCLUDED from a set named
299
+ #: ``LOG_ARCHIVE_UNAVAILABLE_CODES``, which is a trap for every reader who
300
+ #: greps for one and finds the other. Do not "align" it back.
301
+ LOG_ARCHIVE_READ_FAILED_CODE = "log_archive_read_failed"
302
+
225
303
  #: Statuses after which a job's log stream and record no longer change. A log
226
304
  #: follower drains the remaining bytes and stops once the status is terminal.
227
305
  TERMINAL_JOB_STATUSES = frozenset({JobStatus.COMPLETED, JobStatus.FAILED, JobStatus.CANCELLED})
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: simulo-interfaces
3
- Version: 0.16.0
3
+ Version: 0.17.0
4
4
  Summary: Type contracts for the Simulo SDK. Installed automatically as a dependency of the simulo package.
5
5
  Author-email: Simulo Team <team@simulo.ai>
6
6
  License: BSD-3-Clause