calkit-python 0.11.2__tar.gz → 0.11.3__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.11.2 → calkit_python-0.11.3}/PKG-INFO +1 -1
- {calkit_python-0.11.2 → calkit_python-0.11.3}/calkit/__init__.py +1 -1
- {calkit_python-0.11.2 → calkit_python-0.11.3}/calkit/cli/main.py +7 -3
- {calkit_python-0.11.2 → calkit_python-0.11.3}/calkit/cli/new.py +64 -0
- {calkit_python-0.11.2 → calkit_python-0.11.3}/calkit/core.py +1 -1
- {calkit_python-0.11.2 → calkit_python-0.11.3}/calkit/models.py +18 -3
- {calkit_python-0.11.2 → calkit_python-0.11.3}/calkit/tests/cli/test_main.py +17 -0
- {calkit_python-0.11.2 → calkit_python-0.11.3}/calkit/tests/cli/test_new.py +43 -0
- {calkit_python-0.11.2 → calkit_python-0.11.3}/.github/FUNDING.yml +0 -0
- {calkit_python-0.11.2 → calkit_python-0.11.3}/.github/workflows/publish-test.yml +0 -0
- {calkit_python-0.11.2 → calkit_python-0.11.3}/.github/workflows/publish.yml +0 -0
- {calkit_python-0.11.2 → calkit_python-0.11.3}/.gitignore +0 -0
- {calkit_python-0.11.2 → calkit_python-0.11.3}/LICENSE +0 -0
- {calkit_python-0.11.2 → calkit_python-0.11.3}/README.md +0 -0
- {calkit_python-0.11.2 → calkit_python-0.11.3}/calkit/calc.py +0 -0
- {calkit_python-0.11.2 → calkit_python-0.11.3}/calkit/check.py +0 -0
- {calkit_python-0.11.2 → calkit_python-0.11.3}/calkit/cli/__init__.py +0 -0
- {calkit_python-0.11.2 → calkit_python-0.11.3}/calkit/cli/check.py +0 -0
- {calkit_python-0.11.2 → calkit_python-0.11.3}/calkit/cli/config.py +0 -0
- {calkit_python-0.11.2 → calkit_python-0.11.3}/calkit/cli/core.py +0 -0
- {calkit_python-0.11.2 → calkit_python-0.11.3}/calkit/cli/import_.py +0 -0
- {calkit_python-0.11.2 → calkit_python-0.11.3}/calkit/cli/list.py +0 -0
- {calkit_python-0.11.2 → calkit_python-0.11.3}/calkit/cli/notebooks.py +0 -0
- {calkit_python-0.11.2 → calkit_python-0.11.3}/calkit/cli/office.py +0 -0
- {calkit_python-0.11.2 → calkit_python-0.11.3}/calkit/cli/update.py +0 -0
- {calkit_python-0.11.2 → calkit_python-0.11.3}/calkit/cloud.py +0 -0
- {calkit_python-0.11.2 → calkit_python-0.11.3}/calkit/conda.py +0 -0
- {calkit_python-0.11.2 → calkit_python-0.11.3}/calkit/config.py +0 -0
- {calkit_python-0.11.2 → calkit_python-0.11.3}/calkit/data.py +0 -0
- {calkit_python-0.11.2 → calkit_python-0.11.3}/calkit/docker.py +0 -0
- {calkit_python-0.11.2 → calkit_python-0.11.3}/calkit/dvc.py +0 -0
- {calkit_python-0.11.2 → calkit_python-0.11.3}/calkit/git.py +0 -0
- {calkit_python-0.11.2 → calkit_python-0.11.3}/calkit/gui.py +0 -0
- {calkit_python-0.11.2 → calkit_python-0.11.3}/calkit/jupyter.py +0 -0
- {calkit_python-0.11.2 → calkit_python-0.11.3}/calkit/magics.py +0 -0
- {calkit_python-0.11.2 → calkit_python-0.11.3}/calkit/office.py +0 -0
- {calkit_python-0.11.2 → calkit_python-0.11.3}/calkit/server.py +0 -0
- {calkit_python-0.11.2 → calkit_python-0.11.3}/calkit/templates/__init__.py +0 -0
- {calkit_python-0.11.2 → calkit_python-0.11.3}/calkit/templates/core.py +0 -0
- {calkit_python-0.11.2 → calkit_python-0.11.3}/calkit/templates/latex/__init__.py +0 -0
- {calkit_python-0.11.2 → calkit_python-0.11.3}/calkit/templates/latex/article/paper.tex +0 -0
- {calkit_python-0.11.2 → calkit_python-0.11.3}/calkit/templates/latex/core.py +0 -0
- {calkit_python-0.11.2 → calkit_python-0.11.3}/calkit/templates/latex/jfm/jfm.bst +0 -0
- {calkit_python-0.11.2 → calkit_python-0.11.3}/calkit/templates/latex/jfm/jfm.cls +0 -0
- {calkit_python-0.11.2 → calkit_python-0.11.3}/calkit/templates/latex/jfm/lineno-FLM.sty +0 -0
- {calkit_python-0.11.2 → calkit_python-0.11.3}/calkit/templates/latex/jfm/paper.tex +0 -0
- {calkit_python-0.11.2 → calkit_python-0.11.3}/calkit/templates/latex/jfm/upmath.sty +0 -0
- {calkit_python-0.11.2 → calkit_python-0.11.3}/calkit/tests/__init__.py +0 -0
- {calkit_python-0.11.2 → calkit_python-0.11.3}/calkit/tests/cli/__init__.py +0 -0
- {calkit_python-0.11.2 → calkit_python-0.11.3}/calkit/tests/cli/test_list.py +0 -0
- {calkit_python-0.11.2 → calkit_python-0.11.3}/calkit/tests/test_calc.py +0 -0
- {calkit_python-0.11.2 → calkit_python-0.11.3}/calkit/tests/test_check.py +0 -0
- {calkit_python-0.11.2 → calkit_python-0.11.3}/calkit/tests/test_conda.py +0 -0
- {calkit_python-0.11.2 → calkit_python-0.11.3}/calkit/tests/test_core.py +0 -0
- {calkit_python-0.11.2 → calkit_python-0.11.3}/calkit/tests/test_dvc.py +0 -0
- {calkit_python-0.11.2 → calkit_python-0.11.3}/calkit/tests/test_jupyter.py +0 -0
- {calkit_python-0.11.2 → calkit_python-0.11.3}/calkit/tests/test_magics.py +0 -0
- {calkit_python-0.11.2 → calkit_python-0.11.3}/calkit/tests/test_templates.py +0 -0
- {calkit_python-0.11.2 → calkit_python-0.11.3}/docs/img/calkit-no-bg.png +0 -0
- {calkit_python-0.11.2 → calkit_python-0.11.3}/docs/tutorials/adding-latex-pub-docker.md +0 -0
- {calkit_python-0.11.2 → calkit_python-0.11.3}/docs/tutorials/conda-envs.md +0 -0
- {calkit_python-0.11.2 → calkit_python-0.11.3}/docs/tutorials/img/run-proc.png +0 -0
- {calkit_python-0.11.2 → calkit_python-0.11.3}/docs/tutorials/notebook-pipeline.md +0 -0
- {calkit_python-0.11.2 → calkit_python-0.11.3}/docs/tutorials/procedures.md +0 -0
- {calkit_python-0.11.2 → calkit_python-0.11.3}/pyproject.toml +0 -0
- {calkit_python-0.11.2 → calkit_python-0.11.3}/test/pipeline.ipynb +0 -0
|
@@ -7,6 +7,7 @@ import functools
|
|
|
7
7
|
import hashlib
|
|
8
8
|
import json
|
|
9
9
|
import os
|
|
10
|
+
import platform as _platform
|
|
10
11
|
import subprocess
|
|
11
12
|
import sys
|
|
12
13
|
import time
|
|
@@ -657,7 +658,6 @@ def run_in_env(
|
|
|
657
658
|
except subprocess.CalledProcessError:
|
|
658
659
|
raise_error(f"Failed to run in {env['kind']} environment")
|
|
659
660
|
elif env["kind"] == "uv-venv":
|
|
660
|
-
# TODO: This doesn't work on Windows
|
|
661
661
|
if "prefix" not in env:
|
|
662
662
|
raise_error("uv-venv environments require a prefix")
|
|
663
663
|
if "path" not in env:
|
|
@@ -676,8 +676,12 @@ def run_in_env(
|
|
|
676
676
|
raise_error(f"Failed to create uv-venv at {prefix}")
|
|
677
677
|
fname, ext = os.path.splitext(path)
|
|
678
678
|
lock_fpath = fname + "-lock" + ext
|
|
679
|
+
if _platform.system() == "Windows":
|
|
680
|
+
activate_cmd = f"{prefix}\\Scripts\\activate"
|
|
681
|
+
else:
|
|
682
|
+
activate_cmd = f". {prefix}/bin/activate"
|
|
679
683
|
check_cmd = (
|
|
680
|
-
f"
|
|
684
|
+
f"{activate_cmd} "
|
|
681
685
|
f"&& uv pip install -q -r {path} "
|
|
682
686
|
f"&& uv pip freeze > {lock_fpath} "
|
|
683
687
|
"&& deactivate"
|
|
@@ -689,7 +693,7 @@ def run_in_env(
|
|
|
689
693
|
except subprocess.CalledProcessError:
|
|
690
694
|
raise_error("Failed to check uv-venv")
|
|
691
695
|
# Now run the command
|
|
692
|
-
cmd = f"
|
|
696
|
+
cmd = f"{activate_cmd} && {shell_cmd} && deactivate"
|
|
693
697
|
if verbose:
|
|
694
698
|
typer.echo(f"Running command: {cmd}")
|
|
695
699
|
try:
|
|
@@ -1035,3 +1035,67 @@ def new_conda_env(
|
|
|
1035
1035
|
repo.git.add("dvc.yaml")
|
|
1036
1036
|
if not no_commit and repo.git.diff("--staged"):
|
|
1037
1037
|
repo.git.commit(["-m", f"Add Conda environment {name}"])
|
|
1038
|
+
|
|
1039
|
+
|
|
1040
|
+
@new_app.command("uv-venv")
|
|
1041
|
+
def new_uv_venv(
|
|
1042
|
+
packages: Annotated[
|
|
1043
|
+
list[str],
|
|
1044
|
+
typer.Argument(help="Packages to include in the environment."),
|
|
1045
|
+
],
|
|
1046
|
+
name: Annotated[
|
|
1047
|
+
str, typer.Option("--name", "-n", help="Environment name.")
|
|
1048
|
+
],
|
|
1049
|
+
path: Annotated[
|
|
1050
|
+
str, typer.Option("--path", help="Path for requirements file.")
|
|
1051
|
+
] = "requirements.txt",
|
|
1052
|
+
prefix: Annotated[
|
|
1053
|
+
str, typer.Option("--prefix", help="Prefix for environment location.")
|
|
1054
|
+
] = ".venv",
|
|
1055
|
+
description: Annotated[
|
|
1056
|
+
str, typer.Option("--description", help="Description.")
|
|
1057
|
+
] = None,
|
|
1058
|
+
overwrite: Annotated[
|
|
1059
|
+
bool,
|
|
1060
|
+
typer.Option(
|
|
1061
|
+
"--overwrite",
|
|
1062
|
+
"-f",
|
|
1063
|
+
help="Overwrite any existing environment with this name.",
|
|
1064
|
+
),
|
|
1065
|
+
] = False,
|
|
1066
|
+
no_commit: Annotated[
|
|
1067
|
+
bool, typer.Option("--no-commit", help="Do not commit changes.")
|
|
1068
|
+
] = False,
|
|
1069
|
+
):
|
|
1070
|
+
"""Create a new uv virtual environment."""
|
|
1071
|
+
if os.path.isfile(path) and not overwrite:
|
|
1072
|
+
raise_error("Output path already exists (use -f to overwrite)")
|
|
1073
|
+
repo = git.Repo()
|
|
1074
|
+
# Add environment to Calkit info
|
|
1075
|
+
ck_info = calkit.load_calkit_info()
|
|
1076
|
+
# If environments is a list instead of a dict, reformulate it
|
|
1077
|
+
envs = ck_info.get("environments", {})
|
|
1078
|
+
if isinstance(envs, list):
|
|
1079
|
+
typer.echo("Converting environments from list to dict")
|
|
1080
|
+
envs = {env.pop("name"): env for env in envs}
|
|
1081
|
+
if name in envs and not overwrite:
|
|
1082
|
+
raise_error(
|
|
1083
|
+
f"Environment with name {name} already exists "
|
|
1084
|
+
"(use -f to overwrite)"
|
|
1085
|
+
)
|
|
1086
|
+
packages_txt = "\n".join(packages)
|
|
1087
|
+
# Write environment to path
|
|
1088
|
+
with open(path, "w") as f:
|
|
1089
|
+
f.write(packages_txt)
|
|
1090
|
+
repo.git.add(path)
|
|
1091
|
+
typer.echo("Adding environment to calkit.yaml")
|
|
1092
|
+
env = dict(path=path, kind="uv-venv", prefix=prefix)
|
|
1093
|
+
if description is not None:
|
|
1094
|
+
env["description"] = description
|
|
1095
|
+
envs[name] = env
|
|
1096
|
+
ck_info["environments"] = envs
|
|
1097
|
+
with open("calkit.yaml", "w") as f:
|
|
1098
|
+
ryaml.dump(ck_info, f)
|
|
1099
|
+
repo.git.add("calkit.yaml")
|
|
1100
|
+
if not no_commit and repo.git.diff("--staged"):
|
|
1101
|
+
repo.git.commit(["-m", f"Add uv venv {name}"])
|
|
@@ -63,7 +63,15 @@ class ReferenceCollection(BaseModel):
|
|
|
63
63
|
|
|
64
64
|
class Environment(BaseModel):
|
|
65
65
|
kind: Literal[
|
|
66
|
-
"conda",
|
|
66
|
+
"conda",
|
|
67
|
+
"docker",
|
|
68
|
+
"poetry",
|
|
69
|
+
"npm",
|
|
70
|
+
"yarn",
|
|
71
|
+
"remote-ssh",
|
|
72
|
+
"uv",
|
|
73
|
+
"pixi",
|
|
74
|
+
"uv-venv",
|
|
67
75
|
]
|
|
68
76
|
path: str | None = None
|
|
69
77
|
description: str | None = None
|
|
@@ -71,8 +79,13 @@ class Environment(BaseModel):
|
|
|
71
79
|
default: bool | None = None
|
|
72
80
|
|
|
73
81
|
|
|
82
|
+
class UvVenvEnvironment(Environment):
|
|
83
|
+
kind: Literal["uv-venv"]
|
|
84
|
+
prefix: str
|
|
85
|
+
|
|
86
|
+
|
|
74
87
|
class DockerEnvironment(Environment):
|
|
75
|
-
kind:
|
|
88
|
+
kind: Literal["docker"]
|
|
76
89
|
image: str
|
|
77
90
|
layers: list[str] | None = None
|
|
78
91
|
shell: Literal["bash", "sh"] = "sh"
|
|
@@ -202,7 +215,9 @@ class ProjectInfo(BaseModel):
|
|
|
202
215
|
figures: list[Figure] = []
|
|
203
216
|
publications: list[Publication] = []
|
|
204
217
|
references: list[ReferenceCollection] = []
|
|
205
|
-
environments: dict[
|
|
218
|
+
environments: dict[
|
|
219
|
+
str, Environment | DockerEnvironment | UvVenvEnvironment
|
|
220
|
+
] = {}
|
|
206
221
|
software: list[Software] = []
|
|
207
222
|
notebooks: list[Notebook] = []
|
|
208
223
|
procedures: dict[str, Procedure] = {}
|
|
@@ -89,6 +89,23 @@ def test_run_in_env(tmp_dir):
|
|
|
89
89
|
ck_info = calkit.load_calkit_info()
|
|
90
90
|
env = ck_info["environments"]["py3.10"]
|
|
91
91
|
assert env.get("path") is None
|
|
92
|
+
# Test uv venv
|
|
93
|
+
subprocess.check_call(
|
|
94
|
+
["calkit", "new", "uv-venv", "-n", "uv1", "polars==1.18.0"]
|
|
95
|
+
)
|
|
96
|
+
out = subprocess.check_output(
|
|
97
|
+
[
|
|
98
|
+
"calkit",
|
|
99
|
+
"runenv",
|
|
100
|
+
"-n",
|
|
101
|
+
"uv1",
|
|
102
|
+
"--",
|
|
103
|
+
"python",
|
|
104
|
+
"-c",
|
|
105
|
+
"'import polars; print(polars.__version__)'",
|
|
106
|
+
]
|
|
107
|
+
).decode().strip()
|
|
108
|
+
assert out == "1.18.0"
|
|
92
109
|
|
|
93
110
|
|
|
94
111
|
def test_check_call():
|
|
@@ -169,3 +169,46 @@ def test_new_publication(tmp_dir):
|
|
|
169
169
|
"calkit runenv -n my-latex-env "
|
|
170
170
|
'"cd my-paper && latexmk -interaction=nonstopmode -pdf paper.tex"'
|
|
171
171
|
)
|
|
172
|
+
|
|
173
|
+
|
|
174
|
+
def test_new_uv_venv(tmp_dir):
|
|
175
|
+
subprocess.check_call(["git", "init"])
|
|
176
|
+
subprocess.check_call(["dvc", "init"])
|
|
177
|
+
subprocess.check_call(
|
|
178
|
+
[
|
|
179
|
+
"calkit",
|
|
180
|
+
"new",
|
|
181
|
+
"uv-venv",
|
|
182
|
+
"-n",
|
|
183
|
+
"my-uv-venv",
|
|
184
|
+
"pandas>=2.0",
|
|
185
|
+
"matplotlib",
|
|
186
|
+
]
|
|
187
|
+
)
|
|
188
|
+
ck_info = calkit.load_calkit_info(as_pydantic=True)
|
|
189
|
+
envs = ck_info.environments
|
|
190
|
+
env = envs["my-uv-venv"]
|
|
191
|
+
assert env.path == "requirements.txt"
|
|
192
|
+
assert env.prefix == ".venv"
|
|
193
|
+
assert env.kind == "uv-venv"
|
|
194
|
+
subprocess.check_call(
|
|
195
|
+
[
|
|
196
|
+
"calkit",
|
|
197
|
+
"new",
|
|
198
|
+
"uv-venv",
|
|
199
|
+
"-n",
|
|
200
|
+
"my-uv-venv2",
|
|
201
|
+
"--path",
|
|
202
|
+
"requirements-2.txt",
|
|
203
|
+
"--prefix",
|
|
204
|
+
".venv2",
|
|
205
|
+
"pandas>=2.0",
|
|
206
|
+
"matplotlib",
|
|
207
|
+
]
|
|
208
|
+
)
|
|
209
|
+
ck_info = calkit.load_calkit_info(as_pydantic=True)
|
|
210
|
+
envs = ck_info.environments
|
|
211
|
+
env = envs["my-uv-venv2"]
|
|
212
|
+
assert env.path == "requirements-2.txt"
|
|
213
|
+
assert env.prefix == ".venv2"
|
|
214
|
+
assert env.kind == "uv-venv"
|
|
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
|