calkit-python 0.32.11__tar.gz → 0.33.1__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.
- {calkit_python-0.32.11 → calkit_python-0.33.1}/.gitignore +7 -0
- {calkit_python-0.32.11 → calkit_python-0.33.1}/.pre-commit-config.yaml +2 -0
- calkit_python-0.33.1/.prettierignore +10 -0
- calkit_python-0.33.1/.yarnrc.yml +2 -0
- {calkit_python-0.32.11 → calkit_python-0.33.1}/CONTRIBUTING.md +18 -0
- {calkit_python-0.32.11 → calkit_python-0.33.1}/Makefile +22 -3
- {calkit_python-0.32.11 → calkit_python-0.33.1}/PKG-INFO +13 -2
- calkit_python-0.33.1/babel.config.js +1 -0
- calkit_python-0.33.1/calkit/__init__.py +49 -0
- {calkit_python-0.32.11 → calkit_python-0.33.1}/calkit/cli/import_.py +200 -3
- {calkit_python-0.32.11 → calkit_python-0.33.1}/calkit/cli/main.py +45 -75
- {calkit_python-0.32.11 → calkit_python-0.33.1}/calkit/cli/new.py +6 -5
- {calkit_python-0.32.11 → calkit_python-0.33.1}/calkit/core.py +63 -2
- {calkit_python-0.32.11 → calkit_python-0.33.1}/calkit/dvc.py +86 -0
- {calkit_python-0.32.11 → calkit_python-0.33.1}/calkit/git.py +2 -1
- {calkit_python-0.32.11 → calkit_python-0.33.1}/calkit/invenio.py +22 -10
- calkit_python-0.33.1/calkit/jupyterlab/routes.py +1343 -0
- calkit_python-0.33.1/calkit/labextension/package.json +217 -0
- calkit_python-0.33.1/calkit/labextension/schemas/calkit/package.json.orig +212 -0
- calkit_python-0.33.1/calkit/labextension/schemas/calkit/plugin.json +44 -0
- calkit_python-0.33.1/calkit/labextension/static/502.9a2c5772a15466e923ef.js +1 -0
- calkit_python-0.33.1/calkit/labextension/static/695.2c41003a452d43d2b358.js +1 -0
- calkit_python-0.33.1/calkit/labextension/static/867.a42a046aa5108f54f8fb.js +1 -0
- calkit_python-0.33.1/calkit/labextension/static/909.bc803769ea27551457d9.js +1 -0
- calkit_python-0.33.1/calkit/labextension/static/946.050af2abf7845cfbdbd2.js +2 -0
- calkit_python-0.33.1/calkit/labextension/static/946.050af2abf7845cfbdbd2.js.LICENSE.txt +9 -0
- calkit_python-0.33.1/calkit/labextension/static/remoteEntry.bc3529435b6f02f41e8d.js +1 -0
- calkit_python-0.33.1/calkit/labextension/static/style.js +4 -0
- calkit_python-0.33.1/calkit/labextension/static/third-party-licenses.json +52 -0
- calkit_python-0.33.1/calkit/tests/cli/test_import.py +25 -0
- {calkit_python-0.32.11 → calkit_python-0.33.1}/calkit/tests/cli/test_main.py +9 -4
- calkit_python-0.33.1/calkit/tests/jupyterlab/__init__.py +0 -0
- calkit_python-0.33.1/calkit/tests/jupyterlab/test_routes.py +16 -0
- calkit_python-0.33.1/calkit/tests/models/__init__.py +0 -0
- {calkit_python-0.32.11 → calkit_python-0.33.1}/calkit/tests/test_check.py +2 -4
- {calkit_python-0.32.11 → calkit_python-0.33.1}/calkit/tests/test_core.py +11 -2
- {calkit_python-0.32.11 → calkit_python-0.33.1}/calkit/tests/test_dvc.py +11 -0
- calkit_python-0.33.1/conftest.py +8 -0
- {calkit_python-0.32.11 → calkit_python-0.33.1}/docs/cloud-integration.md +3 -0
- calkit_python-0.33.1/docs/img/calkit-no-bg.png +0 -0
- calkit_python-0.33.1/docs/img/jupyterlab/all-green.png +0 -0
- calkit_python-0.33.1/docs/img/jupyterlab/collect-data-stale.png +0 -0
- calkit_python-0.33.1/docs/img/jupyterlab/new-env.png +0 -0
- calkit_python-0.33.1/docs/img/jupyterlab/new-notebook.png +0 -0
- calkit_python-0.33.1/docs/img/jupyterlab/pipeline-badge.png +0 -0
- calkit_python-0.33.1/docs/jupyterlab.md +85 -0
- {calkit_python-0.32.11 → calkit_python-0.33.1}/docs/notebooks.md +3 -0
- calkit_python-0.33.1/install.json +5 -0
- calkit_python-0.33.1/jest.config.js +42 -0
- calkit_python-0.33.1/jupyter-config/server-config/calkit.json +7 -0
- {calkit_python-0.32.11 → calkit_python-0.33.1}/mkdocs.yml +2 -0
- calkit_python-0.33.1/package.json +212 -0
- calkit_python-0.33.1/pyproject.toml +162 -0
- calkit_python-0.33.1/schema/plugin.json +44 -0
- calkit_python-0.33.1/src/__tests__/useQueries.spec.ts +163 -0
- calkit_python-0.33.1/src/calkit-config.ts +130 -0
- calkit_python-0.33.1/src/cell-output-marker.ts +128 -0
- calkit_python-0.33.1/src/components/commit-dialog.tsx +233 -0
- calkit_python-0.33.1/src/components/environment-editor.tsx +819 -0
- calkit_python-0.33.1/src/components/notebook-registration.tsx +379 -0
- calkit_python-0.33.1/src/components/notebook-toolbar.tsx +1398 -0
- calkit_python-0.33.1/src/components/pipeline-status-bar.tsx +174 -0
- calkit_python-0.33.1/src/components/project-info-editor.tsx +218 -0
- calkit_python-0.33.1/src/components/sidebar-settings.tsx +80 -0
- calkit_python-0.33.1/src/components/sidebar.tsx +2079 -0
- calkit_python-0.33.1/src/components/stage-editor.tsx +692 -0
- calkit_python-0.33.1/src/feature-flags.ts +172 -0
- calkit_python-0.33.1/src/file-browser-menu.ts +327 -0
- calkit_python-0.33.1/src/hooks/__tests__/useQueries.test.tsx +356 -0
- calkit_python-0.33.1/src/hooks/useQueries.ts +438 -0
- calkit_python-0.33.1/src/icons.ts +41 -0
- calkit_python-0.33.1/src/index.ts +504 -0
- calkit_python-0.33.1/src/io-tracker.ts +218 -0
- calkit_python-0.33.1/src/pipeline-state.ts +89 -0
- calkit_python-0.33.1/src/queryClient.ts +15 -0
- calkit_python-0.33.1/src/request.ts +59 -0
- calkit_python-0.33.1/src/shims-mainmenu.d.ts +10 -0
- calkit_python-0.33.1/style/base.css +7 -0
- calkit_python-0.33.1/style/cell-output-marker.css +23 -0
- calkit_python-0.33.1/style/environment-editor.css +539 -0
- calkit_python-0.33.1/style/environment-selector.css +78 -0
- calkit_python-0.33.1/style/img/calkit-no-bg.png +0 -0
- calkit_python-0.33.1/style/index.css +5 -0
- calkit_python-0.33.1/style/index.js +2 -0
- calkit_python-0.33.1/style/notebook-toolbar.css +729 -0
- calkit_python-0.33.1/style/pipeline-status-bar.css +88 -0
- calkit_python-0.33.1/style/sidebar.css +1256 -0
- calkit_python-0.33.1/test/dvc-md5-dir/osx-arm64.txt +70 -0
- calkit_python-0.33.1/tsconfig.json +25 -0
- calkit_python-0.33.1/tsconfig.test.json +3 -0
- calkit_python-0.33.1/ui-tests/.gitignore +5 -0
- calkit_python-0.33.1/ui-tests/README.md +167 -0
- calkit_python-0.33.1/ui-tests/jupyter_server_test_config.py +13 -0
- calkit_python-0.33.1/ui-tests/package.json +15 -0
- calkit_python-0.33.1/ui-tests/playwright.config.js +14 -0
- calkit_python-0.33.1/ui-tests/tests/calkit.spec.ts +360 -0
- calkit_python-0.33.1/ui-tests/yarn.lock +5977 -0
- {calkit_python-0.32.11 → calkit_python-0.33.1}/uv.lock +546 -405
- calkit_python-0.33.1/yarn.lock +11371 -0
- calkit_python-0.32.11/.github/FUNDING.yml +0 -16
- calkit_python-0.32.11/.github/workflows/docs.yml +0 -31
- calkit_python-0.32.11/.github/workflows/format.yml +0 -13
- calkit_python-0.32.11/.github/workflows/publish-test.yml +0 -49
- calkit_python-0.32.11/.github/workflows/publish.yml +0 -48
- calkit_python-0.32.11/.github/workflows/test.yml +0 -78
- calkit_python-0.32.11/calkit/__init__.py +0 -20
- calkit_python-0.32.11/pyproject.toml +0 -108
- {calkit_python-0.32.11 → calkit_python-0.33.1}/.python-version +0 -0
- {calkit_python-0.32.11 → calkit_python-0.33.1}/CITATION.cff +0 -0
- {calkit_python-0.32.11 → calkit_python-0.33.1}/CODE_OF_CONDUCT.md +0 -0
- {calkit_python-0.32.11 → calkit_python-0.33.1}/LICENSE +0 -0
- {calkit_python-0.32.11 → calkit_python-0.33.1}/README.md +0 -0
- {calkit_python-0.32.11 → calkit_python-0.33.1}/calkit/__main__.py +0 -0
- {calkit_python-0.32.11 → calkit_python-0.33.1}/calkit/calc.py +0 -0
- {calkit_python-0.32.11 → calkit_python-0.33.1}/calkit/check.py +0 -0
- {calkit_python-0.32.11 → calkit_python-0.33.1}/calkit/cli/__init__.py +0 -0
- {calkit_python-0.32.11 → calkit_python-0.33.1}/calkit/cli/check.py +0 -0
- {calkit_python-0.32.11 → calkit_python-0.33.1}/calkit/cli/cloud.py +0 -0
- {calkit_python-0.32.11 → calkit_python-0.33.1}/calkit/cli/config.py +0 -0
- {calkit_python-0.32.11 → calkit_python-0.33.1}/calkit/cli/core.py +0 -0
- {calkit_python-0.32.11 → calkit_python-0.33.1}/calkit/cli/describe.py +0 -0
- {calkit_python-0.32.11 → calkit_python-0.33.1}/calkit/cli/latex.py +0 -0
- {calkit_python-0.32.11 → calkit_python-0.33.1}/calkit/cli/list.py +0 -0
- {calkit_python-0.32.11 → calkit_python-0.33.1}/calkit/cli/notebooks.py +0 -0
- {calkit_python-0.32.11 → calkit_python-0.33.1}/calkit/cli/office.py +0 -0
- {calkit_python-0.32.11 → calkit_python-0.33.1}/calkit/cli/overleaf.py +0 -0
- {calkit_python-0.32.11 → calkit_python-0.33.1}/calkit/cli/slurm.py +0 -0
- {calkit_python-0.32.11 → calkit_python-0.33.1}/calkit/cli/update.py +0 -0
- {calkit_python-0.32.11 → calkit_python-0.33.1}/calkit/cloud.py +0 -0
- {calkit_python-0.32.11 → calkit_python-0.33.1}/calkit/conda.py +0 -0
- {calkit_python-0.32.11 → calkit_python-0.33.1}/calkit/config.py +0 -0
- {calkit_python-0.32.11 → calkit_python-0.33.1}/calkit/datasets.py +0 -0
- {calkit_python-0.32.11 → calkit_python-0.33.1}/calkit/docker.py +0 -0
- {calkit_python-0.32.11 → calkit_python-0.33.1}/calkit/environments.py +0 -0
- {calkit_python-0.32.11 → calkit_python-0.33.1}/calkit/github.py +0 -0
- {calkit_python-0.32.11 → calkit_python-0.33.1}/calkit/gui.py +0 -0
- {calkit_python-0.32.11 → calkit_python-0.33.1}/calkit/jupyter.py +0 -0
- {calkit_python-0.32.11/calkit/tests → calkit_python-0.33.1/calkit/jupyterlab}/__init__.py +0 -0
- /calkit_python-0.32.11/docs/img/calkit-no-bg.png → /calkit_python-0.33.1/calkit/labextension/static/b2f1c3efe70cb539d121.png +0 -0
- {calkit_python-0.32.11 → calkit_python-0.33.1}/calkit/licenses.py +0 -0
- {calkit_python-0.32.11 → calkit_python-0.33.1}/calkit/magics.py +0 -0
- {calkit_python-0.32.11 → calkit_python-0.33.1}/calkit/matlab.py +0 -0
- {calkit_python-0.32.11 → calkit_python-0.33.1}/calkit/models/__init__.py +0 -0
- {calkit_python-0.32.11 → calkit_python-0.33.1}/calkit/models/core.py +0 -0
- {calkit_python-0.32.11 → calkit_python-0.33.1}/calkit/models/io.py +0 -0
- {calkit_python-0.32.11 → calkit_python-0.33.1}/calkit/models/iteration.py +0 -0
- {calkit_python-0.32.11 → calkit_python-0.33.1}/calkit/models/pipeline.py +0 -0
- {calkit_python-0.32.11 → calkit_python-0.33.1}/calkit/notebooks.py +0 -0
- {calkit_python-0.32.11 → calkit_python-0.33.1}/calkit/office.py +0 -0
- {calkit_python-0.32.11 → calkit_python-0.33.1}/calkit/ops.py +0 -0
- {calkit_python-0.32.11 → calkit_python-0.33.1}/calkit/overleaf.py +0 -0
- {calkit_python-0.32.11 → calkit_python-0.33.1}/calkit/pipeline.py +0 -0
- {calkit_python-0.32.11 → calkit_python-0.33.1}/calkit/releases.py +0 -0
- {calkit_python-0.32.11 → calkit_python-0.33.1}/calkit/server.py +0 -0
- {calkit_python-0.32.11 → calkit_python-0.33.1}/calkit/templates/__init__.py +0 -0
- {calkit_python-0.32.11 → calkit_python-0.33.1}/calkit/templates/core.py +0 -0
- {calkit_python-0.32.11 → calkit_python-0.33.1}/calkit/templates/latex/__init__.py +0 -0
- {calkit_python-0.32.11 → calkit_python-0.33.1}/calkit/templates/latex/article/paper.tex +0 -0
- {calkit_python-0.32.11 → calkit_python-0.33.1}/calkit/templates/latex/core.py +0 -0
- {calkit_python-0.32.11 → calkit_python-0.33.1}/calkit/templates/latex/jfm/jfm.bst +0 -0
- {calkit_python-0.32.11 → calkit_python-0.33.1}/calkit/templates/latex/jfm/jfm.cls +0 -0
- {calkit_python-0.32.11 → calkit_python-0.33.1}/calkit/templates/latex/jfm/lineno-FLM.sty +0 -0
- {calkit_python-0.32.11 → calkit_python-0.33.1}/calkit/templates/latex/jfm/paper.tex +0 -0
- {calkit_python-0.32.11 → calkit_python-0.33.1}/calkit/templates/latex/jfm/upmath.sty +0 -0
- {calkit_python-0.32.11/calkit/tests/cli → calkit_python-0.33.1/calkit/tests}/__init__.py +0 -0
- {calkit_python-0.32.11/calkit/tests/models → calkit_python-0.33.1/calkit/tests/cli}/__init__.py +0 -0
- {calkit_python-0.32.11 → calkit_python-0.33.1}/calkit/tests/cli/test_check.py +0 -0
- {calkit_python-0.32.11 → calkit_python-0.33.1}/calkit/tests/cli/test_config.py +0 -0
- {calkit_python-0.32.11 → calkit_python-0.33.1}/calkit/tests/cli/test_latex.py +0 -0
- {calkit_python-0.32.11 → calkit_python-0.33.1}/calkit/tests/cli/test_list.py +0 -0
- {calkit_python-0.32.11 → calkit_python-0.33.1}/calkit/tests/cli/test_new.py +0 -0
- {calkit_python-0.32.11 → calkit_python-0.33.1}/calkit/tests/cli/test_notebooks.py +0 -0
- {calkit_python-0.32.11 → calkit_python-0.33.1}/calkit/tests/cli/test_overleaf.py +0 -0
- {calkit_python-0.32.11 → calkit_python-0.33.1}/calkit/tests/models/test_iteration.py +0 -0
- {calkit_python-0.32.11 → calkit_python-0.33.1}/calkit/tests/models/test_pipeline.py +0 -0
- {calkit_python-0.32.11 → calkit_python-0.33.1}/calkit/tests/test_calc.py +0 -0
- {calkit_python-0.32.11 → calkit_python-0.33.1}/calkit/tests/test_conda.py +0 -0
- {calkit_python-0.32.11 → calkit_python-0.33.1}/calkit/tests/test_environments.py +0 -0
- {calkit_python-0.32.11 → calkit_python-0.33.1}/calkit/tests/test_git.py +0 -0
- {calkit_python-0.32.11 → calkit_python-0.33.1}/calkit/tests/test_invenio.py +0 -0
- {calkit_python-0.32.11 → calkit_python-0.33.1}/calkit/tests/test_jupyter.py +0 -0
- {calkit_python-0.32.11 → calkit_python-0.33.1}/calkit/tests/test_magics.py +0 -0
- {calkit_python-0.32.11 → calkit_python-0.33.1}/calkit/tests/test_notebooks.py +0 -0
- {calkit_python-0.32.11 → calkit_python-0.33.1}/calkit/tests/test_pipeline.py +0 -0
- {calkit_python-0.32.11 → calkit_python-0.33.1}/calkit/tests/test_templates.py +0 -0
- {calkit_python-0.32.11 → calkit_python-0.33.1}/docs/CNAME +0 -0
- {calkit_python-0.32.11 → calkit_python-0.33.1}/docs/apps.md +0 -0
- {calkit_python-0.32.11 → calkit_python-0.33.1}/docs/calculations.md +0 -0
- {calkit_python-0.32.11 → calkit_python-0.33.1}/docs/calkit-yaml.md +0 -0
- {calkit_python-0.32.11 → calkit_python-0.33.1}/docs/cli-reference.md +0 -0
- {calkit_python-0.32.11 → calkit_python-0.33.1}/docs/datasets.md +0 -0
- {calkit_python-0.32.11 → calkit_python-0.33.1}/docs/dependencies.md +0 -0
- {calkit_python-0.32.11 → calkit_python-0.33.1}/docs/environments.md +0 -0
- {calkit_python-0.32.11 → calkit_python-0.33.1}/docs/examples.md +0 -0
- {calkit_python-0.32.11 → calkit_python-0.33.1}/docs/governance.md +0 -0
- {calkit_python-0.32.11 → calkit_python-0.33.1}/docs/help.md +0 -0
- {calkit_python-0.32.11 → calkit_python-0.33.1}/docs/img/c-to-the-k-white.svg +0 -0
- {calkit_python-0.32.11 → calkit_python-0.33.1}/docs/img/calkit-fragmentation-compendium.png +0 -0
- {calkit_python-0.32.11 → calkit_python-0.33.1}/docs/img/connect-zenodo.png +0 -0
- {calkit_python-0.32.11 → calkit_python-0.33.1}/docs/img/jupyterlab-params.png +0 -0
- {calkit_python-0.32.11 → calkit_python-0.33.1}/docs/img/plos-osi-code-2024-03.png +0 -0
- {calkit_python-0.32.11 → calkit_python-0.33.1}/docs/img/vscode-nb-params.png +0 -0
- {calkit_python-0.32.11 → calkit_python-0.33.1}/docs/index.md +0 -0
- {calkit_python-0.32.11 → calkit_python-0.33.1}/docs/installation.md +0 -0
- {calkit_python-0.32.11 → calkit_python-0.33.1}/docs/local-server.md +0 -0
- {calkit_python-0.32.11 → calkit_python-0.33.1}/docs/overleaf.md +0 -0
- {calkit_python-0.32.11 → calkit_python-0.33.1}/docs/pipeline/index.md +0 -0
- {calkit_python-0.32.11 → calkit_python-0.33.1}/docs/pipeline/manual-steps.md +0 -0
- {calkit_python-0.32.11 → calkit_python-0.33.1}/docs/pipeline/running-and-logging.md +0 -0
- {calkit_python-0.32.11 → calkit_python-0.33.1}/docs/pipeline/slurm.md +0 -0
- {calkit_python-0.32.11 → calkit_python-0.33.1}/docs/quickstart.md +0 -0
- {calkit_python-0.32.11 → calkit_python-0.33.1}/docs/references.md +0 -0
- {calkit_python-0.32.11 → calkit_python-0.33.1}/docs/releases.md +0 -0
- {calkit_python-0.32.11 → calkit_python-0.33.1}/docs/tutorials/adding-latex-pub-docker.md +0 -0
- {calkit_python-0.32.11 → calkit_python-0.33.1}/docs/tutorials/conda-envs.md +0 -0
- {calkit_python-0.32.11 → calkit_python-0.33.1}/docs/tutorials/existing-project.md +0 -0
- {calkit_python-0.32.11 → calkit_python-0.33.1}/docs/tutorials/first-project.md +0 -0
- {calkit_python-0.32.11 → calkit_python-0.33.1}/docs/tutorials/github-actions.md +0 -0
- {calkit_python-0.32.11 → calkit_python-0.33.1}/docs/tutorials/img/actions-repo-secrets.png +0 -0
- {calkit_python-0.32.11 → calkit_python-0.33.1}/docs/tutorials/img/latex-codespaces/building-codespace.png +0 -0
- {calkit_python-0.32.11 → calkit_python-0.33.1}/docs/tutorials/img/latex-codespaces/codespaces-secrets-2.png +0 -0
- {calkit_python-0.32.11 → calkit_python-0.33.1}/docs/tutorials/img/latex-codespaces/editor-split.png +0 -0
- {calkit_python-0.32.11 → calkit_python-0.33.1}/docs/tutorials/img/latex-codespaces/go-to-linked-code.png +0 -0
- {calkit_python-0.32.11 → calkit_python-0.33.1}/docs/tutorials/img/latex-codespaces/issue-from-selection.png +0 -0
- {calkit_python-0.32.11 → calkit_python-0.33.1}/docs/tutorials/img/latex-codespaces/new-project.png +0 -0
- {calkit_python-0.32.11 → calkit_python-0.33.1}/docs/tutorials/img/latex-codespaces/new-pub-2.png +0 -0
- {calkit_python-0.32.11 → calkit_python-0.33.1}/docs/tutorials/img/latex-codespaces/new-token.png +0 -0
- {calkit_python-0.32.11 → calkit_python-0.33.1}/docs/tutorials/img/latex-codespaces/paper.tex.png +0 -0
- {calkit_python-0.32.11 → calkit_python-0.33.1}/docs/tutorials/img/latex-codespaces/project-home-3.png +0 -0
- {calkit_python-0.32.11 → calkit_python-0.33.1}/docs/tutorials/img/latex-codespaces/push.png +0 -0
- {calkit_python-0.32.11 → calkit_python-0.33.1}/docs/tutorials/img/latex-codespaces/stage.png +0 -0
- {calkit_python-0.32.11 → calkit_python-0.33.1}/docs/tutorials/img/office/anakin-excel.jpg +0 -0
- {calkit_python-0.32.11 → calkit_python-0.33.1}/docs/tutorials/img/office/chart-more-rows.png +0 -0
- {calkit_python-0.32.11 → calkit_python-0.33.1}/docs/tutorials/img/office/create-project.png +0 -0
- {calkit_python-0.32.11 → calkit_python-0.33.1}/docs/tutorials/img/office/elsevier-research-data-guidelines.png +0 -0
- {calkit_python-0.32.11 → calkit_python-0.33.1}/docs/tutorials/img/office/excel-chart.png +0 -0
- {calkit_python-0.32.11 → calkit_python-0.33.1}/docs/tutorials/img/office/excel-data.png +0 -0
- {calkit_python-0.32.11 → calkit_python-0.33.1}/docs/tutorials/img/office/insert-link-to-file.png +0 -0
- {calkit_python-0.32.11 → calkit_python-0.33.1}/docs/tutorials/img/office/needs-clone.png +0 -0
- {calkit_python-0.32.11 → calkit_python-0.33.1}/docs/tutorials/img/office/new-stage.png +0 -0
- {calkit_python-0.32.11 → calkit_python-0.33.1}/docs/tutorials/img/office/phd-comics-version-control.webp +0 -0
- {calkit_python-0.32.11 → calkit_python-0.33.1}/docs/tutorials/img/office/pipeline-out-of-date.png +0 -0
- {calkit_python-0.32.11 → calkit_python-0.33.1}/docs/tutorials/img/office/status-more-rows.png +0 -0
- {calkit_python-0.32.11 → calkit_python-0.33.1}/docs/tutorials/img/office/uncommitted-changes.png +0 -0
- {calkit_python-0.32.11 → calkit_python-0.33.1}/docs/tutorials/img/office/untracked-data.png +0 -0
- {calkit_python-0.32.11 → calkit_python-0.33.1}/docs/tutorials/img/office/updated-publication.png +0 -0
- {calkit_python-0.32.11 → calkit_python-0.33.1}/docs/tutorials/img/office/word-to-pdf-stage-2.png +0 -0
- {calkit_python-0.32.11 → calkit_python-0.33.1}/docs/tutorials/img/office/workflow-page.png +0 -0
- {calkit_python-0.32.11 → calkit_python-0.33.1}/docs/tutorials/img/openfoam/clone.png +0 -0
- {calkit_python-0.32.11 → calkit_python-0.33.1}/docs/tutorials/img/openfoam/create-project.png +0 -0
- {calkit_python-0.32.11 → calkit_python-0.33.1}/docs/tutorials/img/openfoam/datasets-page.png +0 -0
- {calkit_python-0.32.11 → calkit_python-0.33.1}/docs/tutorials/img/openfoam/figure-on-website-updated.png +0 -0
- {calkit_python-0.32.11 → calkit_python-0.33.1}/docs/tutorials/img/openfoam/figure-on-website.png +0 -0
- {calkit_python-0.32.11 → calkit_python-0.33.1}/docs/tutorials/img/openfoam/new-token.png +0 -0
- {calkit_python-0.32.11 → calkit_python-0.33.1}/docs/tutorials/img/openfoam/reclone.png +0 -0
- {calkit_python-0.32.11 → calkit_python-0.33.1}/docs/tutorials/img/openfoam/status-after-import-dataset.png +0 -0
- {calkit_python-0.32.11 → calkit_python-0.33.1}/docs/tutorials/img/quick-actions.png +0 -0
- {calkit_python-0.32.11 → calkit_python-0.33.1}/docs/tutorials/img/run-proc.png +0 -0
- {calkit_python-0.32.11 → calkit_python-0.33.1}/docs/tutorials/index.md +0 -0
- {calkit_python-0.32.11 → calkit_python-0.33.1}/docs/tutorials/latex-codespaces.md +0 -0
- {calkit_python-0.32.11 → calkit_python-0.33.1}/docs/tutorials/matlab.md +0 -0
- {calkit_python-0.32.11 → calkit_python-0.33.1}/docs/tutorials/notebook-pipeline.md +0 -0
- {calkit_python-0.32.11 → calkit_python-0.33.1}/docs/tutorials/office.md +0 -0
- {calkit_python-0.32.11 → calkit_python-0.33.1}/docs/tutorials/openfoam.md +0 -0
- {calkit_python-0.32.11 → calkit_python-0.33.1}/docs/tutorials/procedures.md +0 -0
- {calkit_python-0.32.11 → calkit_python-0.33.1}/docs/version-control.md +0 -0
- {calkit_python-0.32.11 → calkit_python-0.33.1}/scripts/install.ps1 +0 -0
- {calkit_python-0.32.11 → calkit_python-0.33.1}/scripts/install.sh +0 -0
- {calkit_python-0.32.11 → calkit_python-0.33.1}/test/nb-julia.ipynb +0 -0
- {calkit_python-0.32.11 → calkit_python-0.33.1}/test/nb-params.ipynb +0 -0
- {calkit_python-0.32.11 → calkit_python-0.33.1}/test/nb-subdir.ipynb +0 -0
- {calkit_python-0.32.11 → calkit_python-0.33.1}/test/pipeline.ipynb +0 -0
- {calkit_python-0.32.11 → calkit_python-0.33.1}/test/script.py +0 -0
- {calkit_python-0.32.11 → calkit_python-0.33.1}/test/test-log.log +0 -0
|
@@ -31,6 +31,24 @@ This guide will help you get started.
|
|
|
31
31
|
```bash
|
|
32
32
|
uv run pytest
|
|
33
33
|
```
|
|
34
|
+
1. Install the Calkit CLI in dev mode:
|
|
35
|
+
```sh
|
|
36
|
+
uv tool install -e .
|
|
37
|
+
```
|
|
38
|
+
1. Install the JupyterLab extension in development mode
|
|
39
|
+
(if working on the JupyterLab extension):
|
|
40
|
+
```sh
|
|
41
|
+
uv run jupyter labextension develop . --overwrite
|
|
42
|
+
```
|
|
43
|
+
1. Start the JupyterLab extension TypeScript compiler in watch mode
|
|
44
|
+
(if working on the JupyterLab extension):
|
|
45
|
+
```sh
|
|
46
|
+
make jlab-dev
|
|
47
|
+
```
|
|
48
|
+
1. Start JupyterLab:
|
|
49
|
+
```sh
|
|
50
|
+
uv run jupyter lab
|
|
51
|
+
```
|
|
34
52
|
|
|
35
53
|
### 3. Make your changes
|
|
36
54
|
|
|
@@ -32,14 +32,33 @@ test-cov: ## Test the code coverage with pytest.
|
|
|
32
32
|
@echo "🚀 Testing code coverage with pytest"
|
|
33
33
|
@uv run pytest --cov --cov-config=pyproject.toml
|
|
34
34
|
|
|
35
|
-
.PHONY: docs
|
|
36
|
-
docs
|
|
35
|
+
.PHONY: test-docs
|
|
36
|
+
test-docs: ## Test if documentation can be built without warnings or errors.
|
|
37
37
|
@uv run mkdocs build -s
|
|
38
38
|
|
|
39
39
|
.PHONY: docs
|
|
40
40
|
docs: ## Build and serve the documentation.
|
|
41
|
-
@uv run mkdocs serve
|
|
41
|
+
@uv run mkdocs serve --livereload
|
|
42
42
|
|
|
43
43
|
.PHONY: import-profile
|
|
44
44
|
import-profile: ## Profile the import time of the CLI.
|
|
45
45
|
uv run python -X importtime -m calkit --help 2> import.log && uvx tuna import.log
|
|
46
|
+
|
|
47
|
+
.PHONY: jlab-dev
|
|
48
|
+
jlab-dev: ## Develop the JupyterLab extension.
|
|
49
|
+
uv run jlpm run watch
|
|
50
|
+
|
|
51
|
+
.PHONY: jlab
|
|
52
|
+
jlab: ## Build the JupyterLab extension.
|
|
53
|
+
uv run jlpm run build:prod
|
|
54
|
+
|
|
55
|
+
.PHONY: test-frontend
|
|
56
|
+
test-frontend: ## Run frontend unit tests with Jest.
|
|
57
|
+
@echo "🚀 Running frontend unit tests"
|
|
58
|
+
@uv run jlpm test
|
|
59
|
+
|
|
60
|
+
.PHONY: test-ui
|
|
61
|
+
test-ui: ## Run the JupyterLab UI integration tests.
|
|
62
|
+
@echo "🚀 Running JupyterLab UI tests with Playwright"
|
|
63
|
+
@uv run npm run build
|
|
64
|
+
@uv run --directory=ui-tests jlpm playwright test -u --reporter=list
|
|
@@ -1,15 +1,26 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: calkit-python
|
|
3
|
-
Version: 0.
|
|
3
|
+
Version: 0.33.1
|
|
4
4
|
Summary: Reproducibility simplified.
|
|
5
5
|
Project-URL: Homepage, https://calkit.org
|
|
6
6
|
Project-URL: Issues, https://github.com/calkit/calkit/issues
|
|
7
7
|
Project-URL: Repository, https://github.com/calkit/calkit
|
|
8
8
|
Author-email: Pete Bachant <petebachant@gmail.com>
|
|
9
9
|
License-File: LICENSE
|
|
10
|
+
Classifier: Framework :: Jupyter
|
|
11
|
+
Classifier: Framework :: Jupyter :: JupyterLab
|
|
12
|
+
Classifier: Framework :: Jupyter :: JupyterLab :: 4
|
|
13
|
+
Classifier: Framework :: Jupyter :: JupyterLab :: Extensions
|
|
14
|
+
Classifier: Framework :: Jupyter :: JupyterLab :: Extensions :: Prebuilt
|
|
10
15
|
Classifier: License :: OSI Approved :: MIT License
|
|
11
16
|
Classifier: Operating System :: OS Independent
|
|
17
|
+
Classifier: Programming Language :: Python
|
|
12
18
|
Classifier: Programming Language :: Python :: 3
|
|
19
|
+
Classifier: Programming Language :: Python :: 3.10
|
|
20
|
+
Classifier: Programming Language :: Python :: 3.11
|
|
21
|
+
Classifier: Programming Language :: Python :: 3.12
|
|
22
|
+
Classifier: Programming Language :: Python :: 3.13
|
|
23
|
+
Classifier: Programming Language :: Python :: 3.14
|
|
13
24
|
Requires-Python: >=3.10
|
|
14
25
|
Requires-Dist: arithmeval
|
|
15
26
|
Requires-Dist: bibtexparser
|
|
@@ -34,7 +45,7 @@ Requires-Dist: pywin32; platform_system == 'Windows'
|
|
|
34
45
|
Requires-Dist: requests
|
|
35
46
|
Requires-Dist: sqlitedict>=2.1.0
|
|
36
47
|
Requires-Dist: tqdm>=4.67.1
|
|
37
|
-
Requires-Dist: typer==0.
|
|
48
|
+
Requires-Dist: typer==0.21.1
|
|
38
49
|
Requires-Dist: uvicorn
|
|
39
50
|
Provides-Extra: data
|
|
40
51
|
Requires-Dist: pandas>=2.2.3; extra == 'data'
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
module.exports = require("@jupyterlab/testutils/lib/babel.config");
|
|
@@ -0,0 +1,49 @@
|
|
|
1
|
+
__version__ = "0.33.1"
|
|
2
|
+
|
|
3
|
+
from .core import * # noqa: F403, I001
|
|
4
|
+
from . import git # noqa: F401
|
|
5
|
+
from . import dvc # noqa: F401
|
|
6
|
+
from . import cloud # noqa: F401
|
|
7
|
+
from . import jupyter # noqa: F401
|
|
8
|
+
from . import config # noqa: F401
|
|
9
|
+
from . import models # noqa: F401
|
|
10
|
+
from . import office # noqa: F401
|
|
11
|
+
from . import templates # noqa: F401
|
|
12
|
+
from . import conda # noqa: F401
|
|
13
|
+
from . import calc # noqa: F401
|
|
14
|
+
from . import check # noqa: F401
|
|
15
|
+
from . import github # noqa: F401
|
|
16
|
+
from . import invenio # noqa: F401
|
|
17
|
+
from . import releases # noqa: F401
|
|
18
|
+
from . import licenses # noqa: F401
|
|
19
|
+
from . import overleaf # noqa: F401
|
|
20
|
+
from .notebooks import declare_notebook # noqa: F401
|
|
21
|
+
from .jupyterlab.routes import setup_route_handlers
|
|
22
|
+
|
|
23
|
+
|
|
24
|
+
def _jupyter_labextension_paths():
|
|
25
|
+
return [{"src": "labextension", "dest": "calkit"}]
|
|
26
|
+
|
|
27
|
+
|
|
28
|
+
def _jupyter_server_extension_points():
|
|
29
|
+
return [{"module": "calkit"}]
|
|
30
|
+
|
|
31
|
+
|
|
32
|
+
def _load_jupyter_server_extension(server_app):
|
|
33
|
+
"""Registers the API handler to receive HTTP requests from the frontend
|
|
34
|
+
extension.
|
|
35
|
+
|
|
36
|
+
Parameters
|
|
37
|
+
----------
|
|
38
|
+
server_app: jupyterlab.labapp.LabApp
|
|
39
|
+
JupyterLab application instance
|
|
40
|
+
"""
|
|
41
|
+
import os
|
|
42
|
+
|
|
43
|
+
# Change to root_dir so all handlers work in the correct directory context
|
|
44
|
+
root_dir = server_app.root_dir
|
|
45
|
+
os.chdir(root_dir)
|
|
46
|
+
server_app.log.info(f"Changed working directory to {root_dir}")
|
|
47
|
+
setup_route_handlers(server_app.web_app)
|
|
48
|
+
name = "calkit"
|
|
49
|
+
server_app.log.info(f"Registered {name} server extension")
|
|
@@ -3,6 +3,8 @@
|
|
|
3
3
|
from __future__ import annotations
|
|
4
4
|
|
|
5
5
|
import base64
|
|
6
|
+
import fnmatch
|
|
7
|
+
import json
|
|
6
8
|
import os
|
|
7
9
|
import subprocess
|
|
8
10
|
import sys
|
|
@@ -15,7 +17,9 @@ import typer
|
|
|
15
17
|
from tqdm import tqdm
|
|
16
18
|
|
|
17
19
|
import calkit
|
|
20
|
+
import calkit.invenio
|
|
18
21
|
from calkit.cli import raise_error
|
|
22
|
+
from calkit.models.core import _ImportedFromProject
|
|
19
23
|
|
|
20
24
|
import_app = typer.Typer(no_args_is_help=True)
|
|
21
25
|
|
|
@@ -32,11 +36,11 @@ def import_dataset(
|
|
|
32
36
|
),
|
|
33
37
|
],
|
|
34
38
|
dest_path: Annotated[
|
|
35
|
-
str,
|
|
39
|
+
str | None,
|
|
36
40
|
typer.Argument(help="Output path at which to save."),
|
|
37
41
|
] = None,
|
|
38
42
|
filter_paths: Annotated[
|
|
39
|
-
list[str],
|
|
43
|
+
list[str] | None,
|
|
40
44
|
typer.Option(
|
|
41
45
|
"--filter-paths",
|
|
42
46
|
help="Filter paths in target dataset if it's a folder.",
|
|
@@ -186,7 +190,7 @@ def import_dataset(
|
|
|
186
190
|
title=resp.get("title"),
|
|
187
191
|
description=resp.get("description"),
|
|
188
192
|
stage=None,
|
|
189
|
-
imported_from=
|
|
193
|
+
imported_from=_ImportedFromProject(
|
|
190
194
|
project=f"{owner_name}/{project_name}",
|
|
191
195
|
path=path,
|
|
192
196
|
git_rev=resp.get("git_rev"),
|
|
@@ -301,3 +305,196 @@ def import_environment(
|
|
|
301
305
|
repo.git.add("calkit.yaml")
|
|
302
306
|
if not no_commit and calkit.git.get_staged_files():
|
|
303
307
|
repo.git.commit(["-m", f"Import environment {src}"])
|
|
308
|
+
|
|
309
|
+
|
|
310
|
+
@import_app.command(name="zenodo")
|
|
311
|
+
def import_from_zenodo(
|
|
312
|
+
src: Annotated[str, typer.Argument(help="Source URL or DOI.")],
|
|
313
|
+
dest_dir: Annotated[
|
|
314
|
+
str,
|
|
315
|
+
typer.Argument(
|
|
316
|
+
help="Destination folder. Will be created if it doesn't exist"
|
|
317
|
+
),
|
|
318
|
+
],
|
|
319
|
+
kind: Annotated[
|
|
320
|
+
str | None,
|
|
321
|
+
typer.Option(
|
|
322
|
+
"--kind",
|
|
323
|
+
"-k",
|
|
324
|
+
help=(
|
|
325
|
+
"What kind of artifact is being imported, "
|
|
326
|
+
"e.g., a figure, dataset, publication."
|
|
327
|
+
),
|
|
328
|
+
),
|
|
329
|
+
] = None,
|
|
330
|
+
name_like: Annotated[
|
|
331
|
+
list[str],
|
|
332
|
+
typer.Option(
|
|
333
|
+
"--name-like",
|
|
334
|
+
help="Filter for file names like this. Glob patterns accepted.",
|
|
335
|
+
),
|
|
336
|
+
] = [],
|
|
337
|
+
name_not_like: Annotated[
|
|
338
|
+
list[str],
|
|
339
|
+
typer.Option(
|
|
340
|
+
"--name-not-like",
|
|
341
|
+
help="Exclude names matching pattern.",
|
|
342
|
+
),
|
|
343
|
+
] = [],
|
|
344
|
+
storage: Annotated[
|
|
345
|
+
str | None,
|
|
346
|
+
typer.Option(
|
|
347
|
+
"--storage",
|
|
348
|
+
help="Storage backend to use (Git or DVC). "
|
|
349
|
+
"If not specified, will be chosen based on size.",
|
|
350
|
+
),
|
|
351
|
+
] = None,
|
|
352
|
+
no_commit: Annotated[
|
|
353
|
+
bool,
|
|
354
|
+
typer.Option("--no-commit", help="Do not commit changes to project."),
|
|
355
|
+
] = False,
|
|
356
|
+
):
|
|
357
|
+
"""Import files from a Zenodo record."""
|
|
358
|
+
# Ensure destination directory either doesn't exist or is empty
|
|
359
|
+
if os.path.isdir(dest_dir):
|
|
360
|
+
if os.listdir(dest_dir):
|
|
361
|
+
raise_error("Destination directory exists and is not empty")
|
|
362
|
+
if kind is not None and kind not in ["figure", "dataset", "publication"]:
|
|
363
|
+
raise_error(
|
|
364
|
+
"Invalid kind; must be one of 'figure', 'dataset', or "
|
|
365
|
+
"'publication'"
|
|
366
|
+
)
|
|
367
|
+
# Fetch information about the record
|
|
368
|
+
# First, extract the record ID from the src
|
|
369
|
+
if "zenodo.org/record/" in src:
|
|
370
|
+
try:
|
|
371
|
+
record_id = int(src.split("zenodo.org/record/")[1].split("/")[0])
|
|
372
|
+
except Exception:
|
|
373
|
+
raise_error("Could not parse Zenodo record ID from URL")
|
|
374
|
+
elif "10.5281/zenodo." in src:
|
|
375
|
+
try:
|
|
376
|
+
record_id = int(src.split("10.5281/zenodo.")[1])
|
|
377
|
+
except Exception:
|
|
378
|
+
raise_error("Could not parse Zenodo record ID from DOI")
|
|
379
|
+
else:
|
|
380
|
+
raise_error("Source must be a Zenodo URL or DOI")
|
|
381
|
+
typer.echo(f"Fetching info for Zenodo record {record_id}")
|
|
382
|
+
try:
|
|
383
|
+
record = calkit.invenio.get(
|
|
384
|
+
f"/records/{record_id}", service="zenodo", auth=False
|
|
385
|
+
)
|
|
386
|
+
except Exception as e:
|
|
387
|
+
raise_error(f"Could not fetch record info from Zenodo: {e}")
|
|
388
|
+
# Get download URLs
|
|
389
|
+
download_urls = calkit.invenio.get_download_urls(
|
|
390
|
+
record_id, service="zenodo", auth=False
|
|
391
|
+
)
|
|
392
|
+
# Filter download URLs
|
|
393
|
+
filtered_urls = {}
|
|
394
|
+
for fname, url in download_urls.items():
|
|
395
|
+
if name_like:
|
|
396
|
+
if not any(
|
|
397
|
+
fnmatch.fnmatch(fname, pattern) for pattern in name_like
|
|
398
|
+
):
|
|
399
|
+
continue
|
|
400
|
+
if name_not_like:
|
|
401
|
+
if any(
|
|
402
|
+
fnmatch.fnmatch(fname, pattern) for pattern in name_not_like
|
|
403
|
+
):
|
|
404
|
+
continue
|
|
405
|
+
filtered_urls[fname] = url
|
|
406
|
+
if not filtered_urls:
|
|
407
|
+
raise_error("No files matched the specified name filters")
|
|
408
|
+
# Download files
|
|
409
|
+
for fname, url in filtered_urls.items():
|
|
410
|
+
out_path = os.path.join(dest_dir, fname) # fname may include subdirs
|
|
411
|
+
os.makedirs(os.path.dirname(out_path), exist_ok=True)
|
|
412
|
+
typer.echo(f"Downloading {fname} to {out_path}")
|
|
413
|
+
resp = requests.get(url, stream=True)
|
|
414
|
+
try:
|
|
415
|
+
resp.raise_for_status()
|
|
416
|
+
except Exception as e:
|
|
417
|
+
raise_error(f"Failed to download {fname} from {url}: {e}")
|
|
418
|
+
with open(out_path, "wb") as f:
|
|
419
|
+
for chunk in resp.iter_content(chunk_size=8192):
|
|
420
|
+
f.write(chunk)
|
|
421
|
+
# Decide if this should be stored in Git or DVC
|
|
422
|
+
repo = git.Repo()
|
|
423
|
+
commit_paths = []
|
|
424
|
+
if storage is None:
|
|
425
|
+
if calkit.get_size(dest_dir) > calkit.DVC_SIZE_THRESH_BYTES:
|
|
426
|
+
res = subprocess.run(
|
|
427
|
+
[sys.executable, "-m", "dvc", "add"], check=False
|
|
428
|
+
)
|
|
429
|
+
if res.returncode != 0:
|
|
430
|
+
raise_error("Failed to DVC add")
|
|
431
|
+
# Git add the .dvc file
|
|
432
|
+
dvc_file = dest_dir + ".dvc"
|
|
433
|
+
repo.git.add(dvc_file)
|
|
434
|
+
commit_paths.append(dvc_file)
|
|
435
|
+
else:
|
|
436
|
+
repo.git.add(dest_dir)
|
|
437
|
+
commit_paths.append(dest_dir)
|
|
438
|
+
elif storage.lower() == "dvc":
|
|
439
|
+
res = subprocess.run(
|
|
440
|
+
[sys.executable, "-m", "dvc", "add", dest_dir], check=False
|
|
441
|
+
)
|
|
442
|
+
if res.returncode != 0:
|
|
443
|
+
raise_error("Failed to DVC add")
|
|
444
|
+
# Git add the .dvc file
|
|
445
|
+
dvc_file = dest_dir + ".dvc"
|
|
446
|
+
repo.git.add(dvc_file)
|
|
447
|
+
commit_paths.append(dvc_file)
|
|
448
|
+
elif storage.lower() == "git":
|
|
449
|
+
repo.git.add(dest_dir)
|
|
450
|
+
commit_paths.append(dest_dir)
|
|
451
|
+
else:
|
|
452
|
+
raise_error("Invalid storage option; must be 'git' or 'dvc'")
|
|
453
|
+
# Determine if we should put this in one of the calkit.yaml categories
|
|
454
|
+
if kind is not None:
|
|
455
|
+
ck_info = calkit.load_calkit_info()
|
|
456
|
+
items = ck_info.get(kind + "s", [])
|
|
457
|
+
item_record = {
|
|
458
|
+
"path": dest_dir,
|
|
459
|
+
"imported_from": {
|
|
460
|
+
"doi": record.get("doi"),
|
|
461
|
+
},
|
|
462
|
+
"title": record.get("metadata", {}).get("title"),
|
|
463
|
+
}
|
|
464
|
+
items.append(item_record)
|
|
465
|
+
ck_info[kind + "s"] = items
|
|
466
|
+
with open("calkit.yaml", "w") as f:
|
|
467
|
+
calkit.ryaml.dump(ck_info, f)
|
|
468
|
+
commit_paths.append("calkit.yaml")
|
|
469
|
+
# Save a record of this import in .calkit/imports.json
|
|
470
|
+
import_record = {
|
|
471
|
+
"from": "zenodo",
|
|
472
|
+
"record_id": record_id,
|
|
473
|
+
"src": src,
|
|
474
|
+
"dest_dir": dest_dir,
|
|
475
|
+
"timestamp": calkit.utcnow(),
|
|
476
|
+
"kind": kind,
|
|
477
|
+
"storage": storage,
|
|
478
|
+
"name_like": name_like,
|
|
479
|
+
"name_not_like": name_not_like,
|
|
480
|
+
}
|
|
481
|
+
os.makedirs(".calkit", exist_ok=True)
|
|
482
|
+
imports_fpath = os.path.join(".calkit", "imports.json")
|
|
483
|
+
commit_paths.append(imports_fpath)
|
|
484
|
+
if os.path.isfile(imports_fpath):
|
|
485
|
+
with open(imports_fpath) as f:
|
|
486
|
+
imports = json.load(f)
|
|
487
|
+
else:
|
|
488
|
+
imports = []
|
|
489
|
+
imports.append(import_record)
|
|
490
|
+
with open(imports_fpath, "w") as f:
|
|
491
|
+
json.dump(imports, f, indent=2)
|
|
492
|
+
# Commit if desired
|
|
493
|
+
if not no_commit:
|
|
494
|
+
repo = git.Repo()
|
|
495
|
+
repo.git.add(commit_paths)
|
|
496
|
+
if repo.git.diff(commit_paths + ["--staged"]):
|
|
497
|
+
repo.git.commit(
|
|
498
|
+
commit_paths
|
|
499
|
+
+ ["-m", f"Import {src} from Zenodo to {dest_dir}"]
|
|
500
|
+
)
|
|
@@ -27,6 +27,13 @@ from typing_extensions import Annotated, Optional
|
|
|
27
27
|
import calkit
|
|
28
28
|
import calkit.matlab
|
|
29
29
|
import calkit.pipeline
|
|
30
|
+
from calkit import (
|
|
31
|
+
AUTO_IGNORE_PATHS,
|
|
32
|
+
AUTO_IGNORE_PREFIXES,
|
|
33
|
+
AUTO_IGNORE_SUFFIXES,
|
|
34
|
+
DVC_EXTENSIONS,
|
|
35
|
+
DVC_SIZE_THRESH_BYTES,
|
|
36
|
+
)
|
|
30
37
|
from calkit.cli import print_sep, raise_error, run_cmd, warn
|
|
31
38
|
from calkit.cli.check import (
|
|
32
39
|
check_app,
|
|
@@ -76,46 +83,6 @@ app.add_typer(overleaf_app, name="overleaf", help="Interact with Overleaf.")
|
|
|
76
83
|
app.add_typer(cloud_app, name="cloud", help="Interact with a Calkit Cloud.")
|
|
77
84
|
app.add_typer(slurm_app, name="slurm", help="Work with SLURM.")
|
|
78
85
|
|
|
79
|
-
# Constants for version control auto-ignore
|
|
80
|
-
AUTO_IGNORE_SUFFIXES = [
|
|
81
|
-
".DS_Store",
|
|
82
|
-
".env",
|
|
83
|
-
".pyc",
|
|
84
|
-
".synctex.gz",
|
|
85
|
-
".ipynb_checkpoints",
|
|
86
|
-
]
|
|
87
|
-
AUTO_IGNORE_PATHS = [os.path.join(".dvc", "config.local")]
|
|
88
|
-
AUTO_IGNORE_PREFIXES = [
|
|
89
|
-
".venv",
|
|
90
|
-
"__pycache__",
|
|
91
|
-
".ipynb_checkpoints",
|
|
92
|
-
".calkit/overleaf/",
|
|
93
|
-
]
|
|
94
|
-
# Constants for version control auto-add to DVC
|
|
95
|
-
DVC_EXTENSIONS = [
|
|
96
|
-
".png",
|
|
97
|
-
".jpeg",
|
|
98
|
-
".jpg",
|
|
99
|
-
".gif",
|
|
100
|
-
".h5",
|
|
101
|
-
".parquet",
|
|
102
|
-
".pickle",
|
|
103
|
-
".mp4",
|
|
104
|
-
".avi",
|
|
105
|
-
".webm",
|
|
106
|
-
".pdf",
|
|
107
|
-
".xlsx",
|
|
108
|
-
".docx",
|
|
109
|
-
".pptx",
|
|
110
|
-
".xls",
|
|
111
|
-
".doc",
|
|
112
|
-
".ppt",
|
|
113
|
-
".nc",
|
|
114
|
-
".nc4",
|
|
115
|
-
".zarr",
|
|
116
|
-
]
|
|
117
|
-
DVC_SIZE_THRESH_BYTES = 1_000_000
|
|
118
|
-
|
|
119
86
|
|
|
120
87
|
def _to_shell_cmd(cmd: list[str]) -> str:
|
|
121
88
|
"""Join a command to be compatible with running at the shell.
|
|
@@ -891,9 +858,9 @@ def _stage_run_info_from_log_content(log_content: str) -> dict:
|
|
|
891
858
|
|
|
892
859
|
@app.command(name="run")
|
|
893
860
|
def run(
|
|
894
|
-
targets:
|
|
895
|
-
|
|
896
|
-
|
|
861
|
+
targets: Annotated[
|
|
862
|
+
list[str] | None, typer.Argument(help="Stages to run.")
|
|
863
|
+
] = None,
|
|
897
864
|
quiet: Annotated[
|
|
898
865
|
bool, typer.Option("-q", "--quiet", help="Be quiet.")
|
|
899
866
|
] = False,
|
|
@@ -993,9 +960,11 @@ def run(
|
|
|
993
960
|
no_run_cache: Annotated[
|
|
994
961
|
bool, typer.Option("--no-run-cache", help="Ignore the run cache.")
|
|
995
962
|
] = False,
|
|
996
|
-
|
|
963
|
+
save_logs: Annotated[
|
|
997
964
|
bool,
|
|
998
|
-
typer.Option(
|
|
965
|
+
typer.Option(
|
|
966
|
+
"--log", "-l", help="Log the run and system information."
|
|
967
|
+
),
|
|
999
968
|
] = False,
|
|
1000
969
|
save_after_run: Annotated[
|
|
1001
970
|
bool,
|
|
@@ -1031,7 +1000,7 @@ def run(
|
|
|
1031
1000
|
help="Sync with Overleaf before and after running.",
|
|
1032
1001
|
),
|
|
1033
1002
|
] = False,
|
|
1034
|
-
):
|
|
1003
|
+
) -> dict:
|
|
1035
1004
|
"""Check dependencies and run the pipeline."""
|
|
1036
1005
|
import dvc.log
|
|
1037
1006
|
import dvc.repo
|
|
@@ -1059,7 +1028,7 @@ def run(
|
|
|
1059
1028
|
typer.echo("Getting system information")
|
|
1060
1029
|
# Get system information
|
|
1061
1030
|
system_info = calkit.get_system_info()
|
|
1062
|
-
if
|
|
1031
|
+
if save_logs:
|
|
1063
1032
|
# Save the system to .calkit/systems
|
|
1064
1033
|
if verbose:
|
|
1065
1034
|
typer.echo("Saving system information:")
|
|
@@ -1144,7 +1113,7 @@ def run(
|
|
|
1144
1113
|
targets.append(dvc_stage_name)
|
|
1145
1114
|
if not targets:
|
|
1146
1115
|
raise_error("No stages found to run")
|
|
1147
|
-
if
|
|
1116
|
+
if save_logs:
|
|
1148
1117
|
# Get status of Git repo before running
|
|
1149
1118
|
repo = git.Repo()
|
|
1150
1119
|
git_rev = repo.head.commit.hexsha
|
|
@@ -1191,35 +1160,37 @@ def run(
|
|
|
1191
1160
|
start_time_no_tz = calkit.utcnow(remove_tz=True)
|
|
1192
1161
|
start_time = calkit.utcnow(remove_tz=False)
|
|
1193
1162
|
run_id = uuid.uuid4().hex
|
|
1194
|
-
if
|
|
1195
|
-
|
|
1196
|
-
|
|
1197
|
-
|
|
1198
|
-
|
|
1199
|
-
|
|
1200
|
-
|
|
1201
|
-
|
|
1202
|
-
|
|
1203
|
-
|
|
1204
|
-
|
|
1205
|
-
|
|
1206
|
-
|
|
1207
|
-
|
|
1208
|
-
|
|
1209
|
-
|
|
1210
|
-
|
|
1211
|
-
|
|
1212
|
-
|
|
1213
|
-
|
|
1214
|
-
file_handler.setFormatter(formatter)
|
|
1215
|
-
dvc.log.logger.addHandler(file_handler)
|
|
1163
|
+
# Always log output, but only save systems/run data if specified
|
|
1164
|
+
log_fpath = os.path.join(
|
|
1165
|
+
".calkit",
|
|
1166
|
+
"logs",
|
|
1167
|
+
start_time_no_tz.isoformat(timespec="seconds").replace(":", "-")
|
|
1168
|
+
+ "-"
|
|
1169
|
+
+ run_id
|
|
1170
|
+
+ ".log",
|
|
1171
|
+
)
|
|
1172
|
+
if verbose:
|
|
1173
|
+
typer.echo(f"Starting run ID: {run_id}")
|
|
1174
|
+
typer.echo(f"Saving logs to {log_fpath}")
|
|
1175
|
+
os.makedirs(os.path.dirname(log_fpath), exist_ok=True)
|
|
1176
|
+
# Create a file handler for dvc.stage.run logger
|
|
1177
|
+
file_handler = logging.FileHandler(log_fpath, mode="w")
|
|
1178
|
+
file_handler.setLevel(logging.DEBUG)
|
|
1179
|
+
formatter = logging.Formatter("%(asctime)s - %(levelname)s - %(message)s")
|
|
1180
|
+
formatter.converter = time.gmtime # Use UTC time for asctime
|
|
1181
|
+
file_handler.setFormatter(formatter)
|
|
1182
|
+
dvc.log.logger.addHandler(file_handler)
|
|
1216
1183
|
# Remove newline logging in dvc.repo.reproduce
|
|
1217
1184
|
dvc.repo.reproduce.logger.setLevel(logging.ERROR)
|
|
1218
1185
|
# Disable other misc DVC output
|
|
1219
1186
|
dvc.ui.ui.write = lambda *args, **kwargs: None
|
|
1220
1187
|
res = dvc_cli_main(["repro"] + args)
|
|
1221
1188
|
failed = res != 0
|
|
1222
|
-
|
|
1189
|
+
# Parse log to get timing
|
|
1190
|
+
with open(log_fpath, "r") as f:
|
|
1191
|
+
log_content = f.read()
|
|
1192
|
+
stage_run_info = _stage_run_info_from_log_content(log_content)
|
|
1193
|
+
if save_logs:
|
|
1223
1194
|
# Get Git status after running
|
|
1224
1195
|
git_changed_files_after = calkit.git.get_changed_files(repo=repo)
|
|
1225
1196
|
git_staged_files_after = calkit.git.get_staged_files(repo=repo)
|
|
@@ -1228,10 +1199,6 @@ def run(
|
|
|
1228
1199
|
dvc_status_after = dvc_repo.status()
|
|
1229
1200
|
dvc_data_status_after = dvc_repo.data_status()
|
|
1230
1201
|
dvc_data_status_after.pop("git", None) # Remove git status
|
|
1231
|
-
# Parse log to get timing
|
|
1232
|
-
with open(log_fpath, "r") as f:
|
|
1233
|
-
log_content = f.read()
|
|
1234
|
-
stage_run_info = _stage_run_info_from_log_content(log_content)
|
|
1235
1202
|
# Save run information to a file
|
|
1236
1203
|
if verbose:
|
|
1237
1204
|
typer.echo("Saving run info")
|
|
@@ -1269,6 +1236,8 @@ def run(
|
|
|
1269
1236
|
os.makedirs(os.path.dirname(run_info_fpath), exist_ok=True)
|
|
1270
1237
|
with open(run_info_fpath, "w") as f:
|
|
1271
1238
|
json.dump(run_info, f, indent=2)
|
|
1239
|
+
else:
|
|
1240
|
+
os.remove(log_fpath)
|
|
1272
1241
|
os.environ.pop("CALKIT_PIPELINE_RUNNING", None)
|
|
1273
1242
|
if failed:
|
|
1274
1243
|
raise_error("Pipeline failed")
|
|
@@ -1291,6 +1260,7 @@ def run(
|
|
|
1291
1260
|
no_commit=False,
|
|
1292
1261
|
no_push=not save_after_run,
|
|
1293
1262
|
)
|
|
1263
|
+
return {"dvc_stages": dvc_stages, "stage_run_info": stage_run_info}
|
|
1294
1264
|
|
|
1295
1265
|
|
|
1296
1266
|
@app.command(name="manual-step", help="Execute a manual step.")
|
|
@@ -1246,7 +1246,7 @@ def new_uv_venv(
|
|
|
1246
1246
|
] = ".venv",
|
|
1247
1247
|
python_version: Annotated[
|
|
1248
1248
|
str | None, typer.Option("--python", "-p", help="Python version.")
|
|
1249
|
-
] = "3.
|
|
1249
|
+
] = "3.14",
|
|
1250
1250
|
description: Annotated[
|
|
1251
1251
|
str | None, typer.Option("--description", help="Description.")
|
|
1252
1252
|
] = None,
|
|
@@ -1274,7 +1274,6 @@ def new_uv_venv(
|
|
|
1274
1274
|
raise_error("Output path already exists (use -f to overwrite)")
|
|
1275
1275
|
elif packages is None and not os.path.isfile(path):
|
|
1276
1276
|
raise_error("If path doesn't exist, packages must be specified")
|
|
1277
|
-
repo = git.Repo()
|
|
1278
1277
|
# Add environment to Calkit info
|
|
1279
1278
|
ck_info = calkit.load_calkit_info()
|
|
1280
1279
|
# If environments is a list instead of a dict, reformulate it
|
|
@@ -1301,7 +1300,6 @@ def new_uv_venv(
|
|
|
1301
1300
|
_check_path_dir(path)
|
|
1302
1301
|
with open(path, "w") as f:
|
|
1303
1302
|
f.write(packages_txt)
|
|
1304
|
-
repo.git.add(path)
|
|
1305
1303
|
typer.echo("Adding environment to calkit.yaml")
|
|
1306
1304
|
env = dict(path=path, kind="uv-venv", prefix=prefix)
|
|
1307
1305
|
if python_version is not None:
|
|
@@ -1312,10 +1310,13 @@ def new_uv_venv(
|
|
|
1312
1310
|
ck_info["environments"] = envs
|
|
1313
1311
|
with open("calkit.yaml", "w") as f:
|
|
1314
1312
|
ryaml.dump(ck_info, f)
|
|
1315
|
-
|
|
1313
|
+
if not no_commit:
|
|
1314
|
+
repo = git.Repo()
|
|
1315
|
+
repo.git.add(path)
|
|
1316
|
+
repo.git.add("calkit.yaml")
|
|
1316
1317
|
if not no_check:
|
|
1317
1318
|
env_lock_fpath = check_environment(env_name=name)
|
|
1318
|
-
if env_lock_fpath is not None:
|
|
1319
|
+
if env_lock_fpath is not None and not no_commit:
|
|
1319
1320
|
repo.git.add(env_lock_fpath)
|
|
1320
1321
|
if not no_commit and repo.git.diff("--staged"):
|
|
1321
1322
|
repo.git.commit(["-m", f"Add uv venv {name}"])
|