calkit-python 0.19.1__tar.gz → 0.20.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.20.1/.pre-commit-config.yaml +24 -0
- calkit_python-0.20.1/CONTRIBUTING.md +75 -0
- calkit_python-0.20.1/Makefile +36 -0
- {calkit_python-0.19.1 → calkit_python-0.20.1}/PKG-INFO +23 -23
- {calkit_python-0.19.1 → calkit_python-0.20.1}/README.md +16 -12
- {calkit_python-0.19.1 → calkit_python-0.20.1}/calkit/__init__.py +4 -1
- calkit_python-0.20.1/calkit/cli/import_.py +247 -0
- {calkit_python-0.19.1 → calkit_python-0.20.1}/calkit/cli/new.py +447 -0
- {calkit_python-0.19.1 → calkit_python-0.20.1}/calkit/cloud.py +9 -1
- {calkit_python-0.19.1 → calkit_python-0.20.1}/calkit/config.py +23 -8
- {calkit_python-0.19.1 → calkit_python-0.20.1}/calkit/dvc.py +11 -3
- calkit_python-0.20.1/calkit/github.py +70 -0
- {calkit_python-0.19.1 → calkit_python-0.20.1}/calkit/models.py +1 -0
- calkit_python-0.20.1/calkit/releases.py +159 -0
- {calkit_python-0.19.1 → calkit_python-0.20.1}/calkit/templates/latex/jfm/jfm.bst +5 -5
- {calkit_python-0.19.1 → calkit_python-0.20.1}/calkit/templates/latex/jfm/jfm.cls +1 -1
- {calkit_python-0.19.1 → calkit_python-0.20.1}/calkit/templates/latex/jfm/lineno-FLM.sty +1 -1
- {calkit_python-0.19.1 → calkit_python-0.20.1}/calkit/templates/latex/jfm/upmath.sty +0 -1
- calkit_python-0.20.1/calkit/zenodo.py +82 -0
- calkit_python-0.20.1/docs/img/connect-zenodo.png +0 -0
- calkit_python-0.20.1/docs/releases.md +86 -0
- {calkit_python-0.19.1 → calkit_python-0.20.1}/docs/tutorials/existing-project.md +4 -4
- calkit_python-0.20.1/docs/tutorials/index.md +12 -0
- {calkit_python-0.19.1 → calkit_python-0.20.1}/docs/tutorials/notebook-pipeline.md +1 -0
- {calkit_python-0.19.1 → calkit_python-0.20.1}/docs/tutorials/office.md +26 -25
- {calkit_python-0.19.1 → calkit_python-0.20.1}/docs/tutorials/openfoam.md +2 -2
- {calkit_python-0.19.1 → calkit_python-0.20.1}/mkdocs.yml +2 -0
- {calkit_python-0.19.1 → calkit_python-0.20.1}/pyproject.toml +35 -7
- {calkit_python-0.19.1 → calkit_python-0.20.1}/uv.lock +1378 -428
- calkit_python-0.19.1/calkit/cli/import_.py +0 -164
- {calkit_python-0.19.1 → calkit_python-0.20.1}/.github/FUNDING.yml +0 -0
- {calkit_python-0.19.1 → calkit_python-0.20.1}/.github/workflows/docs.yml +0 -0
- {calkit_python-0.19.1 → calkit_python-0.20.1}/.github/workflows/publish-test.yml +0 -0
- {calkit_python-0.19.1 → calkit_python-0.20.1}/.github/workflows/publish.yml +0 -0
- {calkit_python-0.19.1 → calkit_python-0.20.1}/.gitignore +0 -0
- {calkit_python-0.19.1 → calkit_python-0.20.1}/LICENSE +0 -0
- {calkit_python-0.19.1 → calkit_python-0.20.1}/calkit/__main__.py +0 -0
- {calkit_python-0.19.1 → calkit_python-0.20.1}/calkit/calc.py +0 -0
- {calkit_python-0.19.1 → calkit_python-0.20.1}/calkit/check.py +0 -0
- {calkit_python-0.19.1 → calkit_python-0.20.1}/calkit/cli/__init__.py +0 -0
- {calkit_python-0.19.1 → calkit_python-0.20.1}/calkit/cli/check.py +0 -0
- {calkit_python-0.19.1 → calkit_python-0.20.1}/calkit/cli/config.py +0 -0
- {calkit_python-0.19.1 → calkit_python-0.20.1}/calkit/cli/core.py +0 -0
- {calkit_python-0.19.1 → calkit_python-0.20.1}/calkit/cli/list.py +0 -0
- {calkit_python-0.19.1 → calkit_python-0.20.1}/calkit/cli/main.py +0 -0
- {calkit_python-0.19.1 → calkit_python-0.20.1}/calkit/cli/notebooks.py +0 -0
- {calkit_python-0.19.1 → calkit_python-0.20.1}/calkit/cli/office.py +0 -0
- {calkit_python-0.19.1 → calkit_python-0.20.1}/calkit/cli/update.py +0 -0
- {calkit_python-0.19.1 → calkit_python-0.20.1}/calkit/conda.py +0 -0
- {calkit_python-0.19.1 → calkit_python-0.20.1}/calkit/core.py +0 -0
- {calkit_python-0.19.1 → calkit_python-0.20.1}/calkit/datasets.py +0 -0
- {calkit_python-0.19.1 → calkit_python-0.20.1}/calkit/docker.py +0 -0
- {calkit_python-0.19.1 → calkit_python-0.20.1}/calkit/git.py +0 -0
- {calkit_python-0.19.1 → calkit_python-0.20.1}/calkit/gui.py +0 -0
- {calkit_python-0.19.1 → calkit_python-0.20.1}/calkit/jupyter.py +0 -0
- {calkit_python-0.19.1 → calkit_python-0.20.1}/calkit/magics.py +0 -0
- {calkit_python-0.19.1 → calkit_python-0.20.1}/calkit/office.py +0 -0
- {calkit_python-0.19.1 → calkit_python-0.20.1}/calkit/ops.py +0 -0
- {calkit_python-0.19.1 → calkit_python-0.20.1}/calkit/server.py +0 -0
- {calkit_python-0.19.1 → calkit_python-0.20.1}/calkit/templates/__init__.py +0 -0
- {calkit_python-0.19.1 → calkit_python-0.20.1}/calkit/templates/core.py +0 -0
- {calkit_python-0.19.1 → calkit_python-0.20.1}/calkit/templates/latex/__init__.py +0 -0
- {calkit_python-0.19.1 → calkit_python-0.20.1}/calkit/templates/latex/article/paper.tex +0 -0
- {calkit_python-0.19.1 → calkit_python-0.20.1}/calkit/templates/latex/core.py +0 -0
- {calkit_python-0.19.1 → calkit_python-0.20.1}/calkit/templates/latex/jfm/paper.tex +0 -0
- {calkit_python-0.19.1 → calkit_python-0.20.1}/calkit/tests/__init__.py +0 -0
- {calkit_python-0.19.1 → calkit_python-0.20.1}/calkit/tests/cli/__init__.py +0 -0
- {calkit_python-0.19.1 → calkit_python-0.20.1}/calkit/tests/cli/test_list.py +0 -0
- {calkit_python-0.19.1 → calkit_python-0.20.1}/calkit/tests/cli/test_main.py +0 -0
- {calkit_python-0.19.1 → calkit_python-0.20.1}/calkit/tests/cli/test_new.py +0 -0
- {calkit_python-0.19.1 → calkit_python-0.20.1}/calkit/tests/test_calc.py +0 -0
- {calkit_python-0.19.1 → calkit_python-0.20.1}/calkit/tests/test_check.py +0 -0
- {calkit_python-0.19.1 → calkit_python-0.20.1}/calkit/tests/test_conda.py +0 -0
- {calkit_python-0.19.1 → calkit_python-0.20.1}/calkit/tests/test_core.py +0 -0
- {calkit_python-0.19.1 → calkit_python-0.20.1}/calkit/tests/test_dvc.py +0 -0
- {calkit_python-0.19.1 → calkit_python-0.20.1}/calkit/tests/test_jupyter.py +0 -0
- {calkit_python-0.19.1 → calkit_python-0.20.1}/calkit/tests/test_magics.py +0 -0
- {calkit_python-0.19.1 → calkit_python-0.20.1}/calkit/tests/test_templates.py +0 -0
- {calkit_python-0.19.1 → calkit_python-0.20.1}/docs/CNAME +0 -0
- {calkit_python-0.19.1 → calkit_python-0.20.1}/docs/apps.md +0 -0
- {calkit_python-0.19.1 → calkit_python-0.20.1}/docs/calculations.md +0 -0
- {calkit_python-0.19.1 → calkit_python-0.20.1}/docs/calkit-yaml.md +0 -0
- {calkit_python-0.19.1 → calkit_python-0.20.1}/docs/cli-reference.md +0 -0
- {calkit_python-0.19.1 → calkit_python-0.20.1}/docs/cloud-integration.md +0 -0
- {calkit_python-0.19.1 → calkit_python-0.20.1}/docs/datasets.md +0 -0
- {calkit_python-0.19.1 → calkit_python-0.20.1}/docs/environments.md +0 -0
- {calkit_python-0.19.1 → calkit_python-0.20.1}/docs/examples.md +0 -0
- {calkit_python-0.19.1 → calkit_python-0.20.1}/docs/help.md +0 -0
- {calkit_python-0.19.1 → calkit_python-0.20.1}/docs/img/c-to-the-k-white.svg +0 -0
- {calkit_python-0.19.1 → calkit_python-0.20.1}/docs/img/calkit-no-bg.png +0 -0
- {calkit_python-0.19.1 → calkit_python-0.20.1}/docs/index.md +0 -0
- {calkit_python-0.19.1 → calkit_python-0.20.1}/docs/installation.md +0 -0
- {calkit_python-0.19.1 → calkit_python-0.20.1}/docs/local-server.md +0 -0
- {calkit_python-0.19.1 → calkit_python-0.20.1}/docs/pipeline/index.md +0 -0
- {calkit_python-0.19.1 → calkit_python-0.20.1}/docs/pipeline/manual-steps.md +0 -0
- {calkit_python-0.19.1 → calkit_python-0.20.1}/docs/references.md +0 -0
- {calkit_python-0.19.1 → calkit_python-0.20.1}/docs/tutorials/adding-latex-pub-docker.md +0 -0
- {calkit_python-0.19.1 → calkit_python-0.20.1}/docs/tutorials/conda-envs.md +0 -0
- {calkit_python-0.19.1 → calkit_python-0.20.1}/docs/tutorials/first-project.md +0 -0
- {calkit_python-0.19.1 → calkit_python-0.20.1}/docs/tutorials/img/latex-codespaces/building-codespace.png +0 -0
- {calkit_python-0.19.1 → calkit_python-0.20.1}/docs/tutorials/img/latex-codespaces/codespaces-secrets-2.png +0 -0
- {calkit_python-0.19.1 → calkit_python-0.20.1}/docs/tutorials/img/latex-codespaces/editor-split.png +0 -0
- {calkit_python-0.19.1 → calkit_python-0.20.1}/docs/tutorials/img/latex-codespaces/go-to-linked-code.png +0 -0
- {calkit_python-0.19.1 → calkit_python-0.20.1}/docs/tutorials/img/latex-codespaces/issue-from-selection.png +0 -0
- {calkit_python-0.19.1 → calkit_python-0.20.1}/docs/tutorials/img/latex-codespaces/new-project.png +0 -0
- {calkit_python-0.19.1 → calkit_python-0.20.1}/docs/tutorials/img/latex-codespaces/new-pub-2.png +0 -0
- {calkit_python-0.19.1 → calkit_python-0.20.1}/docs/tutorials/img/latex-codespaces/new-token.png +0 -0
- {calkit_python-0.19.1 → calkit_python-0.20.1}/docs/tutorials/img/latex-codespaces/paper.tex.png +0 -0
- {calkit_python-0.19.1 → calkit_python-0.20.1}/docs/tutorials/img/latex-codespaces/project-home-3.png +0 -0
- {calkit_python-0.19.1 → calkit_python-0.20.1}/docs/tutorials/img/latex-codespaces/push.png +0 -0
- {calkit_python-0.19.1 → calkit_python-0.20.1}/docs/tutorials/img/latex-codespaces/stage.png +0 -0
- {calkit_python-0.19.1 → calkit_python-0.20.1}/docs/tutorials/img/office/anakin-excel.jpg +0 -0
- {calkit_python-0.19.1 → calkit_python-0.20.1}/docs/tutorials/img/office/chart-more-rows.png +0 -0
- {calkit_python-0.19.1 → calkit_python-0.20.1}/docs/tutorials/img/office/create-project.png +0 -0
- {calkit_python-0.19.1 → calkit_python-0.20.1}/docs/tutorials/img/office/elsevier-research-data-guidelines.png +0 -0
- {calkit_python-0.19.1 → calkit_python-0.20.1}/docs/tutorials/img/office/excel-chart.png +0 -0
- {calkit_python-0.19.1 → calkit_python-0.20.1}/docs/tutorials/img/office/excel-data.png +0 -0
- {calkit_python-0.19.1 → calkit_python-0.20.1}/docs/tutorials/img/office/insert-link-to-file.png +0 -0
- {calkit_python-0.19.1 → calkit_python-0.20.1}/docs/tutorials/img/office/needs-clone.png +0 -0
- {calkit_python-0.19.1 → calkit_python-0.20.1}/docs/tutorials/img/office/new-stage.png +0 -0
- {calkit_python-0.19.1 → calkit_python-0.20.1}/docs/tutorials/img/office/phd-comics-version-control.webp +0 -0
- {calkit_python-0.19.1 → calkit_python-0.20.1}/docs/tutorials/img/office/pipeline-out-of-date.png +0 -0
- {calkit_python-0.19.1 → calkit_python-0.20.1}/docs/tutorials/img/office/status-more-rows.png +0 -0
- {calkit_python-0.19.1 → calkit_python-0.20.1}/docs/tutorials/img/office/uncommitted-changes.png +0 -0
- {calkit_python-0.19.1 → calkit_python-0.20.1}/docs/tutorials/img/office/untracked-data.png +0 -0
- {calkit_python-0.19.1 → calkit_python-0.20.1}/docs/tutorials/img/office/updated-publication.png +0 -0
- {calkit_python-0.19.1 → calkit_python-0.20.1}/docs/tutorials/img/office/word-to-pdf-stage-2.png +0 -0
- {calkit_python-0.19.1 → calkit_python-0.20.1}/docs/tutorials/img/office/workflow-page.png +0 -0
- {calkit_python-0.19.1 → calkit_python-0.20.1}/docs/tutorials/img/openfoam/clone.png +0 -0
- {calkit_python-0.19.1 → calkit_python-0.20.1}/docs/tutorials/img/openfoam/create-project.png +0 -0
- {calkit_python-0.19.1 → calkit_python-0.20.1}/docs/tutorials/img/openfoam/datasets-page.png +0 -0
- {calkit_python-0.19.1 → calkit_python-0.20.1}/docs/tutorials/img/openfoam/figure-on-website-updated.png +0 -0
- {calkit_python-0.19.1 → calkit_python-0.20.1}/docs/tutorials/img/openfoam/figure-on-website.png +0 -0
- {calkit_python-0.19.1 → calkit_python-0.20.1}/docs/tutorials/img/openfoam/new-token.png +0 -0
- {calkit_python-0.19.1 → calkit_python-0.20.1}/docs/tutorials/img/openfoam/reclone.png +0 -0
- {calkit_python-0.19.1 → calkit_python-0.20.1}/docs/tutorials/img/openfoam/status-after-import-dataset.png +0 -0
- {calkit_python-0.19.1 → calkit_python-0.20.1}/docs/tutorials/img/run-proc.png +0 -0
- {calkit_python-0.19.1 → calkit_python-0.20.1}/docs/tutorials/latex-codespaces.md +0 -0
- {calkit_python-0.19.1 → calkit_python-0.20.1}/docs/tutorials/matlab.md +0 -0
- {calkit_python-0.19.1 → calkit_python-0.20.1}/docs/tutorials/procedures.md +0 -0
- {calkit_python-0.19.1 → calkit_python-0.20.1}/docs/version-control.md +0 -0
- {calkit_python-0.19.1 → calkit_python-0.20.1}/test/pipeline.ipynb +0 -0
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
repos:
|
|
2
|
+
- repo: https://github.com/pre-commit/pre-commit-hooks
|
|
3
|
+
rev: "v4.4.0"
|
|
4
|
+
hooks:
|
|
5
|
+
- id: check-case-conflict
|
|
6
|
+
- id: check-merge-conflict
|
|
7
|
+
- id: end-of-file-fixer
|
|
8
|
+
- id: trailing-whitespace
|
|
9
|
+
|
|
10
|
+
- repo: https://github.com/astral-sh/ruff-pre-commit
|
|
11
|
+
rev: "v0.6.3"
|
|
12
|
+
hooks:
|
|
13
|
+
- id: ruff
|
|
14
|
+
args: [--exit-non-zero-on-fix, --config=pyproject.toml]
|
|
15
|
+
exclude: calkit
|
|
16
|
+
- id: ruff-format
|
|
17
|
+
args: [--config=pyproject.toml]
|
|
18
|
+
exclude: calkit
|
|
19
|
+
|
|
20
|
+
- repo: https://github.com/pre-commit/mirrors-prettier
|
|
21
|
+
rev: "v3.0.3"
|
|
22
|
+
hooks:
|
|
23
|
+
- id: prettier
|
|
24
|
+
exclude: calkit
|
|
@@ -0,0 +1,75 @@
|
|
|
1
|
+
# Contributing to Calkit
|
|
2
|
+
|
|
3
|
+
Thank you for considering contributing to Calkit!
|
|
4
|
+
We welcome contributions of all kinds, including code, documentation,
|
|
5
|
+
bug reports, and feature suggestions.
|
|
6
|
+
This guide will help you get started.
|
|
7
|
+
|
|
8
|
+
## 🛠 How to contribute
|
|
9
|
+
|
|
10
|
+
### 1. Find an issue to work on
|
|
11
|
+
|
|
12
|
+
- Check the **[backlog](https://github.com/orgs/calkit/projects/1/views/1)**
|
|
13
|
+
for issues that are ready to be worked on.
|
|
14
|
+
- Look for issues labeled `good first issue` if you're new.
|
|
15
|
+
- If you have an idea, open a new issue and discuss it before coding.
|
|
16
|
+
|
|
17
|
+
### 2. Set up your development environment
|
|
18
|
+
|
|
19
|
+
1. [**Fork** the repository](https://github.com/calkit/calkit/fork).
|
|
20
|
+
1. **Clone** your fork locally:
|
|
21
|
+
```bash
|
|
22
|
+
git clone https://github.com/{your-username}/calkit.git
|
|
23
|
+
cd calkit
|
|
24
|
+
```
|
|
25
|
+
1. **Install system-level dependencies:**
|
|
26
|
+
- [Docker](https://docker.com)
|
|
27
|
+
- [Miniforge](https://conda-forge.org/download/)
|
|
28
|
+
- [uv](https://docs.astral.sh/uv/getting-started/installation/)
|
|
29
|
+
1. **Run tests** to ensure everything is working:
|
|
30
|
+
```bash
|
|
31
|
+
uv run pytest
|
|
32
|
+
```
|
|
33
|
+
|
|
34
|
+
### 3. Make your changes
|
|
35
|
+
|
|
36
|
+
- Create a new branch:
|
|
37
|
+
```bash
|
|
38
|
+
git checkout -b your-feature-name
|
|
39
|
+
```
|
|
40
|
+
- Check and fix code formatting:
|
|
41
|
+
```bash
|
|
42
|
+
make format
|
|
43
|
+
```
|
|
44
|
+
- Commit your changes
|
|
45
|
+
(use the imperative mood and capitalize the first letter,
|
|
46
|
+
but don't use punctuation):
|
|
47
|
+
```bash
|
|
48
|
+
git add .
|
|
49
|
+
git commit -m "Short description of your change"
|
|
50
|
+
```
|
|
51
|
+
- Push your branch:
|
|
52
|
+
```bash
|
|
53
|
+
git push origin your-feature-name -u
|
|
54
|
+
```
|
|
55
|
+
|
|
56
|
+
### 4. Submit a pull request (PR)
|
|
57
|
+
|
|
58
|
+
- Open a **Pull request** on GitHub.
|
|
59
|
+
- Link the PR to the issue it resolves by adding "resolves #{issue number}"
|
|
60
|
+
to the description.
|
|
61
|
+
- Wait for a review and make necessary changes.
|
|
62
|
+
|
|
63
|
+
## 💡 Other ways to contribute
|
|
64
|
+
|
|
65
|
+
- **Report bugs**: Open an issue with detailed reproduction steps.
|
|
66
|
+
- **Improve documentation**: Help us make Calkit's docs better.
|
|
67
|
+
- **Suggest features**: Share your ideas for improvements.
|
|
68
|
+
|
|
69
|
+
## 🎉 Join the community
|
|
70
|
+
|
|
71
|
+
- Participate in **[GitHub Discussions](https://github.com/calkit/discussions)**.
|
|
72
|
+
- Join our [**Discord**](https://discord.gg/ubb7gAXc) for real-time collaboration.
|
|
73
|
+
- Follow our updates on [**LinkedIn**](https://linkedin.com/company/calkit).
|
|
74
|
+
|
|
75
|
+
We appreciate your help in making Calkit better! 🚀
|
|
@@ -0,0 +1,36 @@
|
|
|
1
|
+
.PHONY: help
|
|
2
|
+
help: ## Show this help.
|
|
3
|
+
@uv run python -c "import re; \
|
|
4
|
+
[[print(f'\033[36m{m[0]:<20}\033[0m {m[1]}') for m in re.findall(r'^([a-zA-Z_-]+):.*?## (.*)$$', open(makefile).read(), re.M)] for makefile in ('$(MAKEFILE_LIST)').strip().split()]"
|
|
5
|
+
|
|
6
|
+
.PHONY: install
|
|
7
|
+
install: ## Create the project's virtual environment.
|
|
8
|
+
@echo "🚀 Creating virtual environment"
|
|
9
|
+
@uv sync
|
|
10
|
+
|
|
11
|
+
.PHONY: format
|
|
12
|
+
format: ## Automatically format files.
|
|
13
|
+
@echo "🚀 Linting code with pre-commit"
|
|
14
|
+
@uv run pre-commit run -a
|
|
15
|
+
|
|
16
|
+
.PHONY: check
|
|
17
|
+
check: format ## Run code quality tools.
|
|
18
|
+
@echo "🚀 Checking lock file consistency with 'pyproject.toml'"
|
|
19
|
+
@uv lock --locked
|
|
20
|
+
@echo "🚀 Static type checking with mypy"
|
|
21
|
+
@uv run mypy .
|
|
22
|
+
@echo "🚀 Checking for obsolete dependencies with deptry"
|
|
23
|
+
@uv run deptry .
|
|
24
|
+
|
|
25
|
+
.PHONY: test
|
|
26
|
+
test: ## Test the code with pytest.
|
|
27
|
+
@echo "🚀 Testing code with pytest"
|
|
28
|
+
@uv run pytest --cov --cov-config=pyproject.toml --cov-report=xml
|
|
29
|
+
|
|
30
|
+
.PHONY: docs-test
|
|
31
|
+
docs-test: ## Test if documentation can be built without warnings or errors.
|
|
32
|
+
@uv run mkdocs build -s
|
|
33
|
+
|
|
34
|
+
.PHONY: docs
|
|
35
|
+
docs: ## Build and serve the documentation.
|
|
36
|
+
@uv run mkdocs serve
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: calkit-python
|
|
3
|
-
Version: 0.
|
|
3
|
+
Version: 0.20.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
|
|
@@ -10,11 +10,12 @@ License-File: LICENSE
|
|
|
10
10
|
Classifier: License :: OSI Approved :: MIT License
|
|
11
11
|
Classifier: Operating System :: OS Independent
|
|
12
12
|
Classifier: Programming Language :: Python :: 3
|
|
13
|
-
Requires-Python: >=3.
|
|
13
|
+
Requires-Python: >=3.9
|
|
14
14
|
Requires-Dist: arithmeval
|
|
15
|
+
Requires-Dist: bibtexparser
|
|
15
16
|
Requires-Dist: checksumdir
|
|
16
17
|
Requires-Dist: docx2pdf
|
|
17
|
-
Requires-Dist: dvc
|
|
18
|
+
Requires-Dist: dvc>=3.59.0
|
|
18
19
|
Requires-Dist: eval-type-backport; python_version < '3.10'
|
|
19
20
|
Requires-Dist: fastapi
|
|
20
21
|
Requires-Dist: gitpython
|
|
@@ -27,17 +28,12 @@ Requires-Dist: pyjwt
|
|
|
27
28
|
Requires-Dist: python-dotenv>=1
|
|
28
29
|
Requires-Dist: pywin32; platform_system == 'Windows'
|
|
29
30
|
Requires-Dist: requests
|
|
31
|
+
Requires-Dist: tqdm>=4.67.1
|
|
30
32
|
Requires-Dist: typer
|
|
31
33
|
Requires-Dist: uvicorn
|
|
32
34
|
Provides-Extra: data
|
|
33
|
-
Requires-Dist: pandas; extra == 'data'
|
|
34
|
-
Requires-Dist: polars; extra == 'data'
|
|
35
|
-
Provides-Extra: dev
|
|
36
|
-
Requires-Dist: pytest; extra == 'dev'
|
|
37
|
-
Provides-Extra: docs
|
|
38
|
-
Requires-Dist: mkdocs; extra == 'docs'
|
|
39
|
-
Requires-Dist: mkdocs-material; extra == 'docs'
|
|
40
|
-
Requires-Dist: mkdocs-mermaid2-plugin; extra == 'docs'
|
|
35
|
+
Requires-Dist: pandas>=2.2.3; extra == 'data'
|
|
36
|
+
Requires-Dist: polars>=1.18.0; extra == 'data'
|
|
41
37
|
Description-Content-Type: text/markdown
|
|
42
38
|
|
|
43
39
|
<p align="center">
|
|
@@ -45,6 +41,19 @@ Description-Content-Type: text/markdown
|
|
|
45
41
|
<img width="40%" src="docs/img/calkit-no-bg.png" alt="Calkit">
|
|
46
42
|
</a>
|
|
47
43
|
</p>
|
|
44
|
+
<p align="center">
|
|
45
|
+
<a href="https://docs.calkit.org" target="_blank">
|
|
46
|
+
Documentation
|
|
47
|
+
</a>
|
|
48
|
+
|
|
|
49
|
+
<a href="https://docs.calkit.org/tutorials" target="_blank">
|
|
50
|
+
Tutorials
|
|
51
|
+
</a>
|
|
52
|
+
|
|
|
53
|
+
<a href="https://github.com/orgs/calkit/discussions" target="_blank">
|
|
54
|
+
Discussions
|
|
55
|
+
</a>
|
|
56
|
+
</p>
|
|
48
57
|
|
|
49
58
|
Calkit is a framework and toolkit for reproducible research projects.
|
|
50
59
|
It acts as a top-level layer to integrate and simplify the use of enabling
|
|
@@ -57,8 +66,6 @@ Calkit also adds a domain-specific data model
|
|
|
57
66
|
such that all aspects of the research process can be fully described in a
|
|
58
67
|
single repository and therefore easily consumed by others.
|
|
59
68
|
|
|
60
|
-
To learn more, see the [documentation](https://docs.calkit.org).
|
|
61
|
-
|
|
62
69
|
## Installation
|
|
63
70
|
|
|
64
71
|
To install Calkit, [Git](https://git-scm.com) and Python must be installed.
|
|
@@ -131,17 +138,10 @@ calkit save -am "Run pipeline"
|
|
|
131
138
|
|
|
132
139
|
This will commit and push to both GitHub and the Calkit Cloud.
|
|
133
140
|
|
|
134
|
-
##
|
|
135
|
-
|
|
136
|
-
- [LaTeX collaboration with GitHub Codespaces](https://docs.calkit.org/tutorials/latex-codespaces/)
|
|
137
|
-
- [Jupyter notebook as a DVC pipeline](https://docs.calkit.org/tutorials/notebook-pipeline/)
|
|
138
|
-
- [Keeping track of conda environments](https://docs.calkit.org/tutorials/conda-envs/)
|
|
139
|
-
- [Defining and executing manual procedures](https://docs.calkit.org/tutorials/procedures/)
|
|
140
|
-
- [Adding a new LaTeX-based publication with its own Docker build environment](https://docs.calkit.org/tutorials/adding-latex-pub-docker/)
|
|
141
|
-
- [A reproducible workflow using Microsoft Office (Word and Excel)](https://docs.calkit.org/tutorials/office/)
|
|
142
|
-
- [Reproducible OpenFOAM simulations](https://docs.calkit.org/tutorials/openfoam/)
|
|
141
|
+
## Get involved
|
|
143
142
|
|
|
144
|
-
|
|
143
|
+
We welcome all kinds of contributions!
|
|
144
|
+
See [CONTRIBUTING.md](CONTRIBUTING.md) to learn how to get involved.
|
|
145
145
|
|
|
146
146
|
## Why does reproducibility matter?
|
|
147
147
|
|
|
@@ -3,6 +3,19 @@
|
|
|
3
3
|
<img width="40%" src="docs/img/calkit-no-bg.png" alt="Calkit">
|
|
4
4
|
</a>
|
|
5
5
|
</p>
|
|
6
|
+
<p align="center">
|
|
7
|
+
<a href="https://docs.calkit.org" target="_blank">
|
|
8
|
+
Documentation
|
|
9
|
+
</a>
|
|
10
|
+
|
|
|
11
|
+
<a href="https://docs.calkit.org/tutorials" target="_blank">
|
|
12
|
+
Tutorials
|
|
13
|
+
</a>
|
|
14
|
+
|
|
|
15
|
+
<a href="https://github.com/orgs/calkit/discussions" target="_blank">
|
|
16
|
+
Discussions
|
|
17
|
+
</a>
|
|
18
|
+
</p>
|
|
6
19
|
|
|
7
20
|
Calkit is a framework and toolkit for reproducible research projects.
|
|
8
21
|
It acts as a top-level layer to integrate and simplify the use of enabling
|
|
@@ -15,8 +28,6 @@ Calkit also adds a domain-specific data model
|
|
|
15
28
|
such that all aspects of the research process can be fully described in a
|
|
16
29
|
single repository and therefore easily consumed by others.
|
|
17
30
|
|
|
18
|
-
To learn more, see the [documentation](https://docs.calkit.org).
|
|
19
|
-
|
|
20
31
|
## Installation
|
|
21
32
|
|
|
22
33
|
To install Calkit, [Git](https://git-scm.com) and Python must be installed.
|
|
@@ -89,17 +100,10 @@ calkit save -am "Run pipeline"
|
|
|
89
100
|
|
|
90
101
|
This will commit and push to both GitHub and the Calkit Cloud.
|
|
91
102
|
|
|
92
|
-
##
|
|
93
|
-
|
|
94
|
-
- [LaTeX collaboration with GitHub Codespaces](https://docs.calkit.org/tutorials/latex-codespaces/)
|
|
95
|
-
- [Jupyter notebook as a DVC pipeline](https://docs.calkit.org/tutorials/notebook-pipeline/)
|
|
96
|
-
- [Keeping track of conda environments](https://docs.calkit.org/tutorials/conda-envs/)
|
|
97
|
-
- [Defining and executing manual procedures](https://docs.calkit.org/tutorials/procedures/)
|
|
98
|
-
- [Adding a new LaTeX-based publication with its own Docker build environment](https://docs.calkit.org/tutorials/adding-latex-pub-docker/)
|
|
99
|
-
- [A reproducible workflow using Microsoft Office (Word and Excel)](https://docs.calkit.org/tutorials/office/)
|
|
100
|
-
- [Reproducible OpenFOAM simulations](https://docs.calkit.org/tutorials/openfoam/)
|
|
103
|
+
## Get involved
|
|
101
104
|
|
|
102
|
-
|
|
105
|
+
We welcome all kinds of contributions!
|
|
106
|
+
See [CONTRIBUTING.md](CONTRIBUTING.md) to learn how to get involved.
|
|
103
107
|
|
|
104
108
|
## Why does reproducibility matter?
|
|
105
109
|
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
__version__ = "0.
|
|
1
|
+
__version__ = "0.20.1"
|
|
2
2
|
|
|
3
3
|
from .core import *
|
|
4
4
|
from . import git
|
|
@@ -12,3 +12,6 @@ from . import templates
|
|
|
12
12
|
from . import conda
|
|
13
13
|
from . import calc
|
|
14
14
|
from . import check
|
|
15
|
+
from . import github
|
|
16
|
+
from . import zenodo
|
|
17
|
+
from . import releases
|
|
@@ -0,0 +1,247 @@
|
|
|
1
|
+
"""CLI for importing objects."""
|
|
2
|
+
|
|
3
|
+
from __future__ import annotations
|
|
4
|
+
|
|
5
|
+
import base64
|
|
6
|
+
import os
|
|
7
|
+
import subprocess
|
|
8
|
+
from typing import Annotated
|
|
9
|
+
|
|
10
|
+
import git
|
|
11
|
+
import requests
|
|
12
|
+
import typer
|
|
13
|
+
from tqdm import tqdm
|
|
14
|
+
|
|
15
|
+
import calkit
|
|
16
|
+
from calkit.cli import raise_error
|
|
17
|
+
|
|
18
|
+
import_app = typer.Typer(no_args_is_help=True)
|
|
19
|
+
|
|
20
|
+
|
|
21
|
+
@import_app.command(name="dataset")
|
|
22
|
+
def import_dataset(
|
|
23
|
+
src_path: Annotated[
|
|
24
|
+
str,
|
|
25
|
+
typer.Argument(
|
|
26
|
+
help=(
|
|
27
|
+
"Location of dataset, including project owner and name, e.g., "
|
|
28
|
+
"someone/some-project/data/some-data.csv"
|
|
29
|
+
)
|
|
30
|
+
),
|
|
31
|
+
],
|
|
32
|
+
dest_path: Annotated[
|
|
33
|
+
str,
|
|
34
|
+
typer.Argument(help="Output path at which to save."),
|
|
35
|
+
] = None,
|
|
36
|
+
filter_paths: Annotated[
|
|
37
|
+
list[str],
|
|
38
|
+
typer.Option(
|
|
39
|
+
"--filter-paths",
|
|
40
|
+
help="Filter paths in target dataset if it's a folder.",
|
|
41
|
+
),
|
|
42
|
+
] = None,
|
|
43
|
+
no_commit: Annotated[
|
|
44
|
+
bool,
|
|
45
|
+
typer.Option("--no-commit", help="Do not commit changes to repo."),
|
|
46
|
+
] = False,
|
|
47
|
+
no_dvc_pull: Annotated[
|
|
48
|
+
bool,
|
|
49
|
+
typer.Option(
|
|
50
|
+
"--no-dvc-pull", help="Do not pull imported dataset with DVC."
|
|
51
|
+
),
|
|
52
|
+
] = False,
|
|
53
|
+
overwrite: Annotated[
|
|
54
|
+
bool,
|
|
55
|
+
typer.Option(
|
|
56
|
+
"--overwrite",
|
|
57
|
+
"-f",
|
|
58
|
+
help="Force adding the dataset even if it already exists.",
|
|
59
|
+
),
|
|
60
|
+
] = False,
|
|
61
|
+
):
|
|
62
|
+
"""Import a dataset.
|
|
63
|
+
|
|
64
|
+
Currently only supports datasets kept in DVC, not Git.
|
|
65
|
+
"""
|
|
66
|
+
# Ensure we don't already have a dataset at this path
|
|
67
|
+
path_split = src_path.split("/")
|
|
68
|
+
owner_name = path_split[0]
|
|
69
|
+
project_name = path_split[1]
|
|
70
|
+
path = "/".join(path_split[2:])
|
|
71
|
+
if dest_path is None:
|
|
72
|
+
ds_dest_path = path
|
|
73
|
+
else:
|
|
74
|
+
ds_dest_path = dest_path
|
|
75
|
+
ck_info = calkit.load_calkit_info()
|
|
76
|
+
datasets = ck_info.get("datasets", [])
|
|
77
|
+
ds_paths = [ds["path"] for ds in datasets]
|
|
78
|
+
if not overwrite and ds_dest_path in ds_paths:
|
|
79
|
+
raise_error("A dataset already exists in this project at this path")
|
|
80
|
+
elif overwrite and ds_dest_path in ds_paths:
|
|
81
|
+
datasets = [ds for ds in datasets if ds["path"] != ds_dest_path]
|
|
82
|
+
repo = git.Repo()
|
|
83
|
+
# Obtain, save, and commit the .dvc file for the dataset, or if this is
|
|
84
|
+
# kept in Git, just download the files and commit them here
|
|
85
|
+
typer.echo("Fetching import info")
|
|
86
|
+
params = None
|
|
87
|
+
if filter_paths is not None:
|
|
88
|
+
params = {"filter_paths": filter_paths}
|
|
89
|
+
try:
|
|
90
|
+
resp = calkit.cloud.get(
|
|
91
|
+
f"/projects/{owner_name}/{project_name}/datasets/{path}",
|
|
92
|
+
params=params,
|
|
93
|
+
)
|
|
94
|
+
except Exception as e:
|
|
95
|
+
raise_error(f"Failed to fetch dataset info from cloud: {e}")
|
|
96
|
+
dvc_import, git_import = resp["dvc_import"], resp["git_import"]
|
|
97
|
+
if dest_path is not None:
|
|
98
|
+
typer.echo(f"Importing to destination path: {dest_path}")
|
|
99
|
+
if dvc_import is not None:
|
|
100
|
+
if dest_path is not None and len(dvc_import["outs"]) > 1:
|
|
101
|
+
raise_error(
|
|
102
|
+
"Cannot specify destination path when importing multiple "
|
|
103
|
+
"DVC files"
|
|
104
|
+
)
|
|
105
|
+
# Ensure we have a DVC remote corresponding to this project, and that we
|
|
106
|
+
# have a token set for that remote
|
|
107
|
+
typer.echo("Adding new DVC remote")
|
|
108
|
+
remote = calkit.dvc.add_external_remote(
|
|
109
|
+
owner_name=owner_name, project_name=project_name
|
|
110
|
+
)
|
|
111
|
+
repo.git.add(".dvc/config")
|
|
112
|
+
# Import this data with DVC
|
|
113
|
+
dvc_fpath = ds_dest_path + ".dvc"
|
|
114
|
+
dvc_dir = os.path.dirname(dvc_fpath)
|
|
115
|
+
os.makedirs(dvc_dir, exist_ok=True)
|
|
116
|
+
# Update paths in .dvc file so they are relative to the DVC file
|
|
117
|
+
if len(dvc_import["outs"]) > 1:
|
|
118
|
+
for n, out in enumerate(dvc_import["outs"]):
|
|
119
|
+
dvc_import["outs"][n]["path"] = os.path.relpath(
|
|
120
|
+
out["path"], dvc_dir
|
|
121
|
+
)
|
|
122
|
+
dvc_import["outs"][n]["remote"] = remote["name"]
|
|
123
|
+
else:
|
|
124
|
+
dvc_import["outs"][0]["path"] = os.path.basename(
|
|
125
|
+
dvc_import["outs"][0]["path"]
|
|
126
|
+
)
|
|
127
|
+
dvc_import["outs"][0]["remote"] = remote["name"]
|
|
128
|
+
typer.echo("Saving .dvc file")
|
|
129
|
+
with open(dvc_fpath, "w") as f:
|
|
130
|
+
calkit.ryaml.dump(dvc_import, f)
|
|
131
|
+
repo.git.add(dvc_fpath)
|
|
132
|
+
# Add to .gitignore
|
|
133
|
+
typer.echo("Checking .gitignore")
|
|
134
|
+
if os.path.isfile(".gitignore"):
|
|
135
|
+
with open(".gitignore") as f:
|
|
136
|
+
gitignore = f.read()
|
|
137
|
+
else:
|
|
138
|
+
gitignore = ""
|
|
139
|
+
if ds_dest_path not in gitignore.split("\n"):
|
|
140
|
+
typer.echo(f"Adding {ds_dest_path} to .gitignore")
|
|
141
|
+
gitignore = gitignore.rstrip() + "\n" + ds_dest_path + "\n"
|
|
142
|
+
with open(".gitignore", "w") as f:
|
|
143
|
+
f.write(gitignore)
|
|
144
|
+
repo.git.add(".gitignore")
|
|
145
|
+
elif git_import is not None:
|
|
146
|
+
typer.echo("Fetching files directly since they're kept in Git")
|
|
147
|
+
files = git_import["files"]
|
|
148
|
+
if dest_path is not None:
|
|
149
|
+
os.makedirs(dest_path, exist_ok=True)
|
|
150
|
+
for f in tqdm(files):
|
|
151
|
+
# Fetch content from API
|
|
152
|
+
resp_i = calkit.cloud.get(
|
|
153
|
+
f"/projects/{owner_name}/{project_name}/contents/{f}"
|
|
154
|
+
)
|
|
155
|
+
content = resp_i.get("content")
|
|
156
|
+
fname = os.path.basename(f)
|
|
157
|
+
dirname = os.path.dirname(f) if dest_path is None else dest_path
|
|
158
|
+
os.makedirs(dirname, exist_ok=True)
|
|
159
|
+
out_path = os.path.join(dirname, fname)
|
|
160
|
+
if content is not None:
|
|
161
|
+
# Decode base64 content and save locally
|
|
162
|
+
with open(out_path, "wb") as f:
|
|
163
|
+
f.write(base64.b64decode(content))
|
|
164
|
+
else:
|
|
165
|
+
url = resp_i.get("url")
|
|
166
|
+
if url is None:
|
|
167
|
+
raise_error(f"Could not fetch {f}")
|
|
168
|
+
# Download from URL
|
|
169
|
+
resp_dl = requests.get(url, stream=True)
|
|
170
|
+
try:
|
|
171
|
+
resp_dl.raise_for_status()
|
|
172
|
+
except Exception as e:
|
|
173
|
+
raise_error(f"Failed to download {f} from {url}: {e}")
|
|
174
|
+
with open(out_path, "wb") as f:
|
|
175
|
+
for chunk in resp_dl.iter_content(chunk_size=8192):
|
|
176
|
+
f.write(chunk)
|
|
177
|
+
repo.git.add(out_path)
|
|
178
|
+
else:
|
|
179
|
+
raise_error("Could not fetch import info from Calkit Cloud")
|
|
180
|
+
# Add to datasets in calkit.yaml
|
|
181
|
+
typer.echo("Adding dataset to calkit.yaml")
|
|
182
|
+
new_ds = calkit.models.ImportedDataset(
|
|
183
|
+
path=ds_dest_path,
|
|
184
|
+
title=resp.get("title"),
|
|
185
|
+
description=resp.get("description"),
|
|
186
|
+
stage=None,
|
|
187
|
+
imported_from=calkit.models._ImportedFromProject(
|
|
188
|
+
project=f"{owner_name}/{project_name}",
|
|
189
|
+
path=path,
|
|
190
|
+
git_rev=None, # TODO?
|
|
191
|
+
filter_paths=filter_paths,
|
|
192
|
+
),
|
|
193
|
+
)
|
|
194
|
+
datasets.append(new_ds.model_dump())
|
|
195
|
+
ck_info["datasets"] = datasets
|
|
196
|
+
with open("calkit.yaml", "w") as f:
|
|
197
|
+
calkit.ryaml.dump(ck_info, f)
|
|
198
|
+
repo.git.add("calkit.yaml")
|
|
199
|
+
if not no_commit:
|
|
200
|
+
# Commit any necessary changes
|
|
201
|
+
typer.echo("Committing changes")
|
|
202
|
+
repo.git.commit(["-m", f"Import dataset {src_path}"])
|
|
203
|
+
if not no_dvc_pull and dvc_import is not None:
|
|
204
|
+
# Run dvc pull
|
|
205
|
+
typer.echo("Running dvc pull")
|
|
206
|
+
subprocess.call(["dvc", "pull", dvc_fpath])
|
|
207
|
+
|
|
208
|
+
|
|
209
|
+
@import_app.command(name="environment")
|
|
210
|
+
def import_environment(
|
|
211
|
+
src_path: Annotated[
|
|
212
|
+
str,
|
|
213
|
+
typer.Argument(
|
|
214
|
+
help=(
|
|
215
|
+
"Environment location and name, e.g., "
|
|
216
|
+
"someone/some-project:env-name. If not present, the Calkit "
|
|
217
|
+
"Cloud will be queried."
|
|
218
|
+
)
|
|
219
|
+
),
|
|
220
|
+
],
|
|
221
|
+
dest_path: Annotated[
|
|
222
|
+
str,
|
|
223
|
+
typer.Option("--path", help="Output path at which to save."),
|
|
224
|
+
] = None,
|
|
225
|
+
dest_name: Annotated[
|
|
226
|
+
str,
|
|
227
|
+
typer.Option(
|
|
228
|
+
"--name", "-n", help="Name to use in the destination project."
|
|
229
|
+
),
|
|
230
|
+
] = None,
|
|
231
|
+
overwrite: Annotated[
|
|
232
|
+
bool,
|
|
233
|
+
typer.Option(
|
|
234
|
+
"--overwrite",
|
|
235
|
+
"-f",
|
|
236
|
+
help="Force adding the dataset even if it already exists.",
|
|
237
|
+
),
|
|
238
|
+
] = False,
|
|
239
|
+
) -> None:
|
|
240
|
+
project, env_name = src_path.split(":")
|
|
241
|
+
if os.path.isdir(project):
|
|
242
|
+
cloud = False
|
|
243
|
+
typer.echo("Importing from local project directory")
|
|
244
|
+
else:
|
|
245
|
+
cloud = True
|
|
246
|
+
typer.echo("Importing from Cloud project")
|
|
247
|
+
raise_error("Not yet implemented") # TODO
|