calkit-python 0.21.5__tar.gz → 0.21.6__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.21.5 → calkit_python-0.21.6}/PKG-INFO +9 -3
- {calkit_python-0.21.5 → calkit_python-0.21.6}/README.md +8 -2
- {calkit_python-0.21.5 → calkit_python-0.21.6}/calkit/__init__.py +1 -1
- {calkit_python-0.21.5 → calkit_python-0.21.6}/calkit/cli/core.py +2 -0
- {calkit_python-0.21.5 → calkit_python-0.21.6}/calkit/cli/import_.py +2 -1
- {calkit_python-0.21.5 → calkit_python-0.21.6}/calkit/cli/main.py +38 -13
- {calkit_python-0.21.5 → calkit_python-0.21.6}/calkit/cli/new.py +18 -6
- {calkit_python-0.21.5 → calkit_python-0.21.6}/calkit/dvc.py +49 -5
- {calkit_python-0.21.5 → calkit_python-0.21.6}/calkit/magics.py +2 -0
- {calkit_python-0.21.5 → calkit_python-0.21.6}/calkit/ops.py +3 -0
- {calkit_python-0.21.5 → calkit_python-0.21.6}/calkit/server.py +10 -4
- {calkit_python-0.21.5 → calkit_python-0.21.6}/calkit/templates/core.py +2 -0
- {calkit_python-0.21.5 → calkit_python-0.21.6}/calkit/tests/cli/test_main.py +7 -4
- {calkit_python-0.21.5 → calkit_python-0.21.6}/calkit/tests/cli/test_new.py +4 -8
- {calkit_python-0.21.5 → calkit_python-0.21.6}/calkit/tests/test_check.py +2 -1
- {calkit_python-0.21.5 → calkit_python-0.21.6}/calkit/tests/test_conda.py +1 -2
- {calkit_python-0.21.5 → calkit_python-0.21.6}/calkit/tests/test_dvc.py +9 -1
- {calkit_python-0.21.5 → calkit_python-0.21.6}/docs/installation.md +8 -2
- {calkit_python-0.21.5 → calkit_python-0.21.6}/pyproject.toml +1 -0
- {calkit_python-0.21.5 → calkit_python-0.21.6}/.github/FUNDING.yml +0 -0
- {calkit_python-0.21.5 → calkit_python-0.21.6}/.github/workflows/docs.yml +0 -0
- {calkit_python-0.21.5 → calkit_python-0.21.6}/.github/workflows/format.yml +0 -0
- {calkit_python-0.21.5 → calkit_python-0.21.6}/.github/workflows/publish-test.yml +0 -0
- {calkit_python-0.21.5 → calkit_python-0.21.6}/.github/workflows/publish.yml +0 -0
- {calkit_python-0.21.5 → calkit_python-0.21.6}/.github/workflows/test.yml +0 -0
- {calkit_python-0.21.5 → calkit_python-0.21.6}/.gitignore +0 -0
- {calkit_python-0.21.5 → calkit_python-0.21.6}/.pre-commit-config.yaml +0 -0
- {calkit_python-0.21.5 → calkit_python-0.21.6}/CONTRIBUTING.md +0 -0
- {calkit_python-0.21.5 → calkit_python-0.21.6}/LICENSE +0 -0
- {calkit_python-0.21.5 → calkit_python-0.21.6}/Makefile +0 -0
- {calkit_python-0.21.5 → calkit_python-0.21.6}/calkit/__main__.py +0 -0
- {calkit_python-0.21.5 → calkit_python-0.21.6}/calkit/calc.py +0 -0
- {calkit_python-0.21.5 → calkit_python-0.21.6}/calkit/check.py +0 -0
- {calkit_python-0.21.5 → calkit_python-0.21.6}/calkit/cli/__init__.py +0 -0
- {calkit_python-0.21.5 → calkit_python-0.21.6}/calkit/cli/check.py +0 -0
- {calkit_python-0.21.5 → calkit_python-0.21.6}/calkit/cli/cloud.py +0 -0
- {calkit_python-0.21.5 → calkit_python-0.21.6}/calkit/cli/config.py +0 -0
- {calkit_python-0.21.5 → calkit_python-0.21.6}/calkit/cli/list.py +0 -0
- {calkit_python-0.21.5 → calkit_python-0.21.6}/calkit/cli/notebooks.py +0 -0
- {calkit_python-0.21.5 → calkit_python-0.21.6}/calkit/cli/office.py +0 -0
- {calkit_python-0.21.5 → calkit_python-0.21.6}/calkit/cli/update.py +0 -0
- {calkit_python-0.21.5 → calkit_python-0.21.6}/calkit/cloud.py +0 -0
- {calkit_python-0.21.5 → calkit_python-0.21.6}/calkit/conda.py +0 -0
- {calkit_python-0.21.5 → calkit_python-0.21.6}/calkit/config.py +0 -0
- {calkit_python-0.21.5 → calkit_python-0.21.6}/calkit/core.py +0 -0
- {calkit_python-0.21.5 → calkit_python-0.21.6}/calkit/datasets.py +0 -0
- {calkit_python-0.21.5 → calkit_python-0.21.6}/calkit/docker.py +0 -0
- {calkit_python-0.21.5 → calkit_python-0.21.6}/calkit/git.py +0 -0
- {calkit_python-0.21.5 → calkit_python-0.21.6}/calkit/github.py +0 -0
- {calkit_python-0.21.5 → calkit_python-0.21.6}/calkit/gui.py +0 -0
- {calkit_python-0.21.5 → calkit_python-0.21.6}/calkit/jupyter.py +0 -0
- {calkit_python-0.21.5 → calkit_python-0.21.6}/calkit/models.py +0 -0
- {calkit_python-0.21.5 → calkit_python-0.21.6}/calkit/office.py +0 -0
- {calkit_python-0.21.5 → calkit_python-0.21.6}/calkit/releases.py +0 -0
- {calkit_python-0.21.5 → calkit_python-0.21.6}/calkit/templates/__init__.py +0 -0
- {calkit_python-0.21.5 → calkit_python-0.21.6}/calkit/templates/latex/__init__.py +0 -0
- {calkit_python-0.21.5 → calkit_python-0.21.6}/calkit/templates/latex/article/paper.tex +0 -0
- {calkit_python-0.21.5 → calkit_python-0.21.6}/calkit/templates/latex/core.py +0 -0
- {calkit_python-0.21.5 → calkit_python-0.21.6}/calkit/templates/latex/jfm/jfm.bst +0 -0
- {calkit_python-0.21.5 → calkit_python-0.21.6}/calkit/templates/latex/jfm/jfm.cls +0 -0
- {calkit_python-0.21.5 → calkit_python-0.21.6}/calkit/templates/latex/jfm/lineno-FLM.sty +0 -0
- {calkit_python-0.21.5 → calkit_python-0.21.6}/calkit/templates/latex/jfm/paper.tex +0 -0
- {calkit_python-0.21.5 → calkit_python-0.21.6}/calkit/templates/latex/jfm/upmath.sty +0 -0
- {calkit_python-0.21.5 → calkit_python-0.21.6}/calkit/tests/__init__.py +0 -0
- {calkit_python-0.21.5 → calkit_python-0.21.6}/calkit/tests/cli/__init__.py +0 -0
- {calkit_python-0.21.5 → calkit_python-0.21.6}/calkit/tests/cli/test_list.py +0 -0
- {calkit_python-0.21.5 → calkit_python-0.21.6}/calkit/tests/test_calc.py +0 -0
- {calkit_python-0.21.5 → calkit_python-0.21.6}/calkit/tests/test_core.py +0 -0
- {calkit_python-0.21.5 → calkit_python-0.21.6}/calkit/tests/test_jupyter.py +0 -0
- {calkit_python-0.21.5 → calkit_python-0.21.6}/calkit/tests/test_magics.py +0 -0
- {calkit_python-0.21.5 → calkit_python-0.21.6}/calkit/tests/test_templates.py +0 -0
- {calkit_python-0.21.5 → calkit_python-0.21.6}/calkit/zenodo.py +0 -0
- {calkit_python-0.21.5 → calkit_python-0.21.6}/docs/CNAME +0 -0
- {calkit_python-0.21.5 → calkit_python-0.21.6}/docs/apps.md +0 -0
- {calkit_python-0.21.5 → calkit_python-0.21.6}/docs/calculations.md +0 -0
- {calkit_python-0.21.5 → calkit_python-0.21.6}/docs/calkit-yaml.md +0 -0
- {calkit_python-0.21.5 → calkit_python-0.21.6}/docs/cli-reference.md +0 -0
- {calkit_python-0.21.5 → calkit_python-0.21.6}/docs/cloud-integration.md +0 -0
- {calkit_python-0.21.5 → calkit_python-0.21.6}/docs/datasets.md +0 -0
- {calkit_python-0.21.5 → calkit_python-0.21.6}/docs/environments.md +0 -0
- {calkit_python-0.21.5 → calkit_python-0.21.6}/docs/examples.md +0 -0
- {calkit_python-0.21.5 → calkit_python-0.21.6}/docs/help.md +0 -0
- {calkit_python-0.21.5 → calkit_python-0.21.6}/docs/img/c-to-the-k-white.svg +0 -0
- {calkit_python-0.21.5 → calkit_python-0.21.6}/docs/img/calkit-no-bg.png +0 -0
- {calkit_python-0.21.5 → calkit_python-0.21.6}/docs/img/connect-zenodo.png +0 -0
- {calkit_python-0.21.5 → calkit_python-0.21.6}/docs/index.md +0 -0
- {calkit_python-0.21.5 → calkit_python-0.21.6}/docs/local-server.md +0 -0
- {calkit_python-0.21.5 → calkit_python-0.21.6}/docs/pipeline/index.md +0 -0
- {calkit_python-0.21.5 → calkit_python-0.21.6}/docs/pipeline/manual-steps.md +0 -0
- {calkit_python-0.21.5 → calkit_python-0.21.6}/docs/references.md +0 -0
- {calkit_python-0.21.5 → calkit_python-0.21.6}/docs/releases.md +0 -0
- {calkit_python-0.21.5 → calkit_python-0.21.6}/docs/tutorials/adding-latex-pub-docker.md +0 -0
- {calkit_python-0.21.5 → calkit_python-0.21.6}/docs/tutorials/conda-envs.md +0 -0
- {calkit_python-0.21.5 → calkit_python-0.21.6}/docs/tutorials/existing-project.md +0 -0
- {calkit_python-0.21.5 → calkit_python-0.21.6}/docs/tutorials/first-project.md +0 -0
- {calkit_python-0.21.5 → calkit_python-0.21.6}/docs/tutorials/img/latex-codespaces/building-codespace.png +0 -0
- {calkit_python-0.21.5 → calkit_python-0.21.6}/docs/tutorials/img/latex-codespaces/codespaces-secrets-2.png +0 -0
- {calkit_python-0.21.5 → calkit_python-0.21.6}/docs/tutorials/img/latex-codespaces/editor-split.png +0 -0
- {calkit_python-0.21.5 → calkit_python-0.21.6}/docs/tutorials/img/latex-codespaces/go-to-linked-code.png +0 -0
- {calkit_python-0.21.5 → calkit_python-0.21.6}/docs/tutorials/img/latex-codespaces/issue-from-selection.png +0 -0
- {calkit_python-0.21.5 → calkit_python-0.21.6}/docs/tutorials/img/latex-codespaces/new-project.png +0 -0
- {calkit_python-0.21.5 → calkit_python-0.21.6}/docs/tutorials/img/latex-codespaces/new-pub-2.png +0 -0
- {calkit_python-0.21.5 → calkit_python-0.21.6}/docs/tutorials/img/latex-codespaces/new-token.png +0 -0
- {calkit_python-0.21.5 → calkit_python-0.21.6}/docs/tutorials/img/latex-codespaces/paper.tex.png +0 -0
- {calkit_python-0.21.5 → calkit_python-0.21.6}/docs/tutorials/img/latex-codespaces/project-home-3.png +0 -0
- {calkit_python-0.21.5 → calkit_python-0.21.6}/docs/tutorials/img/latex-codespaces/push.png +0 -0
- {calkit_python-0.21.5 → calkit_python-0.21.6}/docs/tutorials/img/latex-codespaces/stage.png +0 -0
- {calkit_python-0.21.5 → calkit_python-0.21.6}/docs/tutorials/img/office/anakin-excel.jpg +0 -0
- {calkit_python-0.21.5 → calkit_python-0.21.6}/docs/tutorials/img/office/chart-more-rows.png +0 -0
- {calkit_python-0.21.5 → calkit_python-0.21.6}/docs/tutorials/img/office/create-project.png +0 -0
- {calkit_python-0.21.5 → calkit_python-0.21.6}/docs/tutorials/img/office/elsevier-research-data-guidelines.png +0 -0
- {calkit_python-0.21.5 → calkit_python-0.21.6}/docs/tutorials/img/office/excel-chart.png +0 -0
- {calkit_python-0.21.5 → calkit_python-0.21.6}/docs/tutorials/img/office/excel-data.png +0 -0
- {calkit_python-0.21.5 → calkit_python-0.21.6}/docs/tutorials/img/office/insert-link-to-file.png +0 -0
- {calkit_python-0.21.5 → calkit_python-0.21.6}/docs/tutorials/img/office/needs-clone.png +0 -0
- {calkit_python-0.21.5 → calkit_python-0.21.6}/docs/tutorials/img/office/new-stage.png +0 -0
- {calkit_python-0.21.5 → calkit_python-0.21.6}/docs/tutorials/img/office/phd-comics-version-control.webp +0 -0
- {calkit_python-0.21.5 → calkit_python-0.21.6}/docs/tutorials/img/office/pipeline-out-of-date.png +0 -0
- {calkit_python-0.21.5 → calkit_python-0.21.6}/docs/tutorials/img/office/status-more-rows.png +0 -0
- {calkit_python-0.21.5 → calkit_python-0.21.6}/docs/tutorials/img/office/uncommitted-changes.png +0 -0
- {calkit_python-0.21.5 → calkit_python-0.21.6}/docs/tutorials/img/office/untracked-data.png +0 -0
- {calkit_python-0.21.5 → calkit_python-0.21.6}/docs/tutorials/img/office/updated-publication.png +0 -0
- {calkit_python-0.21.5 → calkit_python-0.21.6}/docs/tutorials/img/office/word-to-pdf-stage-2.png +0 -0
- {calkit_python-0.21.5 → calkit_python-0.21.6}/docs/tutorials/img/office/workflow-page.png +0 -0
- {calkit_python-0.21.5 → calkit_python-0.21.6}/docs/tutorials/img/openfoam/clone.png +0 -0
- {calkit_python-0.21.5 → calkit_python-0.21.6}/docs/tutorials/img/openfoam/create-project.png +0 -0
- {calkit_python-0.21.5 → calkit_python-0.21.6}/docs/tutorials/img/openfoam/datasets-page.png +0 -0
- {calkit_python-0.21.5 → calkit_python-0.21.6}/docs/tutorials/img/openfoam/figure-on-website-updated.png +0 -0
- {calkit_python-0.21.5 → calkit_python-0.21.6}/docs/tutorials/img/openfoam/figure-on-website.png +0 -0
- {calkit_python-0.21.5 → calkit_python-0.21.6}/docs/tutorials/img/openfoam/new-token.png +0 -0
- {calkit_python-0.21.5 → calkit_python-0.21.6}/docs/tutorials/img/openfoam/reclone.png +0 -0
- {calkit_python-0.21.5 → calkit_python-0.21.6}/docs/tutorials/img/openfoam/status-after-import-dataset.png +0 -0
- {calkit_python-0.21.5 → calkit_python-0.21.6}/docs/tutorials/img/run-proc.png +0 -0
- {calkit_python-0.21.5 → calkit_python-0.21.6}/docs/tutorials/index.md +0 -0
- {calkit_python-0.21.5 → calkit_python-0.21.6}/docs/tutorials/latex-codespaces.md +0 -0
- {calkit_python-0.21.5 → calkit_python-0.21.6}/docs/tutorials/matlab.md +0 -0
- {calkit_python-0.21.5 → calkit_python-0.21.6}/docs/tutorials/notebook-pipeline.md +0 -0
- {calkit_python-0.21.5 → calkit_python-0.21.6}/docs/tutorials/office.md +0 -0
- {calkit_python-0.21.5 → calkit_python-0.21.6}/docs/tutorials/openfoam.md +0 -0
- {calkit_python-0.21.5 → calkit_python-0.21.6}/docs/tutorials/procedures.md +0 -0
- {calkit_python-0.21.5 → calkit_python-0.21.6}/docs/version-control.md +0 -0
- {calkit_python-0.21.5 → calkit_python-0.21.6}/mkdocs.yml +0 -0
- {calkit_python-0.21.5 → calkit_python-0.21.6}/test/pipeline.ipynb +0 -0
- {calkit_python-0.21.5 → calkit_python-0.21.6}/uv.lock +0 -0
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: calkit-python
|
|
3
|
-
Version: 0.21.
|
|
3
|
+
Version: 0.21.6
|
|
4
4
|
Summary: Reproducibility simplified.
|
|
5
5
|
Project-URL: Homepage, https://calkit.org
|
|
6
6
|
Project-URL: Issues, https://github.com/calkit/calkit/issues
|
|
@@ -73,9 +73,15 @@ If you want to use [Docker](https://docker.com) containers,
|
|
|
73
73
|
which is typically a good idea,
|
|
74
74
|
that should also be installed.
|
|
75
75
|
For Python, we recommend
|
|
76
|
-
[
|
|
76
|
+
[uv](https://docs.astral.sh/uv/).
|
|
77
77
|
|
|
78
|
-
|
|
78
|
+
With uv installed, install Calkit with:
|
|
79
|
+
|
|
80
|
+
```sh
|
|
81
|
+
uv tool install calkit-python
|
|
82
|
+
```
|
|
83
|
+
|
|
84
|
+
Alternatively, but less ideally, you can install with your system Python:
|
|
79
85
|
|
|
80
86
|
```sh
|
|
81
87
|
pip install calkit-python
|
|
@@ -35,9 +35,15 @@ If you want to use [Docker](https://docker.com) containers,
|
|
|
35
35
|
which is typically a good idea,
|
|
36
36
|
that should also be installed.
|
|
37
37
|
For Python, we recommend
|
|
38
|
-
[
|
|
38
|
+
[uv](https://docs.astral.sh/uv/).
|
|
39
39
|
|
|
40
|
-
|
|
40
|
+
With uv installed, install Calkit with:
|
|
41
|
+
|
|
42
|
+
```sh
|
|
43
|
+
uv tool install calkit-python
|
|
44
|
+
```
|
|
45
|
+
|
|
46
|
+
Alternatively, but less ideally, you can install with your system Python:
|
|
41
47
|
|
|
42
48
|
```sh
|
|
43
49
|
pip install calkit-python
|
|
@@ -5,6 +5,7 @@ from __future__ import annotations
|
|
|
5
5
|
import base64
|
|
6
6
|
import os
|
|
7
7
|
import subprocess
|
|
8
|
+
import sys
|
|
8
9
|
from copy import deepcopy
|
|
9
10
|
from typing import Annotated
|
|
10
11
|
|
|
@@ -204,7 +205,7 @@ def import_dataset(
|
|
|
204
205
|
if not no_dvc_pull and dvc_import is not None:
|
|
205
206
|
# Run dvc pull
|
|
206
207
|
typer.echo("Running dvc pull")
|
|
207
|
-
subprocess.call(["dvc", "pull", dvc_fpath])
|
|
208
|
+
subprocess.call([sys.executable, "-m", "dvc", "pull", dvc_fpath])
|
|
208
209
|
|
|
209
210
|
|
|
210
211
|
@import_app.command(name="environment")
|
|
@@ -122,12 +122,14 @@ def init(
|
|
|
122
122
|
):
|
|
123
123
|
"""Initialize the current working directory."""
|
|
124
124
|
subprocess.run(["git", "init"])
|
|
125
|
-
dvc_cmd = ["dvc", "init"]
|
|
125
|
+
dvc_cmd = [sys.executable, "-m", "dvc", "init"]
|
|
126
126
|
if force:
|
|
127
127
|
dvc_cmd.append("-f")
|
|
128
128
|
subprocess.run(dvc_cmd)
|
|
129
129
|
# Ensure autostage is enabled for DVC
|
|
130
|
-
subprocess.call(
|
|
130
|
+
subprocess.call(
|
|
131
|
+
[sys.executable, "-m", "dvc", "config", "core.autostage", "true"]
|
|
132
|
+
)
|
|
131
133
|
# Commit the newly created .dvc directory
|
|
132
134
|
repo = git.Repo()
|
|
133
135
|
repo.git.add(".dvc")
|
|
@@ -214,7 +216,7 @@ def clone(
|
|
|
214
216
|
# DVC pull
|
|
215
217
|
if not no_dvc_pull:
|
|
216
218
|
try:
|
|
217
|
-
subprocess.check_call(["dvc", "pull"])
|
|
219
|
+
subprocess.check_call([sys.executable, "-m", "dvc", "pull"])
|
|
218
220
|
except subprocess.CalledProcessError:
|
|
219
221
|
raise_error("Failed to pull from DVC remote(s)")
|
|
220
222
|
|
|
@@ -243,10 +245,10 @@ def get_status():
|
|
|
243
245
|
run_cmd(["git", "status"])
|
|
244
246
|
typer.echo()
|
|
245
247
|
print_sep("Data (DVC)")
|
|
246
|
-
run_cmd(["dvc", "data", "status"])
|
|
248
|
+
run_cmd([sys.executable, "-m", "dvc", "data", "status"])
|
|
247
249
|
typer.echo()
|
|
248
250
|
print_sep("Pipeline (DVC)")
|
|
249
|
-
run_cmd(["dvc", "status"])
|
|
251
|
+
run_cmd([sys.executable, "-m", "dvc", "status"])
|
|
250
252
|
|
|
251
253
|
|
|
252
254
|
@app.command(name="diff")
|
|
@@ -255,7 +257,7 @@ def diff():
|
|
|
255
257
|
print_sep("Code (Git)")
|
|
256
258
|
run_cmd(["git", "diff"])
|
|
257
259
|
print_sep("Pipeline (DVC)")
|
|
258
|
-
run_cmd(["dvc", "diff"])
|
|
260
|
+
run_cmd([sys.executable, "-m", "dvc", "diff"])
|
|
259
261
|
|
|
260
262
|
|
|
261
263
|
@app.command(name="add")
|
|
@@ -331,7 +333,9 @@ def add(
|
|
|
331
333
|
warn("DVC not initialized yet; initializing")
|
|
332
334
|
dvc_repo = dvc.repo.Repo.init()
|
|
333
335
|
# Ensure autostage is enabled for DVC
|
|
334
|
-
subprocess.call(
|
|
336
|
+
subprocess.call(
|
|
337
|
+
[sys.executable, "-m", "dvc", "config", "core.autostage", "true"]
|
|
338
|
+
)
|
|
335
339
|
subprocess.call(["git", "add", ".dvc/config"])
|
|
336
340
|
dvc_paths = calkit.dvc.list_paths()
|
|
337
341
|
untracked_git_files = repo.untracked_files
|
|
@@ -393,15 +397,15 @@ def add(
|
|
|
393
397
|
typer.echo(
|
|
394
398
|
f"Adding {path} to DVC since it's already tracked with DVC"
|
|
395
399
|
)
|
|
396
|
-
subprocess.call(["dvc", "add", path])
|
|
400
|
+
subprocess.call([sys.executable, "-m", "dvc", "add", path])
|
|
397
401
|
elif os.path.splitext(path)[-1] in DVC_EXTENSIONS:
|
|
398
402
|
typer.echo(f"Adding {path} to DVC per its extension")
|
|
399
|
-
subprocess.call(["dvc", "add", path])
|
|
403
|
+
subprocess.call([sys.executable, "-m", "dvc", "add", path])
|
|
400
404
|
elif calkit.get_size(path) > DVC_SIZE_THRESH_BYTES:
|
|
401
405
|
typer.echo(
|
|
402
406
|
f"Adding {path} to DVC since it's greater than 1 MB"
|
|
403
407
|
)
|
|
404
|
-
subprocess.call(["dvc", "add", path])
|
|
408
|
+
subprocess.call([sys.executable, "-m", "dvc", "add", path])
|
|
405
409
|
else:
|
|
406
410
|
typer.echo(f"Adding {path} to Git")
|
|
407
411
|
subprocess.call(["git", "add", path])
|
|
@@ -561,7 +565,7 @@ def pull(
|
|
|
561
565
|
typer.echo(f"Checking authentication for DVC remote: {name}")
|
|
562
566
|
calkit.dvc.set_remote_auth(remote_name=name)
|
|
563
567
|
try:
|
|
564
|
-
subprocess.check_call(["dvc", "pull"])
|
|
568
|
+
subprocess.check_call([sys.executable, "-m", "dvc", "pull"])
|
|
565
569
|
except subprocess.CalledProcessError:
|
|
566
570
|
raise_error("DVC pull failed")
|
|
567
571
|
|
|
@@ -589,7 +593,7 @@ def push(
|
|
|
589
593
|
)
|
|
590
594
|
calkit.dvc.set_remote_auth(remote_name=name)
|
|
591
595
|
try:
|
|
592
|
-
subprocess.check_call(["dvc", "push"])
|
|
596
|
+
subprocess.check_call([sys.executable, "-m", "dvc", "push"])
|
|
593
597
|
except subprocess.CalledProcessError:
|
|
594
598
|
raise_error("DVC push failed")
|
|
595
599
|
|
|
@@ -716,7 +720,7 @@ def run(
|
|
|
716
720
|
if downstream is not None:
|
|
717
721
|
args += downstream
|
|
718
722
|
try:
|
|
719
|
-
subprocess.check_call(["dvc", "repro"] + args)
|
|
723
|
+
subprocess.check_call([sys.executable, "-m", "dvc", "repro"] + args)
|
|
720
724
|
except subprocess.CalledProcessError:
|
|
721
725
|
raise_error("DVC pipeline failed")
|
|
722
726
|
# Now parse stage metadata for calkit objects
|
|
@@ -1391,3 +1395,24 @@ def switch_branch(name: Annotated[str, typer.Argument(help="Branch name.")]):
|
|
|
1391
1395
|
else:
|
|
1392
1396
|
cmd = [name]
|
|
1393
1397
|
repo.git.checkout(cmd)
|
|
1398
|
+
|
|
1399
|
+
|
|
1400
|
+
@app.command(
|
|
1401
|
+
name="dvc",
|
|
1402
|
+
add_help_option=False,
|
|
1403
|
+
context_settings={
|
|
1404
|
+
"ignore_unknown_options": True,
|
|
1405
|
+
"allow_extra_args": True,
|
|
1406
|
+
},
|
|
1407
|
+
)
|
|
1408
|
+
def call_dvc(
|
|
1409
|
+
ctx: typer.Context,
|
|
1410
|
+
help: Annotated[bool, typer.Option("-h", "--help")] = False,
|
|
1411
|
+
):
|
|
1412
|
+
"""Run a command with the DVC CLI.
|
|
1413
|
+
|
|
1414
|
+
Useful if Calkit is installed as a tool, e.g., with `uv tool` or `pipx`,
|
|
1415
|
+
and DVC is not installed.
|
|
1416
|
+
"""
|
|
1417
|
+
process = subprocess.run([sys.executable, "-m", "dvc"] + sys.argv[2:])
|
|
1418
|
+
sys.exit(process.returncode)
|
|
@@ -7,6 +7,7 @@ import os
|
|
|
7
7
|
import pathlib
|
|
8
8
|
import shutil
|
|
9
9
|
import subprocess
|
|
10
|
+
import sys
|
|
10
11
|
import zipfile
|
|
11
12
|
from enum import Enum
|
|
12
13
|
|
|
@@ -127,7 +128,7 @@ def new_project(
|
|
|
127
128
|
typer.echo("Initializing DVC repository")
|
|
128
129
|
try:
|
|
129
130
|
subprocess.run(
|
|
130
|
-
["dvc", "init", "-q"],
|
|
131
|
+
[sys.executable, "-m", "dvc", "init", "-q"],
|
|
131
132
|
cwd=abs_path,
|
|
132
133
|
capture_output=True,
|
|
133
134
|
check=True,
|
|
@@ -287,7 +288,16 @@ def new_project(
|
|
|
287
288
|
"and `calkit config remote`"
|
|
288
289
|
)
|
|
289
290
|
subprocess.call(
|
|
290
|
-
[
|
|
291
|
+
[
|
|
292
|
+
sys.executable,
|
|
293
|
+
"-m",
|
|
294
|
+
"dvc",
|
|
295
|
+
"remote",
|
|
296
|
+
"remove",
|
|
297
|
+
"calkit",
|
|
298
|
+
"-q",
|
|
299
|
+
],
|
|
300
|
+
cwd=abs_path,
|
|
291
301
|
)
|
|
292
302
|
try:
|
|
293
303
|
calkit.dvc.set_remote_auth(wdir=abs_path)
|
|
@@ -308,7 +318,9 @@ def new_project(
|
|
|
308
318
|
repo = git.Repo(abs_path)
|
|
309
319
|
if not os.path.isfile(os.path.join(abs_path, ".dvc", "config")):
|
|
310
320
|
typer.echo("Initializing DVC repository")
|
|
311
|
-
subprocess.run(
|
|
321
|
+
subprocess.run(
|
|
322
|
+
[sys.executable, "-m", "dvc", "init", "-q"], cwd=abs_path
|
|
323
|
+
)
|
|
312
324
|
# Create calkit.yaml file
|
|
313
325
|
ck_info = calkit.load_calkit_info(wdir=abs_path)
|
|
314
326
|
ck_info = dict(name=name, title=title, description=description) | ck_info
|
|
@@ -439,7 +451,7 @@ def new_figure(
|
|
|
439
451
|
for out in outs:
|
|
440
452
|
outs_cmd += ["-o", out]
|
|
441
453
|
subprocess.check_call(
|
|
442
|
-
["dvc", "stage", "add", "-n", stage_name]
|
|
454
|
+
[sys.executable, "-m", "dvc", "stage", "add", "-n", stage_name]
|
|
443
455
|
+ (["-f"] if overwrite else [])
|
|
444
456
|
+ deps_cmd
|
|
445
457
|
+ outs_cmd
|
|
@@ -779,7 +791,7 @@ def new_dataset(
|
|
|
779
791
|
for out in outs:
|
|
780
792
|
outs_cmd += ["-o", out]
|
|
781
793
|
subprocess.check_call(
|
|
782
|
-
["dvc", "stage", "add", "-n", stage_name]
|
|
794
|
+
[sys.executable, "-m", "dvc", "stage", "add", "-n", stage_name]
|
|
783
795
|
+ (["-f"] if overwrite else [])
|
|
784
796
|
+ deps_cmd
|
|
785
797
|
+ outs_cmd
|
|
@@ -1486,7 +1498,7 @@ def new_stage(
|
|
|
1486
1498
|
cmd += f"zsh {target}"
|
|
1487
1499
|
elif kind.value == "r-script":
|
|
1488
1500
|
cmd += f"Rscript {target}"
|
|
1489
|
-
add_cmd = ["dvc", "stage", "add", "-n", name]
|
|
1501
|
+
add_cmd = [sys.executable, "-m", "dvc", "stage", "add", "-n", name]
|
|
1490
1502
|
for dep in [target] + deps:
|
|
1491
1503
|
add_cmd += ["-d", dep]
|
|
1492
1504
|
for out in outs:
|
|
@@ -5,6 +5,7 @@ from __future__ import annotations
|
|
|
5
5
|
import logging
|
|
6
6
|
import os
|
|
7
7
|
import subprocess
|
|
8
|
+
import sys
|
|
8
9
|
|
|
9
10
|
import dvc.repo
|
|
10
11
|
import git
|
|
@@ -40,11 +41,30 @@ def configure_remote(wdir: str = None):
|
|
|
40
41
|
base_url = calkit.cloud.get_base_url()
|
|
41
42
|
remote_url = f"{base_url}/projects/{project_name}/dvc"
|
|
42
43
|
subprocess.check_call(
|
|
43
|
-
[
|
|
44
|
+
[
|
|
45
|
+
sys.executable,
|
|
46
|
+
"-m",
|
|
47
|
+
"dvc",
|
|
48
|
+
"remote",
|
|
49
|
+
"add",
|
|
50
|
+
"-d",
|
|
51
|
+
"-f",
|
|
52
|
+
get_app_name(),
|
|
53
|
+
remote_url,
|
|
54
|
+
],
|
|
44
55
|
cwd=wdir,
|
|
45
56
|
)
|
|
46
57
|
subprocess.check_call(
|
|
47
|
-
[
|
|
58
|
+
[
|
|
59
|
+
sys.executable,
|
|
60
|
+
"-m",
|
|
61
|
+
"dvc",
|
|
62
|
+
"remote",
|
|
63
|
+
"modify",
|
|
64
|
+
get_app_name(),
|
|
65
|
+
"auth",
|
|
66
|
+
"custom",
|
|
67
|
+
],
|
|
48
68
|
cwd=wdir,
|
|
49
69
|
)
|
|
50
70
|
|
|
@@ -95,8 +115,30 @@ def add_external_remote(owner_name: str, project_name: str) -> dict:
|
|
|
95
115
|
base_url = calkit.cloud.get_base_url()
|
|
96
116
|
remote_url = f"{base_url}/projects/{owner_name}/{project_name}/dvc"
|
|
97
117
|
remote_name = f"{get_app_name()}:{owner_name}/{project_name}"
|
|
98
|
-
subprocess.call(
|
|
99
|
-
|
|
118
|
+
subprocess.call(
|
|
119
|
+
[
|
|
120
|
+
sys.executable,
|
|
121
|
+
"-m",
|
|
122
|
+
"dvc",
|
|
123
|
+
"remote",
|
|
124
|
+
"add",
|
|
125
|
+
"-f",
|
|
126
|
+
remote_name,
|
|
127
|
+
remote_url,
|
|
128
|
+
]
|
|
129
|
+
)
|
|
130
|
+
subprocess.call(
|
|
131
|
+
[
|
|
132
|
+
sys.executable,
|
|
133
|
+
"-m",
|
|
134
|
+
"dvc",
|
|
135
|
+
"remote",
|
|
136
|
+
"modify",
|
|
137
|
+
remote_name,
|
|
138
|
+
"auth",
|
|
139
|
+
"custom",
|
|
140
|
+
]
|
|
141
|
+
)
|
|
100
142
|
set_remote_auth(remote_name)
|
|
101
143
|
return {"name": remote_name, "url": remote_url}
|
|
102
144
|
|
|
@@ -114,7 +156,9 @@ def get_remotes(wdir: str = None) -> dict[str, str]:
|
|
|
114
156
|
value.
|
|
115
157
|
"""
|
|
116
158
|
out = (
|
|
117
|
-
subprocess.check_output(
|
|
159
|
+
subprocess.check_output(
|
|
160
|
+
[sys.executable, "-m", "dvc", "remote", "list"], cwd=wdir
|
|
161
|
+
)
|
|
118
162
|
.decode()
|
|
119
163
|
.strip()
|
|
120
164
|
)
|
|
@@ -4,7 +4,10 @@ An op is a process that runs outside the pipeline, e.g., for continuous data
|
|
|
4
4
|
collection, a task run on a schedule, or a fixed number of iterations.
|
|
5
5
|
"""
|
|
6
6
|
|
|
7
|
+
from __future__ import annotations
|
|
8
|
+
|
|
7
9
|
from typing import Literal
|
|
10
|
+
|
|
8
11
|
from pydantic import BaseModel
|
|
9
12
|
|
|
10
13
|
|
|
@@ -7,6 +7,7 @@ import os
|
|
|
7
7
|
import platform
|
|
8
8
|
import re
|
|
9
9
|
import subprocess
|
|
10
|
+
import sys
|
|
10
11
|
from typing import Literal
|
|
11
12
|
|
|
12
13
|
import dvc
|
|
@@ -218,7 +219,9 @@ def dvc_pull(owner_name: str, project_name: str) -> Message:
|
|
|
218
219
|
logger.info(f"Looking for project {owner_name}/{project_name}")
|
|
219
220
|
project = get_local_project(owner_name, project_name)
|
|
220
221
|
logger.info(f"Found project at {project.wdir}")
|
|
221
|
-
subprocess.check_call(
|
|
222
|
+
subprocess.check_call(
|
|
223
|
+
[sys.executable, "-m", "dvc", "pull"], cwd=project.wdir
|
|
224
|
+
)
|
|
222
225
|
return Message(message="Success!")
|
|
223
226
|
|
|
224
227
|
|
|
@@ -227,7 +230,9 @@ def dvc_push(owner_name: str, project_name: str) -> Message:
|
|
|
227
230
|
logger.info(f"Looking for project {owner_name}/{project_name}")
|
|
228
231
|
project = get_local_project(owner_name, project_name)
|
|
229
232
|
logger.info(f"Found project at {project.wdir}")
|
|
230
|
-
subprocess.check_call(
|
|
233
|
+
subprocess.check_call(
|
|
234
|
+
[sys.executable, "-m", "dvc", "push"], cwd=project.wdir
|
|
235
|
+
)
|
|
231
236
|
return Message(message="Success!")
|
|
232
237
|
|
|
233
238
|
|
|
@@ -453,7 +458,8 @@ def discard_changes(owner_name: str, project_name: str) -> Message:
|
|
|
453
458
|
for path in changed:
|
|
454
459
|
logger.info(f"Checking out {path} with DVC")
|
|
455
460
|
subprocess.check_call(
|
|
456
|
-
["dvc", "checkout", path, "--force"],
|
|
461
|
+
[sys.executable, "-m", "dvc", "checkout", path, "--force"],
|
|
462
|
+
cwd=project.wdir,
|
|
457
463
|
)
|
|
458
464
|
except dvc.config.ConfigError:
|
|
459
465
|
pass
|
|
@@ -496,7 +502,7 @@ def get_pipeline(owner_name: str, project_name: str) -> Pipeline:
|
|
|
496
502
|
raw_yaml = f.read()
|
|
497
503
|
pipeline = calkit.ryaml.load(raw_yaml)
|
|
498
504
|
mermaid = subprocess.check_output(
|
|
499
|
-
["dvc", "dag", "--mermaid"], cwd=project.wdir
|
|
505
|
+
[sys.executable, "-m", "dvc", "dag", "--mermaid"], cwd=project.wdir
|
|
500
506
|
).decode()
|
|
501
507
|
return Pipeline(
|
|
502
508
|
raw_yaml=raw_yaml,
|
|
@@ -14,8 +14,7 @@ from calkit.cli.main import _to_shell_cmd
|
|
|
14
14
|
|
|
15
15
|
|
|
16
16
|
def test_run_in_env(tmp_dir):
|
|
17
|
-
subprocess.check_call("
|
|
18
|
-
subprocess.check_call("dvc init", shell=True)
|
|
17
|
+
subprocess.check_call("calkit init", shell=True)
|
|
19
18
|
# First create a new Docker environment for this bare project
|
|
20
19
|
subprocess.check_call(
|
|
21
20
|
"calkit new docker-env "
|
|
@@ -110,8 +109,7 @@ def test_run_in_env(tmp_dir):
|
|
|
110
109
|
|
|
111
110
|
|
|
112
111
|
def test_run_in_venv(tmp_dir):
|
|
113
|
-
subprocess.check_call("
|
|
114
|
-
subprocess.check_call("dvc init", shell=True)
|
|
112
|
+
subprocess.check_call("calkit init", shell=True)
|
|
115
113
|
# Test uv venv
|
|
116
114
|
subprocess.check_call(
|
|
117
115
|
[
|
|
@@ -353,3 +351,8 @@ def test_save(tmp_dir):
|
|
|
353
351
|
)
|
|
354
352
|
last_commit_message = repo.head.commit.message.strip()
|
|
355
353
|
assert last_commit_message == "A unique message"
|
|
354
|
+
|
|
355
|
+
|
|
356
|
+
def test_call_dvc():
|
|
357
|
+
subprocess.check_call(["calkit", "dvc", "--help"])
|
|
358
|
+
subprocess.check_call(["calkit", "dvc", "stage", "--help"])
|
|
@@ -10,8 +10,7 @@ import calkit
|
|
|
10
10
|
|
|
11
11
|
|
|
12
12
|
def test_new_foreach_stage(tmp_dir):
|
|
13
|
-
subprocess.check_call(["
|
|
14
|
-
subprocess.check_call(["dvc", "init"])
|
|
13
|
+
subprocess.check_call(["calkit", "init"])
|
|
15
14
|
subprocess.check_call(
|
|
16
15
|
[
|
|
17
16
|
"calkit",
|
|
@@ -54,8 +53,7 @@ def test_new_foreach_stage(tmp_dir):
|
|
|
54
53
|
|
|
55
54
|
|
|
56
55
|
def test_new_figure(tmp_dir):
|
|
57
|
-
subprocess.check_call(["
|
|
58
|
-
subprocess.check_call(["dvc", "init"])
|
|
56
|
+
subprocess.check_call(["calkit", "init"])
|
|
59
57
|
subprocess.check_call(
|
|
60
58
|
[
|
|
61
59
|
"calkit",
|
|
@@ -134,8 +132,7 @@ def test_new_figure(tmp_dir):
|
|
|
134
132
|
|
|
135
133
|
|
|
136
134
|
def test_new_publication(tmp_dir):
|
|
137
|
-
subprocess.check_call(["
|
|
138
|
-
subprocess.check_call(["dvc", "init"])
|
|
135
|
+
subprocess.check_call(["calkit", "init"])
|
|
139
136
|
subprocess.check_call(
|
|
140
137
|
[
|
|
141
138
|
"calkit",
|
|
@@ -173,8 +170,7 @@ def test_new_publication(tmp_dir):
|
|
|
173
170
|
|
|
174
171
|
|
|
175
172
|
def test_new_uv_venv(tmp_dir):
|
|
176
|
-
subprocess.check_call(["
|
|
177
|
-
subprocess.check_call(["dvc", "init"])
|
|
173
|
+
subprocess.check_call(["calkit", "init"])
|
|
178
174
|
subprocess.check_call(
|
|
179
175
|
[
|
|
180
176
|
"calkit",
|
|
@@ -2,6 +2,7 @@
|
|
|
2
2
|
|
|
3
3
|
import os
|
|
4
4
|
import subprocess
|
|
5
|
+
import sys
|
|
5
6
|
|
|
6
7
|
from calkit.check import check_reproducibility
|
|
7
8
|
|
|
@@ -16,7 +17,7 @@ def test_check_reproducibility(tmp_path):
|
|
|
16
17
|
assert not res.is_dvc_repo
|
|
17
18
|
assert not res.has_readme
|
|
18
19
|
assert "no README.md" in res.recommendation
|
|
19
|
-
subprocess.run(["dvc", "init"])
|
|
20
|
+
subprocess.run([sys.executable, "-m", "dvc", "init"])
|
|
20
21
|
res = check_reproducibility()
|
|
21
22
|
assert res.is_dvc_repo
|
|
22
23
|
assert res.n_dvc_remotes == 0
|
|
@@ -10,6 +10,14 @@ def test_get_remotes(tmp_dir):
|
|
|
10
10
|
assert not calkit.dvc.get_remotes()
|
|
11
11
|
subprocess.call(["dvc", "init"])
|
|
12
12
|
assert not calkit.dvc.get_remotes()
|
|
13
|
-
subprocess.call(
|
|
13
|
+
subprocess.call(
|
|
14
|
+
[
|
|
15
|
+
"dvc",
|
|
16
|
+
"remote",
|
|
17
|
+
"add",
|
|
18
|
+
"something",
|
|
19
|
+
"https://sup.com",
|
|
20
|
+
]
|
|
21
|
+
)
|
|
14
22
|
resp = calkit.dvc.get_remotes()
|
|
15
23
|
assert resp == {"something": "https://sup.com"}
|
|
@@ -5,9 +5,15 @@ If you want to use [Docker](https://docker.com) containers,
|
|
|
5
5
|
which is typically a good idea,
|
|
6
6
|
that should also be installed.
|
|
7
7
|
For Python, we recommend
|
|
8
|
-
[
|
|
8
|
+
[uv](https://docs.astral.sh/uv/).
|
|
9
9
|
|
|
10
|
-
|
|
10
|
+
With uv installed, install Calkit with:
|
|
11
|
+
|
|
12
|
+
```sh
|
|
13
|
+
uv tool install calkit-python
|
|
14
|
+
```
|
|
15
|
+
|
|
16
|
+
Alternatively, but less ideally, you can install with your system Python:
|
|
11
17
|
|
|
12
18
|
```sh
|
|
13
19
|
pip install calkit-python
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{calkit_python-0.21.5 → calkit_python-0.21.6}/docs/tutorials/img/latex-codespaces/editor-split.png
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
{calkit_python-0.21.5 → calkit_python-0.21.6}/docs/tutorials/img/latex-codespaces/new-project.png
RENAMED
|
File without changes
|
{calkit_python-0.21.5 → calkit_python-0.21.6}/docs/tutorials/img/latex-codespaces/new-pub-2.png
RENAMED
|
File without changes
|
{calkit_python-0.21.5 → calkit_python-0.21.6}/docs/tutorials/img/latex-codespaces/new-token.png
RENAMED
|
File without changes
|
{calkit_python-0.21.5 → calkit_python-0.21.6}/docs/tutorials/img/latex-codespaces/paper.tex.png
RENAMED
|
File without changes
|
{calkit_python-0.21.5 → calkit_python-0.21.6}/docs/tutorials/img/latex-codespaces/project-home-3.png
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{calkit_python-0.21.5 → calkit_python-0.21.6}/docs/tutorials/img/office/insert-link-to-file.png
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{calkit_python-0.21.5 → calkit_python-0.21.6}/docs/tutorials/img/office/pipeline-out-of-date.png
RENAMED
|
File without changes
|
{calkit_python-0.21.5 → calkit_python-0.21.6}/docs/tutorials/img/office/status-more-rows.png
RENAMED
|
File without changes
|
{calkit_python-0.21.5 → calkit_python-0.21.6}/docs/tutorials/img/office/uncommitted-changes.png
RENAMED
|
File without changes
|
|
File without changes
|
{calkit_python-0.21.5 → calkit_python-0.21.6}/docs/tutorials/img/office/updated-publication.png
RENAMED
|
File without changes
|
{calkit_python-0.21.5 → calkit_python-0.21.6}/docs/tutorials/img/office/word-to-pdf-stage-2.png
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
{calkit_python-0.21.5 → calkit_python-0.21.6}/docs/tutorials/img/openfoam/create-project.png
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
{calkit_python-0.21.5 → calkit_python-0.21.6}/docs/tutorials/img/openfoam/figure-on-website.png
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|