calkit-python 0.8.2__tar.gz → 0.8.4__tar.gz
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- {calkit_python-0.8.2 → calkit_python-0.8.4}/PKG-INFO +1 -1
- {calkit_python-0.8.2 → calkit_python-0.8.4}/calkit/__init__.py +1 -1
- {calkit_python-0.8.2 → calkit_python-0.8.4}/calkit/cli/main.py +2 -2
- {calkit_python-0.8.2 → calkit_python-0.8.4}/calkit/conda.py +14 -8
- {calkit_python-0.8.2 → calkit_python-0.8.4}/calkit/core.py +1 -1
- {calkit_python-0.8.2 → calkit_python-0.8.4}/calkit/magics.py +35 -7
- {calkit_python-0.8.2 → calkit_python-0.8.4}/docs/tutorials/notebook-pipeline.md +8 -1
- {calkit_python-0.8.2 → calkit_python-0.8.4}/test/pipeline.ipynb +8 -1
- {calkit_python-0.8.2 → calkit_python-0.8.4}/.github/FUNDING.yml +0 -0
- {calkit_python-0.8.2 → calkit_python-0.8.4}/.github/workflows/publish-test.yml +0 -0
- {calkit_python-0.8.2 → calkit_python-0.8.4}/.github/workflows/publish.yml +0 -0
- {calkit_python-0.8.2 → calkit_python-0.8.4}/.gitignore +0 -0
- {calkit_python-0.8.2 → calkit_python-0.8.4}/LICENSE +0 -0
- {calkit_python-0.8.2 → calkit_python-0.8.4}/README.md +0 -0
- {calkit_python-0.8.2 → calkit_python-0.8.4}/calkit/cli/__init__.py +0 -0
- {calkit_python-0.8.2 → calkit_python-0.8.4}/calkit/cli/config.py +0 -0
- {calkit_python-0.8.2 → calkit_python-0.8.4}/calkit/cli/core.py +0 -0
- {calkit_python-0.8.2 → calkit_python-0.8.4}/calkit/cli/import_.py +0 -0
- {calkit_python-0.8.2 → calkit_python-0.8.4}/calkit/cli/list.py +0 -0
- {calkit_python-0.8.2 → calkit_python-0.8.4}/calkit/cli/new.py +0 -0
- {calkit_python-0.8.2 → calkit_python-0.8.4}/calkit/cli/notebooks.py +0 -0
- {calkit_python-0.8.2 → calkit_python-0.8.4}/calkit/cli/office.py +0 -0
- {calkit_python-0.8.2 → calkit_python-0.8.4}/calkit/cloud.py +0 -0
- {calkit_python-0.8.2 → calkit_python-0.8.4}/calkit/config.py +0 -0
- {calkit_python-0.8.2 → calkit_python-0.8.4}/calkit/data.py +0 -0
- {calkit_python-0.8.2 → calkit_python-0.8.4}/calkit/docker.py +0 -0
- {calkit_python-0.8.2 → calkit_python-0.8.4}/calkit/dvc.py +0 -0
- {calkit_python-0.8.2 → calkit_python-0.8.4}/calkit/git.py +0 -0
- {calkit_python-0.8.2 → calkit_python-0.8.4}/calkit/gui.py +0 -0
- {calkit_python-0.8.2 → calkit_python-0.8.4}/calkit/jupyter.py +0 -0
- {calkit_python-0.8.2 → calkit_python-0.8.4}/calkit/models.py +0 -0
- {calkit_python-0.8.2 → calkit_python-0.8.4}/calkit/office.py +0 -0
- {calkit_python-0.8.2 → calkit_python-0.8.4}/calkit/server.py +0 -0
- {calkit_python-0.8.2 → calkit_python-0.8.4}/calkit/templates/__init__.py +0 -0
- {calkit_python-0.8.2 → calkit_python-0.8.4}/calkit/templates/core.py +0 -0
- {calkit_python-0.8.2 → calkit_python-0.8.4}/calkit/templates/latex/__init__.py +0 -0
- {calkit_python-0.8.2 → calkit_python-0.8.4}/calkit/templates/latex/article/paper.tex +0 -0
- {calkit_python-0.8.2 → calkit_python-0.8.4}/calkit/templates/latex/core.py +0 -0
- {calkit_python-0.8.2 → calkit_python-0.8.4}/calkit/templates/latex/jfm/jfm.bst +0 -0
- {calkit_python-0.8.2 → calkit_python-0.8.4}/calkit/templates/latex/jfm/jfm.cls +0 -0
- {calkit_python-0.8.2 → calkit_python-0.8.4}/calkit/templates/latex/jfm/lineno-FLM.sty +0 -0
- {calkit_python-0.8.2 → calkit_python-0.8.4}/calkit/templates/latex/jfm/paper.tex +0 -0
- {calkit_python-0.8.2 → calkit_python-0.8.4}/calkit/templates/latex/jfm/upmath.sty +0 -0
- {calkit_python-0.8.2 → calkit_python-0.8.4}/calkit/tests/__init__.py +0 -0
- {calkit_python-0.8.2 → calkit_python-0.8.4}/calkit/tests/cli/__init__.py +0 -0
- {calkit_python-0.8.2 → calkit_python-0.8.4}/calkit/tests/cli/test_list.py +0 -0
- {calkit_python-0.8.2 → calkit_python-0.8.4}/calkit/tests/cli/test_main.py +0 -0
- {calkit_python-0.8.2 → calkit_python-0.8.4}/calkit/tests/cli/test_new.py +0 -0
- {calkit_python-0.8.2 → calkit_python-0.8.4}/calkit/tests/test_core.py +0 -0
- {calkit_python-0.8.2 → calkit_python-0.8.4}/calkit/tests/test_dvc.py +0 -0
- {calkit_python-0.8.2 → calkit_python-0.8.4}/calkit/tests/test_jupyter.py +0 -0
- {calkit_python-0.8.2 → calkit_python-0.8.4}/calkit/tests/test_magics.py +0 -0
- {calkit_python-0.8.2 → calkit_python-0.8.4}/calkit/tests/test_templates.py +0 -0
- {calkit_python-0.8.2 → calkit_python-0.8.4}/docs/tutorials/adding-latex-pub-docker.md +0 -0
- {calkit_python-0.8.2 → calkit_python-0.8.4}/docs/tutorials/conda-envs.md +0 -0
- {calkit_python-0.8.2 → calkit_python-0.8.4}/docs/tutorials/img/run-proc.png +0 -0
- {calkit_python-0.8.2 → calkit_python-0.8.4}/docs/tutorials/procedures.md +0 -0
- {calkit_python-0.8.2 → calkit_python-0.8.4}/pyproject.toml +0 -0
|
@@ -560,14 +560,14 @@ def run_in_env(
|
|
|
560
560
|
]
|
|
561
561
|
if verbose:
|
|
562
562
|
typer.echo(f"Running command: {docker_cmd}")
|
|
563
|
-
subprocess.
|
|
563
|
+
subprocess.check_call(docker_cmd, cwd=wdir)
|
|
564
564
|
elif env["kind"] == "conda":
|
|
565
565
|
with open(env["path"]) as f:
|
|
566
566
|
conda_env = calkit.ryaml.load(f)
|
|
567
567
|
cmd = ["conda", "run", "-n", conda_env["name"]] + cmd
|
|
568
568
|
if verbose:
|
|
569
569
|
typer.echo(f"Running command: {cmd}")
|
|
570
|
-
subprocess.
|
|
570
|
+
subprocess.check_call(cmd, cwd=wdir)
|
|
571
571
|
else:
|
|
572
572
|
raise_error("Environment kind not supported")
|
|
573
573
|
|
|
@@ -21,14 +21,15 @@ def check_env(
|
|
|
21
21
|
Note that this only works with exact or no version specification.
|
|
22
22
|
Using greater than and less than operators is not supported.
|
|
23
23
|
"""
|
|
24
|
+
conda = "mamba" if use_mamba else "conda"
|
|
24
25
|
if log_func is None:
|
|
25
26
|
log_func = calkit.logger.info
|
|
26
27
|
log_func(f"Checking conda env defined in {env_fpath}")
|
|
27
28
|
envs = json.loads(
|
|
28
|
-
subprocess.check_output([
|
|
29
|
+
subprocess.check_output([conda, "env", "list", "--json"]).decode()
|
|
29
30
|
)["envs"]
|
|
30
31
|
# Get existing env names, but skip the base environment
|
|
31
|
-
existing_env_names = [
|
|
32
|
+
existing_env_names = [os.path.basename(env) for env in envs[1:]]
|
|
32
33
|
with open(env_fpath) as f:
|
|
33
34
|
env_spec = ryaml.load(f)
|
|
34
35
|
env_name = env_spec["name"]
|
|
@@ -40,7 +41,6 @@ def check_env(
|
|
|
40
41
|
)
|
|
41
42
|
env_check_dir = os.path.dirname(env_check_fpath)
|
|
42
43
|
os.makedirs(env_check_dir, exist_ok=True)
|
|
43
|
-
conda = "mamba" if use_mamba else "conda"
|
|
44
44
|
# Check if env even exists
|
|
45
45
|
if env_name not in existing_env_names:
|
|
46
46
|
log_func(f"Environment {env_name} doesn't exist; creating")
|
|
@@ -60,7 +60,9 @@ def check_env(
|
|
|
60
60
|
# If they match, the environment saved in env_check is still
|
|
61
61
|
# valid, so we don't need to re-export
|
|
62
62
|
existing_mtime = env_check["mtime"]
|
|
63
|
-
current_mtime = os.path.getmtime(
|
|
63
|
+
current_mtime = os.path.getmtime(
|
|
64
|
+
os.path.normpath(env_check["prefix"])
|
|
65
|
+
)
|
|
64
66
|
env_needs_export = existing_mtime != current_mtime
|
|
65
67
|
else:
|
|
66
68
|
env_needs_export = True
|
|
@@ -69,7 +71,7 @@ def check_env(
|
|
|
69
71
|
env_check = json.loads(
|
|
70
72
|
subprocess.check_output(
|
|
71
73
|
[
|
|
72
|
-
"conda",
|
|
74
|
+
"conda", # Mamba output is slightly different
|
|
73
75
|
"env",
|
|
74
76
|
"export",
|
|
75
77
|
"-n",
|
|
@@ -79,7 +81,9 @@ def check_env(
|
|
|
79
81
|
]
|
|
80
82
|
).decode()
|
|
81
83
|
)
|
|
82
|
-
env_check["mtime"] = os.path.getmtime(
|
|
84
|
+
env_check["mtime"] = os.path.getmtime(
|
|
85
|
+
os.path.normpath(env_check["prefix"])
|
|
86
|
+
)
|
|
83
87
|
with open(env_check_fpath, "w") as f:
|
|
84
88
|
ryaml.dump(env_check, f)
|
|
85
89
|
# Determine if the env matches
|
|
@@ -149,7 +153,7 @@ def check_env(
|
|
|
149
153
|
env_check = json.loads(
|
|
150
154
|
subprocess.check_output(
|
|
151
155
|
[
|
|
152
|
-
"conda",
|
|
156
|
+
"conda", # Mamba output is slightly different
|
|
153
157
|
"env",
|
|
154
158
|
"export",
|
|
155
159
|
"-n",
|
|
@@ -159,7 +163,9 @@ def check_env(
|
|
|
159
163
|
]
|
|
160
164
|
).decode()
|
|
161
165
|
)
|
|
162
|
-
env_check["mtime"] = os.path.getmtime(
|
|
166
|
+
env_check["mtime"] = os.path.getmtime(
|
|
167
|
+
os.path.normpath(env_check["prefix"])
|
|
168
|
+
)
|
|
163
169
|
with open(env_check_fpath, "w") as f:
|
|
164
170
|
ryaml.dump(env_check, f)
|
|
165
171
|
if output_fpath is None:
|
|
@@ -114,7 +114,7 @@ NOTEBOOK_STAGE_OUT_FORMATS = ["pickle", "parquet", "json", "yaml", "csv"]
|
|
|
114
114
|
|
|
115
115
|
|
|
116
116
|
def get_notebook_stage_dir(stage_name: str) -> str:
|
|
117
|
-
return
|
|
117
|
+
return os.path.join(".calkit", "notebook-stages", stage_name)
|
|
118
118
|
|
|
119
119
|
|
|
120
120
|
def get_notebook_stage_script_path(stage_name: str) -> str:
|
|
@@ -2,6 +2,7 @@
|
|
|
2
2
|
|
|
3
3
|
import ast
|
|
4
4
|
import os
|
|
5
|
+
import pathlib
|
|
5
6
|
import subprocess
|
|
6
7
|
|
|
7
8
|
from IPython.core import magic_arguments
|
|
@@ -18,6 +19,10 @@ def _parse_string_arg(val: str):
|
|
|
18
19
|
return val
|
|
19
20
|
|
|
20
21
|
|
|
22
|
+
def _posix_path(path: str):
|
|
23
|
+
return pathlib.Path(path).as_posix()
|
|
24
|
+
|
|
25
|
+
|
|
21
26
|
@magics_class
|
|
22
27
|
class Calkit(Magics):
|
|
23
28
|
|
|
@@ -29,6 +34,15 @@ class Calkit(Magics):
|
|
|
29
34
|
required=True,
|
|
30
35
|
type=_parse_string_arg,
|
|
31
36
|
)
|
|
37
|
+
@magic_arguments.argument(
|
|
38
|
+
"--env",
|
|
39
|
+
nargs="?",
|
|
40
|
+
const=True,
|
|
41
|
+
help=(
|
|
42
|
+
"Whether or not this cell should be run in an environment. "
|
|
43
|
+
"If no environment name is provided, the default will be used."
|
|
44
|
+
),
|
|
45
|
+
)
|
|
32
46
|
@magic_arguments.argument(
|
|
33
47
|
"--dep",
|
|
34
48
|
"-d",
|
|
@@ -106,7 +120,15 @@ class Calkit(Magics):
|
|
|
106
120
|
Then variables will be loaded back into the user namespace state by
|
|
107
121
|
loading the DVC output.
|
|
108
122
|
"""
|
|
109
|
-
|
|
123
|
+
# Allow command for this line to continue with backslashes
|
|
124
|
+
cell_split = cell.split("\n")
|
|
125
|
+
line_combined = line.strip().removesuffix("\\")
|
|
126
|
+
while line.strip().endswith("\\"):
|
|
127
|
+
newline = cell_split.pop(0)
|
|
128
|
+
line += newline
|
|
129
|
+
line_combined += " " + newline.strip().removesuffix("\\")
|
|
130
|
+
cell = "\n".join(cell_split)
|
|
131
|
+
args = magic_arguments.parse_argstring(self.stage, line_combined)
|
|
110
132
|
# If an output object type is specified, make sure we only have one
|
|
111
133
|
# output
|
|
112
134
|
if args.out_type:
|
|
@@ -209,7 +231,7 @@ class Calkit(Magics):
|
|
|
209
231
|
"--run",
|
|
210
232
|
"--force",
|
|
211
233
|
"-d",
|
|
212
|
-
script_fpath,
|
|
234
|
+
_posix_path(script_fpath),
|
|
213
235
|
]
|
|
214
236
|
if args.dep:
|
|
215
237
|
for dep in args.dep:
|
|
@@ -221,11 +243,11 @@ class Calkit(Magics):
|
|
|
221
243
|
kws["fmt"] = dep_split[2]
|
|
222
244
|
cmd += [
|
|
223
245
|
"-d",
|
|
224
|
-
calkit.get_notebook_stage_out_path(**kws),
|
|
246
|
+
_posix_path(calkit.get_notebook_stage_out_path(**kws)),
|
|
225
247
|
]
|
|
226
248
|
if args.dep_path:
|
|
227
249
|
for dep in args.dep_path:
|
|
228
|
-
cmd += ["-d", dep]
|
|
250
|
+
cmd += ["-d", _posix_path(dep)]
|
|
229
251
|
if args.out:
|
|
230
252
|
for out in args.out:
|
|
231
253
|
out_split = out.split(":")
|
|
@@ -235,12 +257,18 @@ class Calkit(Magics):
|
|
|
235
257
|
kws["fmt"] = out_split[1]
|
|
236
258
|
cmd += [
|
|
237
259
|
"-o",
|
|
238
|
-
calkit.get_notebook_stage_out_path(**kws),
|
|
260
|
+
_posix_path(calkit.get_notebook_stage_out_path(**kws)),
|
|
239
261
|
]
|
|
240
262
|
if args.out_path:
|
|
241
263
|
for path in args.out_path:
|
|
242
|
-
cmd += ["-o", path]
|
|
243
|
-
|
|
264
|
+
cmd += ["-o", _posix_path(path)]
|
|
265
|
+
stage_cmd = f'python "{_posix_path(script_fpath)}"'
|
|
266
|
+
if args.env:
|
|
267
|
+
runenv = "calkit runenv"
|
|
268
|
+
if isinstance(args.env, str):
|
|
269
|
+
runenv += f" -n {args.env}"
|
|
270
|
+
stage_cmd = runenv + " -- " + stage_cmd
|
|
271
|
+
cmd.append(stage_cmd)
|
|
244
272
|
try:
|
|
245
273
|
subprocess.run(cmd, check=True, capture_output=True, text=True)
|
|
246
274
|
except subprocess.CalledProcessError as e:
|
|
@@ -143,7 +143,14 @@ We can add a line that saves the figure and declare an additional output path
|
|
|
143
143
|
and metadata like (note this requires `plotly` and `kaleido` to be installed):
|
|
144
144
|
|
|
145
145
|
```python
|
|
146
|
-
%%stage
|
|
146
|
+
%%stage \
|
|
147
|
+
--name plot \
|
|
148
|
+
--dep get-data:df:parquet:pandas \
|
|
149
|
+
--out fig \
|
|
150
|
+
--out-path figures/plot.png \
|
|
151
|
+
--out-type figure \
|
|
152
|
+
--out-title "A plot of the data" \
|
|
153
|
+
--out-desc "This is a plot of the data."
|
|
147
154
|
|
|
148
155
|
import os
|
|
149
156
|
|
|
@@ -65,7 +65,14 @@
|
|
|
65
65
|
"metadata": {},
|
|
66
66
|
"outputs": [],
|
|
67
67
|
"source": [
|
|
68
|
-
"%%stage
|
|
68
|
+
"%%stage \\\n",
|
|
69
|
+
" --name plot-fig \\\n",
|
|
70
|
+
" --dep get-data:df:parquet:pandas \\\n",
|
|
71
|
+
" --out fig \\\n",
|
|
72
|
+
" --out-path figures/plot.png \\\n",
|
|
73
|
+
" --out-type figure \\\n",
|
|
74
|
+
" --out-title \"A plot of the data\" \\\n",
|
|
75
|
+
" --out-desc \"This is a plot of the data.\"\n",
|
|
69
76
|
"\n",
|
|
70
77
|
"import os\n",
|
|
71
78
|
"\n",
|
|
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
|