marimo-export 0.0.3__tar.gz → 0.0.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.
- {marimo_export-0.0.3 → marimo_export-0.0.4}/.agent-plugin/skills/notebook-to-static-app/scripts/scaffold_app.py +1 -1
- {marimo_export-0.0.3 → marimo_export-0.0.4}/PKG-INFO +1 -1
- {marimo_export-0.0.3 → marimo_export-0.0.4}/pyproject.toml +1 -1
- {marimo_export-0.0.3 → marimo_export-0.0.4}/pyproject.toml.orig +1 -1
- marimo_export-0.0.3/src/marimo_export/_services/identity.py → marimo_export-0.0.4/src/marimo_export/_environment.py +19 -200
- {marimo_export-0.0.3 → marimo_export-0.0.4}/src/marimo_export/_marimo/compat/cache/attempts.py +59 -2
- {marimo_export-0.0.3 → marimo_export-0.0.4}/src/marimo_export/_marimo/compat/cache/lifecycle.py +3 -0
- {marimo_export-0.0.3 → marimo_export-0.0.4}/src/marimo_export/_marimo/compat/cache/patch.py +11 -2
- {marimo_export-0.0.3 → marimo_export-0.0.4}/src/marimo_export/_marimo/compat/cache/probe.py +2 -0
- {marimo_export-0.0.3 → marimo_export-0.0.4}/src/marimo_export/_marimo/compat/execution.py +10 -0
- {marimo_export-0.0.3 → marimo_export-0.0.4}/src/marimo_export/_marimo/compat/managed_kernel.py +6 -4
- {marimo_export-0.0.3 → marimo_export-0.0.4}/src/marimo_export/_marimo/compat/release.json +6 -5
- {marimo_export-0.0.3 → marimo_export-0.0.4}/src/marimo_export/_publication.py +13 -6
- {marimo_export-0.0.3 → marimo_export-0.0.4}/src/marimo_export/_repository/observations.py +29 -19
- {marimo_export-0.0.3 → marimo_export-0.0.4}/src/marimo_export/_repository/preparation.py +33 -24
- {marimo_export-0.0.3 → marimo_export-0.0.4}/src/marimo_export/_services/export_artifacts.py +9 -13
- marimo_export-0.0.4/src/marimo_export/_services/identity.py +206 -0
- {marimo_export-0.0.3 → marimo_export-0.0.4}/src/marimo_export/prepared.py +18 -2
- {marimo_export-0.0.3 → marimo_export-0.0.4}/src/marimo_export/repository.py +11 -2
- {marimo_export-0.0.3 → marimo_export-0.0.4}/.agent-plugin/plugin.json +0 -0
- {marimo_export-0.0.3 → marimo_export-0.0.4}/.agent-plugin/skills/notebook-to-static-app/SKILL.md +0 -0
- {marimo_export-0.0.3 → marimo_export-0.0.4}/.agent-plugin/skills/notebook-to-static-app/agents/openai.yaml +0 -0
- {marimo_export-0.0.3 → marimo_export-0.0.4}/.agent-plugin/skills/notebook-to-static-app/assets/app/.gitignore +0 -0
- {marimo_export-0.0.3 → marimo_export-0.0.4}/.agent-plugin/skills/notebook-to-static-app/assets/app/index.html +0 -0
- {marimo_export-0.0.3 → marimo_export-0.0.4}/.agent-plugin/skills/notebook-to-static-app/assets/app/pnpm-workspace.yaml +0 -0
- {marimo_export-0.0.3 → marimo_export-0.0.4}/.agent-plugin/skills/notebook-to-static-app/assets/app/src/main.ts +0 -0
- {marimo_export-0.0.3 → marimo_export-0.0.4}/.agent-plugin/skills/notebook-to-static-app/assets/app/src/style.css +0 -0
- {marimo_export-0.0.3 → marimo_export-0.0.4}/.agent-plugin/skills/notebook-to-static-app/assets/app/src/vite-env.d.ts +0 -0
- {marimo_export-0.0.3 → marimo_export-0.0.4}/.agent-plugin/skills/notebook-to-static-app/assets/app/tsconfig.json +0 -0
- {marimo_export-0.0.3 → marimo_export-0.0.4}/.agent-plugin/skills/notebook-to-static-app/assets/app/vite.config.ts +0 -0
- {marimo_export-0.0.3 → marimo_export-0.0.4}/.agent-plugin/skills/notebook-to-static-app/references/contracts.md +0 -0
- {marimo_export-0.0.3 → marimo_export-0.0.4}/.agent-plugin/skills/notebook-to-static-app/references/workflow.md +0 -0
- {marimo_export-0.0.3 → marimo_export-0.0.4}/LICENSE +0 -0
- {marimo_export-0.0.3 → marimo_export-0.0.4}/README.md +0 -0
- {marimo_export-0.0.3 → marimo_export-0.0.4}/src/marimo_export/__init__.py +0 -0
- {marimo_export-0.0.3 → marimo_export-0.0.4}/src/marimo_export/_blob_asset.py +0 -0
- {marimo_export-0.0.3 → marimo_export-0.0.4}/src/marimo_export/_build.py +0 -0
- {marimo_export-0.0.3 → marimo_export-0.0.4}/src/marimo_export/_cell_ids.py +0 -0
- {marimo_export-0.0.3 → marimo_export-0.0.4}/src/marimo_export/_cli/__init__.py +0 -0
- {marimo_export-0.0.3 → marimo_export-0.0.4}/src/marimo_export/_cli/arguments.py +0 -0
- {marimo_export-0.0.3 → marimo_export-0.0.4}/src/marimo_export/_cli/commands.py +0 -0
- {marimo_export-0.0.3 → marimo_export-0.0.4}/src/marimo_export/_cli/errors.py +0 -0
- {marimo_export-0.0.3 → marimo_export-0.0.4}/src/marimo_export/_cli/render.py +0 -0
- {marimo_export-0.0.3 → marimo_export-0.0.4}/src/marimo_export/_client_protocol.py +0 -0
- {marimo_export-0.0.3 → marimo_export-0.0.4}/src/marimo_export/_control_roots.py +0 -0
- {marimo_export-0.0.3 → marimo_export-0.0.4}/src/marimo_export/_delivery.py +0 -0
- {marimo_export-0.0.3 → marimo_export-0.0.4}/src/marimo_export/_delivery_validation.py +0 -0
- {marimo_export-0.0.3 → marimo_export-0.0.4}/src/marimo_export/_diagnostics.py +0 -0
- {marimo_export-0.0.3 → marimo_export-0.0.4}/src/marimo_export/_directory.py +0 -0
- {marimo_export-0.0.3 → marimo_export-0.0.4}/src/marimo_export/_directory_native.py +0 -0
- {marimo_export-0.0.3 → marimo_export-0.0.4}/src/marimo_export/_directory_security.py +0 -0
- {marimo_export-0.0.3 → marimo_export-0.0.4}/src/marimo_export/_directory_target.py +0 -0
- {marimo_export-0.0.3 → marimo_export-0.0.4}/src/marimo_export/_execution/__init__.py +0 -0
- {marimo_export-0.0.3 → marimo_export-0.0.4}/src/marimo_export/_execution/plan.py +0 -0
- {marimo_export-0.0.3 → marimo_export-0.0.4}/src/marimo_export/_format.py +0 -0
- {marimo_export-0.0.3 → marimo_export-0.0.4}/src/marimo_export/_http_url.py +0 -0
- {marimo_export-0.0.3 → marimo_export-0.0.4}/src/marimo_export/_identity.py +0 -0
- {marimo_export-0.0.3 → marimo_export-0.0.4}/src/marimo_export/_json.py +0 -0
- {marimo_export-0.0.3 → marimo_export-0.0.4}/src/marimo_export/_limits.py +0 -0
- {marimo_export-0.0.3 → marimo_export-0.0.4}/src/marimo_export/_marimo/__init__.py +0 -0
- {marimo_export-0.0.3 → marimo_export-0.0.4}/src/marimo_export/_marimo/anywidget.py +0 -0
- {marimo_export-0.0.3 → marimo_export-0.0.4}/src/marimo_export/_marimo/blob.py +0 -0
- {marimo_export-0.0.3 → marimo_export-0.0.4}/src/marimo_export/_marimo/bridge.py +0 -0
- {marimo_export-0.0.3 → marimo_export-0.0.4}/src/marimo_export/_marimo/capabilities.py +0 -0
- {marimo_export-0.0.3 → marimo_export-0.0.4}/src/marimo_export/_marimo/compat/__init__.py +0 -0
- {marimo_export-0.0.3 → marimo_export-0.0.4}/src/marimo_export/_marimo/compat/anywidget.py +0 -0
- {marimo_export-0.0.3 → marimo_export-0.0.4}/src/marimo_export/_marimo/compat/anywidget_assets.py +0 -0
- {marimo_export-0.0.3 → marimo_export-0.0.4}/src/marimo_export/_marimo/compat/blob.py +0 -0
- {marimo_export-0.0.3 → marimo_export-0.0.4}/src/marimo_export/_marimo/compat/cache/__init__.py +0 -0
- {marimo_export-0.0.3 → marimo_export-0.0.4}/src/marimo_export/_marimo/compat/cache/barrier.py +0 -0
- {marimo_export-0.0.3 → marimo_export-0.0.4}/src/marimo_export/_marimo/compat/cache/host.py +0 -0
- {marimo_export-0.0.3 → marimo_export-0.0.4}/src/marimo_export/_marimo/compat/cache/loader.py +0 -0
- {marimo_export-0.0.3 → marimo_export-0.0.4}/src/marimo_export/_marimo/compat/cache/receipts.py +0 -0
- {marimo_export-0.0.3 → marimo_export-0.0.4}/src/marimo_export/_marimo/compat/child_run.py +0 -0
- {marimo_export-0.0.3 → marimo_export-0.0.4}/src/marimo_export/_marimo/compat/exporter_identity.py +0 -0
- {marimo_export-0.0.3 → marimo_export-0.0.4}/src/marimo_export/_marimo/compat/exporters.py +0 -0
- {marimo_export-0.0.3 → marimo_export-0.0.4}/src/marimo_export/_marimo/compat/file_closure.py +0 -0
- {marimo_export-0.0.3 → marimo_export-0.0.4}/src/marimo_export/_marimo/compat/inspection.py +0 -0
- {marimo_export-0.0.3 → marimo_export-0.0.4}/src/marimo_export/_marimo/compat/kernel.py +0 -0
- {marimo_export-0.0.3 → marimo_export-0.0.4}/src/marimo_export/_marimo/compat/managed_server.py +0 -0
- {marimo_export-0.0.3 → marimo_export-0.0.4}/src/marimo_export/_marimo/compat/observations.py +0 -0
- {marimo_export-0.0.3 → marimo_export-0.0.4}/src/marimo_export/_marimo/compat/output_data.py +0 -0
- {marimo_export-0.0.3 → marimo_export-0.0.4}/src/marimo_export/_marimo/compat/projections.py +0 -0
- {marimo_export-0.0.3 → marimo_export-0.0.4}/src/marimo_export/_marimo/compat/receipts.py +0 -0
- {marimo_export-0.0.3 → marimo_export-0.0.4}/src/marimo_export/_marimo/compat/replay.py +0 -0
- {marimo_export-0.0.3 → marimo_export-0.0.4}/src/marimo_export/_marimo/compat/transfer.py +0 -0
- {marimo_export-0.0.3 → marimo_export-0.0.4}/src/marimo_export/_marimo/composition.py +0 -0
- {marimo_export-0.0.3 → marimo_export-0.0.4}/src/marimo_export/_marimo/entrypoints.py +0 -0
- {marimo_export-0.0.3 → marimo_export-0.0.4}/src/marimo_export/_marimo/managed_server.py +0 -0
- {marimo_export-0.0.3 → marimo_export-0.0.4}/src/marimo_export/_marimo/transfer.py +0 -0
- {marimo_export-0.0.3 → marimo_export-0.0.4}/src/marimo_export/_media_type.py +0 -0
- {marimo_export-0.0.3 → marimo_export-0.0.4}/src/marimo_export/_notebook.py +0 -0
- {marimo_export-0.0.3 → marimo_export-0.0.4}/src/marimo_export/_observations/__init__.py +0 -0
- {marimo_export-0.0.3 → marimo_export-0.0.4}/src/marimo_export/_observations/candidates.py +0 -0
- {marimo_export-0.0.3 → marimo_export-0.0.4}/src/marimo_export/_observations/ledger.py +0 -0
- {marimo_export-0.0.3 → marimo_export-0.0.4}/src/marimo_export/_observations/queue.py +0 -0
- {marimo_export-0.0.3 → marimo_export-0.0.4}/src/marimo_export/_observations/source.py +0 -0
- {marimo_export-0.0.3 → marimo_export-0.0.4}/src/marimo_export/_portable.py +0 -0
- {marimo_export-0.0.3 → marimo_export-0.0.4}/src/marimo_export/_prepared_integrity.py +0 -0
- {marimo_export-0.0.3 → marimo_export-0.0.4}/src/marimo_export/_remote/__init__.py +0 -0
- {marimo_export-0.0.3 → marimo_export-0.0.4}/src/marimo_export/_remote/auth.py +0 -0
- {marimo_export-0.0.3 → marimo_export-0.0.4}/src/marimo_export/_remote/client.py +0 -0
- {marimo_export-0.0.3 → marimo_export-0.0.4}/src/marimo_export/_remote/managed.py +0 -0
- {marimo_export-0.0.3 → marimo_export-0.0.4}/src/marimo_export/_remote/sse.py +0 -0
- {marimo_export-0.0.3 → marimo_export-0.0.4}/src/marimo_export/_remote/windows_job.py +0 -0
- {marimo_export-0.0.3 → marimo_export-0.0.4}/src/marimo_export/_repository/__init__.py +0 -0
- {marimo_export-0.0.3 → marimo_export-0.0.4}/src/marimo_export/_repository/artifact_access.py +0 -0
- {marimo_export-0.0.3 → marimo_export-0.0.4}/src/marimo_export/_repository/artifact_commit.py +0 -0
- {marimo_export-0.0.3 → marimo_export-0.0.4}/src/marimo_export/_repository/artifact_context.py +0 -0
- {marimo_export-0.0.3 → marimo_export-0.0.4}/src/marimo_export/_repository/artifact_lifecycle.py +0 -0
- {marimo_export-0.0.3 → marimo_export-0.0.4}/src/marimo_export/_repository/artifacts.py +0 -0
- {marimo_export-0.0.3 → marimo_export-0.0.4}/src/marimo_export/_repository/capabilities.py +0 -0
- {marimo_export-0.0.3 → marimo_export-0.0.4}/src/marimo_export/_repository/files.py +0 -0
- {marimo_export-0.0.3 → marimo_export-0.0.4}/src/marimo_export/_repository/handles.py +0 -0
- {marimo_export-0.0.3 → marimo_export-0.0.4}/src/marimo_export/_repository/leases.py +0 -0
- {marimo_export-0.0.3 → marimo_export-0.0.4}/src/marimo_export/_repository/models.py +0 -0
- {marimo_export-0.0.3 → marimo_export-0.0.4}/src/marimo_export/_repository/paths.py +0 -0
- {marimo_export-0.0.3 → marimo_export-0.0.4}/src/marimo_export/_repository/sqlite/__init__.py +0 -0
- {marimo_export-0.0.3 → marimo_export-0.0.4}/src/marimo_export/_repository/sqlite/artifacts.py +0 -0
- {marimo_export-0.0.3 → marimo_export-0.0.4}/src/marimo_export/_repository/sqlite/catalog.py +0 -0
- {marimo_export-0.0.3 → marimo_export-0.0.4}/src/marimo_export/_repository/sqlite/generations.py +0 -0
- {marimo_export-0.0.3 → marimo_export-0.0.4}/src/marimo_export/_repository/sqlite/leases.py +0 -0
- {marimo_export-0.0.3 → marimo_export-0.0.4}/src/marimo_export/_repository/sqlite/maintenance.py +0 -0
- {marimo_export-0.0.3 → marimo_export-0.0.4}/src/marimo_export/_repository/sqlite/observations.py +0 -0
- {marimo_export-0.0.3 → marimo_export-0.0.4}/src/marimo_export/_repository/sqlite/open.py +0 -0
- {marimo_export-0.0.3 → marimo_export-0.0.4}/src/marimo_export/_repository/sqlite/prepared_states.py +0 -0
- {marimo_export-0.0.3 → marimo_export-0.0.4}/src/marimo_export/_repository/sqlite/records.py +0 -0
- {marimo_export-0.0.3 → marimo_export-0.0.4}/src/marimo_export/_repository/sqlite/recovery.py +0 -0
- {marimo_export-0.0.3 → marimo_export-0.0.4}/src/marimo_export/_repository/sqlite/retention.py +0 -0
- {marimo_export-0.0.3 → marimo_export-0.0.4}/src/marimo_export/_repository/sqlite/retired.py +0 -0
- {marimo_export-0.0.3 → marimo_export-0.0.4}/src/marimo_export/_repository/sqlite/schema.py +0 -0
- {marimo_export-0.0.3 → marimo_export-0.0.4}/src/marimo_export/_repository/sqlite/status.py +0 -0
- {marimo_export-0.0.3 → marimo_export-0.0.4}/src/marimo_export/_secure_io.py +0 -0
- {marimo_export-0.0.3 → marimo_export-0.0.4}/src/marimo_export/_selector.py +0 -0
- {marimo_export-0.0.3 → marimo_export-0.0.4}/src/marimo_export/_services/__init__.py +0 -0
- {marimo_export-0.0.3 → marimo_export-0.0.4}/src/marimo_export/_services/capture_export.py +0 -0
- {marimo_export-0.0.3 → marimo_export-0.0.4}/src/marimo_export/_services/plan_export.py +0 -0
- {marimo_export-0.0.3 → marimo_export-0.0.4}/src/marimo_export/_services/plan_wire.py +0 -0
- {marimo_export-0.0.3 → marimo_export-0.0.4}/src/marimo_export/_services/preparation_support.py +0 -0
- {marimo_export-0.0.3 → marimo_export-0.0.4}/src/marimo_export/_services/prepare_export.py +0 -0
- {marimo_export-0.0.3 → marimo_export-0.0.4}/src/marimo_export/_services/state_preparation.py +0 -0
- {marimo_export-0.0.3 → marimo_export-0.0.4}/src/marimo_export/_services/write_export.py +0 -0
- {marimo_export-0.0.3 → marimo_export-0.0.4}/src/marimo_export/_snapshot.py +0 -0
- {marimo_export-0.0.3 → marimo_export-0.0.4}/src/marimo_export/_writer.py +0 -0
- {marimo_export-0.0.3 → marimo_export-0.0.4}/src/marimo_export/agent.py +0 -0
- {marimo_export-0.0.3 → marimo_export-0.0.4}/src/marimo_export/cli.py +0 -0
- {marimo_export-0.0.3 → marimo_export-0.0.4}/src/marimo_export/client.py +0 -0
- {marimo_export-0.0.3 → marimo_export-0.0.4}/src/marimo_export/delivery.py +0 -0
- {marimo_export-0.0.3 → marimo_export-0.0.4}/src/marimo_export/descriptors.py +0 -0
- {marimo_export-0.0.3 → marimo_export-0.0.4}/src/marimo_export/diagnostics.py +0 -0
- {marimo_export-0.0.3 → marimo_export-0.0.4}/src/marimo_export/errors.py +0 -0
- {marimo_export-0.0.3 → marimo_export-0.0.4}/src/marimo_export/exporters/__init__.py +0 -0
- {marimo_export-0.0.3 → marimo_export-0.0.4}/src/marimo_export/exporters/_anywidget_payload.py +0 -0
- {marimo_export-0.0.3 → marimo_export-0.0.4}/src/marimo_export/exporters/_definitions.py +0 -0
- {marimo_export-0.0.3 → marimo_export-0.0.4}/src/marimo_export/exporters/_optional.py +0 -0
- {marimo_export-0.0.3 → marimo_export-0.0.4}/src/marimo_export/exporters/_runtime/__init__.py +0 -0
- {marimo_export-0.0.3 → marimo_export-0.0.4}/src/marimo_export/exporters/_runtime/altair.py +0 -0
- {marimo_export-0.0.3 → marimo_export-0.0.4}/src/marimo_export/exporters/_runtime/anywidget.py +0 -0
- {marimo_export-0.0.3 → marimo_export-0.0.4}/src/marimo_export/exporters/_runtime/blob.py +0 -0
- {marimo_export-0.0.3 → marimo_export-0.0.4}/src/marimo_export/exporters/_runtime/parquet.py +0 -0
- {marimo_export-0.0.3 → marimo_export-0.0.4}/src/marimo_export/exporters/_spec.py +0 -0
- {marimo_export-0.0.3 → marimo_export-0.0.4}/src/marimo_export/exporters/altair.py +0 -0
- {marimo_export-0.0.3 → marimo_export-0.0.4}/src/marimo_export/exporters/anywidget.py +0 -0
- {marimo_export-0.0.3 → marimo_export-0.0.4}/src/marimo_export/exporters/blob.py +0 -0
- {marimo_export-0.0.3 → marimo_export-0.0.4}/src/marimo_export/exporters/parquet.py +0 -0
- {marimo_export-0.0.3 → marimo_export-0.0.4}/src/marimo_export/index.py +0 -0
- {marimo_export-0.0.3 → marimo_export-0.0.4}/src/marimo_export/inspection.py +0 -0
- {marimo_export-0.0.3 → marimo_export-0.0.4}/src/marimo_export/integration.py +0 -0
- {marimo_export-0.0.3 → marimo_export-0.0.4}/src/marimo_export/limits.py +0 -0
- {marimo_export-0.0.3 → marimo_export-0.0.4}/src/marimo_export/manifest.py +0 -0
- {marimo_export-0.0.3 → marimo_export-0.0.4}/src/marimo_export/observations.py +0 -0
- {marimo_export-0.0.3 → marimo_export-0.0.4}/src/marimo_export/outputs.py +0 -0
- {marimo_export-0.0.3 → marimo_export-0.0.4}/src/marimo_export/planning.py +0 -0
- {marimo_export-0.0.3 → marimo_export-0.0.4}/src/marimo_export/producer.py +0 -0
- {marimo_export-0.0.3 → marimo_export-0.0.4}/src/marimo_export/progress.py +0 -0
- {marimo_export-0.0.3 → marimo_export-0.0.4}/src/marimo_export/publication.py +0 -0
- {marimo_export-0.0.3 → marimo_export-0.0.4}/src/marimo_export/py.typed +0 -0
- {marimo_export-0.0.3 → marimo_export-0.0.4}/src/marimo_export/reader.py +0 -0
- {marimo_export-0.0.3 → marimo_export-0.0.4}/src/marimo_export/result.py +0 -0
- {marimo_export-0.0.3 → marimo_export-0.0.4}/src/marimo_export/sessions.py +0 -0
- {marimo_export-0.0.3 → marimo_export-0.0.4}/src/marimo_export/spec.py +0 -0
- {marimo_export-0.0.3 → marimo_export-0.0.4}/src/marimo_export/verification.py +0 -0
- {marimo_export-0.0.3 → marimo_export-0.0.4}/src/marimo_export/wire.py +0 -0
|
@@ -380,7 +380,7 @@ def _write_package_json(
|
|
|
380
380
|
"vite-plus": "0.3.0",
|
|
381
381
|
},
|
|
382
382
|
"engines": {"node": ">=22.18.0"},
|
|
383
|
-
"packageManager": "pnpm@
|
|
383
|
+
"packageManager": "pnpm@12.3.4",
|
|
384
384
|
}
|
|
385
385
|
path.write_text(json.dumps(value, indent=2) + "\n", encoding="utf-8")
|
|
386
386
|
|
|
@@ -7,7 +7,7 @@ build-backend = "agent_plugins.build.uv_build"
|
|
|
7
7
|
|
|
8
8
|
[project]
|
|
9
9
|
name = "marimo-export"
|
|
10
|
-
version = "0.0.
|
|
10
|
+
version = "0.0.4"
|
|
11
11
|
description = "Prepare and read verified exports of selected marimo notebook outputs."
|
|
12
12
|
readme = "README.md"
|
|
13
13
|
license = "Apache-2.0"
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
"""
|
|
1
|
+
"""Fingerprint installed distributions and local runtime dependencies."""
|
|
2
2
|
|
|
3
3
|
from __future__ import annotations
|
|
4
4
|
|
|
@@ -7,185 +7,18 @@ import hashlib
|
|
|
7
7
|
import importlib.metadata
|
|
8
8
|
import importlib.util
|
|
9
9
|
import os
|
|
10
|
-
import platform
|
|
11
|
-
import stat
|
|
12
10
|
import sys
|
|
13
|
-
from dataclasses import dataclass
|
|
14
11
|
from pathlib import Path
|
|
15
12
|
from typing import Any
|
|
16
13
|
|
|
17
|
-
from marimo_export._format import digest
|
|
18
|
-
from marimo_export._identity import require_implementation_stable
|
|
19
14
|
from marimo_export._json import JsonObject, canonical_bytes, sha256_bytes
|
|
20
|
-
from marimo_export._notebook import _notebook_path, _read_stable_source, document_sha256
|
|
21
|
-
from marimo_export._portable import validate_portable_basename
|
|
22
|
-
from marimo_export.errors import CompatibilityError, ExecutionError
|
|
23
|
-
from marimo_export.index import ProducerProvenance
|
|
24
|
-
from marimo_export.spec import StrPath
|
|
25
15
|
|
|
26
16
|
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
"""Stable producer facts used for repository reuse and export provenance."""
|
|
17
|
+
def environment_identity(source: Path | None, *, exclude_source: bool = False) -> str:
|
|
18
|
+
"""Hash stable runtime dependencies, optionally leaving notebook code to Marimo."""
|
|
30
19
|
|
|
31
|
-
source: Path | None
|
|
32
|
-
filename: str | None
|
|
33
|
-
source_sha256: str
|
|
34
|
-
document_sha256: str
|
|
35
|
-
producer_sha256: str
|
|
36
|
-
marimo_version: str
|
|
37
|
-
marimo_export_version: str
|
|
38
|
-
implementation_sha256: str
|
|
39
|
-
environment_sha256: str
|
|
40
|
-
|
|
41
|
-
def __post_init__(self) -> None:
|
|
42
|
-
if self.source is not None:
|
|
43
|
-
if not isinstance(self.source, Path) or not self.source.is_absolute():
|
|
44
|
-
raise ValueError("producer source must be an absolute pathlib.Path or None")
|
|
45
|
-
try:
|
|
46
|
-
metadata = self.source.lstat()
|
|
47
|
-
except OSError as error:
|
|
48
|
-
raise ValueError("producer source must be available") from error
|
|
49
|
-
if not stat.S_ISREG(metadata.st_mode):
|
|
50
|
-
raise ValueError("producer source must be a regular file")
|
|
51
|
-
if self.filename != self.source.name:
|
|
52
|
-
raise ValueError("producer filename must match its source basename")
|
|
53
|
-
if self.filename is not None:
|
|
54
|
-
validate_portable_basename(self.filename, "producer filename")
|
|
55
|
-
for name in (
|
|
56
|
-
"source_sha256",
|
|
57
|
-
"document_sha256",
|
|
58
|
-
"producer_sha256",
|
|
59
|
-
"implementation_sha256",
|
|
60
|
-
"environment_sha256",
|
|
61
|
-
):
|
|
62
|
-
digest(getattr(self, name), f"producer {name}")
|
|
63
|
-
for name in ("marimo_version", "marimo_export_version"):
|
|
64
|
-
value = getattr(self, name)
|
|
65
|
-
if (
|
|
66
|
-
not isinstance(value, str)
|
|
67
|
-
or not value
|
|
68
|
-
or len(value.encode("utf-8")) > 255
|
|
69
|
-
or any(ord(character) < 32 or ord(character) == 127 for character in value)
|
|
70
|
-
):
|
|
71
|
-
raise ValueError(f"producer {name} must be a bounded nonempty string")
|
|
72
|
-
|
|
73
|
-
@property
|
|
74
|
-
def provenance(self) -> ProducerProvenance:
|
|
75
|
-
return ProducerProvenance(
|
|
76
|
-
marimo=self.marimo_version,
|
|
77
|
-
marimo_export=self.marimo_export_version,
|
|
78
|
-
implementation_sha256=self.implementation_sha256,
|
|
79
|
-
)
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
def producer_identity(source: StrPath) -> ProducerIdentity:
|
|
83
|
-
"""Return exact source and runtime identity without executing notebook code."""
|
|
84
|
-
|
|
85
|
-
notebook = _notebook_path(source)
|
|
86
|
-
_, source_sha256, source_revision = _read_stable_source(notebook)
|
|
87
|
-
document = document_sha256(notebook)
|
|
88
|
-
_, after_sha256, after_revision = _read_stable_source(notebook)
|
|
89
|
-
if after_sha256 != source_sha256 or after_revision != source_revision:
|
|
90
|
-
raise RuntimeError("notebook source changed while producer identity was computed")
|
|
91
|
-
|
|
92
|
-
return _identity_from_facts(
|
|
93
|
-
document_sha256=document,
|
|
94
|
-
source_sha256=source_sha256,
|
|
95
|
-
source=notebook,
|
|
96
|
-
filename=notebook.name,
|
|
97
|
-
)
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
def runtime_producer_identity(
|
|
101
|
-
*,
|
|
102
|
-
document_sha256: str,
|
|
103
|
-
source: StrPath | None = None,
|
|
104
|
-
source_sha256: str | None = None,
|
|
105
|
-
filename: str | None = None,
|
|
106
|
-
) -> ProducerIdentity:
|
|
107
|
-
"""Return producer identity from runtime facts available inside a kernel."""
|
|
108
|
-
|
|
109
|
-
if source is not None:
|
|
110
|
-
stable = producer_identity(source)
|
|
111
|
-
if stable.document_sha256 != document_sha256:
|
|
112
|
-
raise ExecutionError(
|
|
113
|
-
"the runtime source does not match the inspected notebook document",
|
|
114
|
-
code="parent_document_changed",
|
|
115
|
-
details={
|
|
116
|
-
"expected": document_sha256,
|
|
117
|
-
"actual": stable.document_sha256,
|
|
118
|
-
},
|
|
119
|
-
)
|
|
120
|
-
return stable
|
|
121
|
-
return _identity_from_facts(
|
|
122
|
-
document_sha256=document_sha256,
|
|
123
|
-
source_sha256=document_sha256 if source_sha256 is None else source_sha256,
|
|
124
|
-
source=None,
|
|
125
|
-
filename=filename,
|
|
126
|
-
)
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
def _identity_from_facts(
|
|
130
|
-
*,
|
|
131
|
-
document_sha256: str,
|
|
132
|
-
source_sha256: str,
|
|
133
|
-
source: Path | None,
|
|
134
|
-
filename: str | None,
|
|
135
|
-
) -> ProducerIdentity:
|
|
136
|
-
marimo_version = _required_distribution_version("marimo")
|
|
137
|
-
export_version = _distribution_version("marimo-export", fallback="0.0.0")
|
|
138
|
-
implementation = require_implementation_stable()
|
|
139
|
-
environment = _environment_identity(source)
|
|
140
|
-
producer = sha256_bytes(
|
|
141
|
-
canonical_bytes(
|
|
142
|
-
{
|
|
143
|
-
"document_sha256": document_sha256,
|
|
144
|
-
"environment_sha256": environment,
|
|
145
|
-
"implementation_sha256": implementation,
|
|
146
|
-
"marimo": marimo_version,
|
|
147
|
-
"marimo_export": export_version,
|
|
148
|
-
"platform": {
|
|
149
|
-
"machine": platform.machine(),
|
|
150
|
-
"system": platform.system(),
|
|
151
|
-
},
|
|
152
|
-
"python": {
|
|
153
|
-
"abi": sys.implementation.cache_tag or "unknown",
|
|
154
|
-
"implementation": sys.implementation.name,
|
|
155
|
-
"version": platform.python_version(),
|
|
156
|
-
},
|
|
157
|
-
"source_sha256": source_sha256,
|
|
158
|
-
}
|
|
159
|
-
)
|
|
160
|
-
)
|
|
161
|
-
return ProducerIdentity(
|
|
162
|
-
source=source,
|
|
163
|
-
filename=filename,
|
|
164
|
-
source_sha256=source_sha256,
|
|
165
|
-
document_sha256=document_sha256,
|
|
166
|
-
producer_sha256=producer,
|
|
167
|
-
marimo_version=marimo_version,
|
|
168
|
-
marimo_export_version=export_version,
|
|
169
|
-
implementation_sha256=implementation,
|
|
170
|
-
environment_sha256=environment,
|
|
171
|
-
)
|
|
172
|
-
|
|
173
|
-
|
|
174
|
-
def producer_sha256(source: StrPath) -> str:
|
|
175
|
-
"""Return the spec-independent producer identity for one notebook source."""
|
|
176
|
-
|
|
177
|
-
return producer_identity(source).producer_sha256
|
|
178
|
-
|
|
179
|
-
|
|
180
|
-
def managed_runtime_source(runtime_path: str | None) -> str | None:
|
|
181
|
-
"""Return the authored source path selected for an attached runtime."""
|
|
182
|
-
|
|
183
|
-
return os.environ.get("MARIMO_EXPORT_MANAGED_SOURCE") or runtime_path
|
|
184
|
-
|
|
185
|
-
|
|
186
|
-
def _environment_identity(source: Path | None) -> str:
|
|
187
20
|
distributions = _installed_distributions()
|
|
188
|
-
sources = {} if source is None else _local_source_record(source)
|
|
21
|
+
sources = {} if source is None else _local_source_record(source, exclude_source=exclude_source)
|
|
189
22
|
if _installed_distributions() != distributions:
|
|
190
23
|
raise RuntimeError("installed distributions changed while identity was computed")
|
|
191
24
|
return sha256_bytes(
|
|
@@ -214,16 +47,20 @@ def _installed_distributions() -> list[JsonObject]:
|
|
|
214
47
|
return distributions
|
|
215
48
|
|
|
216
49
|
|
|
217
|
-
def _local_source_record(source: Path) -> JsonObject:
|
|
50
|
+
def _local_source_record(source: Path, *, exclude_source: bool = False) -> JsonObject:
|
|
218
51
|
try:
|
|
219
52
|
resolved = source.resolve(strict=True)
|
|
220
53
|
root, search_roots = _local_source_roots(resolved)
|
|
221
54
|
before = _local_source_manifest(root, search_roots)
|
|
55
|
+
if exclude_source:
|
|
56
|
+
before = tuple(row for row in before if root / row[0] != resolved)
|
|
222
57
|
records: JsonObject = {}
|
|
223
58
|
for relative, *_revision_parts in before:
|
|
224
59
|
records[relative] = _stable_file_sha256(root / relative)
|
|
225
60
|
after_root, after_search_roots = _local_source_roots(resolved)
|
|
226
61
|
after = _local_source_manifest(root, search_roots)
|
|
62
|
+
if exclude_source:
|
|
63
|
+
after = tuple(row for row in after if root / row[0] != resolved)
|
|
227
64
|
after_records = {
|
|
228
65
|
relative: _stable_file_sha256(root / relative) for relative, *_revision_parts in after
|
|
229
66
|
}
|
|
@@ -249,7 +86,7 @@ def _local_source_manifest(
|
|
|
249
86
|
paths: set[Path] = set()
|
|
250
87
|
for search_root in selected:
|
|
251
88
|
if search_root.is_file():
|
|
252
|
-
if _source_file(search_root) and not _excluded_source(search_root,
|
|
89
|
+
if _source_file(search_root) and not _excluded_source(search_root, search_root.parent):
|
|
253
90
|
paths.add(search_root)
|
|
254
91
|
continue
|
|
255
92
|
if not search_root.is_dir() or search_root.is_symlink():
|
|
@@ -259,12 +96,12 @@ def _local_source_manifest(
|
|
|
259
96
|
directories[:] = [
|
|
260
97
|
name
|
|
261
98
|
for name in sorted(directories)
|
|
262
|
-
if not _excluded_source(current_path / name,
|
|
99
|
+
if not _excluded_source(current_path / name, search_root)
|
|
263
100
|
and not (current_path / name).is_symlink()
|
|
264
101
|
]
|
|
265
102
|
for name in sorted(filenames):
|
|
266
103
|
path = current_path / name
|
|
267
|
-
if _source_file(path) and not _excluded_source(path,
|
|
104
|
+
if _source_file(path) and not _excluded_source(path, search_root):
|
|
268
105
|
paths.add(path)
|
|
269
106
|
return tuple(
|
|
270
107
|
(
|
|
@@ -301,7 +138,12 @@ def _local_source_roots(source: Path) -> tuple[Path, tuple[Path, ...]]:
|
|
|
301
138
|
if not base.is_dir() or base.is_symlink():
|
|
302
139
|
continue
|
|
303
140
|
for child in base.iterdir():
|
|
304
|
-
if
|
|
141
|
+
if (
|
|
142
|
+
child.is_dir()
|
|
143
|
+
and not child.is_symlink()
|
|
144
|
+
and not _excluded_source(child, base)
|
|
145
|
+
and (child / "__init__.py").is_file()
|
|
146
|
+
):
|
|
305
147
|
roots.add(child)
|
|
306
148
|
for name in names:
|
|
307
149
|
module = base / f"{name}.py"
|
|
@@ -400,27 +242,4 @@ def _revision(value: Any) -> tuple[int, int, int, int, int]:
|
|
|
400
242
|
)
|
|
401
243
|
|
|
402
244
|
|
|
403
|
-
|
|
404
|
-
try:
|
|
405
|
-
return importlib.metadata.version(name)
|
|
406
|
-
except importlib.metadata.PackageNotFoundError as error:
|
|
407
|
-
raise CompatibilityError(
|
|
408
|
-
f"required runtime distribution {name!r} is unavailable",
|
|
409
|
-
code="runtime_distribution_unavailable",
|
|
410
|
-
) from error
|
|
411
|
-
|
|
412
|
-
|
|
413
|
-
def _distribution_version(name: str, *, fallback: str) -> str:
|
|
414
|
-
try:
|
|
415
|
-
return importlib.metadata.version(name)
|
|
416
|
-
except importlib.metadata.PackageNotFoundError:
|
|
417
|
-
return fallback
|
|
418
|
-
|
|
419
|
-
|
|
420
|
-
__all__ = [
|
|
421
|
-
"ProducerIdentity",
|
|
422
|
-
"managed_runtime_source",
|
|
423
|
-
"producer_identity",
|
|
424
|
-
"producer_sha256",
|
|
425
|
-
"runtime_producer_identity",
|
|
426
|
-
]
|
|
245
|
+
__all__ = ["environment_identity"]
|
{marimo_export-0.0.3 → marimo_export-0.0.4}/src/marimo_export/_marimo/compat/cache/attempts.py
RENAMED
|
@@ -2,6 +2,8 @@
|
|
|
2
2
|
|
|
3
3
|
from __future__ import annotations
|
|
4
4
|
|
|
5
|
+
import ast
|
|
6
|
+
import copy
|
|
5
7
|
import threading
|
|
6
8
|
from collections.abc import Callable, Iterator
|
|
7
9
|
from contextlib import contextmanager
|
|
@@ -54,6 +56,7 @@ class _GraphScope:
|
|
|
54
56
|
graph: Any
|
|
55
57
|
output_cells: frozenset[Any]
|
|
56
58
|
activity: CacheAttemptLog
|
|
59
|
+
environment: str | None = None
|
|
57
60
|
forced_cells: frozenset[Any] = frozenset()
|
|
58
61
|
|
|
59
62
|
|
|
@@ -65,6 +68,8 @@ _SCOPES: dict[int, _GraphScope] = {}
|
|
|
65
68
|
def track_notebook_cache(
|
|
66
69
|
child_graph: Any,
|
|
67
70
|
output_cell_ids: frozenset[Any],
|
|
71
|
+
*,
|
|
72
|
+
environment: str | None = None,
|
|
68
73
|
) -> Iterator[CacheAttemptLog]:
|
|
69
74
|
"""Record effective cache decisions for one exact child graph."""
|
|
70
75
|
|
|
@@ -72,6 +77,7 @@ def track_notebook_cache(
|
|
|
72
77
|
graph=child_graph,
|
|
73
78
|
output_cells=output_cell_ids,
|
|
74
79
|
activity=CacheAttemptLog(),
|
|
80
|
+
environment=environment,
|
|
75
81
|
)
|
|
76
82
|
key = id(child_graph)
|
|
77
83
|
with _SCOPES_LOCK:
|
|
@@ -88,10 +94,10 @@ def track_notebook_cache(
|
|
|
88
94
|
|
|
89
95
|
|
|
90
96
|
@contextmanager
|
|
91
|
-
def track_managed_parent_cache(graph: Any) -> Iterator[None]:
|
|
97
|
+
def track_managed_parent_cache(graph: Any, *, environment: str | None = None) -> Iterator[None]:
|
|
92
98
|
"""Activate export cache policy for one owned parent graph."""
|
|
93
99
|
|
|
94
|
-
with track_notebook_cache(graph, frozenset()):
|
|
100
|
+
with track_notebook_cache(graph, frozenset(), environment=environment):
|
|
95
101
|
yield
|
|
96
102
|
|
|
97
103
|
|
|
@@ -124,6 +130,11 @@ def cache_attempt_wrapper(native: Callable[..., Cache]) -> Callable[..., Cache]:
|
|
|
124
130
|
*args: Any,
|
|
125
131
|
**kwargs: Any,
|
|
126
132
|
) -> Cache:
|
|
133
|
+
with _SCOPES_LOCK:
|
|
134
|
+
scope = _SCOPES.get(id(graph))
|
|
135
|
+
environment = scope.environment if scope is not None and scope.graph is graph else None
|
|
136
|
+
if environment is not None:
|
|
137
|
+
module, scope_values = _with_environment(module, scope_values, environment)
|
|
127
138
|
attempt = native(
|
|
128
139
|
module,
|
|
129
140
|
graph,
|
|
@@ -160,6 +171,42 @@ def cache_attempt_wrapper(native: Callable[..., Cache]) -> Callable[..., Cache]:
|
|
|
160
171
|
return tracked
|
|
161
172
|
|
|
162
173
|
|
|
174
|
+
def _with_environment(
|
|
175
|
+
module: ast.Module,
|
|
176
|
+
scope: dict[str, Any],
|
|
177
|
+
environment: str,
|
|
178
|
+
) -> tuple[ast.Module, dict[str, Any]]:
|
|
179
|
+
from marimo._ast.transformers import DeprivateVisitor
|
|
180
|
+
from marimo._ast.variables import unmangle_local
|
|
181
|
+
from marimo._ast.visitor import ScopedVisitor
|
|
182
|
+
|
|
183
|
+
lookup = DeprivateVisitor().visit(copy.deepcopy(module))
|
|
184
|
+
visitor = ScopedVisitor("", ignore_local=True)
|
|
185
|
+
visitor.visit(lookup)
|
|
186
|
+
names = visitor.defs | visitor.refs | {unmangle_local(name).name for name in scope}
|
|
187
|
+
name = "__marimo_export_cache_environment"
|
|
188
|
+
while name in scope or name in names:
|
|
189
|
+
name += "_"
|
|
190
|
+
reference = ast.Expr(value=ast.Name(id=name, ctx=ast.Load()))
|
|
191
|
+
# The native hasher receives this reference. Authored execution keeps its
|
|
192
|
+
# original AST and scope, so the dependency input creates no notebook name.
|
|
193
|
+
lookup.body.append(reference)
|
|
194
|
+
return ast.fix_missing_locations(lookup), {**scope, name: environment}
|
|
195
|
+
|
|
196
|
+
|
|
197
|
+
def record_cache_miss(graph: Any, cell_id: Any) -> None:
|
|
198
|
+
"""Record a live run chosen after native restoration."""
|
|
199
|
+
|
|
200
|
+
with _SCOPES_LOCK:
|
|
201
|
+
scope = _scope_for(graph)
|
|
202
|
+
target = (
|
|
203
|
+
scope.activity.output_cells
|
|
204
|
+
if cell_id in scope.output_cells
|
|
205
|
+
else scope.activity.authored_cells
|
|
206
|
+
)
|
|
207
|
+
target[cell_id] = "miss"
|
|
208
|
+
|
|
209
|
+
|
|
163
210
|
def _scope_for(graph: Any) -> _GraphScope:
|
|
164
211
|
scope = _SCOPES.get(id(graph))
|
|
165
212
|
if scope is None or scope.graph is not graph:
|
|
@@ -175,6 +222,14 @@ def has_cache_scope(graph: Any) -> bool:
|
|
|
175
222
|
return scope is not None and scope.graph is graph
|
|
176
223
|
|
|
177
224
|
|
|
225
|
+
def tracked_environment(graph: Any) -> str | None:
|
|
226
|
+
"""Return the dependency identity frozen by this graph's owner."""
|
|
227
|
+
|
|
228
|
+
with _SCOPES_LOCK:
|
|
229
|
+
scope = _SCOPES.get(id(graph))
|
|
230
|
+
return scope.environment if scope is not None and scope.graph is graph else None
|
|
231
|
+
|
|
232
|
+
|
|
178
233
|
def _rerun_unavailable_attempt(attempt: Cache) -> Cache:
|
|
179
234
|
if not attempt.hit or not (
|
|
180
235
|
any(_contains_unavailable(value) for value in attempt.defs.values())
|
|
@@ -213,6 +268,8 @@ __all__ = [
|
|
|
213
268
|
"cache_attempt_wrapper",
|
|
214
269
|
"force_cache_misses",
|
|
215
270
|
"has_cache_scope",
|
|
271
|
+
"record_cache_miss",
|
|
216
272
|
"track_managed_parent_cache",
|
|
217
273
|
"track_notebook_cache",
|
|
274
|
+
"tracked_environment",
|
|
218
275
|
]
|
{marimo_export-0.0.3 → marimo_export-0.0.4}/src/marimo_export/_marimo/compat/cache/lifecycle.py
RENAMED
|
@@ -12,6 +12,7 @@ from marimo_export._marimo.compat.cache.attempts import (
|
|
|
12
12
|
_empty_attempt,
|
|
13
13
|
_rerun_unavailable_attempt,
|
|
14
14
|
has_cache_scope,
|
|
15
|
+
record_cache_miss,
|
|
15
16
|
)
|
|
16
17
|
|
|
17
18
|
|
|
@@ -23,6 +24,7 @@ class CompleteCachedLifecycle(CachedLifecycle):
|
|
|
23
24
|
if not has_cache_scope(self._graph):
|
|
24
25
|
return decision
|
|
25
26
|
if not isinstance(decision, Skip):
|
|
27
|
+
record_cache_miss(self._graph, cell.cell_id)
|
|
26
28
|
return decision
|
|
27
29
|
attempt = self._attempts.get(cell.cell_id)
|
|
28
30
|
if attempt is None:
|
|
@@ -36,6 +38,7 @@ class CompleteCachedLifecycle(CachedLifecycle):
|
|
|
36
38
|
return decision
|
|
37
39
|
self._attempts[cell.cell_id] = retry
|
|
38
40
|
self._exec_starts[cell.cell_id] = time.time()
|
|
41
|
+
record_cache_miss(self._graph, cell.cell_id)
|
|
39
42
|
return None
|
|
40
43
|
|
|
41
44
|
|
|
@@ -179,13 +179,22 @@ async def sequential_cache_loader() -> AsyncIterator[None]:
|
|
|
179
179
|
|
|
180
180
|
|
|
181
181
|
@contextmanager
|
|
182
|
-
def managed_cache_compat(
|
|
182
|
+
def managed_cache_compat(
|
|
183
|
+
hooks: Any,
|
|
184
|
+
parent_graph: Any | None = None,
|
|
185
|
+
*,
|
|
186
|
+
environment: str | None = None,
|
|
187
|
+
) -> Iterator[None]:
|
|
183
188
|
"""Install cache behavior for one owned kernel lifespan."""
|
|
184
189
|
|
|
185
190
|
from marimo_export._marimo.compat.cache.attempts import track_managed_parent_cache
|
|
186
191
|
from marimo_export._marimo.compat.cache.barrier import add_cache_write_barrier
|
|
187
192
|
|
|
188
|
-
scope =
|
|
193
|
+
scope = (
|
|
194
|
+
nullcontext()
|
|
195
|
+
if parent_graph is None
|
|
196
|
+
else track_managed_parent_cache(parent_graph, environment=environment)
|
|
197
|
+
)
|
|
189
198
|
with scope:
|
|
190
199
|
handle = _PATCHES.open()
|
|
191
200
|
try:
|
|
@@ -49,6 +49,7 @@ def require_cache_capabilities() -> None:
|
|
|
49
49
|
|
|
50
50
|
try:
|
|
51
51
|
import marimo._runtime.context as context_module
|
|
52
|
+
import marimo._save.hash as hash_module
|
|
52
53
|
import marimo._save.loaders as loaders_module
|
|
53
54
|
import marimo._save.loaders.lazy as lazy_module
|
|
54
55
|
import marimo._save.stubs as stubs_module
|
|
@@ -71,6 +72,7 @@ def require_cache_capabilities() -> None:
|
|
|
71
72
|
blob_schema = getattr(stubs_module, "BlobAsset", None)
|
|
72
73
|
|
|
73
74
|
symbols = {
|
|
75
|
+
"BlockHasher": getattr(hash_module, "BlockHasher", None),
|
|
74
76
|
"CachedLifecycle.__init__": getattr(lifecycle, "__init__", None),
|
|
75
77
|
"CachedLifecycle._restored_ui_defs": restored_ui_defs,
|
|
76
78
|
"CachedLifecycle.setup": getattr(lifecycle, "setup", None),
|
|
@@ -7,9 +7,11 @@ import time
|
|
|
7
7
|
from collections.abc import Iterator, Mapping
|
|
8
8
|
from contextlib import contextmanager
|
|
9
9
|
from dataclasses import dataclass
|
|
10
|
+
from pathlib import Path
|
|
10
11
|
from types import MappingProxyType
|
|
11
12
|
from typing import Any
|
|
12
13
|
|
|
14
|
+
from marimo_export._environment import environment_identity
|
|
13
15
|
from marimo_export._execution.plan import ExecutionPlan, NormalizedState, PlannedOutput
|
|
14
16
|
from marimo_export._json import (
|
|
15
17
|
JsonObject,
|
|
@@ -21,6 +23,7 @@ from marimo_export._marimo.compat.cache.attempts import (
|
|
|
21
23
|
CacheAttemptLog,
|
|
22
24
|
force_cache_misses,
|
|
23
25
|
track_notebook_cache,
|
|
26
|
+
tracked_environment,
|
|
24
27
|
)
|
|
25
28
|
from marimo_export._marimo.compat.child_run import (
|
|
26
29
|
StateChild,
|
|
@@ -94,9 +97,16 @@ async def execute_state(
|
|
|
94
97
|
state=state,
|
|
95
98
|
plan=plan,
|
|
96
99
|
)
|
|
100
|
+
environment = tracked_environment(state_child.context.parent.graph)
|
|
101
|
+
if environment is None:
|
|
102
|
+
source = state_child.context.filename
|
|
103
|
+
environment = environment_identity(
|
|
104
|
+
None if source is None else Path(source), exclude_source=True
|
|
105
|
+
)
|
|
97
106
|
with track_notebook_cache(
|
|
98
107
|
state_child.runner._kernel.graph,
|
|
99
108
|
run_plan.transient_cache_cells,
|
|
109
|
+
environment=environment,
|
|
100
110
|
) as notebook_cache:
|
|
101
111
|
input_phase = await _execute_inputs(state_child, state, run_plan)
|
|
102
112
|
output_phase = await _execute_outputs(
|
{marimo_export-0.0.3 → marimo_export-0.0.4}/src/marimo_export/_marimo/compat/managed_kernel.py
RENAMED
|
@@ -5,6 +5,9 @@ from __future__ import annotations
|
|
|
5
5
|
import os
|
|
6
6
|
from collections.abc import AsyncIterator
|
|
7
7
|
from contextlib import asynccontextmanager
|
|
8
|
+
from pathlib import Path
|
|
9
|
+
|
|
10
|
+
from marimo_export._environment import environment_identity
|
|
8
11
|
|
|
9
12
|
_MANAGED_CACHE_COMPAT_ENV = "MARIMO_EXPORT_MANAGED_CACHE_COMPAT"
|
|
10
13
|
_MANAGED_CACHE_ACTIVATION_ENV = "MARIMO_EXPORT_MANAGED_CACHE_ACTIVATION"
|
|
@@ -39,14 +42,13 @@ async def kernel_lifespan(_: None) -> AsyncIterator[None]:
|
|
|
39
42
|
from marimo_export._marimo.compat.inspection import install_parent_stop_provenance
|
|
40
43
|
|
|
41
44
|
context = get_context()
|
|
42
|
-
if not isinstance(context, KernelRuntimeContext):
|
|
45
|
+
if not isinstance(context, KernelRuntimeContext) or context.filename is None:
|
|
43
46
|
raise RuntimeError("managed cache integration requires a file-backed marimo kernel")
|
|
44
47
|
require_cache_capabilities()
|
|
48
|
+
environment = environment_identity(Path(context.filename), exclude_source=True)
|
|
45
49
|
release_stop_provenance = install_parent_stop_provenance(context)
|
|
46
50
|
try:
|
|
47
|
-
with managed_cache_compat(context._kernel._hooks, context.graph):
|
|
48
|
-
from pathlib import Path
|
|
49
|
-
|
|
51
|
+
with managed_cache_compat(context._kernel._hooks, context.graph, environment=environment):
|
|
50
52
|
Path(activation_path).write_text(activation_token, encoding="utf-8")
|
|
51
53
|
yield
|
|
52
54
|
finally:
|
|
@@ -2,12 +2,13 @@
|
|
|
2
2
|
"version": "0.24.0",
|
|
3
3
|
"commit": "854f7f2910b4bb4b6aebe650efc1f83ad40d9bef",
|
|
4
4
|
"cache_source_sha256": {
|
|
5
|
-
"CachedLifecycle.__init__": "b68aab07eac87ce3e1d1dfb4aaf586cc4903e7e962b86aa6f05f369b487d5650",
|
|
6
|
-
"CachedLifecycle._restored_ui_defs": "4f1d2220a6d7e78d208d76fd4e08b4ab4ddb8da724e9725260e0264bf7cd77fc",
|
|
7
|
-
"CachedLifecycle.setup": "90d8e2a30661c728df5c4e40370e1224c61dc26de08f2e72bb273179e85ebfcc",
|
|
8
5
|
"BlobAsset.schema_source": "ade24b0b25f4816aa296c3eda6623960f4a77c514c9124b5b6394f0c1ef3818a",
|
|
6
|
+
"BlockHasher": "c0b088d5c51322419fc3dbc8a0ed0bf715348300c4568b0eecaf25b5eb2e6ce1",
|
|
9
7
|
"Cache.schema_source": "c587eb7298afd67887d9cb0c75d9f81e16d54c9f0c6b819d673ecbba35df8119",
|
|
10
8
|
"CacheSignatureError": "ee0427f2e16982e20dad8ee34ea25b7ddb53ff545b2478ba36ab087c27e7280a",
|
|
9
|
+
"CachedLifecycle.__init__": "b68aab07eac87ce3e1d1dfb4aaf586cc4903e7e962b86aa6f05f369b487d5650",
|
|
10
|
+
"CachedLifecycle._restored_ui_defs": "4f1d2220a6d7e78d208d76fd4e08b4ab4ddb8da724e9725260e0264bf7cd77fc",
|
|
11
|
+
"CachedLifecycle.setup": "90d8e2a30661c728df5c4e40370e1224c61dc26de08f2e72bb273179e85ebfcc",
|
|
11
12
|
"Item.schema_source": "4b7f1722b2d1583d1c905540a3be691d6bca1e5014d8227a48cf245e733f7062",
|
|
12
13
|
"LazyLoader._effective_mode": "0e5efc063f8cf83a3b324f539fe3ed0eead25294cea12e5f1f11734b199bd3bb",
|
|
13
14
|
"LazyLoader._read_blobs": "c0c69d24de338c5ab61669fa8b570e623944c60a014176d98c62df2c0af2f97f",
|
|
@@ -16,8 +17,8 @@
|
|
|
16
17
|
"_verify_signed_blob": "8d650a60e10b9b36b3e312843fc1642e8b67c0b020c30f1afef6fa097473dd50",
|
|
17
18
|
"cache_attempt_from_hash": "4a1b9421f70703337b2b0874997de0a3022dec99c3a7ed15b140c0e4ccb4f576",
|
|
18
19
|
"encode._contiguous_tensor_bytes": "b5af49d65687b2ee6b1469ebe46299cb0f975d2f3135962108cbe1b7255f4642",
|
|
19
|
-
"
|
|
20
|
-
"
|
|
20
|
+
"flush_active_caches": "43a9a8956d21ab9adea51be5daaae66db07e17572dd7d138a53ef9695abe3a7c",
|
|
21
|
+
"from_item": "7a14447ebb9f4a8957580fe3eb16ec2108aefb7f086ae739d020de8a4f3ae7c8"
|
|
21
22
|
},
|
|
22
23
|
"receipt_schema_fields": {
|
|
23
24
|
"BlobAsset": ["data", "media_type", "filename", "metadata"],
|
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
from __future__ import annotations
|
|
2
2
|
|
|
3
3
|
import asyncio
|
|
4
|
+
import math
|
|
4
5
|
import threading
|
|
5
6
|
from collections.abc import Callable, Hashable
|
|
6
7
|
from dataclasses import dataclass, field
|
|
@@ -54,8 +55,12 @@ class PublicationControllerState(Generic[KeyT, MetadataT]):
|
|
|
54
55
|
route_key: Callable[[KeyT], Hashable] | None,
|
|
55
56
|
route_grace_seconds: float,
|
|
56
57
|
) -> None:
|
|
57
|
-
if route_grace_seconds
|
|
58
|
-
|
|
58
|
+
if isinstance(route_grace_seconds, bool) or not isinstance(
|
|
59
|
+
route_grace_seconds, (int, float)
|
|
60
|
+
):
|
|
61
|
+
raise TypeError("route_grace_seconds must be a number")
|
|
62
|
+
if not math.isfinite(route_grace_seconds) or route_grace_seconds < 0:
|
|
63
|
+
raise ValueError("route_grace_seconds must be a finite nonnegative number")
|
|
59
64
|
self._repository_value = repository
|
|
60
65
|
self._owns_repository = repository is None
|
|
61
66
|
self._repository_lock = threading.Lock()
|
|
@@ -118,7 +123,9 @@ class PublicationControllerState(Generic[KeyT, MetadataT]):
|
|
|
118
123
|
return None
|
|
119
124
|
pending = any(work.group == owned.group for work in self._work.values())
|
|
120
125
|
if key not in self._refresh_tasks and not pending:
|
|
121
|
-
task = asyncio.create_task(
|
|
126
|
+
task = asyncio.create_task(
|
|
127
|
+
self._refresh_if_stale(owned, self._desired.get(owned.group))
|
|
128
|
+
)
|
|
122
129
|
self._refresh_tasks[key] = task
|
|
123
130
|
task.add_done_callback(
|
|
124
131
|
lambda completed, selected_key=key: self._refresh_finished(selected_key, completed)
|
|
@@ -202,9 +209,7 @@ class PublicationControllerState(Generic[KeyT, MetadataT]):
|
|
|
202
209
|
work: _Work[KeyT, MetadataT],
|
|
203
210
|
) -> PreparedPublication[KeyT, MetadataT]:
|
|
204
211
|
candidate = await asyncio.to_thread(
|
|
205
|
-
work.prepare,
|
|
206
|
-
self._repository(),
|
|
207
|
-
work.cancelled.is_set,
|
|
212
|
+
lambda: work.prepare(self._repository(), work.cancelled.is_set)
|
|
208
213
|
)
|
|
209
214
|
if not isinstance(candidate, PreparedPublicationCandidate):
|
|
210
215
|
raise TypeError("prepare must return a PreparedPublicationCandidate")
|
|
@@ -245,6 +250,7 @@ class PublicationControllerState(Generic[KeyT, MetadataT]):
|
|
|
245
250
|
async def _refresh_if_stale(
|
|
246
251
|
self,
|
|
247
252
|
selected: _OwnedPublication[KeyT, MetadataT],
|
|
253
|
+
desired: int | None,
|
|
248
254
|
) -> None:
|
|
249
255
|
try:
|
|
250
256
|
revision = await asyncio.to_thread(
|
|
@@ -254,6 +260,7 @@ class PublicationControllerState(Generic[KeyT, MetadataT]):
|
|
|
254
260
|
if (
|
|
255
261
|
self._closed
|
|
256
262
|
or self._current.get(selected.key) is not selected
|
|
263
|
+
or self._desired.get(selected.group) != desired
|
|
257
264
|
or revision <= selected.publication.plan.observation_revision
|
|
258
265
|
):
|
|
259
266
|
return
|