lamin_cli 0.12.3__tar.gz → 0.13.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.12.3 → lamin_cli-0.13.1}/PKG-INFO +1 -1
- lamin_cli-0.13.1/lamin_cli/__init__.py +3 -0
- {lamin_cli-0.12.3 → lamin_cli-0.13.1}/lamin_cli/_get.py +3 -1
- {lamin_cli-0.12.3 → lamin_cli-0.13.1}/lamin_cli/_save.py +38 -1
- {lamin_cli-0.12.3 → lamin_cli-0.13.1}/tests/conftest.py +5 -4
- lamin_cli-0.13.1/tests/notebooks/with-title-and-initialized-consecutive.ipynb +193 -0
- {lamin_cli-0.12.3 → lamin_cli-0.13.1}/tests/notebooks/with-title-and-initialized-non-consecutive.ipynb +0 -1
- lamin_cli-0.13.1/tests/scripts/merely-import-lamindb.py +4 -0
- lamin_cli-0.12.3/tests/scripts/initialized.py → lamin_cli-0.13.1/tests/scripts/run-track-and-finish-sync-git.py +2 -2
- lamin_cli-0.12.3/tests/scripts/initialized-no-git-sync.py → lamin_cli-0.13.1/tests/scripts/run-track-and-finish.py +6 -1
- {lamin_cli-0.12.3 → lamin_cli-0.13.1}/tests/test_get.py +2 -2
- {lamin_cli-0.12.3 → lamin_cli-0.13.1}/tests/test_multi_process.py +1 -1
- {lamin_cli-0.12.3 → lamin_cli-0.13.1}/tests/test_save_notebooks.py +26 -20
- lamin_cli-0.13.1/tests/test_save_scripts.py +103 -0
- lamin_cli-0.12.3/lamin_cli/__init__.py +0 -3
- lamin_cli-0.12.3/tests/notebooks/with-title-and-initialized-consecutive.ipynb +0 -218
- lamin_cli-0.12.3/tests/test_save_scripts.py +0 -57
- {lamin_cli-0.12.3 → lamin_cli-0.13.1}/.gitignore +0 -0
- {lamin_cli-0.12.3 → lamin_cli-0.13.1}/.pre-commit-config.yaml +0 -0
- {lamin_cli-0.12.3 → lamin_cli-0.13.1}/README.md +0 -0
- {lamin_cli-0.12.3 → lamin_cli-0.13.1}/lamin_cli/__main__.py +0 -0
- {lamin_cli-0.12.3 → lamin_cli-0.13.1}/lamin_cli/_cache.py +0 -0
- {lamin_cli-0.12.3 → lamin_cli-0.13.1}/lamin_cli/_migration.py +0 -0
- {lamin_cli-0.12.3 → lamin_cli-0.13.1}/pyproject.toml +0 -0
- {lamin_cli-0.12.3 → lamin_cli-0.13.1}/tests/notebooks/not-initialized.ipynb +0 -0
- {lamin_cli-0.12.3 → lamin_cli-0.13.1}/tests/test_cli.py +0 -0
- {lamin_cli-0.12.3 → lamin_cli-0.13.1}/tests/test_migrate.py +0 -0
- {lamin_cli-0.12.3 → lamin_cli-0.13.1}/tests/test_save_files.py +0 -0
|
@@ -30,7 +30,9 @@ def get(url: str):
|
|
|
30
30
|
if entity == "transform":
|
|
31
31
|
transform = ln.Transform.filter(uid=uid).one()
|
|
32
32
|
filepath_cache = transform.source_code.cache()
|
|
33
|
-
target_filename =
|
|
33
|
+
target_filename = transform.key
|
|
34
|
+
if not target_filename.endswith(transform.source_code.suffix):
|
|
35
|
+
target_filename += transform.source_code.suffix
|
|
34
36
|
filepath_cache.rename(target_filename)
|
|
35
37
|
logger.success(f"cached source code of transform {uid} as {target_filename}")
|
|
36
38
|
else:
|
|
@@ -3,6 +3,44 @@ from pathlib import Path
|
|
|
3
3
|
from typing import Optional, Union
|
|
4
4
|
import lamindb_setup as ln_setup
|
|
5
5
|
from lamin_utils import logger
|
|
6
|
+
import re
|
|
7
|
+
|
|
8
|
+
|
|
9
|
+
def get_stem_uid_and_version_from_file(file_path: Path) -> tuple[str, str]:
|
|
10
|
+
# line-by-line matching might be faster, but let's go with this for now
|
|
11
|
+
with open(file_path) as file:
|
|
12
|
+
content = file.read()
|
|
13
|
+
|
|
14
|
+
if file_path.suffix == ".py":
|
|
15
|
+
stem_uid_pattern = re.compile(
|
|
16
|
+
r'\.transform\.stem_uid\s*=\s*["\']([^"\']+)["\']'
|
|
17
|
+
)
|
|
18
|
+
version_pattern = re.compile(r'\.transform\.version\s*=\s*["\']([^"\']+)["\']')
|
|
19
|
+
elif file_path.suffix == ".ipynb":
|
|
20
|
+
stem_uid_pattern = re.compile(
|
|
21
|
+
r'\.transform\.stem_uid\s*=\s*\\["\']([^"\']+)\\["\']'
|
|
22
|
+
)
|
|
23
|
+
version_pattern = re.compile(
|
|
24
|
+
r'\.transform\.version\s*=\s*\\["\']([^"\']+)\\["\']'
|
|
25
|
+
)
|
|
26
|
+
else:
|
|
27
|
+
raise ValueError("Only .py and .ipynb files are supported.")
|
|
28
|
+
|
|
29
|
+
# Search for matches in the entire file content
|
|
30
|
+
stem_uid_match = stem_uid_pattern.search(content)
|
|
31
|
+
version_match = version_pattern.search(content)
|
|
32
|
+
|
|
33
|
+
# Extract values if matches are found
|
|
34
|
+
stem_uid = stem_uid_match.group(1) if stem_uid_match else None
|
|
35
|
+
version = version_match.group(1) if version_match else None
|
|
36
|
+
|
|
37
|
+
if stem_uid is None or version is None:
|
|
38
|
+
raise SystemExit(
|
|
39
|
+
"ln.settings.transform.stem_uid and ln.settings.transform.version aren't"
|
|
40
|
+
f" set in {file_path}\nCall ln.track() and copy/paste the output into the"
|
|
41
|
+
" notebook"
|
|
42
|
+
)
|
|
43
|
+
return stem_uid, version
|
|
6
44
|
|
|
7
45
|
|
|
8
46
|
def save_from_filepath_cli(
|
|
@@ -17,7 +55,6 @@ def save_from_filepath_cli(
|
|
|
17
55
|
ln_setup.settings.auto_connect = True
|
|
18
56
|
|
|
19
57
|
import lamindb as ln
|
|
20
|
-
from lamindb.core._run_context import get_stem_uid_and_version_from_file
|
|
21
58
|
from lamindb._finish import save_run_context_core
|
|
22
59
|
|
|
23
60
|
ln_setup.settings.auto_connect = auto_connect_state
|
|
@@ -7,12 +7,13 @@ from lamin_utils import logger
|
|
|
7
7
|
|
|
8
8
|
def pytest_sessionstart(session: pytest.Session):
|
|
9
9
|
ln.setup.init(
|
|
10
|
-
storage="./
|
|
11
|
-
name="
|
|
10
|
+
storage="./default_storage_ci",
|
|
11
|
+
name="laminci-unit-tests",
|
|
12
12
|
)
|
|
13
|
+
ln.setup.settings.auto_connect = True
|
|
13
14
|
|
|
14
15
|
|
|
15
16
|
def pytest_sessionfinish(session: pytest.Session):
|
|
16
17
|
logger.set_verbosity(1)
|
|
17
|
-
|
|
18
|
-
|
|
18
|
+
shutil.rmtree("./default_storage_ci")
|
|
19
|
+
ln.setup.delete("laminci-unit-tests", force=True)
|
|
@@ -0,0 +1,193 @@
|
|
|
1
|
+
{
|
|
2
|
+
"cells": [
|
|
3
|
+
{
|
|
4
|
+
"cell_type": "markdown",
|
|
5
|
+
"metadata": {},
|
|
6
|
+
"source": [
|
|
7
|
+
"# My test notebook (consecutive)"
|
|
8
|
+
]
|
|
9
|
+
},
|
|
10
|
+
{
|
|
11
|
+
"cell_type": "code",
|
|
12
|
+
"execution_count": 1,
|
|
13
|
+
"metadata": {
|
|
14
|
+
"execution": {
|
|
15
|
+
"iopub.execute_input": "2024-04-30T02:45:28.590279Z",
|
|
16
|
+
"iopub.status.busy": "2024-04-30T02:45:28.590128Z",
|
|
17
|
+
"iopub.status.idle": "2024-04-30T02:45:29.921019Z",
|
|
18
|
+
"shell.execute_reply": "2024-04-30T02:45:29.920739Z"
|
|
19
|
+
}
|
|
20
|
+
},
|
|
21
|
+
"outputs": [
|
|
22
|
+
{
|
|
23
|
+
"name": "stdout",
|
|
24
|
+
"output_type": "stream",
|
|
25
|
+
"text": [
|
|
26
|
+
"💡 connected lamindb: testuser1/laminci-unit-tests\n"
|
|
27
|
+
]
|
|
28
|
+
}
|
|
29
|
+
],
|
|
30
|
+
"source": [
|
|
31
|
+
"import lamindb as ln"
|
|
32
|
+
]
|
|
33
|
+
},
|
|
34
|
+
{
|
|
35
|
+
"cell_type": "code",
|
|
36
|
+
"execution_count": 2,
|
|
37
|
+
"metadata": {
|
|
38
|
+
"execution": {
|
|
39
|
+
"iopub.execute_input": "2024-04-30T02:45:29.923093Z",
|
|
40
|
+
"iopub.status.busy": "2024-04-30T02:45:29.922808Z",
|
|
41
|
+
"iopub.status.idle": "2024-04-30T02:45:32.189053Z",
|
|
42
|
+
"shell.execute_reply": "2024-04-30T02:45:32.188627Z"
|
|
43
|
+
}
|
|
44
|
+
},
|
|
45
|
+
"outputs": [
|
|
46
|
+
{
|
|
47
|
+
"name": "stdout",
|
|
48
|
+
"output_type": "stream",
|
|
49
|
+
"text": [
|
|
50
|
+
"💡 notebook imports: lamindb==0.71.0\n"
|
|
51
|
+
]
|
|
52
|
+
},
|
|
53
|
+
{
|
|
54
|
+
"name": "stdout",
|
|
55
|
+
"output_type": "stream",
|
|
56
|
+
"text": [
|
|
57
|
+
"💡 saved: Transform(uid='hlsFXswrJjtt5zKv', name='My test notebook (consecutive)', key='with-title-and-initialized-consecutive', version='1', type='notebook', updated_at=2024-04-30 02:45:31 UTC, created_by_id=1)\n"
|
|
58
|
+
]
|
|
59
|
+
},
|
|
60
|
+
{
|
|
61
|
+
"name": "stdout",
|
|
62
|
+
"output_type": "stream",
|
|
63
|
+
"text": [
|
|
64
|
+
"💡 saved: Run(uid='oX11QZyYk6dhucek9jNg', transform_id=1, created_by_id=1)\n"
|
|
65
|
+
]
|
|
66
|
+
}
|
|
67
|
+
],
|
|
68
|
+
"source": [
|
|
69
|
+
"ln.settings.transform.stem_uid = \"hlsFXswrJjtt\"\n",
|
|
70
|
+
"ln.settings.transform.version = \"1\"\n",
|
|
71
|
+
"ln.track()"
|
|
72
|
+
]
|
|
73
|
+
},
|
|
74
|
+
{
|
|
75
|
+
"cell_type": "code",
|
|
76
|
+
"execution_count": 3,
|
|
77
|
+
"metadata": {
|
|
78
|
+
"execution": {
|
|
79
|
+
"iopub.execute_input": "2024-04-30T02:45:32.191144Z",
|
|
80
|
+
"iopub.status.busy": "2024-04-30T02:45:32.191016Z",
|
|
81
|
+
"iopub.status.idle": "2024-04-30T02:45:32.193262Z",
|
|
82
|
+
"shell.execute_reply": "2024-04-30T02:45:32.192907Z"
|
|
83
|
+
}
|
|
84
|
+
},
|
|
85
|
+
"outputs": [
|
|
86
|
+
{
|
|
87
|
+
"name": "stdout",
|
|
88
|
+
"output_type": "stream",
|
|
89
|
+
"text": [
|
|
90
|
+
"my consecutive cell\n"
|
|
91
|
+
]
|
|
92
|
+
}
|
|
93
|
+
],
|
|
94
|
+
"source": [
|
|
95
|
+
"print(\"my consecutive cell\")"
|
|
96
|
+
]
|
|
97
|
+
}
|
|
98
|
+
],
|
|
99
|
+
"metadata": {
|
|
100
|
+
"kernelspec": {
|
|
101
|
+
"display_name": "py39",
|
|
102
|
+
"language": "python",
|
|
103
|
+
"name": "python3"
|
|
104
|
+
},
|
|
105
|
+
"language_info": {
|
|
106
|
+
"codemirror_mode": {
|
|
107
|
+
"name": "ipython",
|
|
108
|
+
"version": 3
|
|
109
|
+
},
|
|
110
|
+
"file_extension": ".py",
|
|
111
|
+
"mimetype": "text/x-python",
|
|
112
|
+
"name": "python",
|
|
113
|
+
"nbconvert_exporter": "python",
|
|
114
|
+
"pygments_lexer": "ipython3",
|
|
115
|
+
"version": "3.10.13"
|
|
116
|
+
},
|
|
117
|
+
"widgets": {
|
|
118
|
+
"application/vnd.jupyter.widget-state+json": {
|
|
119
|
+
"state": {
|
|
120
|
+
"31729cb39d074e8fb483120775f53731": {
|
|
121
|
+
"model_module": "ipylab",
|
|
122
|
+
"model_module_version": "^1.0.0",
|
|
123
|
+
"model_name": "SessionManagerModel",
|
|
124
|
+
"state": {
|
|
125
|
+
"_model_module": "ipylab",
|
|
126
|
+
"_model_module_version": "^1.0.0",
|
|
127
|
+
"_model_name": "SessionManagerModel",
|
|
128
|
+
"_view_count": null,
|
|
129
|
+
"_view_module": null,
|
|
130
|
+
"_view_module_version": "",
|
|
131
|
+
"_view_name": null,
|
|
132
|
+
"current_session": {},
|
|
133
|
+
"sessions": []
|
|
134
|
+
}
|
|
135
|
+
},
|
|
136
|
+
"6939d8a17fbb46b8877f987b20b56757": {
|
|
137
|
+
"model_module": "ipylab",
|
|
138
|
+
"model_module_version": "^1.0.0",
|
|
139
|
+
"model_name": "CommandRegistryModel",
|
|
140
|
+
"state": {
|
|
141
|
+
"_command_list": [],
|
|
142
|
+
"_commands": [],
|
|
143
|
+
"_model_module": "ipylab",
|
|
144
|
+
"_model_module_version": "^1.0.0",
|
|
145
|
+
"_model_name": "CommandRegistryModel",
|
|
146
|
+
"_view_count": null,
|
|
147
|
+
"_view_module": null,
|
|
148
|
+
"_view_module_version": "",
|
|
149
|
+
"_view_name": null
|
|
150
|
+
}
|
|
151
|
+
},
|
|
152
|
+
"82c3ccb5d1114b968e80e1605d528742": {
|
|
153
|
+
"model_module": "ipylab",
|
|
154
|
+
"model_module_version": "^1.0.0",
|
|
155
|
+
"model_name": "JupyterFrontEndModel",
|
|
156
|
+
"state": {
|
|
157
|
+
"_model_module": "ipylab",
|
|
158
|
+
"_model_module_version": "^1.0.0",
|
|
159
|
+
"_model_name": "JupyterFrontEndModel",
|
|
160
|
+
"_view_count": null,
|
|
161
|
+
"_view_module": null,
|
|
162
|
+
"_view_module_version": "",
|
|
163
|
+
"_view_name": null,
|
|
164
|
+
"commands": "IPY_MODEL_6939d8a17fbb46b8877f987b20b56757",
|
|
165
|
+
"sessions": "IPY_MODEL_31729cb39d074e8fb483120775f53731",
|
|
166
|
+
"shell": "IPY_MODEL_9f239e52e3794df9b2c06052072cad24",
|
|
167
|
+
"version": ""
|
|
168
|
+
}
|
|
169
|
+
},
|
|
170
|
+
"9f239e52e3794df9b2c06052072cad24": {
|
|
171
|
+
"model_module": "ipylab",
|
|
172
|
+
"model_module_version": "^1.0.0",
|
|
173
|
+
"model_name": "ShellModel",
|
|
174
|
+
"state": {
|
|
175
|
+
"_model_module": "ipylab",
|
|
176
|
+
"_model_module_version": "^1.0.0",
|
|
177
|
+
"_model_name": "ShellModel",
|
|
178
|
+
"_view_count": null,
|
|
179
|
+
"_view_module": null,
|
|
180
|
+
"_view_module_version": "",
|
|
181
|
+
"_view_name": null,
|
|
182
|
+
"_widgets": []
|
|
183
|
+
}
|
|
184
|
+
}
|
|
185
|
+
},
|
|
186
|
+
"version_major": 2,
|
|
187
|
+
"version_minor": 0
|
|
188
|
+
}
|
|
189
|
+
}
|
|
190
|
+
},
|
|
191
|
+
"nbformat": 4,
|
|
192
|
+
"nbformat_minor": 2
|
|
193
|
+
}
|
|
@@ -1,7 +1,5 @@
|
|
|
1
1
|
import lamindb as ln
|
|
2
2
|
|
|
3
|
-
ln.connect("lamindb-unit-tests")
|
|
4
|
-
|
|
5
3
|
ln.settings.sync_git_repo = "https://github.com/laminlabs/lamin-cli"
|
|
6
4
|
ln.settings.transform.stem_uid = "m5uCHTTpJnjQ"
|
|
7
5
|
ln.settings.transform.version = "1"
|
|
@@ -13,3 +11,5 @@ if __name__ == "__main__":
|
|
|
13
11
|
ln.track(new_run=False)
|
|
14
12
|
|
|
15
13
|
print("hello!")
|
|
14
|
+
|
|
15
|
+
ln.finish()
|
|
@@ -1,9 +1,14 @@
|
|
|
1
1
|
import lamindb as ln
|
|
2
2
|
|
|
3
|
-
ln.
|
|
3
|
+
ln.settings.transform.stem_uid = "VFYCIuaw2GsX"
|
|
4
|
+
ln.settings.transform.version = "1"
|
|
4
5
|
|
|
5
6
|
if __name__ == "__main__":
|
|
6
7
|
# we're using new_run here to mock the notebook situation
|
|
7
8
|
# and cover the look up of an existing run in the tests
|
|
8
9
|
# new_run = True is trivial
|
|
10
|
+
ln.track(new_run=False)
|
|
11
|
+
|
|
9
12
|
print("hello!")
|
|
13
|
+
|
|
14
|
+
ln.finish()
|
|
@@ -3,7 +3,7 @@ import subprocess
|
|
|
3
3
|
|
|
4
4
|
|
|
5
5
|
def test_decompose_url():
|
|
6
|
-
url = "https://lamin.ai/laminlabs/arrayloader-benchmarks/
|
|
6
|
+
url = "https://lamin.ai/laminlabs/arrayloader-benchmarks/transform/1GCKs8zLtkc85zKv" # noqa
|
|
7
7
|
result = decompose_url(url)
|
|
8
8
|
instance_slug, entity, uid = result
|
|
9
9
|
assert instance_slug == "laminlabs/arrayloader-benchmarks"
|
|
@@ -14,7 +14,7 @@ def test_decompose_url():
|
|
|
14
14
|
def test_get():
|
|
15
15
|
result = subprocess.run(
|
|
16
16
|
"lamin get"
|
|
17
|
-
" 'https://lamin.ai/laminlabs/arrayloader-benchmarks/
|
|
17
|
+
" 'https://lamin.ai/laminlabs/arrayloader-benchmarks/transform/1GCKs8zLtkc85zKv'", # noqa
|
|
18
18
|
shell=True,
|
|
19
19
|
capture_output=True,
|
|
20
20
|
)
|
|
@@ -3,7 +3,9 @@ import subprocess
|
|
|
3
3
|
from pathlib import Path
|
|
4
4
|
import nbproject_test
|
|
5
5
|
import pytest
|
|
6
|
+
from nbproject.dev import read_notebook, write_notebook
|
|
6
7
|
from nbclient.exceptions import CellExecutionError
|
|
8
|
+
import lamindb as ln
|
|
7
9
|
|
|
8
10
|
notebook_dir = "./sub/lamin-cli/tests/notebooks/"
|
|
9
11
|
|
|
@@ -30,9 +32,6 @@ def test_save_non_consecutive():
|
|
|
30
32
|
notebook_path = Path(
|
|
31
33
|
f"{notebook_dir}with-title-and-initialized-non-consecutive.ipynb"
|
|
32
34
|
).resolve()
|
|
33
|
-
import lamindb as ln
|
|
34
|
-
|
|
35
|
-
ln.connect("lamindb-unit-tests")
|
|
36
35
|
|
|
37
36
|
# here, we're mimicking a non-consecutive run
|
|
38
37
|
transform = ln.Transform(
|
|
@@ -63,11 +62,6 @@ def test_save_consecutive():
|
|
|
63
62
|
env = os.environ
|
|
64
63
|
env["LAMIN_TESTING"] = "true"
|
|
65
64
|
|
|
66
|
-
# let's inspect what got written to the database
|
|
67
|
-
import lamindb as ln
|
|
68
|
-
|
|
69
|
-
ln.connect("lamindb-unit-tests")
|
|
70
|
-
|
|
71
65
|
transform = ln.Transform.filter(uid="hlsFXswrJjtt5zKv").one_or_none()
|
|
72
66
|
assert transform is None
|
|
73
67
|
|
|
@@ -106,22 +100,26 @@ def test_save_consecutive():
|
|
|
106
100
|
assert transform is not None
|
|
107
101
|
assert transform.latest_report.path.exists()
|
|
108
102
|
assert transform.latest_run.report.path == transform.latest_report.path
|
|
109
|
-
assert transform.source_code.hash == "
|
|
103
|
+
assert transform.source_code.hash == "5nc_HMjPvT9n26OWrjq6uQ"
|
|
110
104
|
assert transform.latest_run.environment.path.exists()
|
|
111
105
|
assert transform.source_code.path.exists()
|
|
112
106
|
|
|
113
|
-
# now, assume the user modifies the notebook
|
|
114
|
-
# it without changing stem uid or version
|
|
115
|
-
# outside of tests, this triggers a dialogue
|
|
116
|
-
# within tests, it automatically overwrites the source
|
|
117
|
-
from nbproject.dev import read_notebook, write_notebook
|
|
118
|
-
|
|
107
|
+
# now, assume the user modifies the notebook
|
|
119
108
|
nb = read_notebook(notebook_path)
|
|
120
109
|
# simulate editing the notebook (here, duplicate last cell)
|
|
121
110
|
new_cell = nb.cells[-1].copy()
|
|
122
111
|
new_cell["execution_count"] += 1
|
|
123
112
|
nb.cells.append(new_cell)
|
|
124
113
|
write_notebook(nb, notebook_path)
|
|
114
|
+
|
|
115
|
+
# try re-running - it fails
|
|
116
|
+
with pytest.raises(CellExecutionError) as error:
|
|
117
|
+
nbproject_test.execute_notebooks(notebook_path, print_outputs=True)
|
|
118
|
+
print(error.exconly())
|
|
119
|
+
assert "UpdateTransformSettings" in error.exconly()
|
|
120
|
+
|
|
121
|
+
# try re-saving - it works but will issue an interactive warning dialogue
|
|
122
|
+
# that clarifies that the user is about to re-save the notebook
|
|
125
123
|
result = subprocess.run(
|
|
126
124
|
f"lamin save {notebook_path}",
|
|
127
125
|
shell=True,
|
|
@@ -130,16 +128,24 @@ def test_save_consecutive():
|
|
|
130
128
|
)
|
|
131
129
|
assert result.returncode == 0
|
|
132
130
|
assert "saved transform" in result.stdout.decode()
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
transform = ln.Transform.filter(uid="hlsFXswrJjtt5zKv").one_or_none()
|
|
136
|
-
assert transform is not None
|
|
131
|
+
# the source code is overwritten with the edits, reflected in a new hash
|
|
132
|
+
transform = ln.Transform.get("hlsFXswrJjtt5zKv")
|
|
137
133
|
assert transform.latest_report.path.exists()
|
|
138
134
|
assert transform.latest_run.report.path == transform.latest_report.path
|
|
139
|
-
assert transform.source_code.hash == "
|
|
135
|
+
assert transform.source_code.hash == "ocLybD0Hv_L3NhhXgTyQcw"
|
|
140
136
|
assert transform.latest_run.environment.path.exists()
|
|
141
137
|
assert transform.source_code.path.exists()
|
|
142
138
|
|
|
139
|
+
# get the the source code via command line
|
|
140
|
+
result = subprocess.run(
|
|
141
|
+
"lamin get"
|
|
142
|
+
f" https://lamin.ai/{ln.setup.settings.user.handle}/laminci-unit-tests/transform/hlsFXswrJjtt5zKv", # noqa
|
|
143
|
+
shell=True,
|
|
144
|
+
capture_output=True,
|
|
145
|
+
)
|
|
146
|
+
print(result.stderr.decode())
|
|
147
|
+
assert result.returncode == 0
|
|
148
|
+
|
|
143
149
|
# now, assume the user renames the notebook
|
|
144
150
|
new_path = notebook_path.with_name("new_name.ipynb")
|
|
145
151
|
os.system(f"cp {notebook_path} {new_path}")
|
|
@@ -0,0 +1,103 @@
|
|
|
1
|
+
from pathlib import Path
|
|
2
|
+
import subprocess
|
|
3
|
+
import os
|
|
4
|
+
import lamindb as ln
|
|
5
|
+
from lamindb_setup import settings
|
|
6
|
+
|
|
7
|
+
|
|
8
|
+
scripts_dir = Path(__file__).parent.resolve() / "scripts"
|
|
9
|
+
|
|
10
|
+
|
|
11
|
+
def test_run_save_cache():
|
|
12
|
+
env = os.environ
|
|
13
|
+
env["LAMIN_TESTING"] = "true"
|
|
14
|
+
filepath = scripts_dir / "run-track-and-finish-sync-git.py"
|
|
15
|
+
|
|
16
|
+
# attempt to save the script without it yet being run
|
|
17
|
+
result = subprocess.run(
|
|
18
|
+
f"lamin save {filepath}",
|
|
19
|
+
shell=True,
|
|
20
|
+
capture_output=True,
|
|
21
|
+
)
|
|
22
|
+
print(result.stderr.decode())
|
|
23
|
+
assert result.returncode == 1
|
|
24
|
+
assert "Did you run ln.track()" in result.stdout.decode()
|
|
25
|
+
|
|
26
|
+
# run the script
|
|
27
|
+
result = subprocess.run(
|
|
28
|
+
f"python {filepath}",
|
|
29
|
+
shell=True,
|
|
30
|
+
capture_output=True,
|
|
31
|
+
)
|
|
32
|
+
print(result.stdout.decode())
|
|
33
|
+
print(result.stderr.decode())
|
|
34
|
+
assert result.returncode == 0
|
|
35
|
+
assert "saved: Transform" in result.stdout.decode()
|
|
36
|
+
assert "m5uCHTTpJnjQ5zKv" in result.stdout.decode()
|
|
37
|
+
assert "saved: Run" in result.stdout.decode()
|
|
38
|
+
|
|
39
|
+
transform = ln.Transform.get("m5uCHTTpJnjQ")
|
|
40
|
+
assert transform.source_code.hash == "-QN2dVdC8T3xWG8vBl-wew"
|
|
41
|
+
assert transform.latest_run.environment.path.exists()
|
|
42
|
+
assert transform.source_code.path.exists()
|
|
43
|
+
|
|
44
|
+
# you can rerun the same script
|
|
45
|
+
result = subprocess.run(
|
|
46
|
+
f"python {filepath}",
|
|
47
|
+
shell=True,
|
|
48
|
+
capture_output=True,
|
|
49
|
+
env=env,
|
|
50
|
+
)
|
|
51
|
+
print(result.stdout.decode())
|
|
52
|
+
print(result.stderr.decode())
|
|
53
|
+
assert result.returncode == 0
|
|
54
|
+
assert "loaded: Transform" in result.stdout.decode()
|
|
55
|
+
assert "m5uCHTTpJnjQ5zKv" in result.stdout.decode()
|
|
56
|
+
assert "loaded: Run" in result.stdout.decode()
|
|
57
|
+
|
|
58
|
+
# edit the script
|
|
59
|
+
content = filepath.read_text() + "\n # edited"
|
|
60
|
+
filepath.write_text(content)
|
|
61
|
+
|
|
62
|
+
# re-run the script
|
|
63
|
+
result = subprocess.run(
|
|
64
|
+
f"python {filepath}",
|
|
65
|
+
shell=True,
|
|
66
|
+
capture_output=True,
|
|
67
|
+
env=env,
|
|
68
|
+
)
|
|
69
|
+
print(result.stdout.decode())
|
|
70
|
+
print(result.stderr.decode())
|
|
71
|
+
assert result.returncode == 1
|
|
72
|
+
assert "Did not find blob hash" in result.stderr.decode()
|
|
73
|
+
|
|
74
|
+
# edit the script to remove the git integration
|
|
75
|
+
content = filepath.read_text()
|
|
76
|
+
content_lines = content.split("\n")
|
|
77
|
+
content_lines.remove(
|
|
78
|
+
'ln.settings.sync_git_repo = "https://github.com/laminlabs/lamin-cli"'
|
|
79
|
+
)
|
|
80
|
+
content = "\n".join(content_lines)
|
|
81
|
+
filepath.write_text(content)
|
|
82
|
+
|
|
83
|
+
# re-run the script
|
|
84
|
+
result = subprocess.run(
|
|
85
|
+
f"python {filepath}",
|
|
86
|
+
shell=True,
|
|
87
|
+
capture_output=True,
|
|
88
|
+
env=env,
|
|
89
|
+
)
|
|
90
|
+
print(result.stdout.decode())
|
|
91
|
+
print(result.stderr.decode())
|
|
92
|
+
assert result.returncode == 1
|
|
93
|
+
assert "Please update your transform settings as follows" in result.stderr.decode()
|
|
94
|
+
|
|
95
|
+
# try to get the the source code via command line
|
|
96
|
+
result = subprocess.run(
|
|
97
|
+
"lamin get"
|
|
98
|
+
f" https://lamin.ai/{settings.user.handle}/laminci-unit-tests/transform/m5uCHTTpJnjQ5zKv", # noqa
|
|
99
|
+
shell=True,
|
|
100
|
+
capture_output=True,
|
|
101
|
+
)
|
|
102
|
+
print(result.stderr.decode())
|
|
103
|
+
assert result.returncode == 0
|
|
@@ -1,218 +0,0 @@
|
|
|
1
|
-
{
|
|
2
|
-
"cells": [
|
|
3
|
-
{
|
|
4
|
-
"cell_type": "markdown",
|
|
5
|
-
"metadata": {},
|
|
6
|
-
"source": [
|
|
7
|
-
"# My test notebook (consecutive)"
|
|
8
|
-
]
|
|
9
|
-
},
|
|
10
|
-
{
|
|
11
|
-
"cell_type": "code",
|
|
12
|
-
"execution_count": 1,
|
|
13
|
-
"metadata": {
|
|
14
|
-
"execution": {
|
|
15
|
-
"iopub.execute_input": "2024-02-28T10:26:34.123001Z",
|
|
16
|
-
"iopub.status.busy": "2024-02-28T10:26:34.122692Z",
|
|
17
|
-
"iopub.status.idle": "2024-02-28T10:26:35.334278Z",
|
|
18
|
-
"shell.execute_reply": "2024-02-28T10:26:35.333942Z"
|
|
19
|
-
}
|
|
20
|
-
},
|
|
21
|
-
"outputs": [
|
|
22
|
-
{
|
|
23
|
-
"name": "stdout",
|
|
24
|
-
"output_type": "stream",
|
|
25
|
-
"text": [
|
|
26
|
-
"💡 lamindb instance: falexwolf/lamindb-setup-notebook-tests\n"
|
|
27
|
-
]
|
|
28
|
-
}
|
|
29
|
-
],
|
|
30
|
-
"source": [
|
|
31
|
-
"import lamindb as ln"
|
|
32
|
-
]
|
|
33
|
-
},
|
|
34
|
-
{
|
|
35
|
-
"cell_type": "code",
|
|
36
|
-
"execution_count": 2,
|
|
37
|
-
"metadata": {
|
|
38
|
-
"execution": {
|
|
39
|
-
"iopub.execute_input": "2024-02-28T10:26:35.351854Z",
|
|
40
|
-
"iopub.status.busy": "2024-02-28T10:26:35.351500Z",
|
|
41
|
-
"iopub.status.idle": "2024-02-28T10:26:37.516724Z",
|
|
42
|
-
"shell.execute_reply": "2024-02-28T10:26:37.516289Z"
|
|
43
|
-
}
|
|
44
|
-
},
|
|
45
|
-
"outputs": [
|
|
46
|
-
{
|
|
47
|
-
"name": "stdout",
|
|
48
|
-
"output_type": "stream",
|
|
49
|
-
"text": [
|
|
50
|
-
"💡 notebook imports: lamindb==0.67.3\n"
|
|
51
|
-
]
|
|
52
|
-
},
|
|
53
|
-
{
|
|
54
|
-
"name": "stdout",
|
|
55
|
-
"output_type": "stream",
|
|
56
|
-
"text": [
|
|
57
|
-
"💡 saved: Transform(uid='hlsFXswrJjtt5zKv', name='My test notebook (consecutive)', key='with-title-and-initialized-consecutive', version='1', type=notebook, updated_at=2024-02-28 10:26:36 UTC, created_by_id=1)\n"
|
|
58
|
-
]
|
|
59
|
-
},
|
|
60
|
-
{
|
|
61
|
-
"name": "stdout",
|
|
62
|
-
"output_type": "stream",
|
|
63
|
-
"text": [
|
|
64
|
-
"💡 saved: Run(uid='FyKeQx6bw3o1okN4khF7', started_at=2024-02-28 10:26:36 UTC, transform_id=1, created_by_id=1)\n"
|
|
65
|
-
]
|
|
66
|
-
}
|
|
67
|
-
],
|
|
68
|
-
"source": [
|
|
69
|
-
"ln.connect(\"lamindb-unit-tests\")\n",
|
|
70
|
-
"ln.settings.transform.stem_uid = \"hlsFXswrJjtt\"\n",
|
|
71
|
-
"ln.settings.transform.version = \"1\"\n",
|
|
72
|
-
"ln.track()"
|
|
73
|
-
]
|
|
74
|
-
},
|
|
75
|
-
{
|
|
76
|
-
"cell_type": "code",
|
|
77
|
-
"execution_count": 3,
|
|
78
|
-
"metadata": {
|
|
79
|
-
"execution": {
|
|
80
|
-
"iopub.execute_input": "2024-02-28T10:26:37.518448Z",
|
|
81
|
-
"iopub.status.busy": "2024-02-28T10:26:37.518331Z",
|
|
82
|
-
"iopub.status.idle": "2024-02-28T10:26:37.520409Z",
|
|
83
|
-
"shell.execute_reply": "2024-02-28T10:26:37.520130Z"
|
|
84
|
-
}
|
|
85
|
-
},
|
|
86
|
-
"outputs": [
|
|
87
|
-
{
|
|
88
|
-
"name": "stdout",
|
|
89
|
-
"output_type": "stream",
|
|
90
|
-
"text": [
|
|
91
|
-
"my consecutive cell\n"
|
|
92
|
-
]
|
|
93
|
-
}
|
|
94
|
-
],
|
|
95
|
-
"source": [
|
|
96
|
-
"print(\"my consecutive cell\")"
|
|
97
|
-
]
|
|
98
|
-
},
|
|
99
|
-
{
|
|
100
|
-
"cell_type": "code",
|
|
101
|
-
"execution_count": 4,
|
|
102
|
-
"metadata": {
|
|
103
|
-
"execution": {
|
|
104
|
-
"iopub.execute_input": "2024-02-28T10:26:37.518448Z",
|
|
105
|
-
"iopub.status.busy": "2024-02-28T10:26:37.518331Z",
|
|
106
|
-
"iopub.status.idle": "2024-02-28T10:26:37.520409Z",
|
|
107
|
-
"shell.execute_reply": "2024-02-28T10:26:37.520130Z"
|
|
108
|
-
}
|
|
109
|
-
},
|
|
110
|
-
"outputs": [
|
|
111
|
-
{
|
|
112
|
-
"name": "stdout",
|
|
113
|
-
"output_type": "stream",
|
|
114
|
-
"text": [
|
|
115
|
-
"my consecutive cell\n"
|
|
116
|
-
]
|
|
117
|
-
}
|
|
118
|
-
],
|
|
119
|
-
"source": [
|
|
120
|
-
"print(\"my consecutive cell\")"
|
|
121
|
-
]
|
|
122
|
-
}
|
|
123
|
-
],
|
|
124
|
-
"metadata": {
|
|
125
|
-
"kernelspec": {
|
|
126
|
-
"display_name": "py39",
|
|
127
|
-
"language": "python",
|
|
128
|
-
"name": "python3"
|
|
129
|
-
},
|
|
130
|
-
"language_info": {
|
|
131
|
-
"codemirror_mode": {
|
|
132
|
-
"name": "ipython",
|
|
133
|
-
"version": 3
|
|
134
|
-
},
|
|
135
|
-
"file_extension": ".py",
|
|
136
|
-
"mimetype": "text/x-python",
|
|
137
|
-
"name": "python",
|
|
138
|
-
"nbconvert_exporter": "python",
|
|
139
|
-
"pygments_lexer": "ipython3",
|
|
140
|
-
"version": "3.10.13"
|
|
141
|
-
},
|
|
142
|
-
"widgets": {
|
|
143
|
-
"application/vnd.jupyter.widget-state+json": {
|
|
144
|
-
"state": {
|
|
145
|
-
"444383c3d65b4d12a4f133df8dc72a9f": {
|
|
146
|
-
"model_module": "ipylab",
|
|
147
|
-
"model_module_version": "^1.0.0",
|
|
148
|
-
"model_name": "ShellModel",
|
|
149
|
-
"state": {
|
|
150
|
-
"_model_module": "ipylab",
|
|
151
|
-
"_model_module_version": "^1.0.0",
|
|
152
|
-
"_model_name": "ShellModel",
|
|
153
|
-
"_view_count": null,
|
|
154
|
-
"_view_module": null,
|
|
155
|
-
"_view_module_version": "",
|
|
156
|
-
"_view_name": null,
|
|
157
|
-
"_widgets": []
|
|
158
|
-
}
|
|
159
|
-
},
|
|
160
|
-
"b782fd14699442f5af38bfdaefae8b43": {
|
|
161
|
-
"model_module": "ipylab",
|
|
162
|
-
"model_module_version": "^1.0.0",
|
|
163
|
-
"model_name": "SessionManagerModel",
|
|
164
|
-
"state": {
|
|
165
|
-
"_model_module": "ipylab",
|
|
166
|
-
"_model_module_version": "^1.0.0",
|
|
167
|
-
"_model_name": "SessionManagerModel",
|
|
168
|
-
"_view_count": null,
|
|
169
|
-
"_view_module": null,
|
|
170
|
-
"_view_module_version": "",
|
|
171
|
-
"_view_name": null,
|
|
172
|
-
"current_session": {},
|
|
173
|
-
"sessions": []
|
|
174
|
-
}
|
|
175
|
-
},
|
|
176
|
-
"c5cf1ccc24ea4a49a6f6a8350c2cea24": {
|
|
177
|
-
"model_module": "ipylab",
|
|
178
|
-
"model_module_version": "^1.0.0",
|
|
179
|
-
"model_name": "CommandRegistryModel",
|
|
180
|
-
"state": {
|
|
181
|
-
"_command_list": [],
|
|
182
|
-
"_commands": [],
|
|
183
|
-
"_model_module": "ipylab",
|
|
184
|
-
"_model_module_version": "^1.0.0",
|
|
185
|
-
"_model_name": "CommandRegistryModel",
|
|
186
|
-
"_view_count": null,
|
|
187
|
-
"_view_module": null,
|
|
188
|
-
"_view_module_version": "",
|
|
189
|
-
"_view_name": null
|
|
190
|
-
}
|
|
191
|
-
},
|
|
192
|
-
"c63b8662332149d7a748445640768bf8": {
|
|
193
|
-
"model_module": "ipylab",
|
|
194
|
-
"model_module_version": "^1.0.0",
|
|
195
|
-
"model_name": "JupyterFrontEndModel",
|
|
196
|
-
"state": {
|
|
197
|
-
"_model_module": "ipylab",
|
|
198
|
-
"_model_module_version": "^1.0.0",
|
|
199
|
-
"_model_name": "JupyterFrontEndModel",
|
|
200
|
-
"_view_count": null,
|
|
201
|
-
"_view_module": null,
|
|
202
|
-
"_view_module_version": "",
|
|
203
|
-
"_view_name": null,
|
|
204
|
-
"commands": "IPY_MODEL_c5cf1ccc24ea4a49a6f6a8350c2cea24",
|
|
205
|
-
"sessions": "IPY_MODEL_b782fd14699442f5af38bfdaefae8b43",
|
|
206
|
-
"shell": "IPY_MODEL_444383c3d65b4d12a4f133df8dc72a9f",
|
|
207
|
-
"version": ""
|
|
208
|
-
}
|
|
209
|
-
}
|
|
210
|
-
},
|
|
211
|
-
"version_major": 2,
|
|
212
|
-
"version_minor": 0
|
|
213
|
-
}
|
|
214
|
-
}
|
|
215
|
-
},
|
|
216
|
-
"nbformat": 4,
|
|
217
|
-
"nbformat_minor": 2
|
|
218
|
-
}
|
|
@@ -1,57 +0,0 @@
|
|
|
1
|
-
from pathlib import Path
|
|
2
|
-
import subprocess
|
|
3
|
-
import os
|
|
4
|
-
from lamindb_setup import settings
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
scripts_dir = Path(__file__).parent.resolve() / "scripts"
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
def test_run_save_cache():
|
|
11
|
-
env = os.environ
|
|
12
|
-
env["LAMIN_TESTING"] = "true"
|
|
13
|
-
|
|
14
|
-
filepath = scripts_dir / "initialized.py"
|
|
15
|
-
# attempt to save the script without it yet being run
|
|
16
|
-
# lamin save sub/lamin-cli/tests/scripts/initialized.py
|
|
17
|
-
result = subprocess.run(
|
|
18
|
-
f"lamin save {filepath}",
|
|
19
|
-
shell=True,
|
|
20
|
-
capture_output=True,
|
|
21
|
-
)
|
|
22
|
-
print(result.stderr.decode())
|
|
23
|
-
assert result.returncode == 1
|
|
24
|
-
assert "Did you run ln.track()" in result.stdout.decode()
|
|
25
|
-
|
|
26
|
-
# python sub/lamin-cli/tests/scripts/initialized.py
|
|
27
|
-
result = subprocess.run(
|
|
28
|
-
f"python {filepath}",
|
|
29
|
-
shell=True,
|
|
30
|
-
capture_output=True,
|
|
31
|
-
)
|
|
32
|
-
print(result.stdout.decode())
|
|
33
|
-
print(result.stderr.decode())
|
|
34
|
-
assert result.returncode == 0
|
|
35
|
-
assert "saved: Transform" in result.stdout.decode()
|
|
36
|
-
assert "saved: Run" in result.stdout.decode()
|
|
37
|
-
|
|
38
|
-
# python sub/lamin-cli/tests/scripts/initialized.py
|
|
39
|
-
# you can rerun the same script
|
|
40
|
-
result = subprocess.run(
|
|
41
|
-
f"python {filepath}",
|
|
42
|
-
shell=True,
|
|
43
|
-
capture_output=True,
|
|
44
|
-
env=env,
|
|
45
|
-
)
|
|
46
|
-
print(result.stdout.decode())
|
|
47
|
-
print(result.stderr.decode())
|
|
48
|
-
assert result.returncode == 0
|
|
49
|
-
|
|
50
|
-
result = subprocess.run(
|
|
51
|
-
"lamin get"
|
|
52
|
-
f" https://lamin.ai/{settings.user.handle}/lamindb-unit-tests/transform/m5uCHTTpJnjQ5zKv", # noqa
|
|
53
|
-
shell=True,
|
|
54
|
-
capture_output=True,
|
|
55
|
-
)
|
|
56
|
-
print(result.stderr.decode())
|
|
57
|
-
assert result.returncode == 0
|
|
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
|