lamin_cli 0.21.3__tar.gz → 0.22.0__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 (34) hide show
  1. {lamin_cli-0.21.3 → lamin_cli-0.22.0}/PKG-INFO +1 -2
  2. lamin_cli-0.22.0/lamin_cli/__init__.py +3 -0
  3. {lamin_cli-0.21.3 → lamin_cli-0.22.0}/lamin_cli/_load.py +33 -13
  4. {lamin_cli-0.21.3 → lamin_cli-0.22.0}/lamin_cli/_save.py +17 -18
  5. {lamin_cli-0.21.3 → lamin_cli-0.22.0}/pyproject.toml +0 -3
  6. {lamin_cli-0.21.3 → lamin_cli-0.22.0}/tests/test_save_scripts.py +0 -3
  7. lamin_cli-0.21.3/lamin_cli/__init__.py +0 -3
  8. {lamin_cli-0.21.3 → lamin_cli-0.22.0}/.github/workflows/doc-changes.yml +0 -0
  9. {lamin_cli-0.21.3 → lamin_cli-0.22.0}/.gitignore +0 -0
  10. {lamin_cli-0.21.3 → lamin_cli-0.22.0}/.pre-commit-config.yaml +0 -0
  11. {lamin_cli-0.21.3 → lamin_cli-0.22.0}/LICENSE +0 -0
  12. {lamin_cli-0.21.3 → lamin_cli-0.22.0}/README.md +0 -0
  13. {lamin_cli-0.21.3 → lamin_cli-0.22.0}/lamin_cli/__main__.py +0 -0
  14. {lamin_cli-0.21.3 → lamin_cli-0.22.0}/lamin_cli/_cache.py +0 -0
  15. {lamin_cli-0.21.3 → lamin_cli-0.22.0}/lamin_cli/_migration.py +0 -0
  16. {lamin_cli-0.21.3 → lamin_cli-0.22.0}/lamin_cli/_settings.py +0 -0
  17. {lamin_cli-0.21.3 → lamin_cli-0.22.0}/tests/conftest.py +0 -0
  18. {lamin_cli-0.21.3 → lamin_cli-0.22.0}/tests/notebooks/not-initialized.ipynb +0 -0
  19. {lamin_cli-0.21.3 → lamin_cli-0.22.0}/tests/notebooks/with-title-and-initialized-consecutive.ipynb +0 -0
  20. {lamin_cli-0.21.3 → lamin_cli-0.22.0}/tests/notebooks/with-title-and-initialized-non-consecutive.ipynb +0 -0
  21. {lamin_cli-0.21.3 → lamin_cli-0.22.0}/tests/scripts/merely-import-lamindb.py +0 -0
  22. {lamin_cli-0.21.3 → lamin_cli-0.22.0}/tests/scripts/run-track-and-finish-sync-git.py +0 -0
  23. {lamin_cli-0.21.3 → lamin_cli-0.22.0}/tests/scripts/run-track-and-finish.py +0 -0
  24. {lamin_cli-0.21.3 → lamin_cli-0.22.0}/tests/scripts/run-track-with-params.py +0 -0
  25. {lamin_cli-0.21.3 → lamin_cli-0.22.0}/tests/scripts/run-track.R +0 -0
  26. {lamin_cli-0.21.3 → lamin_cli-0.22.0}/tests/scripts/run-track.qmd +0 -0
  27. {lamin_cli-0.21.3 → lamin_cli-0.22.0}/tests/test_cli.py +0 -0
  28. {lamin_cli-0.21.3 → lamin_cli-0.22.0}/tests/test_load.py +0 -0
  29. {lamin_cli-0.21.3 → lamin_cli-0.22.0}/tests/test_migrate.py +0 -0
  30. {lamin_cli-0.21.3 → lamin_cli-0.22.0}/tests/test_multi_process.py +0 -0
  31. {lamin_cli-0.21.3 → lamin_cli-0.22.0}/tests/test_parse_uid_from_code.py +0 -0
  32. {lamin_cli-0.21.3 → lamin_cli-0.22.0}/tests/test_save_files.py +0 -0
  33. {lamin_cli-0.21.3 → lamin_cli-0.22.0}/tests/test_save_notebooks.py +0 -0
  34. {lamin_cli-0.21.3 → lamin_cli-0.22.0}/tests/test_save_r_code.py +0 -0
@@ -1,10 +1,9 @@
1
1
  Metadata-Version: 2.1
2
2
  Name: lamin_cli
3
- Version: 0.21.3
3
+ Version: 0.22.0
4
4
  Summary: Lamin CLI.
5
5
  Author-email: Lamin Labs <open-source@lamin.ai>
6
6
  Description-Content-Type: text/markdown
7
- Requires-Dist: lamindb_setup==0.81.1
8
7
  Requires-Dist: rich-click>=1.7
9
8
  Project-URL: Home, https://github.com/laminlabs/lamin-cli
10
9
 
@@ -0,0 +1,3 @@
1
+ """Lamin CLI."""
2
+
3
+ __version__ = "0.22.0"
@@ -2,6 +2,7 @@ from __future__ import annotations
2
2
  from typing import Tuple
3
3
  from lamin_utils import logger
4
4
  import shutil
5
+ import re
5
6
  from pathlib import Path
6
7
 
7
8
 
@@ -35,16 +36,39 @@ def load(entity: str, uid: str = None, key: str = None, with_env: bool = False):
35
36
  import jupytext
36
37
  from lamin_utils._base62 import increment_base62
37
38
 
38
- py_content = transform.source_code.replace(
39
- "# # transform.name", f"# # {transform.name}"
40
- )
39
+ if notebook_path.suffix == ".ipynb":
40
+ new_content = transform.source_code.replace(
41
+ "# # transform.name", f"# # {transform.name}"
42
+ )
43
+ else: # R notebook
44
+ # Pattern to match title only within YAML header section
45
+ title_pattern = r'^---\n.*?title:\s*"([^"]*)".*?---'
46
+ title_match = re.search(
47
+ title_pattern, transform.source_code, flags=re.DOTALL | re.MULTILINE
48
+ )
49
+ new_content = transform.source_code
50
+ if title_match:
51
+ current_title = title_match.group(1)
52
+ if current_title != transform.name:
53
+ pattern = r'^(---\n.*?title:\s*)"([^"]*)"(.*?---)'
54
+ replacement = f'\\1"{transform.name}"\\3'
55
+ new_content = re.sub(
56
+ pattern,
57
+ replacement,
58
+ new_content,
59
+ flags=re.DOTALL | re.MULTILINE,
60
+ )
61
+ logger.important(f"fixed title: {current_title} → {transform.name}")
41
62
  if bump_revision:
42
63
  uid = transform.uid
43
64
  new_uid = f"{uid[:-4]}{increment_base62(uid[-4:])}"
44
- py_content = py_content.replace(uid, new_uid)
65
+ new_content = new_content.replace(uid, new_uid)
45
66
  logger.important(f"updated uid: {uid} → {new_uid}")
46
- notebook = jupytext.reads(py_content, fmt="py:percent")
47
- jupytext.write(notebook, notebook_path)
67
+ if notebook_path.suffix == ".ipynb":
68
+ notebook = jupytext.reads(new_content, fmt="py:percent")
69
+ jupytext.write(notebook, notebook_path)
70
+ else:
71
+ notebook_path.write_text(new_content)
48
72
 
49
73
  query_by_uid = uid is not None
50
74
 
@@ -61,11 +85,7 @@ def load(entity: str, uid: str = None, key: str = None, with_env: bool = False):
61
85
  transforms = ln.Transform.objects.filter(key=key, source_code__isnull=False)
62
86
 
63
87
  if (n_transforms := len(transforms)) == 0:
64
- err_msg = (
65
- f"uid strating with {uid}"
66
- if query_by_uid
67
- else f"key={key} and source_code"
68
- )
88
+ err_msg = f"uid {uid}" if query_by_uid else f"key={key} and source_code"
69
89
  raise SystemExit(f"Transform with {err_msg} does not exist.")
70
90
 
71
91
  if n_transforms > 1:
@@ -87,8 +107,8 @@ def load(entity: str, uid: str = None, key: str = None, with_env: bool = False):
87
107
  target_filename += transform._source_code_artifact.suffix
88
108
  shutil.move(filepath_cache, target_filename)
89
109
  elif transform.source_code is not None:
90
- if transform.key.endswith(".ipynb"):
91
- script_to_notebook(transform, target_filename, bump_revision=True)
110
+ if transform.key.endswith((".ipynb", ".Rmd", ".qmd")):
111
+ script_to_notebook(transform, Path(target_filename), bump_revision=True)
92
112
  else:
93
113
  Path(target_filename).write_text(transform.source_code)
94
114
  else:
@@ -94,14 +94,23 @@ def save_from_filepath_cli(
94
94
  "R": set([".R", ".qmd", ".Rmd"]),
95
95
  }
96
96
 
97
- if (
98
- filepath.suffix in {".qmd", ".Rmd"}
99
- and not filepath.with_suffix(".html").exists()
100
- ):
101
- raise SystemExit(
102
- f"Please export your {filepath.suffix} file as an html file here"
103
- f" {filepath.with_suffix('.html')}"
104
- )
97
+ if filepath.suffix in {".qmd", ".Rmd"}:
98
+ if not (
99
+ filepath.with_suffix(".html").exists()
100
+ or filepath.with_suffix(".nb.html").exists()
101
+ ):
102
+ raise SystemExit(
103
+ f"Please export your {filepath.suffix} file as an html file here"
104
+ f" {filepath.with_suffix('.html')}"
105
+ )
106
+ if (
107
+ filepath.with_suffix(".html").exists()
108
+ and filepath.with_suffix(".nb.html").exists()
109
+ ):
110
+ raise SystemExit(
111
+ f'Please delete one of\n - {filepath.with_suffix(".html")}\n -'
112
+ f' {filepath.with_suffix(".nb.html")}'
113
+ )
105
114
 
106
115
  if registry is None:
107
116
  registry = (
@@ -156,16 +165,6 @@ def save_from_filepath_cli(
156
165
  filepath=filepath,
157
166
  from_cli=True,
158
167
  )
159
- if filepath.suffix in {".qmd", ".Rmd"}:
160
- report_file = ln.Artifact(
161
- filepath.with_suffix(".html"), # validated at the top that this exists
162
- description=f"Report of run {run.uid}",
163
- visibility=0, # hidden file
164
- run=False,
165
- )
166
- report_file.save(upload=True, print_progress=False)
167
- run.report = report_file
168
- run.save()
169
168
  return return_code
170
169
  else:
171
170
  raise SystemExit("Allowed values for '--registry' are: 'artifact', 'transform'")
@@ -8,9 +8,6 @@ authors = [{name = "Lamin Labs", email = "open-source@lamin.ai"}]
8
8
  readme = "README.md"
9
9
  dynamic = ["version", "description"]
10
10
  dependencies = [
11
- # lamindb-setup is only pinned here
12
- # NOT in lamindb
13
- "lamindb_setup==0.81.1",
14
11
  "rich-click>=1.7",
15
12
  ]
16
13
 
@@ -54,7 +54,6 @@ def test_run_save_cache():
54
54
  assert "loaded Transform" in result.stdout.decode()
55
55
  assert "m5uCHTTp" in result.stdout.decode()
56
56
  assert "started Run" in result.stdout.decode()
57
- assert "source code is already saved" in result.stdout.decode()
58
57
 
59
58
  # you can re-save the script
60
59
  result = subprocess.run(
@@ -66,7 +65,6 @@ def test_run_save_cache():
66
65
  # print(result.stdout.decode())
67
66
  # print(result.stderr.decode())
68
67
  assert result.returncode == 0
69
- assert "source code is already saved" in result.stdout.decode()
70
68
  assert "run.environment is already saved" in result.stdout.decode()
71
69
 
72
70
  # edit the script
@@ -204,7 +202,6 @@ def test_run_save_with_params():
204
202
  print(result.stdout.decode())
205
203
  print(result.stderr.decode())
206
204
  assert result.returncode == 0
207
- assert "source code is already saved" in result.stdout.decode()
208
205
  assert (
209
206
  "run-track-with-params.py' on uid 'JjRF4mACd9m00000'" in result.stdout.decode()
210
207
  )
@@ -1,3 +0,0 @@
1
- """Lamin CLI."""
2
-
3
- __version__ = "0.21.3"
File without changes
File without changes
File without changes
File without changes
File without changes