lamin_cli 0.20.1__tar.gz → 0.21.1__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.
- {lamin_cli-0.20.1 → lamin_cli-0.21.1}/PKG-INFO +2 -2
- lamin_cli-0.21.1/lamin_cli/__init__.py +3 -0
- {lamin_cli-0.20.1 → lamin_cli-0.21.1}/lamin_cli/_save.py +58 -15
- {lamin_cli-0.20.1 → lamin_cli-0.21.1}/pyproject.toml +1 -1
- lamin_cli-0.21.1/tests/scripts/run-track.R +20 -0
- lamin_cli-0.21.1/tests/scripts/run-track.qmd +3 -0
- {lamin_cli-0.20.1 → lamin_cli-0.21.1}/tests/test_save_notebooks.py +1 -1
- lamin_cli-0.21.1/tests/test_save_r_code.py +73 -0
- lamin_cli-0.20.1/lamin_cli/__init__.py +0 -3
- {lamin_cli-0.20.1 → lamin_cli-0.21.1}/.github/workflows/doc-changes.yml +0 -0
- {lamin_cli-0.20.1 → lamin_cli-0.21.1}/.gitignore +0 -0
- {lamin_cli-0.20.1 → lamin_cli-0.21.1}/.pre-commit-config.yaml +0 -0
- {lamin_cli-0.20.1 → lamin_cli-0.21.1}/LICENSE +0 -0
- {lamin_cli-0.20.1 → lamin_cli-0.21.1}/README.md +0 -0
- {lamin_cli-0.20.1 → lamin_cli-0.21.1}/lamin_cli/__main__.py +0 -0
- {lamin_cli-0.20.1 → lamin_cli-0.21.1}/lamin_cli/_cache.py +0 -0
- {lamin_cli-0.20.1 → lamin_cli-0.21.1}/lamin_cli/_load.py +0 -0
- {lamin_cli-0.20.1 → lamin_cli-0.21.1}/lamin_cli/_migration.py +0 -0
- {lamin_cli-0.20.1 → lamin_cli-0.21.1}/lamin_cli/_settings.py +0 -0
- {lamin_cli-0.20.1 → lamin_cli-0.21.1}/tests/conftest.py +0 -0
- {lamin_cli-0.20.1 → lamin_cli-0.21.1}/tests/notebooks/not-initialized.ipynb +0 -0
- {lamin_cli-0.20.1 → lamin_cli-0.21.1}/tests/notebooks/with-title-and-initialized-consecutive.ipynb +0 -0
- {lamin_cli-0.20.1 → lamin_cli-0.21.1}/tests/notebooks/with-title-and-initialized-non-consecutive.ipynb +0 -0
- {lamin_cli-0.20.1 → lamin_cli-0.21.1}/tests/scripts/merely-import-lamindb.py +0 -0
- {lamin_cli-0.20.1 → lamin_cli-0.21.1}/tests/scripts/run-track-and-finish-sync-git.py +0 -0
- {lamin_cli-0.20.1 → lamin_cli-0.21.1}/tests/scripts/run-track-and-finish.py +0 -0
- {lamin_cli-0.20.1 → lamin_cli-0.21.1}/tests/scripts/run-track-with-params.py +0 -0
- {lamin_cli-0.20.1 → lamin_cli-0.21.1}/tests/test_cli.py +0 -0
- {lamin_cli-0.20.1 → lamin_cli-0.21.1}/tests/test_load.py +0 -0
- {lamin_cli-0.20.1 → lamin_cli-0.21.1}/tests/test_migrate.py +0 -0
- {lamin_cli-0.20.1 → lamin_cli-0.21.1}/tests/test_multi_process.py +0 -0
- {lamin_cli-0.20.1 → lamin_cli-0.21.1}/tests/test_save_files.py +0 -0
- {lamin_cli-0.20.1 → lamin_cli-0.21.1}/tests/test_save_scripts.py +0 -0
|
@@ -1,10 +1,10 @@
|
|
|
1
1
|
Metadata-Version: 2.1
|
|
2
2
|
Name: lamin_cli
|
|
3
|
-
Version: 0.
|
|
3
|
+
Version: 0.21.1
|
|
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.
|
|
7
|
+
Requires-Dist: lamindb_setup==0.81.0
|
|
8
8
|
Requires-Dist: rich-click>=1.7
|
|
9
9
|
Project-URL: Home, https://github.com/laminlabs/lamin-cli
|
|
10
10
|
|
|
@@ -27,28 +27,40 @@ def parse_uid_from_code(
|
|
|
27
27
|
version_pattern = re.compile(
|
|
28
28
|
r'\.transform\.version\s*=\s*\\["\']([^"\']+)\\["\']'
|
|
29
29
|
)
|
|
30
|
+
elif suffix in {".R", ".qmd", ".Rmd"}:
|
|
31
|
+
track_pattern = re.compile(r'track\(\s*[\'"]([a-zA-Z0-9]{16})[\'"]')
|
|
32
|
+
uid_pattern = None
|
|
33
|
+
stem_uid_pattern = None
|
|
34
|
+
version_pattern = None
|
|
30
35
|
else:
|
|
31
|
-
raise
|
|
36
|
+
raise SystemExit(
|
|
37
|
+
"Only .py, .ipynb, .R, .qmd, .Rmd files are supported for saving"
|
|
38
|
+
" transforms."
|
|
39
|
+
)
|
|
32
40
|
|
|
33
41
|
# Search for matches in the entire file content
|
|
34
42
|
uid_match = track_pattern.search(content)
|
|
35
43
|
uid = uid_match.group(1) if uid_match else None
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
stem_uid_match = stem_uid_pattern.search(content)
|
|
39
|
-
version_match = version_pattern.search(content)
|
|
44
|
+
stem_uid = None
|
|
45
|
+
version = None
|
|
40
46
|
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
47
|
+
if uid_pattern is not None and uid is None:
|
|
48
|
+
uid_match = uid_pattern.search(content)
|
|
49
|
+
uid = uid_match.group(1) if uid_match else None
|
|
50
|
+
if stem_uid_pattern is not None:
|
|
51
|
+
stem_uid_match = stem_uid_pattern.search(content)
|
|
52
|
+
stem_uid = stem_uid_match.group(1) if stem_uid_match else None
|
|
53
|
+
if version_pattern is not None:
|
|
54
|
+
version_match = version_pattern.search(content)
|
|
55
|
+
version = version_match.group(1) if version_match else None
|
|
45
56
|
|
|
46
57
|
if uid is None and (stem_uid is None or version is None):
|
|
58
|
+
target = "script" if suffix == ".py" else "notebook"
|
|
47
59
|
raise SystemExit(
|
|
48
60
|
"Cannot infer transform uid."
|
|
49
|
-
"\nCall `ln.track()` and copy/paste the output"
|
|
50
|
-
" into the notebook"
|
|
61
|
+
f"\nCall `ln.track()` and copy/paste the output into the {target}."
|
|
51
62
|
)
|
|
63
|
+
|
|
52
64
|
return uid, stem_uid, version
|
|
53
65
|
|
|
54
66
|
|
|
@@ -71,8 +83,27 @@ def save_from_filepath_cli(
|
|
|
71
83
|
|
|
72
84
|
ln_setup.settings.auto_connect = auto_connect_state
|
|
73
85
|
|
|
86
|
+
suffixes_transform = {
|
|
87
|
+
"py": set([".py", ".ipynb"]),
|
|
88
|
+
"R": set([".R", ".qmd", ".Rmd"]),
|
|
89
|
+
}
|
|
90
|
+
|
|
91
|
+
if (
|
|
92
|
+
filepath.suffix in {".qmd", ".Rmd"}
|
|
93
|
+
and not filepath.with_suffix(".html").exists()
|
|
94
|
+
):
|
|
95
|
+
raise SystemExit(
|
|
96
|
+
f"Please export your {filepath.suffix} file as an html file here"
|
|
97
|
+
f" {filepath.with_suffix('.html')}"
|
|
98
|
+
)
|
|
99
|
+
|
|
74
100
|
if registry is None:
|
|
75
|
-
registry =
|
|
101
|
+
registry = (
|
|
102
|
+
"transform"
|
|
103
|
+
if filepath.suffix
|
|
104
|
+
in suffixes_transform["py"].union(suffixes_transform["R"])
|
|
105
|
+
else "artifact"
|
|
106
|
+
)
|
|
76
107
|
|
|
77
108
|
if registry == "artifact":
|
|
78
109
|
ln.settings.creation.artifact_silence_missing_run_warning = True
|
|
@@ -107,16 +138,28 @@ def save_from_filepath_cli(
|
|
|
107
138
|
run = ln.Run.filter(transform=transform).order_by("-started_at").first()
|
|
108
139
|
if run.created_by.id != ln_setup.settings.user.id:
|
|
109
140
|
response = input(
|
|
110
|
-
"You are trying to save a transform created by another user: Source
|
|
111
|
-
" report files will be tagged with *your* user id. Proceed?
|
|
141
|
+
"You are trying to save a transform created by another user: Source"
|
|
142
|
+
" and report files will be tagged with *your* user id. Proceed?"
|
|
143
|
+
" (y/n)"
|
|
112
144
|
)
|
|
113
145
|
if response != "y":
|
|
114
146
|
return "aborted-save-notebook-created-by-different-user"
|
|
115
|
-
|
|
147
|
+
return_code = save_context_core(
|
|
116
148
|
run=run,
|
|
117
149
|
transform=transform,
|
|
118
150
|
filepath=filepath,
|
|
119
151
|
from_cli=True,
|
|
120
152
|
)
|
|
153
|
+
if filepath.suffix in {".qmd", ".Rmd"}:
|
|
154
|
+
report_file = ln.Artifact(
|
|
155
|
+
filepath.with_suffix(".html"), # validated at the top that this exists
|
|
156
|
+
description=f"Report of run {run.uid}",
|
|
157
|
+
visibility=0, # hidden file
|
|
158
|
+
run=False,
|
|
159
|
+
)
|
|
160
|
+
report_file.save(upload=True, print_progress=False)
|
|
161
|
+
run.report = report_file
|
|
162
|
+
run.save()
|
|
163
|
+
return return_code
|
|
121
164
|
else:
|
|
122
165
|
raise SystemExit("Allowed values for '--registry' are: 'artifact', 'transform'")
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
library(reticulate)
|
|
2
|
+
|
|
3
|
+
# Import lamindb
|
|
4
|
+
ln <- import("lamindb")
|
|
5
|
+
|
|
6
|
+
ln$track("EPnfDtJz8qbE0000", path="run-track.R") # <-- unique id for the script, script path
|
|
7
|
+
|
|
8
|
+
# Create a sample R dataframe
|
|
9
|
+
r_df <- data.frame(
|
|
10
|
+
id = 1:5,
|
|
11
|
+
value = c(10.5, 20.3, 15.7, 25.1, 30.2),
|
|
12
|
+
category = c("A", "B", "A", "C", "B")
|
|
13
|
+
)
|
|
14
|
+
|
|
15
|
+
# Save the dataframe as RDS
|
|
16
|
+
storage_path <- "example_data.rds"
|
|
17
|
+
saveRDS(r_df, storage_path)
|
|
18
|
+
|
|
19
|
+
ln$Artifact(storage_path, description="Example dataframe")$save() # save an artifact
|
|
20
|
+
ln$finish() # mark the script run as finished
|
|
@@ -0,0 +1,73 @@
|
|
|
1
|
+
from pathlib import Path
|
|
2
|
+
import subprocess
|
|
3
|
+
import os
|
|
4
|
+
import lamindb as ln
|
|
5
|
+
|
|
6
|
+
scripts_dir = Path(__file__).parent.resolve() / "scripts"
|
|
7
|
+
|
|
8
|
+
|
|
9
|
+
def test_run_save_cache():
|
|
10
|
+
env = os.environ
|
|
11
|
+
env["LAMIN_TESTING"] = "true"
|
|
12
|
+
filepath = scripts_dir / "run-track.R"
|
|
13
|
+
|
|
14
|
+
transform = ln.Transform(
|
|
15
|
+
uid="EPnfDtJz8qbE0000", name="run-track.R", key="run-track.R", type="script"
|
|
16
|
+
).save()
|
|
17
|
+
ln.Run(transform=transform).save()
|
|
18
|
+
|
|
19
|
+
assert transform.source_code is None
|
|
20
|
+
|
|
21
|
+
result = subprocess.run(
|
|
22
|
+
f"lamin save {filepath}",
|
|
23
|
+
shell=True,
|
|
24
|
+
capture_output=True,
|
|
25
|
+
)
|
|
26
|
+
# print(result.stdout.decode())
|
|
27
|
+
# print(result.stderr.decode())
|
|
28
|
+
assert result.returncode == 0
|
|
29
|
+
assert "on uid 'EPnfDtJz8qbE0000'" in result.stdout.decode()
|
|
30
|
+
|
|
31
|
+
transform = ln.Transform.get("EPnfDtJz8qbE0000")
|
|
32
|
+
assert transform.source_code is not None
|
|
33
|
+
|
|
34
|
+
# now test a .qmd file (.Rmd adheres to same principles)
|
|
35
|
+
filepath = scripts_dir / "run-track.qmd"
|
|
36
|
+
|
|
37
|
+
transform = ln.Transform(
|
|
38
|
+
uid="HPnfDtJz8qbE0000",
|
|
39
|
+
name="run-track.qmd",
|
|
40
|
+
key="run-track.qmd",
|
|
41
|
+
type="notebook",
|
|
42
|
+
).save()
|
|
43
|
+
ln.Run(transform=transform).save()
|
|
44
|
+
|
|
45
|
+
assert transform.source_code is None
|
|
46
|
+
assert transform.latest_run.report is None
|
|
47
|
+
|
|
48
|
+
result = subprocess.run(
|
|
49
|
+
f"lamin save {filepath}",
|
|
50
|
+
shell=True,
|
|
51
|
+
capture_output=True,
|
|
52
|
+
)
|
|
53
|
+
# print(result.stdout.decode())
|
|
54
|
+
# print(result.stderr.decode())
|
|
55
|
+
assert result.returncode == 1
|
|
56
|
+
assert "Please export your" in result.stderr.decode()
|
|
57
|
+
|
|
58
|
+
filepath.with_suffix(".html").write_text("dummy html")
|
|
59
|
+
|
|
60
|
+
result = subprocess.run(
|
|
61
|
+
f"lamin save {filepath}",
|
|
62
|
+
shell=True,
|
|
63
|
+
capture_output=True,
|
|
64
|
+
)
|
|
65
|
+
print(result.stdout.decode())
|
|
66
|
+
print(result.stderr.decode())
|
|
67
|
+
assert result.returncode == 0
|
|
68
|
+
|
|
69
|
+
transform = ln.Transform.get("HPnfDtJz8qbE0000")
|
|
70
|
+
assert transform.source_code is not None
|
|
71
|
+
assert transform.latest_run.report is not None
|
|
72
|
+
|
|
73
|
+
filepath.with_suffix(".html").unlink()
|
|
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
|
{lamin_cli-0.20.1 → lamin_cli-0.21.1}/tests/notebooks/with-title-and-initialized-consecutive.ipynb
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
|