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.
Files changed (58) hide show
  1. {calkit_python-0.8.2 → calkit_python-0.8.4}/PKG-INFO +1 -1
  2. {calkit_python-0.8.2 → calkit_python-0.8.4}/calkit/__init__.py +1 -1
  3. {calkit_python-0.8.2 → calkit_python-0.8.4}/calkit/cli/main.py +2 -2
  4. {calkit_python-0.8.2 → calkit_python-0.8.4}/calkit/conda.py +14 -8
  5. {calkit_python-0.8.2 → calkit_python-0.8.4}/calkit/core.py +1 -1
  6. {calkit_python-0.8.2 → calkit_python-0.8.4}/calkit/magics.py +35 -7
  7. {calkit_python-0.8.2 → calkit_python-0.8.4}/docs/tutorials/notebook-pipeline.md +8 -1
  8. {calkit_python-0.8.2 → calkit_python-0.8.4}/test/pipeline.ipynb +8 -1
  9. {calkit_python-0.8.2 → calkit_python-0.8.4}/.github/FUNDING.yml +0 -0
  10. {calkit_python-0.8.2 → calkit_python-0.8.4}/.github/workflows/publish-test.yml +0 -0
  11. {calkit_python-0.8.2 → calkit_python-0.8.4}/.github/workflows/publish.yml +0 -0
  12. {calkit_python-0.8.2 → calkit_python-0.8.4}/.gitignore +0 -0
  13. {calkit_python-0.8.2 → calkit_python-0.8.4}/LICENSE +0 -0
  14. {calkit_python-0.8.2 → calkit_python-0.8.4}/README.md +0 -0
  15. {calkit_python-0.8.2 → calkit_python-0.8.4}/calkit/cli/__init__.py +0 -0
  16. {calkit_python-0.8.2 → calkit_python-0.8.4}/calkit/cli/config.py +0 -0
  17. {calkit_python-0.8.2 → calkit_python-0.8.4}/calkit/cli/core.py +0 -0
  18. {calkit_python-0.8.2 → calkit_python-0.8.4}/calkit/cli/import_.py +0 -0
  19. {calkit_python-0.8.2 → calkit_python-0.8.4}/calkit/cli/list.py +0 -0
  20. {calkit_python-0.8.2 → calkit_python-0.8.4}/calkit/cli/new.py +0 -0
  21. {calkit_python-0.8.2 → calkit_python-0.8.4}/calkit/cli/notebooks.py +0 -0
  22. {calkit_python-0.8.2 → calkit_python-0.8.4}/calkit/cli/office.py +0 -0
  23. {calkit_python-0.8.2 → calkit_python-0.8.4}/calkit/cloud.py +0 -0
  24. {calkit_python-0.8.2 → calkit_python-0.8.4}/calkit/config.py +0 -0
  25. {calkit_python-0.8.2 → calkit_python-0.8.4}/calkit/data.py +0 -0
  26. {calkit_python-0.8.2 → calkit_python-0.8.4}/calkit/docker.py +0 -0
  27. {calkit_python-0.8.2 → calkit_python-0.8.4}/calkit/dvc.py +0 -0
  28. {calkit_python-0.8.2 → calkit_python-0.8.4}/calkit/git.py +0 -0
  29. {calkit_python-0.8.2 → calkit_python-0.8.4}/calkit/gui.py +0 -0
  30. {calkit_python-0.8.2 → calkit_python-0.8.4}/calkit/jupyter.py +0 -0
  31. {calkit_python-0.8.2 → calkit_python-0.8.4}/calkit/models.py +0 -0
  32. {calkit_python-0.8.2 → calkit_python-0.8.4}/calkit/office.py +0 -0
  33. {calkit_python-0.8.2 → calkit_python-0.8.4}/calkit/server.py +0 -0
  34. {calkit_python-0.8.2 → calkit_python-0.8.4}/calkit/templates/__init__.py +0 -0
  35. {calkit_python-0.8.2 → calkit_python-0.8.4}/calkit/templates/core.py +0 -0
  36. {calkit_python-0.8.2 → calkit_python-0.8.4}/calkit/templates/latex/__init__.py +0 -0
  37. {calkit_python-0.8.2 → calkit_python-0.8.4}/calkit/templates/latex/article/paper.tex +0 -0
  38. {calkit_python-0.8.2 → calkit_python-0.8.4}/calkit/templates/latex/core.py +0 -0
  39. {calkit_python-0.8.2 → calkit_python-0.8.4}/calkit/templates/latex/jfm/jfm.bst +0 -0
  40. {calkit_python-0.8.2 → calkit_python-0.8.4}/calkit/templates/latex/jfm/jfm.cls +0 -0
  41. {calkit_python-0.8.2 → calkit_python-0.8.4}/calkit/templates/latex/jfm/lineno-FLM.sty +0 -0
  42. {calkit_python-0.8.2 → calkit_python-0.8.4}/calkit/templates/latex/jfm/paper.tex +0 -0
  43. {calkit_python-0.8.2 → calkit_python-0.8.4}/calkit/templates/latex/jfm/upmath.sty +0 -0
  44. {calkit_python-0.8.2 → calkit_python-0.8.4}/calkit/tests/__init__.py +0 -0
  45. {calkit_python-0.8.2 → calkit_python-0.8.4}/calkit/tests/cli/__init__.py +0 -0
  46. {calkit_python-0.8.2 → calkit_python-0.8.4}/calkit/tests/cli/test_list.py +0 -0
  47. {calkit_python-0.8.2 → calkit_python-0.8.4}/calkit/tests/cli/test_main.py +0 -0
  48. {calkit_python-0.8.2 → calkit_python-0.8.4}/calkit/tests/cli/test_new.py +0 -0
  49. {calkit_python-0.8.2 → calkit_python-0.8.4}/calkit/tests/test_core.py +0 -0
  50. {calkit_python-0.8.2 → calkit_python-0.8.4}/calkit/tests/test_dvc.py +0 -0
  51. {calkit_python-0.8.2 → calkit_python-0.8.4}/calkit/tests/test_jupyter.py +0 -0
  52. {calkit_python-0.8.2 → calkit_python-0.8.4}/calkit/tests/test_magics.py +0 -0
  53. {calkit_python-0.8.2 → calkit_python-0.8.4}/calkit/tests/test_templates.py +0 -0
  54. {calkit_python-0.8.2 → calkit_python-0.8.4}/docs/tutorials/adding-latex-pub-docker.md +0 -0
  55. {calkit_python-0.8.2 → calkit_python-0.8.4}/docs/tutorials/conda-envs.md +0 -0
  56. {calkit_python-0.8.2 → calkit_python-0.8.4}/docs/tutorials/img/run-proc.png +0 -0
  57. {calkit_python-0.8.2 → calkit_python-0.8.4}/docs/tutorials/procedures.md +0 -0
  58. {calkit_python-0.8.2 → calkit_python-0.8.4}/pyproject.toml +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.3
2
2
  Name: calkit-python
3
- Version: 0.8.2
3
+ Version: 0.8.4
4
4
  Summary: Reproducibility simplified.
5
5
  Project-URL: Homepage, https://github.com/calkit/calkit
6
6
  Project-URL: Issues, https://github.com/calkit/calkit/issues
@@ -1,4 +1,4 @@
1
- __version__ = "0.8.2"
1
+ __version__ = "0.8.4"
2
2
 
3
3
  from .core import *
4
4
  from . import git
@@ -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.call(docker_cmd, cwd=wdir)
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.call(cmd, cwd=wdir)
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(["conda", "env", "list", "--json"]).decode()
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 = [env.split("/")[-1] for env in envs[1:]]
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(env_check["prefix"])
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(env_check["prefix"])
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(env_check["prefix"])
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 f".calkit/notebook-stages/{stage_name}"
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
- args = magic_arguments.parse_argstring(self.stage, line)
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
- cmd.append(f"python '{script_fpath}'")
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 --name plot --dep get-data:df:parquet:pandas --out fig --out-path figures/plot.png --out-type figure --out-title "A plot of the data" --out-desc "This is a plot of the data."
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 --name plot-fig --dep get-data:df:parquet:pandas --out fig --out-path figures/plot.png --out-type figure --out-title \"A plot of the data\" --out-desc \"This is a plot of the data.\"\n",
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