labcode 0.1.3__tar.gz → 0.1.4__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 (61) hide show
  1. {labcode-0.1.3 → labcode-0.1.4}/.github/workflows/ci.yml +14 -0
  2. labcode-0.1.4/MANIFEST.in +6 -0
  3. {labcode-0.1.3 → labcode-0.1.4}/PKG-INFO +1 -1
  4. {labcode-0.1.3 → labcode-0.1.4}/labcode/run_cli.py +9 -0
  5. {labcode-0.1.3 → labcode-0.1.4}/labcode.egg-info/PKG-INFO +1 -1
  6. {labcode-0.1.3 → labcode-0.1.4}/labcode.egg-info/SOURCES.txt +1 -0
  7. {labcode-0.1.3 → labcode-0.1.4}/labcode.egg-info/scm_file_list.json +2 -0
  8. labcode-0.1.4/labcode.egg-info/scm_version.json +8 -0
  9. {labcode-0.1.3 → labcode-0.1.4}/tests/test_run_cli.py +26 -0
  10. labcode-0.1.3/labcode.egg-info/scm_version.json +0 -8
  11. {labcode-0.1.3 → labcode-0.1.4}/.github/workflows/publish.yml +0 -0
  12. {labcode-0.1.3 → labcode-0.1.4}/.gitignore +0 -0
  13. {labcode-0.1.3 → labcode-0.1.4}/LICENSE +0 -0
  14. {labcode-0.1.3 → labcode-0.1.4}/README.md +0 -0
  15. {labcode-0.1.3 → labcode-0.1.4}/SPECIFICATIONS.md +0 -0
  16. {labcode-0.1.3 → labcode-0.1.4}/examples/README.md +0 -0
  17. {labcode-0.1.3 → labcode-0.1.4}/examples/outputs/plate_line.boundary.yaml +0 -0
  18. {labcode-0.1.3 → labcode-0.1.4}/examples/outputs/plate_line.observation.yaml +0 -0
  19. {labcode-0.1.3 → labcode-0.1.4}/examples/outputs/plate_line.plan.yaml +0 -0
  20. {labcode-0.1.3 → labcode-0.1.4}/examples/outputs/plate_line.svg +0 -0
  21. {labcode-0.1.3 → labcode-0.1.4}/examples/plate_line.boundary.yaml +0 -0
  22. {labcode-0.1.3 → labcode-0.1.4}/examples/plate_line.env.yaml +0 -0
  23. {labcode-0.1.3 → labcode-0.1.4}/examples/plate_line.workflow.yaml +0 -0
  24. {labcode-0.1.3 → labcode-0.1.4}/examples/render_plate_line.py +0 -0
  25. {labcode-0.1.3 → labcode-0.1.4}/examples/run_all_sila2_examples.py +0 -0
  26. {labcode-0.1.3 → labcode-0.1.4}/examples/run_sila2_seal.py +0 -0
  27. {labcode-0.1.3 → labcode-0.1.4}/examples/sila2_seal.boundary.yaml +0 -0
  28. {labcode-0.1.3 → labcode-0.1.4}/examples/sila2_seal.env.yaml +0 -0
  29. {labcode-0.1.3 → labcode-0.1.4}/examples/sila2_seal.workflow.yaml +0 -0
  30. {labcode-0.1.3 → labcode-0.1.4}/examples/sila2_seal.wrapped.env.yaml +0 -0
  31. {labcode-0.1.3 → labcode-0.1.4}/labcode/__init__.py +0 -0
  32. {labcode-0.1.3 → labcode-0.1.4}/labcode/__main__.py +0 -0
  33. {labcode-0.1.3 → labcode-0.1.4}/labcode/_child.py +0 -0
  34. {labcode-0.1.3 → labcode-0.1.4}/labcode/backend.py +0 -0
  35. {labcode-0.1.3 → labcode-0.1.4}/labcode/cli.py +0 -0
  36. {labcode-0.1.3 → labcode-0.1.4}/labcode/dialect.py +0 -0
  37. {labcode-0.1.3 → labcode-0.1.4}/labcode/extension.py +0 -0
  38. {labcode-0.1.3 → labcode-0.1.4}/labcode/idgen.py +0 -0
  39. {labcode-0.1.3 → labcode-0.1.4}/labcode/objectid.py +0 -0
  40. {labcode-0.1.3 → labcode-0.1.4}/labcode/probe.py +0 -0
  41. {labcode-0.1.3 → labcode-0.1.4}/labcode/py.typed +0 -0
  42. {labcode-0.1.3 → labcode-0.1.4}/labcode/runner.py +0 -0
  43. {labcode-0.1.3 → labcode-0.1.4}/labcode/sila2.py +0 -0
  44. {labcode-0.1.3 → labcode-0.1.4}/labcode.egg-info/dependency_links.txt +0 -0
  45. {labcode-0.1.3 → labcode-0.1.4}/labcode.egg-info/entry_points.txt +0 -0
  46. {labcode-0.1.3 → labcode-0.1.4}/labcode.egg-info/requires.txt +0 -0
  47. {labcode-0.1.3 → labcode-0.1.4}/labcode.egg-info/top_level.txt +0 -0
  48. {labcode-0.1.3 → labcode-0.1.4}/pyproject.toml +0 -0
  49. {labcode-0.1.3 → labcode-0.1.4}/setup.cfg +0 -0
  50. {labcode-0.1.3 → labcode-0.1.4}/tests/fixtures/device_script.env.yaml +0 -0
  51. {labcode-0.1.3 → labcode-0.1.4}/tests/fixtures/device_script.workflow.yaml +0 -0
  52. {labcode-0.1.3 → labcode-0.1.4}/tests/fixtures/reroute_device.env.yaml +0 -0
  53. {labcode-0.1.3 → labcode-0.1.4}/tests/fixtures/reroute_transporter.env.yaml +0 -0
  54. {labcode-0.1.3 → labcode-0.1.4}/tests/fixtures/transport.env.yaml +0 -0
  55. {labcode-0.1.3 → labcode-0.1.4}/tests/fixtures/transport.workflow.yaml +0 -0
  56. {labcode-0.1.3 → labcode-0.1.4}/tests/test_backend.py +0 -0
  57. {labcode-0.1.3 → labcode-0.1.4}/tests/test_cli.py +0 -0
  58. {labcode-0.1.3 → labcode-0.1.4}/tests/test_dialect.py +0 -0
  59. {labcode-0.1.3 → labcode-0.1.4}/tests/test_objectid.py +0 -0
  60. {labcode-0.1.3 → labcode-0.1.4}/tests/test_probe.py +0 -0
  61. {labcode-0.1.3 → labcode-0.1.4}/tests/test_sila2.py +0 -0
@@ -43,3 +43,17 @@ jobs:
43
43
  cache: pip
44
44
  - run: pip install -e ".[dev]"
45
45
  - run: mypy
46
+
47
+ # `uv sync --extra sila2` is how a development environment gets built here, and
48
+ # uv.lock records what it produces. This asserts the lock still agrees with
49
+ # pyproject.toml, so a raised dependency floor or a new extra cannot leave the
50
+ # environment pinned to versions the project no longer accepts. It deliberately
51
+ # does not ask whether newer releases exist -- that is `uv lock --upgrade`, run
52
+ # when someone means to move. The jobs above stay on pip so they keep testing
53
+ # against the latest released siblings.
54
+ lock:
55
+ runs-on: ubuntu-latest
56
+ steps:
57
+ - uses: actions/checkout@v4
58
+ - uses: astral-sh/setup-uv@v7
59
+ - run: uv lock --check
@@ -0,0 +1,6 @@
1
+ # setuptools-scm hands the sdist every file git tracks, and uv.lock is tracked so
2
+ # that the versions a developer actually gets stay reviewable. That lock describes
3
+ # the development environment only -- an installer resolves the wheel's dependency
4
+ # metadata and never reads it -- so it has no business in the distribution, where
5
+ # it would roughly double the sdist. Excluded here; still in the repository.
6
+ exclude uv.lock
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: labcode
3
- Version: 0.1.3
3
+ Version: 0.1.4
4
4
  Summary: labcode -- a dialect wrapper over the Object-Flow Programming Language toolchain
5
5
  Author-email: Kazunari Kaizu <kwaizu@gmail.com>
6
6
  License-Expression: MIT
@@ -67,6 +67,14 @@ def _build_parser() -> argparse.ArgumentParser:
67
67
  )
68
68
  p.add_argument("-o", "--output", metavar="OUT", help="write the final status YAML here")
69
69
  p.add_argument("--boundary-out", metavar="FILE", help="write the result boundary document here")
70
+ p.add_argument(
71
+ # Same flag and meaning as `ofp-run run --observation-out`: the value layer's
72
+ # companion to the status document, streamed one YAML document per completed
73
+ # activity. Forwarded verbatim to `run_labcode`, which already took the argument.
74
+ "--observation-out", metavar="FILE",
75
+ help="stream the observation document here (YAML multi-document): each completed"
76
+ " activity's input/output view values, appended as it finishes",
77
+ )
70
78
  p.add_argument(
71
79
  "--no-validate", action="store_true",
72
80
  help="skip the ofplang-validate front-door check of the workflow",
@@ -202,6 +210,7 @@ def main(argv: Sequence[str] | None = None) -> int:
202
210
  poll_interval=args.poll_interval,
203
211
  seconds_per_tick=args.seconds_per_tick,
204
212
  speed=args.speed,
213
+ observation_out=args.observation_out,
205
214
  probe=not args.no_probe,
206
215
  on_availability_change=report_availability,
207
216
  on_cadence_slip=report_cadence_slip,
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: labcode
3
- Version: 0.1.3
3
+ Version: 0.1.4
4
4
  Summary: labcode -- a dialect wrapper over the Object-Flow Programming Language toolchain
5
5
  Author-email: Kazunari Kaizu <kwaizu@gmail.com>
6
6
  License-Expression: MIT
@@ -1,5 +1,6 @@
1
1
  .gitignore
2
2
  LICENSE
3
+ MANIFEST.in
3
4
  README.md
4
5
  SPECIFICATIONS.md
5
6
  pyproject.toml
@@ -1,9 +1,11 @@
1
1
  {
2
2
  "files": [
3
+ "MANIFEST.in",
3
4
  "pyproject.toml",
4
5
  "SPECIFICATIONS.md",
5
6
  "LICENSE",
6
7
  "README.md",
8
+ "uv.lock",
7
9
  ".gitignore",
8
10
  ".github/workflows/ci.yml",
9
11
  ".github/workflows/publish.yml",
@@ -0,0 +1,8 @@
1
+ {
2
+ "tag": "0.1.4",
3
+ "distance": 0,
4
+ "node": "gf78971be7ff6c3a8436ae98fd3aa5fa00a73442b",
5
+ "dirty": false,
6
+ "branch": "HEAD",
7
+ "node_date": "2026-08-07"
8
+ }
@@ -82,6 +82,32 @@ def test_e2e_lc_run_stamps_deterministic_object_ids(tmp_path):
82
82
  assert doc1 == yaml.safe_load(rb2.read_text(encoding="utf-8")) # deterministic
83
83
 
84
84
 
85
+ def test_cli_observation_out_streams_the_observation_document(tmp_path):
86
+ # `--observation-out` forwards to the runner's observation sink, so the flag produces
87
+ # the same YAML multi-document stream `ofp-run run --observation-out` does: a header
88
+ # naming the schema, one entry per completed activity, and a trailer.
89
+ pytest.importorskip("ofplang.schedule", reason="ofplang-schedule not installed")
90
+ import yaml
91
+
92
+ obs = tmp_path / "observation.yaml"
93
+ code = run_cli.main([
94
+ str(EXAMPLES / "plate_line.workflow.yaml"),
95
+ "--env", str(EXAMPLES / "plate_line.env.yaml"),
96
+ "--boundary", str(EXAMPLES / "plate_line.boundary.yaml"),
97
+ "--seconds-per-tick", "0.001",
98
+ "-o", str(tmp_path / "status.yaml"),
99
+ "--observation-out", str(obs),
100
+ ])
101
+ assert code == 0
102
+
103
+ docs = list(yaml.safe_load_all(obs.read_text(encoding="utf-8")))
104
+ assert docs[0]["schema"] == "ofplang-observation/v0"
105
+ assert docs[-1]["final"] is True and docs[-1]["outcome"] == "completed"
106
+ # The Plate the workflow creates is traceable by its `_id` through the entries.
107
+ processed = [d for d in docs[1:-1] if d.get("kind") == "processing"]
108
+ assert processed, "expected at least one completed processing activity"
109
+
110
+
85
111
  def test_e2e_lc_run_expands_imported_object_types_and_stamps_ids(tmp_path):
86
112
  # `$import` and `_id` compose: the object types (Plate/Tube) are moved into an
87
113
  # imported fragment, so the shared front door must expand it first; then
@@ -1,8 +0,0 @@
1
- {
2
- "tag": "0.1.3",
3
- "distance": 0,
4
- "node": "g8b62fc33d3a9f69848967e991b6cea2577cd74a5",
5
- "dirty": false,
6
- "branch": "HEAD",
7
- "node_date": "2026-08-04"
8
- }
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