marimo-export 0.0.0__tar.gz → 0.0.2__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.
- {marimo_export-0.0.0 → marimo_export-0.0.2}/LICENSE +2 -1
- marimo_export-0.0.2/PKG-INFO +160 -0
- marimo_export-0.0.2/README.md +119 -0
- marimo_export-0.0.2/pyproject.toml +65 -0
- marimo_export-0.0.2/pyproject.toml.orig +50 -0
- marimo_export-0.0.2/src/marimo_export/__init__.py +76 -0
- marimo_export-0.0.2/src/marimo_export/_blob_asset.py +83 -0
- marimo_export-0.0.2/src/marimo_export/_build.py +38 -0
- marimo_export-0.0.2/src/marimo_export/_cell_ids.py +28 -0
- marimo_export-0.0.2/src/marimo_export/_cli/__init__.py +1 -0
- marimo_export-0.0.2/src/marimo_export/_cli/arguments.py +285 -0
- marimo_export-0.0.2/src/marimo_export/_cli/commands.py +227 -0
- marimo_export-0.0.2/src/marimo_export/_cli/errors.py +78 -0
- marimo_export-0.0.2/src/marimo_export/_cli/render.py +420 -0
- marimo_export-0.0.2/src/marimo_export/_client_protocol.py +450 -0
- marimo_export-0.0.2/src/marimo_export/_control_roots.py +166 -0
- marimo_export-0.0.2/src/marimo_export/_delivery.py +22 -0
- marimo_export-0.0.2/src/marimo_export/_delivery_validation.py +100 -0
- marimo_export-0.0.2/src/marimo_export/_diagnostics.py +103 -0
- marimo_export-0.0.2/src/marimo_export/_directory.py +252 -0
- marimo_export-0.0.2/src/marimo_export/_directory_native.py +53 -0
- marimo_export-0.0.2/src/marimo_export/_directory_security.py +210 -0
- marimo_export-0.0.2/src/marimo_export/_directory_target.py +147 -0
- marimo_export-0.0.2/src/marimo_export/_execution/__init__.py +31 -0
- marimo_export-0.0.2/src/marimo_export/_execution/plan.py +915 -0
- marimo_export-0.0.2/src/marimo_export/_format.py +139 -0
- marimo_export-0.0.2/src/marimo_export/_http_url.py +81 -0
- marimo_export-0.0.2/src/marimo_export/_identity.py +73 -0
- marimo_export-0.0.2/src/marimo_export/_json.py +683 -0
- marimo_export-0.0.2/src/marimo_export/_limits.py +6 -0
- marimo_export-0.0.2/src/marimo_export/_marimo/__init__.py +1 -0
- marimo_export-0.0.2/src/marimo_export/_marimo/anywidget.py +22 -0
- marimo_export-0.0.2/src/marimo_export/_marimo/blob.py +14 -0
- marimo_export-0.0.2/src/marimo_export/_marimo/bridge.py +492 -0
- marimo_export-0.0.2/src/marimo_export/_marimo/capabilities.py +201 -0
- marimo_export-0.0.2/src/marimo_export/_marimo/compat/__init__.py +1 -0
- marimo_export-0.0.2/src/marimo_export/_marimo/compat/anywidget.py +320 -0
- marimo_export-0.0.2/src/marimo_export/_marimo/compat/anywidget_assets.py +853 -0
- marimo_export-0.0.2/src/marimo_export/_marimo/compat/blob.py +24 -0
- marimo_export-0.0.2/src/marimo_export/_marimo/compat/cache/__init__.py +3 -0
- marimo_export-0.0.2/src/marimo_export/_marimo/compat/cache/attempts.py +218 -0
- marimo_export-0.0.2/src/marimo_export/_marimo/compat/cache/barrier.py +38 -0
- marimo_export-0.0.2/src/marimo_export/_marimo/compat/cache/host.py +247 -0
- marimo_export-0.0.2/src/marimo_export/_marimo/compat/cache/lifecycle.py +52 -0
- marimo_export-0.0.2/src/marimo_export/_marimo/compat/cache/loader.py +65 -0
- marimo_export-0.0.2/src/marimo_export/_marimo/compat/cache/patch.py +218 -0
- marimo_export-0.0.2/src/marimo_export/_marimo/compat/cache/probe.py +159 -0
- marimo_export-0.0.2/src/marimo_export/_marimo/compat/cache/receipts.py +199 -0
- marimo_export-0.0.2/src/marimo_export/_marimo/compat/child_run.py +539 -0
- marimo_export-0.0.2/src/marimo_export/_marimo/compat/execution.py +570 -0
- marimo_export-0.0.2/src/marimo_export/_marimo/compat/exporter_identity.py +314 -0
- marimo_export-0.0.2/src/marimo_export/_marimo/compat/exporters.py +305 -0
- marimo_export-0.0.2/src/marimo_export/_marimo/compat/file_closure.py +436 -0
- marimo_export-0.0.2/src/marimo_export/_marimo/compat/inspection.py +714 -0
- marimo_export-0.0.2/src/marimo_export/_marimo/compat/kernel.py +39 -0
- marimo_export-0.0.2/src/marimo_export/_marimo/compat/managed_kernel.py +56 -0
- marimo_export-0.0.2/src/marimo_export/_marimo/compat/managed_server.py +82 -0
- marimo_export-0.0.2/src/marimo_export/_marimo/compat/observations.py +303 -0
- marimo_export-0.0.2/src/marimo_export/_marimo/compat/output_data.py +572 -0
- marimo_export-0.0.2/src/marimo_export/_marimo/compat/projections.py +475 -0
- marimo_export-0.0.2/src/marimo_export/_marimo/compat/receipts.py +259 -0
- marimo_export-0.0.2/src/marimo_export/_marimo/compat/release.json +44 -0
- marimo_export-0.0.2/src/marimo_export/_marimo/compat/replay.py +277 -0
- marimo_export-0.0.2/src/marimo_export/_marimo/compat/transfer.py +20 -0
- marimo_export-0.0.2/src/marimo_export/_marimo/composition.py +98 -0
- marimo_export-0.0.2/src/marimo_export/_marimo/entrypoints.py +31 -0
- marimo_export-0.0.2/src/marimo_export/_marimo/managed_server.py +6 -0
- marimo_export-0.0.2/src/marimo_export/_marimo/transfer.py +439 -0
- marimo_export-0.0.2/src/marimo_export/_media_type.py +136 -0
- marimo_export-0.0.2/src/marimo_export/_notebook.py +96 -0
- marimo_export-0.0.2/src/marimo_export/_observations/__init__.py +1 -0
- marimo_export-0.0.2/src/marimo_export/_observations/candidates.py +97 -0
- marimo_export-0.0.2/src/marimo_export/_observations/ledger.py +291 -0
- marimo_export-0.0.2/src/marimo_export/_observations/queue.py +120 -0
- marimo_export-0.0.2/src/marimo_export/_observations/source.py +46 -0
- marimo_export-0.0.2/src/marimo_export/_portable.py +142 -0
- marimo_export-0.0.2/src/marimo_export/_prepared_integrity.py +163 -0
- marimo_export-0.0.2/src/marimo_export/_publication.py +394 -0
- marimo_export-0.0.2/src/marimo_export/_remote/__init__.py +15 -0
- marimo_export-0.0.2/src/marimo_export/_remote/auth.py +105 -0
- marimo_export-0.0.2/src/marimo_export/_remote/client.py +822 -0
- marimo_export-0.0.2/src/marimo_export/_remote/managed.py +919 -0
- marimo_export-0.0.2/src/marimo_export/_remote/sse.py +128 -0
- marimo_export-0.0.2/src/marimo_export/_remote/windows_job.py +210 -0
- marimo_export-0.0.2/src/marimo_export/_repository/__init__.py +1 -0
- marimo_export-0.0.2/src/marimo_export/_repository/artifact_access.py +244 -0
- marimo_export-0.0.2/src/marimo_export/_repository/artifact_commit.py +289 -0
- marimo_export-0.0.2/src/marimo_export/_repository/artifact_context.py +34 -0
- marimo_export-0.0.2/src/marimo_export/_repository/artifact_lifecycle.py +569 -0
- marimo_export-0.0.2/src/marimo_export/_repository/artifacts.py +162 -0
- marimo_export-0.0.2/src/marimo_export/_repository/capabilities.py +61 -0
- marimo_export-0.0.2/src/marimo_export/_repository/files.py +562 -0
- marimo_export-0.0.2/src/marimo_export/_repository/handles.py +353 -0
- marimo_export-0.0.2/src/marimo_export/_repository/leases.py +621 -0
- marimo_export-0.0.2/src/marimo_export/_repository/models.py +398 -0
- marimo_export-0.0.2/src/marimo_export/_repository/observations.py +129 -0
- marimo_export-0.0.2/src/marimo_export/_repository/paths.py +114 -0
- marimo_export-0.0.2/src/marimo_export/_repository/preparation.py +310 -0
- marimo_export-0.0.2/src/marimo_export/_repository/sqlite/__init__.py +1 -0
- marimo_export-0.0.2/src/marimo_export/_repository/sqlite/artifacts.py +148 -0
- marimo_export-0.0.2/src/marimo_export/_repository/sqlite/catalog.py +631 -0
- marimo_export-0.0.2/src/marimo_export/_repository/sqlite/generations.py +325 -0
- marimo_export-0.0.2/src/marimo_export/_repository/sqlite/leases.py +351 -0
- marimo_export-0.0.2/src/marimo_export/_repository/sqlite/maintenance.py +177 -0
- marimo_export-0.0.2/src/marimo_export/_repository/sqlite/observations.py +362 -0
- marimo_export-0.0.2/src/marimo_export/_repository/sqlite/open.py +68 -0
- marimo_export-0.0.2/src/marimo_export/_repository/sqlite/prepared_states.py +248 -0
- marimo_export-0.0.2/src/marimo_export/_repository/sqlite/records.py +91 -0
- marimo_export-0.0.2/src/marimo_export/_repository/sqlite/recovery.py +549 -0
- marimo_export-0.0.2/src/marimo_export/_repository/sqlite/retention.py +340 -0
- marimo_export-0.0.2/src/marimo_export/_repository/sqlite/retired.py +58 -0
- marimo_export-0.0.2/src/marimo_export/_repository/sqlite/schema.py +343 -0
- marimo_export-0.0.2/src/marimo_export/_repository/sqlite/status.py +35 -0
- marimo_export-0.0.2/src/marimo_export/_secure_io.py +390 -0
- marimo_export-0.0.2/src/marimo_export/_selector.py +106 -0
- marimo_export-0.0.2/src/marimo_export/_services/__init__.py +1 -0
- marimo_export-0.0.2/src/marimo_export/_services/capture_export.py +225 -0
- marimo_export-0.0.2/src/marimo_export/_services/export_artifacts.py +211 -0
- marimo_export-0.0.2/src/marimo_export/_services/identity.py +426 -0
- marimo_export-0.0.2/src/marimo_export/_services/plan_export.py +250 -0
- marimo_export-0.0.2/src/marimo_export/_services/plan_wire.py +171 -0
- marimo_export-0.0.2/src/marimo_export/_services/preparation_support.py +141 -0
- marimo_export-0.0.2/src/marimo_export/_services/prepare_export.py +160 -0
- marimo_export-0.0.2/src/marimo_export/_services/state_preparation.py +182 -0
- marimo_export-0.0.2/src/marimo_export/_services/write_export.py +152 -0
- marimo_export-0.0.2/src/marimo_export/_snapshot.py +307 -0
- marimo_export-0.0.2/src/marimo_export/_writer.py +243 -0
- marimo_export-0.0.2/src/marimo_export/cli.py +97 -0
- marimo_export-0.0.2/src/marimo_export/client.py +364 -0
- marimo_export-0.0.2/src/marimo_export/delivery.py +240 -0
- marimo_export-0.0.2/src/marimo_export/descriptors.py +525 -0
- marimo_export-0.0.2/src/marimo_export/diagnostics.py +102 -0
- marimo_export-0.0.2/src/marimo_export/errors.py +119 -0
- marimo_export-0.0.2/src/marimo_export/exporters/__init__.py +5 -0
- marimo_export-0.0.2/src/marimo_export/exporters/_anywidget_payload.py +574 -0
- marimo_export-0.0.2/src/marimo_export/exporters/_definitions.py +213 -0
- marimo_export-0.0.2/src/marimo_export/exporters/_optional.py +15 -0
- marimo_export-0.0.2/src/marimo_export/exporters/_runtime/__init__.py +1 -0
- marimo_export-0.0.2/src/marimo_export/exporters/_runtime/altair.py +68 -0
- marimo_export-0.0.2/src/marimo_export/exporters/_runtime/anywidget.py +21 -0
- marimo_export-0.0.2/src/marimo_export/exporters/_runtime/blob.py +52 -0
- marimo_export-0.0.2/src/marimo_export/exporters/_runtime/parquet.py +70 -0
- marimo_export-0.0.2/src/marimo_export/exporters/_spec.py +139 -0
- marimo_export-0.0.2/src/marimo_export/exporters/altair.py +18 -0
- marimo_export-0.0.2/src/marimo_export/exporters/anywidget.py +12 -0
- marimo_export-0.0.2/src/marimo_export/exporters/blob.py +61 -0
- marimo_export-0.0.2/src/marimo_export/exporters/parquet.py +26 -0
- marimo_export-0.0.2/src/marimo_export/index.py +572 -0
- marimo_export-0.0.2/src/marimo_export/inspection.py +381 -0
- marimo_export-0.0.2/src/marimo_export/integration.py +119 -0
- marimo_export-0.0.2/src/marimo_export/limits.py +44 -0
- marimo_export-0.0.2/src/marimo_export/manifest.py +39 -0
- marimo_export-0.0.2/src/marimo_export/observations.py +105 -0
- marimo_export-0.0.2/src/marimo_export/outputs.py +64 -0
- marimo_export-0.0.2/src/marimo_export/planning.py +272 -0
- marimo_export-0.0.2/src/marimo_export/prepared.py +503 -0
- marimo_export-0.0.2/src/marimo_export/producer.py +318 -0
- marimo_export-0.0.2/src/marimo_export/progress.py +108 -0
- marimo_export-0.0.2/src/marimo_export/publication.py +176 -0
- marimo_export-0.0.2/src/marimo_export/py.typed +0 -0
- marimo_export-0.0.2/src/marimo_export/reader.py +762 -0
- marimo_export-0.0.2/src/marimo_export/repository.py +214 -0
- marimo_export-0.0.2/src/marimo_export/result.py +265 -0
- marimo_export-0.0.2/src/marimo_export/sessions.py +25 -0
- marimo_export-0.0.2/src/marimo_export/spec.py +1097 -0
- marimo_export-0.0.2/src/marimo_export/verification.py +15 -0
- marimo_export-0.0.2/src/marimo_export/wire.py +95 -0
- marimo_export-0.0.0/.gitignore +0 -49
- marimo_export-0.0.0/PKG-INFO +0 -14
- marimo_export-0.0.0/README.md +0 -3
- marimo_export-0.0.0/pyproject.toml +0 -19
- marimo_export-0.0.0/src/marimo_export/__init__.py +0 -1
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
|
|
1
2
|
Apache License
|
|
2
3
|
Version 2.0, January 2004
|
|
3
4
|
http://www.apache.org/licenses/
|
|
@@ -186,7 +187,7 @@
|
|
|
186
187
|
same "printed page" as the copyright notice for easier
|
|
187
188
|
identification within third-party archives.
|
|
188
189
|
|
|
189
|
-
Copyright
|
|
190
|
+
Copyright 2026 marimo team
|
|
190
191
|
|
|
191
192
|
Licensed under the Apache License, Version 2.0 (the "License");
|
|
192
193
|
you may not use this file except in compliance with the License.
|
|
@@ -0,0 +1,160 @@
|
|
|
1
|
+
Metadata-Version: 2.4
|
|
2
|
+
Name: marimo-export
|
|
3
|
+
Version: 0.0.2
|
|
4
|
+
Summary: Precompute and read verified exports of selected marimo notebook results.
|
|
5
|
+
Keywords: cache,export,marimo,notebook
|
|
6
|
+
Author: marimo team
|
|
7
|
+
License-Expression: Apache-2.0
|
|
8
|
+
License-File: LICENSE
|
|
9
|
+
Classifier: Programming Language :: Python :: 3
|
|
10
|
+
Classifier: Programming Language :: Python :: 3 :: Only
|
|
11
|
+
Classifier: Programming Language :: Python :: 3.10
|
|
12
|
+
Classifier: Programming Language :: Python :: 3.11
|
|
13
|
+
Classifier: Programming Language :: Python :: 3.12
|
|
14
|
+
Classifier: Programming Language :: Python :: 3.13
|
|
15
|
+
Classifier: Programming Language :: Python :: 3.14
|
|
16
|
+
Requires-Dist: cryptography==50.0.1
|
|
17
|
+
Requires-Dist: idna==3.19
|
|
18
|
+
Requires-Dist: marimo==0.24.0
|
|
19
|
+
Requires-Dist: msgspec>=0.20
|
|
20
|
+
Requires-Dist: numpy>=1.23.5
|
|
21
|
+
Requires-Dist: pydantic>=2,<3
|
|
22
|
+
Requires-Dist: pyyaml>=6.0.1
|
|
23
|
+
Requires-Dist: altair>=5,<7 ; extra == 'all'
|
|
24
|
+
Requires-Dist: anywidget>=0.9,<1 ; extra == 'all'
|
|
25
|
+
Requires-Dist: pyarrow>=15 ; extra == 'all'
|
|
26
|
+
Requires-Dist: vl-convert-python>=1.8 ; extra == 'all'
|
|
27
|
+
Requires-Dist: anywidget>=0.9,<1 ; extra == 'anywidget'
|
|
28
|
+
Requires-Dist: altair>=5,<7 ; extra == 'charts'
|
|
29
|
+
Requires-Dist: vl-convert-python>=1.8 ; extra == 'charts'
|
|
30
|
+
Requires-Dist: pyarrow>=15 ; extra == 'parquet'
|
|
31
|
+
Requires-Python: >=3.10
|
|
32
|
+
Project-URL: Homepage, https://marimo-team.github.io/marimo-export/
|
|
33
|
+
Project-URL: Documentation, https://marimo-team.github.io/marimo-export/
|
|
34
|
+
Project-URL: Repository, https://github.com/marimo-team/marimo-export
|
|
35
|
+
Project-URL: Issues, https://github.com/marimo-team/marimo-export/issues
|
|
36
|
+
Provides-Extra: all
|
|
37
|
+
Provides-Extra: anywidget
|
|
38
|
+
Provides-Extra: charts
|
|
39
|
+
Provides-Extra: parquet
|
|
40
|
+
Description-Content-Type: text/markdown
|
|
41
|
+
|
|
42
|
+
# marimo-export
|
|
43
|
+
|
|
44
|
+
The `marimo-export` Python package plans, prepares, writes, opens, and verifies
|
|
45
|
+
notebook exports from saved [marimo](https://marimo.io/) notebooks or named live sessions.
|
|
46
|
+
|
|
47
|
+
[uv](https://docs.astral.sh/uv/) adds the package to a Python project:
|
|
48
|
+
|
|
49
|
+
```bash
|
|
50
|
+
uv add marimo-export
|
|
51
|
+
```
|
|
52
|
+
|
|
53
|
+
The package requires Python 3.10 or newer, is tested on Python 3.10 through
|
|
54
|
+
3.14, and installs the marimo release pinned by its package metadata.
|
|
55
|
+
|
|
56
|
+
The examples use the repository's
|
|
57
|
+
[`report.py`](https://github.com/marimo-team/marimo-export/blob/main/examples/quickstart/report.py)
|
|
58
|
+
and
|
|
59
|
+
[`report.export.yaml`](https://github.com/marimo-team/marimo-export/blob/main/examples/quickstart/report.export.yaml).
|
|
60
|
+
Download both files into the current directory before running them.
|
|
61
|
+
|
|
62
|
+
## Run the CLI from PyPI
|
|
63
|
+
|
|
64
|
+
```bash
|
|
65
|
+
uvx marimo-export build report.py \
|
|
66
|
+
--spec report.export.yaml \
|
|
67
|
+
--output dist/report
|
|
68
|
+
uvx marimo-export verify dist/report
|
|
69
|
+
```
|
|
70
|
+
|
|
71
|
+
`build` prepares missing states, writes the export, verifies every declared
|
|
72
|
+
asset, and closes the notebook process it started.
|
|
73
|
+
|
|
74
|
+
## Build from Python
|
|
75
|
+
|
|
76
|
+
```python
|
|
77
|
+
from pathlib import Path
|
|
78
|
+
|
|
79
|
+
from marimo_export import ExportSpec, build
|
|
80
|
+
|
|
81
|
+
Path("dist").mkdir(exist_ok=True)
|
|
82
|
+
spec = ExportSpec.from_file("report.export.yaml")
|
|
83
|
+
result = build("report.py", spec=spec, output="dist/report")
|
|
84
|
+
|
|
85
|
+
print(result.path)
|
|
86
|
+
```
|
|
87
|
+
|
|
88
|
+
A matching later call with a new destination or `replace=True` can reuse the
|
|
89
|
+
prepared export before notebook startup.
|
|
90
|
+
|
|
91
|
+
## Read the export
|
|
92
|
+
|
|
93
|
+
```python
|
|
94
|
+
from marimo_export import open_export, verify_export
|
|
95
|
+
|
|
96
|
+
export = open_export("dist/report")
|
|
97
|
+
summary = export.state("monthly").output("summary").json()
|
|
98
|
+
verified = verify_export("dist/report")
|
|
99
|
+
|
|
100
|
+
print(dict(summary))
|
|
101
|
+
print(verified.states, verified.outputs)
|
|
102
|
+
```
|
|
103
|
+
|
|
104
|
+
```text
|
|
105
|
+
{'days': 30, 'label': 'Last 30 days'}
|
|
106
|
+
2 2
|
|
107
|
+
```
|
|
108
|
+
|
|
109
|
+
Opening validates canonical `index.json` and leaves asset data lazy. Complete
|
|
110
|
+
verification reads every declared asset and returns exported-state,
|
|
111
|
+
state-output-pair, unique-asset, and verified-byte counts. The example has two
|
|
112
|
+
states and one output name, so `verified.outputs` is `2`.
|
|
113
|
+
|
|
114
|
+
## Capture a live session
|
|
115
|
+
|
|
116
|
+
After opening `report.py` in a running marimo server, `capture()` borrows the
|
|
117
|
+
named session and returns a leased `PreparedExport`:
|
|
118
|
+
|
|
119
|
+
```python
|
|
120
|
+
from marimo_export import ExportSpec, capture
|
|
121
|
+
|
|
122
|
+
spec = ExportSpec.from_file("report.export.yaml")
|
|
123
|
+
|
|
124
|
+
with capture(
|
|
125
|
+
"http://127.0.0.1:2718",
|
|
126
|
+
session="SESSION_ID",
|
|
127
|
+
spec=spec,
|
|
128
|
+
) as prepared:
|
|
129
|
+
prepared.write("dist/report", replace=True)
|
|
130
|
+
```
|
|
131
|
+
|
|
132
|
+
`replace=True` replaces the complete destination directory. Keep unrelated
|
|
133
|
+
application files outside `dist/report`.
|
|
134
|
+
|
|
135
|
+
Use `marimo-export inspect SERVER` to find session IDs. The selected session
|
|
136
|
+
remains active after capture. The live notebook environment and the client must
|
|
137
|
+
load the same marimo-export implementation and exporter dependencies.
|
|
138
|
+
|
|
139
|
+
## Install output exporters
|
|
140
|
+
|
|
141
|
+
Install the optional families selected by your `ExportSpec`:
|
|
142
|
+
|
|
143
|
+
```bash
|
|
144
|
+
uv add "marimo-export[charts,parquet,anywidget]"
|
|
145
|
+
```
|
|
146
|
+
|
|
147
|
+
The base package supports JSON, native marimo values, and custom exporter
|
|
148
|
+
callables. The optional families add Altair and PNG charts, Parquet tables, and
|
|
149
|
+
AnyWidget bundles.
|
|
150
|
+
|
|
151
|
+
## Learn the complete API
|
|
152
|
+
|
|
153
|
+
- [Getting started](https://marimo-team.github.io/marimo-export/guide/getting-started)
|
|
154
|
+
- [Python API](https://marimo-team.github.io/marimo-export/reference/python-api)
|
|
155
|
+
- [Choose states and outputs](https://marimo-team.github.io/marimo-export/guide/choose-states)
|
|
156
|
+
- [CLI reference](https://marimo-team.github.io/marimo-export/reference/cli)
|
|
157
|
+
- [Use notebook exports with agents](https://marimo-team.github.io/marimo-export/guide/agents-and-automation)
|
|
158
|
+
|
|
159
|
+
Preparing an export executes notebook code with the notebook environment's file,
|
|
160
|
+
credential, network, and package access.
|
|
@@ -0,0 +1,119 @@
|
|
|
1
|
+
# marimo-export
|
|
2
|
+
|
|
3
|
+
The `marimo-export` Python package plans, prepares, writes, opens, and verifies
|
|
4
|
+
notebook exports from saved [marimo](https://marimo.io/) notebooks or named live sessions.
|
|
5
|
+
|
|
6
|
+
[uv](https://docs.astral.sh/uv/) adds the package to a Python project:
|
|
7
|
+
|
|
8
|
+
```bash
|
|
9
|
+
uv add marimo-export
|
|
10
|
+
```
|
|
11
|
+
|
|
12
|
+
The package requires Python 3.10 or newer, is tested on Python 3.10 through
|
|
13
|
+
3.14, and installs the marimo release pinned by its package metadata.
|
|
14
|
+
|
|
15
|
+
The examples use the repository's
|
|
16
|
+
[`report.py`](https://github.com/marimo-team/marimo-export/blob/main/examples/quickstart/report.py)
|
|
17
|
+
and
|
|
18
|
+
[`report.export.yaml`](https://github.com/marimo-team/marimo-export/blob/main/examples/quickstart/report.export.yaml).
|
|
19
|
+
Download both files into the current directory before running them.
|
|
20
|
+
|
|
21
|
+
## Run the CLI from PyPI
|
|
22
|
+
|
|
23
|
+
```bash
|
|
24
|
+
uvx marimo-export build report.py \
|
|
25
|
+
--spec report.export.yaml \
|
|
26
|
+
--output dist/report
|
|
27
|
+
uvx marimo-export verify dist/report
|
|
28
|
+
```
|
|
29
|
+
|
|
30
|
+
`build` prepares missing states, writes the export, verifies every declared
|
|
31
|
+
asset, and closes the notebook process it started.
|
|
32
|
+
|
|
33
|
+
## Build from Python
|
|
34
|
+
|
|
35
|
+
```python
|
|
36
|
+
from pathlib import Path
|
|
37
|
+
|
|
38
|
+
from marimo_export import ExportSpec, build
|
|
39
|
+
|
|
40
|
+
Path("dist").mkdir(exist_ok=True)
|
|
41
|
+
spec = ExportSpec.from_file("report.export.yaml")
|
|
42
|
+
result = build("report.py", spec=spec, output="dist/report")
|
|
43
|
+
|
|
44
|
+
print(result.path)
|
|
45
|
+
```
|
|
46
|
+
|
|
47
|
+
A matching later call with a new destination or `replace=True` can reuse the
|
|
48
|
+
prepared export before notebook startup.
|
|
49
|
+
|
|
50
|
+
## Read the export
|
|
51
|
+
|
|
52
|
+
```python
|
|
53
|
+
from marimo_export import open_export, verify_export
|
|
54
|
+
|
|
55
|
+
export = open_export("dist/report")
|
|
56
|
+
summary = export.state("monthly").output("summary").json()
|
|
57
|
+
verified = verify_export("dist/report")
|
|
58
|
+
|
|
59
|
+
print(dict(summary))
|
|
60
|
+
print(verified.states, verified.outputs)
|
|
61
|
+
```
|
|
62
|
+
|
|
63
|
+
```text
|
|
64
|
+
{'days': 30, 'label': 'Last 30 days'}
|
|
65
|
+
2 2
|
|
66
|
+
```
|
|
67
|
+
|
|
68
|
+
Opening validates canonical `index.json` and leaves asset data lazy. Complete
|
|
69
|
+
verification reads every declared asset and returns exported-state,
|
|
70
|
+
state-output-pair, unique-asset, and verified-byte counts. The example has two
|
|
71
|
+
states and one output name, so `verified.outputs` is `2`.
|
|
72
|
+
|
|
73
|
+
## Capture a live session
|
|
74
|
+
|
|
75
|
+
After opening `report.py` in a running marimo server, `capture()` borrows the
|
|
76
|
+
named session and returns a leased `PreparedExport`:
|
|
77
|
+
|
|
78
|
+
```python
|
|
79
|
+
from marimo_export import ExportSpec, capture
|
|
80
|
+
|
|
81
|
+
spec = ExportSpec.from_file("report.export.yaml")
|
|
82
|
+
|
|
83
|
+
with capture(
|
|
84
|
+
"http://127.0.0.1:2718",
|
|
85
|
+
session="SESSION_ID",
|
|
86
|
+
spec=spec,
|
|
87
|
+
) as prepared:
|
|
88
|
+
prepared.write("dist/report", replace=True)
|
|
89
|
+
```
|
|
90
|
+
|
|
91
|
+
`replace=True` replaces the complete destination directory. Keep unrelated
|
|
92
|
+
application files outside `dist/report`.
|
|
93
|
+
|
|
94
|
+
Use `marimo-export inspect SERVER` to find session IDs. The selected session
|
|
95
|
+
remains active after capture. The live notebook environment and the client must
|
|
96
|
+
load the same marimo-export implementation and exporter dependencies.
|
|
97
|
+
|
|
98
|
+
## Install output exporters
|
|
99
|
+
|
|
100
|
+
Install the optional families selected by your `ExportSpec`:
|
|
101
|
+
|
|
102
|
+
```bash
|
|
103
|
+
uv add "marimo-export[charts,parquet,anywidget]"
|
|
104
|
+
```
|
|
105
|
+
|
|
106
|
+
The base package supports JSON, native marimo values, and custom exporter
|
|
107
|
+
callables. The optional families add Altair and PNG charts, Parquet tables, and
|
|
108
|
+
AnyWidget bundles.
|
|
109
|
+
|
|
110
|
+
## Learn the complete API
|
|
111
|
+
|
|
112
|
+
- [Getting started](https://marimo-team.github.io/marimo-export/guide/getting-started)
|
|
113
|
+
- [Python API](https://marimo-team.github.io/marimo-export/reference/python-api)
|
|
114
|
+
- [Choose states and outputs](https://marimo-team.github.io/marimo-export/guide/choose-states)
|
|
115
|
+
- [CLI reference](https://marimo-team.github.io/marimo-export/reference/cli)
|
|
116
|
+
- [Use notebook exports with agents](https://marimo-team.github.io/marimo-export/guide/agents-and-automation)
|
|
117
|
+
|
|
118
|
+
Preparing an export executes notebook code with the notebook environment's file,
|
|
119
|
+
credential, network, and package access.
|
|
@@ -0,0 +1,65 @@
|
|
|
1
|
+
[build-system]
|
|
2
|
+
requires = ["uv_build>=0.11.28,<0.13.0"]
|
|
3
|
+
build-backend = "uv_build"
|
|
4
|
+
|
|
5
|
+
[project]
|
|
6
|
+
name = "marimo-export"
|
|
7
|
+
version = "0.0.2"
|
|
8
|
+
description = "Precompute and read verified exports of selected marimo notebook results."
|
|
9
|
+
readme = "README.md"
|
|
10
|
+
license = "Apache-2.0"
|
|
11
|
+
license-files = ["LICENSE"]
|
|
12
|
+
requires-python = ">=3.10"
|
|
13
|
+
dependencies = [
|
|
14
|
+
"cryptography==50.0.1",
|
|
15
|
+
"idna==3.19",
|
|
16
|
+
"marimo==0.24.0",
|
|
17
|
+
"msgspec>=0.20",
|
|
18
|
+
"numpy>=1.23.5",
|
|
19
|
+
"pydantic>=2,<3",
|
|
20
|
+
"PyYAML>=6.0.1",
|
|
21
|
+
]
|
|
22
|
+
keywords = [
|
|
23
|
+
"cache",
|
|
24
|
+
"export",
|
|
25
|
+
"marimo",
|
|
26
|
+
"notebook",
|
|
27
|
+
]
|
|
28
|
+
classifiers = [
|
|
29
|
+
"Programming Language :: Python :: 3",
|
|
30
|
+
"Programming Language :: Python :: 3 :: Only",
|
|
31
|
+
"Programming Language :: Python :: 3.10",
|
|
32
|
+
"Programming Language :: Python :: 3.11",
|
|
33
|
+
"Programming Language :: Python :: 3.12",
|
|
34
|
+
"Programming Language :: Python :: 3.13",
|
|
35
|
+
"Programming Language :: Python :: 3.14",
|
|
36
|
+
]
|
|
37
|
+
|
|
38
|
+
[[project.authors]]
|
|
39
|
+
name = "marimo team"
|
|
40
|
+
|
|
41
|
+
[project.urls]
|
|
42
|
+
Homepage = "https://marimo-team.github.io/marimo-export/"
|
|
43
|
+
Documentation = "https://marimo-team.github.io/marimo-export/"
|
|
44
|
+
Repository = "https://github.com/marimo-team/marimo-export"
|
|
45
|
+
Issues = "https://github.com/marimo-team/marimo-export/issues"
|
|
46
|
+
|
|
47
|
+
[project.scripts]
|
|
48
|
+
marimo-export = "marimo_export.cli:main"
|
|
49
|
+
|
|
50
|
+
[project.entry-points."marimo.kernel.lifespan"]
|
|
51
|
+
marimo-export = "marimo_export._marimo.entrypoints:kernel_lifespan"
|
|
52
|
+
|
|
53
|
+
[project.optional-dependencies]
|
|
54
|
+
anywidget = ["anywidget>=0.9,<1"]
|
|
55
|
+
charts = [
|
|
56
|
+
"altair>=5,<7",
|
|
57
|
+
"vl-convert-python>=1.8",
|
|
58
|
+
]
|
|
59
|
+
parquet = ["pyarrow>=15"]
|
|
60
|
+
all = [
|
|
61
|
+
"altair>=5,<7",
|
|
62
|
+
"anywidget>=0.9,<1",
|
|
63
|
+
"pyarrow>=15",
|
|
64
|
+
"vl-convert-python>=1.8",
|
|
65
|
+
]
|
|
@@ -0,0 +1,50 @@
|
|
|
1
|
+
[build-system]
|
|
2
|
+
requires = ["uv_build>=0.11.28,<0.13.0"]
|
|
3
|
+
build-backend = "uv_build"
|
|
4
|
+
|
|
5
|
+
[project]
|
|
6
|
+
name = "marimo-export"
|
|
7
|
+
version = "0.0.2"
|
|
8
|
+
description = "Precompute and read verified exports of selected marimo notebook results."
|
|
9
|
+
readme = "README.md"
|
|
10
|
+
license = "Apache-2.0"
|
|
11
|
+
license-files = ["LICENSE"]
|
|
12
|
+
authors = [{ name = "marimo team" }]
|
|
13
|
+
requires-python = ">=3.10"
|
|
14
|
+
dependencies = [
|
|
15
|
+
"cryptography==50.0.1",
|
|
16
|
+
"idna==3.19",
|
|
17
|
+
"marimo==0.24.0",
|
|
18
|
+
"msgspec>=0.20",
|
|
19
|
+
"numpy>=1.23.5",
|
|
20
|
+
"pydantic>=2,<3",
|
|
21
|
+
"PyYAML>=6.0.1",
|
|
22
|
+
]
|
|
23
|
+
keywords = ["cache", "export", "marimo", "notebook"]
|
|
24
|
+
classifiers = [
|
|
25
|
+
"Programming Language :: Python :: 3",
|
|
26
|
+
"Programming Language :: Python :: 3 :: Only",
|
|
27
|
+
"Programming Language :: Python :: 3.10",
|
|
28
|
+
"Programming Language :: Python :: 3.11",
|
|
29
|
+
"Programming Language :: Python :: 3.12",
|
|
30
|
+
"Programming Language :: Python :: 3.13",
|
|
31
|
+
"Programming Language :: Python :: 3.14",
|
|
32
|
+
]
|
|
33
|
+
|
|
34
|
+
[project.urls]
|
|
35
|
+
Homepage = "https://marimo-team.github.io/marimo-export/"
|
|
36
|
+
Documentation = "https://marimo-team.github.io/marimo-export/"
|
|
37
|
+
Repository = "https://github.com/marimo-team/marimo-export"
|
|
38
|
+
Issues = "https://github.com/marimo-team/marimo-export/issues"
|
|
39
|
+
|
|
40
|
+
[project.scripts]
|
|
41
|
+
marimo-export = "marimo_export.cli:main"
|
|
42
|
+
|
|
43
|
+
[project.entry-points."marimo.kernel.lifespan"]
|
|
44
|
+
marimo-export = "marimo_export._marimo.entrypoints:kernel_lifespan"
|
|
45
|
+
|
|
46
|
+
[project.optional-dependencies]
|
|
47
|
+
anywidget = ["anywidget>=0.9,<1"]
|
|
48
|
+
charts = ["altair>=5,<7", "vl-convert-python>=1.8"]
|
|
49
|
+
parquet = ["pyarrow>=15"]
|
|
50
|
+
all = ["altair>=5,<7", "anywidget>=0.9,<1", "pyarrow>=15", "vl-convert-python>=1.8"]
|
|
@@ -0,0 +1,76 @@
|
|
|
1
|
+
"""Create and read verified exports of prepared marimo notebook results."""
|
|
2
|
+
|
|
3
|
+
from __future__ import annotations
|
|
4
|
+
|
|
5
|
+
from importlib import import_module
|
|
6
|
+
from typing import TYPE_CHECKING, Any
|
|
7
|
+
|
|
8
|
+
from marimo_export._identity import implementation_identity as _implementation_identity
|
|
9
|
+
|
|
10
|
+
_LOADED_SOURCE_IDENTITY = _implementation_identity()
|
|
11
|
+
|
|
12
|
+
if TYPE_CHECKING:
|
|
13
|
+
from marimo_export._build import build
|
|
14
|
+
from marimo_export._services.capture_export import capture
|
|
15
|
+
from marimo_export._services.plan_export import plan
|
|
16
|
+
from marimo_export._services.prepare_export import prepare
|
|
17
|
+
from marimo_export.planning import ExportPlan
|
|
18
|
+
from marimo_export.prepared import PreparedExport
|
|
19
|
+
from marimo_export.progress import ProgressEvent
|
|
20
|
+
from marimo_export.reader import NotebookExport, open_export
|
|
21
|
+
from marimo_export.repository import ExportRepository
|
|
22
|
+
from marimo_export.result import ExportResult
|
|
23
|
+
from marimo_export.spec import ExportSpec, OutputSpec, StateSpace
|
|
24
|
+
from marimo_export.verification import VerificationResult, verify_export
|
|
25
|
+
|
|
26
|
+
_EXPORTS = {
|
|
27
|
+
"ExportPlan": ("marimo_export.planning", "ExportPlan"),
|
|
28
|
+
"ExportRepository": ("marimo_export.repository", "ExportRepository"),
|
|
29
|
+
"ExportResult": ("marimo_export.result", "ExportResult"),
|
|
30
|
+
"ExportSpec": ("marimo_export.spec", "ExportSpec"),
|
|
31
|
+
"NotebookExport": ("marimo_export.reader", "NotebookExport"),
|
|
32
|
+
"OutputSpec": ("marimo_export.spec", "OutputSpec"),
|
|
33
|
+
"PreparedExport": ("marimo_export.prepared", "PreparedExport"),
|
|
34
|
+
"ProgressEvent": ("marimo_export.progress", "ProgressEvent"),
|
|
35
|
+
"StateSpace": ("marimo_export.spec", "StateSpace"),
|
|
36
|
+
"VerificationResult": ("marimo_export.verification", "VerificationResult"),
|
|
37
|
+
"build": ("marimo_export._build", "build"),
|
|
38
|
+
"capture": ("marimo_export._services.capture_export", "capture"),
|
|
39
|
+
"open_export": ("marimo_export.reader", "open_export"),
|
|
40
|
+
"plan": ("marimo_export._services.plan_export", "plan"),
|
|
41
|
+
"prepare": ("marimo_export._services.prepare_export", "prepare"),
|
|
42
|
+
"verify_export": ("marimo_export.verification", "verify_export"),
|
|
43
|
+
}
|
|
44
|
+
|
|
45
|
+
__all__ = (
|
|
46
|
+
"ExportPlan",
|
|
47
|
+
"ExportRepository",
|
|
48
|
+
"ExportResult",
|
|
49
|
+
"ExportSpec",
|
|
50
|
+
"NotebookExport",
|
|
51
|
+
"OutputSpec",
|
|
52
|
+
"PreparedExport",
|
|
53
|
+
"ProgressEvent",
|
|
54
|
+
"StateSpace",
|
|
55
|
+
"VerificationResult",
|
|
56
|
+
"build",
|
|
57
|
+
"capture",
|
|
58
|
+
"open_export",
|
|
59
|
+
"plan",
|
|
60
|
+
"prepare",
|
|
61
|
+
"verify_export",
|
|
62
|
+
)
|
|
63
|
+
|
|
64
|
+
|
|
65
|
+
def __getattr__(name: str) -> Any:
|
|
66
|
+
try:
|
|
67
|
+
module_name, attribute = _EXPORTS[name]
|
|
68
|
+
except KeyError as error:
|
|
69
|
+
raise AttributeError(f"module {__name__!r} has no attribute {name!r}") from error
|
|
70
|
+
value = getattr(import_module(module_name), attribute)
|
|
71
|
+
globals()[name] = value
|
|
72
|
+
return value
|
|
73
|
+
|
|
74
|
+
|
|
75
|
+
def __dir__() -> list[str]:
|
|
76
|
+
return sorted({*globals(), *__all__})
|
|
@@ -0,0 +1,83 @@
|
|
|
1
|
+
from __future__ import annotations
|
|
2
|
+
|
|
3
|
+
from dataclasses import dataclass
|
|
4
|
+
from typing import cast
|
|
5
|
+
|
|
6
|
+
import msgspec
|
|
7
|
+
|
|
8
|
+
from marimo_export._json import JsonObject, canonical_bytes, portable_json_object
|
|
9
|
+
from marimo_export._media_type import MAX_BLOB_METADATA_JSON_BYTES, validate_media_type
|
|
10
|
+
from marimo_export._portable import validate_portable_basename
|
|
11
|
+
|
|
12
|
+
_FIELDS = ("data", "media_type", "filename", "metadata")
|
|
13
|
+
|
|
14
|
+
|
|
15
|
+
@dataclass(frozen=True, slots=True)
|
|
16
|
+
class BlobAssetEnvelope:
|
|
17
|
+
"""The verified native marimo BlobAsset MessagePack envelope."""
|
|
18
|
+
|
|
19
|
+
data: bytes
|
|
20
|
+
media_type: str | None
|
|
21
|
+
filename: str | None
|
|
22
|
+
metadata: JsonObject
|
|
23
|
+
|
|
24
|
+
|
|
25
|
+
def decode_blob_asset(
|
|
26
|
+
data: bytes,
|
|
27
|
+
*,
|
|
28
|
+
maximum_bytes: int | None = None,
|
|
29
|
+
) -> BlobAssetEnvelope:
|
|
30
|
+
"""Strictly decode the exact MessagePack shape emitted by marimo."""
|
|
31
|
+
|
|
32
|
+
if not isinstance(data, bytes):
|
|
33
|
+
raise TypeError("BlobAsset MessagePack must be bytes")
|
|
34
|
+
if maximum_bytes is not None and (
|
|
35
|
+
not isinstance(maximum_bytes, int) or isinstance(maximum_bytes, bool) or maximum_bytes <= 0
|
|
36
|
+
):
|
|
37
|
+
raise TypeError("maximum_bytes must be a positive integer")
|
|
38
|
+
if maximum_bytes is not None and len(data) > maximum_bytes:
|
|
39
|
+
raise ValueError(f"BlobAsset MessagePack exceeds the {maximum_bytes} byte limit")
|
|
40
|
+
|
|
41
|
+
try:
|
|
42
|
+
decoded = msgspec.msgpack.decode(data)
|
|
43
|
+
except msgspec.DecodeError as error:
|
|
44
|
+
raise ValueError("BlobAsset is invalid MessagePack") from error
|
|
45
|
+
if not isinstance(decoded, dict) or tuple(decoded) != _FIELDS:
|
|
46
|
+
raise ValueError("BlobAsset does not use the native four-field envelope")
|
|
47
|
+
if msgspec.msgpack.encode(decoded) != data:
|
|
48
|
+
raise ValueError("BlobAsset MessagePack is not canonical")
|
|
49
|
+
|
|
50
|
+
payload = decoded["data"]
|
|
51
|
+
media_type = decoded["media_type"]
|
|
52
|
+
filename = decoded["filename"]
|
|
53
|
+
metadata = decoded["metadata"]
|
|
54
|
+
if not isinstance(payload, bytes):
|
|
55
|
+
raise ValueError("BlobAsset data must be bytes")
|
|
56
|
+
if media_type is not None:
|
|
57
|
+
try:
|
|
58
|
+
media_type = validate_media_type(media_type, "BlobAsset media_type")
|
|
59
|
+
except (TypeError, ValueError) as error:
|
|
60
|
+
raise ValueError("BlobAsset media_type is invalid") from error
|
|
61
|
+
if filename is not None:
|
|
62
|
+
try:
|
|
63
|
+
filename = validate_portable_basename(filename, "BlobAsset filename")
|
|
64
|
+
except (TypeError, ValueError) as error:
|
|
65
|
+
raise ValueError("BlobAsset filename is invalid") from error
|
|
66
|
+
try:
|
|
67
|
+
metadata_object = portable_json_object(metadata, "BlobAsset metadata")
|
|
68
|
+
except (TypeError, ValueError) as error:
|
|
69
|
+
raise ValueError("BlobAsset metadata must be portable JSON") from error
|
|
70
|
+
if len(canonical_bytes(metadata_object)) > MAX_BLOB_METADATA_JSON_BYTES:
|
|
71
|
+
raise ValueError(
|
|
72
|
+
f"BlobAsset metadata exceeds {MAX_BLOB_METADATA_JSON_BYTES} canonical JSON bytes"
|
|
73
|
+
)
|
|
74
|
+
|
|
75
|
+
return BlobAssetEnvelope(
|
|
76
|
+
data=payload,
|
|
77
|
+
media_type=cast(str | None, media_type),
|
|
78
|
+
filename=cast(str | None, filename),
|
|
79
|
+
metadata=metadata_object,
|
|
80
|
+
)
|
|
81
|
+
|
|
82
|
+
|
|
83
|
+
__all__ = ["BlobAssetEnvelope", "decode_blob_asset"]
|
|
@@ -0,0 +1,38 @@
|
|
|
1
|
+
from __future__ import annotations
|
|
2
|
+
|
|
3
|
+
from collections.abc import Callable
|
|
4
|
+
|
|
5
|
+
from marimo_export._delivery import preflight_export_destination
|
|
6
|
+
from marimo_export._services.prepare_export import prepare
|
|
7
|
+
from marimo_export.progress import ProgressEvent
|
|
8
|
+
from marimo_export.repository import ExportRepository
|
|
9
|
+
from marimo_export.result import ExportResult
|
|
10
|
+
from marimo_export.spec import ExportSpec, StrPath
|
|
11
|
+
|
|
12
|
+
|
|
13
|
+
def build(
|
|
14
|
+
notebook: StrPath,
|
|
15
|
+
*,
|
|
16
|
+
spec: ExportSpec,
|
|
17
|
+
output: StrPath,
|
|
18
|
+
repository: ExportRepository | None = None,
|
|
19
|
+
timeout: float = 30.0,
|
|
20
|
+
replace: bool = False,
|
|
21
|
+
progress: Callable[[ProgressEvent], None] | None = None,
|
|
22
|
+
cancelled: Callable[[], bool] | None = None,
|
|
23
|
+
) -> ExportResult:
|
|
24
|
+
"""Prepare, write, and verify one notebook export."""
|
|
25
|
+
|
|
26
|
+
preflight_export_destination(output, replace=replace)
|
|
27
|
+
with prepare(
|
|
28
|
+
notebook,
|
|
29
|
+
spec=spec,
|
|
30
|
+
repository=repository,
|
|
31
|
+
timeout=timeout,
|
|
32
|
+
progress=progress,
|
|
33
|
+
cancelled=cancelled,
|
|
34
|
+
) as prepared:
|
|
35
|
+
return prepared.write(output, replace=replace, progress=progress)
|
|
36
|
+
|
|
37
|
+
|
|
38
|
+
__all__ = ["build"]
|
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
"""Normalize Marimo cell identifiers at adapter boundaries."""
|
|
2
|
+
|
|
3
|
+
from __future__ import annotations
|
|
4
|
+
|
|
5
|
+
from uuid import UUID
|
|
6
|
+
|
|
7
|
+
_MAX_CELL_ID_BYTES = 1_024
|
|
8
|
+
_UUID_LENGTH = 36
|
|
9
|
+
|
|
10
|
+
|
|
11
|
+
def canonical_cell_id(value: object) -> str:
|
|
12
|
+
"""Remove Marimo's external UUIDv4 scope from one native cell ID."""
|
|
13
|
+
|
|
14
|
+
cell_id = str(value)
|
|
15
|
+
if not cell_id or len(cell_id.encode("utf-8")) > _MAX_CELL_ID_BYTES:
|
|
16
|
+
raise ValueError("cell ID must be a bounded non-empty string")
|
|
17
|
+
if len(cell_id) <= _UUID_LENGTH:
|
|
18
|
+
return cell_id
|
|
19
|
+
prefix = cell_id[:_UUID_LENGTH]
|
|
20
|
+
suffix = cell_id[_UUID_LENGTH:]
|
|
21
|
+
try:
|
|
22
|
+
external = UUID(prefix, version=4)
|
|
23
|
+
except ValueError:
|
|
24
|
+
return cell_id
|
|
25
|
+
return suffix if suffix and str(external) == prefix else cell_id
|
|
26
|
+
|
|
27
|
+
|
|
28
|
+
__all__ = ["canonical_cell_id"]
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
"""Command-line parsing, delegation, rendering, and failure policy."""
|