bluer-objects 6.3.1__py3-none-any.whl
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.
Potentially problematic release.
This version of bluer-objects might be problematic. Click here for more details.
- bluer_objects/.abcli/abcli.sh +9 -0
- bluer_objects/.abcli/actions.sh +11 -0
- bluer_objects/.abcli/aka.sh +3 -0
- bluer_objects/.abcli/alias.sh +36 -0
- bluer_objects/.abcli/blue_objects.sh +11 -0
- bluer_objects/.abcli/cache.sh +5 -0
- bluer_objects/.abcli/clone.sh +94 -0
- bluer_objects/.abcli/download.sh +53 -0
- bluer_objects/.abcli/file.sh +8 -0
- bluer_objects/.abcli/gif.sh +27 -0
- bluer_objects/.abcli/host.sh +29 -0
- bluer_objects/.abcli/ls.sh +24 -0
- bluer_objects/.abcli/metadata/get.sh +24 -0
- bluer_objects/.abcli/metadata/post.sh +22 -0
- bluer_objects/.abcli/metadata.sh +16 -0
- bluer_objects/.abcli/mlflow/browse.sh +36 -0
- bluer_objects/.abcli/mlflow/cache.sh +31 -0
- bluer_objects/.abcli/mlflow/list_registered_models.sh +9 -0
- bluer_objects/.abcli/mlflow/log_artifacts.sh +10 -0
- bluer_objects/.abcli/mlflow/log_run.sh +10 -0
- bluer_objects/.abcli/mlflow/run.sh +11 -0
- bluer_objects/.abcli/mlflow/tags/clone.sh +15 -0
- bluer_objects/.abcli/mlflow/tags/get.sh +10 -0
- bluer_objects/.abcli/mlflow/tags/search.sh +12 -0
- bluer_objects/.abcli/mlflow/tags/set.sh +13 -0
- bluer_objects/.abcli/mlflow/tags.sh +16 -0
- bluer_objects/.abcli/mlflow/test.sh +11 -0
- bluer_objects/.abcli/mlflow/transition.sh +20 -0
- bluer_objects/.abcli/mlflow.sh +29 -0
- bluer_objects/.abcli/mysql/cache.sh +65 -0
- bluer_objects/.abcli/mysql/relations.sh +83 -0
- bluer_objects/.abcli/mysql/tags.sh +85 -0
- bluer_objects/.abcli/mysql.sh +16 -0
- bluer_objects/.abcli/object.sh +54 -0
- bluer_objects/.abcli/publish.sh +58 -0
- bluer_objects/.abcli/select.sh +34 -0
- bluer_objects/.abcli/storage/clear.sh +45 -0
- bluer_objects/.abcli/storage/download_file.sh +9 -0
- bluer_objects/.abcli/storage/exists.sh +8 -0
- bluer_objects/.abcli/storage/list.sh +8 -0
- bluer_objects/.abcli/storage/rm.sh +11 -0
- bluer_objects/.abcli/storage/status.sh +11 -0
- bluer_objects/.abcli/storage.sh +15 -0
- bluer_objects/.abcli/tags.sh +5 -0
- bluer_objects/.abcli/tests/README.sh +8 -0
- bluer_objects/.abcli/tests/clone.sh +32 -0
- bluer_objects/.abcli/tests/help.sh +85 -0
- bluer_objects/.abcli/tests/host.sh +7 -0
- bluer_objects/.abcli/tests/ls.sh +13 -0
- bluer_objects/.abcli/tests/metadata.sh +53 -0
- bluer_objects/.abcli/tests/mlflow_cache.sh +14 -0
- bluer_objects/.abcli/tests/mlflow_logging.sh +12 -0
- bluer_objects/.abcli/tests/mlflow_tags.sh +29 -0
- bluer_objects/.abcli/tests/mlflow_test.sh +7 -0
- bluer_objects/.abcli/tests/mysql_cache.sh +15 -0
- bluer_objects/.abcli/tests/mysql_relations.sh +20 -0
- bluer_objects/.abcli/tests/mysql_tags.sh +16 -0
- bluer_objects/.abcli/tests/test_gif.sh +13 -0
- bluer_objects/.abcli/tests/version.sh +10 -0
- bluer_objects/.abcli/upload.sh +73 -0
- bluer_objects/README/__init__.py +29 -0
- bluer_objects/README/functions.py +285 -0
- bluer_objects/README/items.py +30 -0
- bluer_objects/__init__.py +19 -0
- bluer_objects/__main__.py +16 -0
- bluer_objects/config.env +22 -0
- bluer_objects/env.py +72 -0
- bluer_objects/file/__init__.py +41 -0
- bluer_objects/file/__main__.py +51 -0
- bluer_objects/file/classes.py +38 -0
- bluer_objects/file/functions.py +290 -0
- bluer_objects/file/load.py +219 -0
- bluer_objects/file/save.py +280 -0
- bluer_objects/graphics/__init__.py +4 -0
- bluer_objects/graphics/__main__.py +84 -0
- bluer_objects/graphics/frame.py +15 -0
- bluer_objects/graphics/gif.py +86 -0
- bluer_objects/graphics/screen.py +63 -0
- bluer_objects/graphics/signature.py +97 -0
- bluer_objects/graphics/text.py +165 -0
- bluer_objects/help/__init__.py +0 -0
- bluer_objects/help/__main__.py +10 -0
- bluer_objects/help/functions.py +5 -0
- bluer_objects/host/__init__.py +1 -0
- bluer_objects/host/__main__.py +84 -0
- bluer_objects/host/functions.py +66 -0
- bluer_objects/logger/__init__.py +4 -0
- bluer_objects/logger/matrix.py +209 -0
- bluer_objects/markdown.py +43 -0
- bluer_objects/metadata/__init__.py +8 -0
- bluer_objects/metadata/__main__.py +110 -0
- bluer_objects/metadata/enums.py +29 -0
- bluer_objects/metadata/get.py +89 -0
- bluer_objects/metadata/post.py +101 -0
- bluer_objects/mlflow/__init__.py +28 -0
- bluer_objects/mlflow/__main__.py +271 -0
- bluer_objects/mlflow/cache.py +13 -0
- bluer_objects/mlflow/logging.py +81 -0
- bluer_objects/mlflow/models.py +57 -0
- bluer_objects/mlflow/objects.py +76 -0
- bluer_objects/mlflow/runs.py +100 -0
- bluer_objects/mlflow/tags.py +90 -0
- bluer_objects/mlflow/testing.py +39 -0
- bluer_objects/mysql/cache/__init__.py +8 -0
- bluer_objects/mysql/cache/__main__.py +91 -0
- bluer_objects/mysql/cache/functions.py +181 -0
- bluer_objects/mysql/relations/__init__.py +9 -0
- bluer_objects/mysql/relations/__main__.py +138 -0
- bluer_objects/mysql/relations/functions.py +180 -0
- bluer_objects/mysql/table.py +144 -0
- bluer_objects/mysql/tags/__init__.py +1 -0
- bluer_objects/mysql/tags/__main__.py +130 -0
- bluer_objects/mysql/tags/functions.py +203 -0
- bluer_objects/objects.py +167 -0
- bluer_objects/path.py +194 -0
- bluer_objects/sample.env +16 -0
- bluer_objects/storage/__init__.py +3 -0
- bluer_objects/storage/__main__.py +114 -0
- bluer_objects/storage/classes.py +237 -0
- bluer_objects/tests/__init__.py +0 -0
- bluer_objects/tests/test_README.py +5 -0
- bluer_objects/tests/test_env.py +27 -0
- bluer_objects/tests/test_file_load_save.py +105 -0
- bluer_objects/tests/test_fullname.py +5 -0
- bluer_objects/tests/test_graphics.py +28 -0
- bluer_objects/tests/test_graphics_frame.py +11 -0
- bluer_objects/tests/test_graphics_gif.py +29 -0
- bluer_objects/tests/test_graphics_screen.py +8 -0
- bluer_objects/tests/test_graphics_signature.py +80 -0
- bluer_objects/tests/test_graphics_text.py +14 -0
- bluer_objects/tests/test_logger.py +5 -0
- bluer_objects/tests/test_logger_matrix.py +73 -0
- bluer_objects/tests/test_markdown.py +10 -0
- bluer_objects/tests/test_metadata.py +204 -0
- bluer_objects/tests/test_mlflow.py +60 -0
- bluer_objects/tests/test_mysql_cache.py +14 -0
- bluer_objects/tests/test_mysql_relations.py +16 -0
- bluer_objects/tests/test_mysql_table.py +9 -0
- bluer_objects/tests/test_mysql_tags.py +13 -0
- bluer_objects/tests/test_objects.py +180 -0
- bluer_objects/tests/test_path.py +7 -0
- bluer_objects/tests/test_storage.py +7 -0
- bluer_objects/tests/test_version.py +5 -0
- bluer_objects/urls.py +3 -0
- bluer_objects-6.3.1.dist-info/METADATA +57 -0
- bluer_objects-6.3.1.dist-info/RECORD +149 -0
- bluer_objects-6.3.1.dist-info/WHEEL +5 -0
- bluer_objects-6.3.1.dist-info/licenses/LICENSE +121 -0
- bluer_objects-6.3.1.dist-info/top_level.txt +1 -0
|
@@ -0,0 +1,81 @@
|
|
|
1
|
+
from typing import Dict
|
|
2
|
+
import os
|
|
3
|
+
import glob
|
|
4
|
+
import mlflow
|
|
5
|
+
|
|
6
|
+
from blueness import module
|
|
7
|
+
from blue_options.logger import crash_report
|
|
8
|
+
|
|
9
|
+
from bluer_objects import file, objects, NAME
|
|
10
|
+
from bluer_objects.mlflow.runs import start_run, end_run
|
|
11
|
+
from bluer_objects.logger import logger
|
|
12
|
+
|
|
13
|
+
NAME = module.name(__file__, NAME)
|
|
14
|
+
|
|
15
|
+
|
|
16
|
+
def log_artifacts(
|
|
17
|
+
object_name: str,
|
|
18
|
+
model_name: str = "",
|
|
19
|
+
) -> bool:
|
|
20
|
+
if not start_run(object_name):
|
|
21
|
+
return False
|
|
22
|
+
|
|
23
|
+
object_path = objects.object_path(object_name, create=True)
|
|
24
|
+
|
|
25
|
+
try:
|
|
26
|
+
mlflow.log_artifacts(object_path)
|
|
27
|
+
|
|
28
|
+
logger.info("⬆️ {}".format(object_name))
|
|
29
|
+
|
|
30
|
+
# https://mlflow.org/docs/latest/python_api/mlflow.html#mlflow.register_model
|
|
31
|
+
# https://stackoverflow.com/a/71447758/17619982
|
|
32
|
+
if model_name:
|
|
33
|
+
mv = mlflow.register_model(
|
|
34
|
+
"runs:/{}".format(mlflow.active_run().info.run_id),
|
|
35
|
+
model_name,
|
|
36
|
+
await_registration_for=0,
|
|
37
|
+
)
|
|
38
|
+
|
|
39
|
+
logger.info("*️⃣ {} -> {}.{}".format(object_name, mv.name, mv.version))
|
|
40
|
+
|
|
41
|
+
except:
|
|
42
|
+
crash_report(f"{NAME}.log_artifacts({object_name})")
|
|
43
|
+
return False
|
|
44
|
+
|
|
45
|
+
return end_run(object_name)
|
|
46
|
+
|
|
47
|
+
|
|
48
|
+
def log_run(object_name: str) -> bool:
|
|
49
|
+
if not start_run(object_name):
|
|
50
|
+
return False
|
|
51
|
+
|
|
52
|
+
object_path = objects.object_path(object_name, create=True)
|
|
53
|
+
|
|
54
|
+
counts: Dict[str, int] = {}
|
|
55
|
+
skipped_count = 0
|
|
56
|
+
for extension in "dot,gif,jpeg,jpg,json,png,sh,xml,yaml".split(","):
|
|
57
|
+
for filename in glob.glob(
|
|
58
|
+
os.path.join(object_path, f"*.{extension}"),
|
|
59
|
+
):
|
|
60
|
+
filename_name = file.name(filename)
|
|
61
|
+
|
|
62
|
+
counts[len(filename_name)] = counts.get(len(filename_name), 0) + 1
|
|
63
|
+
|
|
64
|
+
if any(
|
|
65
|
+
[
|
|
66
|
+
file.size(filename) > 10 * 1024 * 1024,
|
|
67
|
+
filename_name.startswith("thumbnail"),
|
|
68
|
+
counts[len(filename_name)] > 20,
|
|
69
|
+
]
|
|
70
|
+
):
|
|
71
|
+
logger.info(f"skipping {filename}")
|
|
72
|
+
skipped_count += 1
|
|
73
|
+
continue
|
|
74
|
+
|
|
75
|
+
mlflow.log_artifact(filename)
|
|
76
|
+
logger.info(f"⬆️ {filename}")
|
|
77
|
+
|
|
78
|
+
if skipped_count:
|
|
79
|
+
logger.info(f"skipped {skipped_count:,} file(s).")
|
|
80
|
+
|
|
81
|
+
return end_run(object_name)
|
|
@@ -0,0 +1,57 @@
|
|
|
1
|
+
from typing import Tuple, List
|
|
2
|
+
from mlflow.tracking import MlflowClient
|
|
3
|
+
|
|
4
|
+
from blueness import module
|
|
5
|
+
from blue_options.logger import crash_report
|
|
6
|
+
|
|
7
|
+
from bluer_objects import NAME
|
|
8
|
+
from bluer_objects.logger import logger
|
|
9
|
+
|
|
10
|
+
NAME = module.name(__file__, NAME)
|
|
11
|
+
|
|
12
|
+
|
|
13
|
+
def list_registered_models() -> Tuple[
|
|
14
|
+
bool,
|
|
15
|
+
List[str],
|
|
16
|
+
]:
|
|
17
|
+
try:
|
|
18
|
+
client = MlflowClient()
|
|
19
|
+
return True, [dict(rm)["name"] for rm in client.search_registered_models()]
|
|
20
|
+
|
|
21
|
+
except:
|
|
22
|
+
crash_report(f"{NAME}.list_registered_models()")
|
|
23
|
+
return False, []
|
|
24
|
+
|
|
25
|
+
|
|
26
|
+
def transition(
|
|
27
|
+
model_name: str,
|
|
28
|
+
version: str,
|
|
29
|
+
stage_name: str,
|
|
30
|
+
description: str,
|
|
31
|
+
) -> bool:
|
|
32
|
+
logger.info(
|
|
33
|
+
'{}.transition: {}(#{}) -> {} - "{}")'.format(
|
|
34
|
+
NAME,
|
|
35
|
+
model_name,
|
|
36
|
+
version,
|
|
37
|
+
stage_name,
|
|
38
|
+
description,
|
|
39
|
+
)
|
|
40
|
+
)
|
|
41
|
+
|
|
42
|
+
try:
|
|
43
|
+
client = MlflowClient()
|
|
44
|
+
client.transition_model_version_stage(
|
|
45
|
+
name=model_name, version=version, stage=stage_name
|
|
46
|
+
)
|
|
47
|
+
|
|
48
|
+
if description:
|
|
49
|
+
client.update_model_version(
|
|
50
|
+
name=model_name, version=version, description=description
|
|
51
|
+
)
|
|
52
|
+
|
|
53
|
+
except:
|
|
54
|
+
crash_report(f"{NAME}.transition({model_name})")
|
|
55
|
+
return False
|
|
56
|
+
|
|
57
|
+
return True
|
|
@@ -0,0 +1,76 @@
|
|
|
1
|
+
from typing import Tuple
|
|
2
|
+
import mlflow
|
|
3
|
+
from mlflow.tracking import MlflowClient
|
|
4
|
+
|
|
5
|
+
from blueness import module
|
|
6
|
+
from blue_options.logger import crash_report
|
|
7
|
+
|
|
8
|
+
from bluer_objects import NAME
|
|
9
|
+
from bluer_objects.env import ABCLI_MLFLOW_EXPERIMENT_PREFIX
|
|
10
|
+
from bluer_objects.logger import logger
|
|
11
|
+
|
|
12
|
+
NAME = module.name(__file__, NAME)
|
|
13
|
+
|
|
14
|
+
|
|
15
|
+
def get_id(
|
|
16
|
+
object_name: str,
|
|
17
|
+
create: bool = False,
|
|
18
|
+
) -> Tuple[bool, str]:
|
|
19
|
+
experiment_name = to_experiment_name(object_name)
|
|
20
|
+
|
|
21
|
+
try:
|
|
22
|
+
experiment = mlflow.get_experiment_by_name(experiment_name)
|
|
23
|
+
if experiment is None:
|
|
24
|
+
if create:
|
|
25
|
+
MlflowClient().create_experiment(name=experiment_name)
|
|
26
|
+
experiment = mlflow.get_experiment_by_name(experiment_name)
|
|
27
|
+
else:
|
|
28
|
+
return True, ""
|
|
29
|
+
|
|
30
|
+
return True, dict(experiment)["experiment_id"]
|
|
31
|
+
except:
|
|
32
|
+
crash_report(f"{NAME}.get_id({object_name})")
|
|
33
|
+
|
|
34
|
+
return False, ""
|
|
35
|
+
|
|
36
|
+
|
|
37
|
+
def rm(
|
|
38
|
+
object_name: str,
|
|
39
|
+
is_id: bool = False,
|
|
40
|
+
) -> bool:
|
|
41
|
+
if is_id:
|
|
42
|
+
experiment_id = object_name
|
|
43
|
+
else:
|
|
44
|
+
success, experiment_id = get_id(object_name)
|
|
45
|
+
if not success:
|
|
46
|
+
return success
|
|
47
|
+
|
|
48
|
+
try:
|
|
49
|
+
client = MlflowClient()
|
|
50
|
+
|
|
51
|
+
# get list of run_ids
|
|
52
|
+
|
|
53
|
+
# delete all runs
|
|
54
|
+
|
|
55
|
+
client.delete_experiment(experiment_id)
|
|
56
|
+
except:
|
|
57
|
+
crash_report("mlflow.rm({})".format(object_name))
|
|
58
|
+
return False
|
|
59
|
+
|
|
60
|
+
logger.info(
|
|
61
|
+
"🚮 {}".format(
|
|
62
|
+
"#{}".format(experiment_id)
|
|
63
|
+
if is_id
|
|
64
|
+
else "{} (#{})".format(object_name, experiment_id)
|
|
65
|
+
)
|
|
66
|
+
)
|
|
67
|
+
|
|
68
|
+
return True
|
|
69
|
+
|
|
70
|
+
|
|
71
|
+
def to_experiment_name(object_name: str) -> str:
|
|
72
|
+
return f"{ABCLI_MLFLOW_EXPERIMENT_PREFIX}{object_name}"
|
|
73
|
+
|
|
74
|
+
|
|
75
|
+
def to_object_name(experiment_name: str) -> str:
|
|
76
|
+
return experiment_name.split(ABCLI_MLFLOW_EXPERIMENT_PREFIX)[-1]
|
|
@@ -0,0 +1,100 @@
|
|
|
1
|
+
from typing import Tuple, List
|
|
2
|
+
import mlflow
|
|
3
|
+
import random
|
|
4
|
+
from mlflow.tracking import MlflowClient
|
|
5
|
+
from mlflow.entities import ViewType
|
|
6
|
+
|
|
7
|
+
from blueness import module
|
|
8
|
+
from blue_options import string
|
|
9
|
+
from blue_options.logger import crash_report
|
|
10
|
+
|
|
11
|
+
from bluer_objects import NAME
|
|
12
|
+
from bluer_objects.mlflow.objects import get_id
|
|
13
|
+
from bluer_objects.mlflow.tags import get_tags
|
|
14
|
+
from bluer_objects.logger import logger
|
|
15
|
+
|
|
16
|
+
NAME = module.name(__file__, NAME)
|
|
17
|
+
|
|
18
|
+
|
|
19
|
+
def end_run(
|
|
20
|
+
object_name: str,
|
|
21
|
+
) -> bool:
|
|
22
|
+
try:
|
|
23
|
+
mlflow.end_run()
|
|
24
|
+
logger.info("⏹️ {}".format(object_name))
|
|
25
|
+
except:
|
|
26
|
+
crash_report(f"{NAME}.end_run({object_name})")
|
|
27
|
+
return False
|
|
28
|
+
|
|
29
|
+
return True
|
|
30
|
+
|
|
31
|
+
|
|
32
|
+
def get_run_id(
|
|
33
|
+
object_name: str,
|
|
34
|
+
count: int = -1,
|
|
35
|
+
offset: int = 0,
|
|
36
|
+
create: bool = False,
|
|
37
|
+
is_id: bool = False,
|
|
38
|
+
) -> Tuple[bool, List[str]]:
|
|
39
|
+
if is_id:
|
|
40
|
+
experiment_id = object_name
|
|
41
|
+
else:
|
|
42
|
+
success, experiment_id = get_id(object_name, create=create)
|
|
43
|
+
if not success:
|
|
44
|
+
return False, []
|
|
45
|
+
|
|
46
|
+
try:
|
|
47
|
+
client = MlflowClient()
|
|
48
|
+
|
|
49
|
+
list_of_runs = client.search_runs(
|
|
50
|
+
experiment_ids=[experiment_id],
|
|
51
|
+
run_view_type=ViewType.ACTIVE_ONLY,
|
|
52
|
+
max_results=count + offset,
|
|
53
|
+
)
|
|
54
|
+
|
|
55
|
+
return True, [run._info.run_id for run in list_of_runs][offset:]
|
|
56
|
+
|
|
57
|
+
except:
|
|
58
|
+
crash_report(f"{NAME}.get_run_id({object_name})")
|
|
59
|
+
return False, []
|
|
60
|
+
|
|
61
|
+
|
|
62
|
+
def start_run(
|
|
63
|
+
object_name: str,
|
|
64
|
+
) -> bool:
|
|
65
|
+
success, experiment_id = get_id(object_name, create=True)
|
|
66
|
+
if not success:
|
|
67
|
+
return False
|
|
68
|
+
|
|
69
|
+
max_count = 25000
|
|
70
|
+
success, list_of_runs = get_run_id(
|
|
71
|
+
experiment_id,
|
|
72
|
+
count=max_count,
|
|
73
|
+
is_id=True,
|
|
74
|
+
)
|
|
75
|
+
if not success:
|
|
76
|
+
return False
|
|
77
|
+
|
|
78
|
+
run_counter = len(list_of_runs) + 1
|
|
79
|
+
if run_counter > max_count:
|
|
80
|
+
logger.warning(f"{object_name}: more than {max_count} runs!")
|
|
81
|
+
run_counter = max_count + random.randint(1, max_count)
|
|
82
|
+
|
|
83
|
+
run_name = f"{object_name}-{run_counter:05d}"
|
|
84
|
+
|
|
85
|
+
success, tags = get_tags(object_name)
|
|
86
|
+
if not success:
|
|
87
|
+
return False
|
|
88
|
+
|
|
89
|
+
try:
|
|
90
|
+
mlflow.start_run(
|
|
91
|
+
experiment_id=experiment_id,
|
|
92
|
+
tags=tags,
|
|
93
|
+
run_name=run_name,
|
|
94
|
+
)
|
|
95
|
+
logger.info(f"⏺️ {object_name} | {run_counter:05d}")
|
|
96
|
+
except:
|
|
97
|
+
crash_report(f"{NAME}.start_run({object_name})")
|
|
98
|
+
return False
|
|
99
|
+
|
|
100
|
+
return True
|
|
@@ -0,0 +1,90 @@
|
|
|
1
|
+
from typing import Tuple, Dict, List, Union
|
|
2
|
+
from mlflow.tracking import MlflowClient
|
|
3
|
+
from mlflow.entities import ViewType
|
|
4
|
+
|
|
5
|
+
from blueness import module
|
|
6
|
+
from blue_options.options import Options
|
|
7
|
+
from blue_options.logger import crash_report
|
|
8
|
+
|
|
9
|
+
from bluer_objects import NAME
|
|
10
|
+
from bluer_objects.mlflow.objects import to_experiment_name, to_object_name
|
|
11
|
+
from bluer_objects.logger import logger
|
|
12
|
+
|
|
13
|
+
NAME = module.name(__file__, NAME)
|
|
14
|
+
|
|
15
|
+
|
|
16
|
+
def create_filter_string(tags: str) -> str:
|
|
17
|
+
tags_options = Options(tags)
|
|
18
|
+
|
|
19
|
+
# https://www.mlflow.org/docs/latest/search-experiments.html
|
|
20
|
+
return " and ".join(
|
|
21
|
+
[f'tags."{keyword}" = "{value}"' for keyword, value in tags_options.items()]
|
|
22
|
+
)
|
|
23
|
+
|
|
24
|
+
|
|
25
|
+
def get_tags(
|
|
26
|
+
object_name: str,
|
|
27
|
+
exclude_system_tags: bool = True,
|
|
28
|
+
) -> Tuple[bool, Dict[str, str]]:
|
|
29
|
+
experiment_name = to_experiment_name(object_name)
|
|
30
|
+
|
|
31
|
+
try:
|
|
32
|
+
client = MlflowClient()
|
|
33
|
+
experiment = client.get_experiment_by_name(experiment_name)
|
|
34
|
+
|
|
35
|
+
if experiment is None:
|
|
36
|
+
return True, {}
|
|
37
|
+
|
|
38
|
+
tags = {
|
|
39
|
+
keyword: value
|
|
40
|
+
for keyword, value in experiment.tags.items()
|
|
41
|
+
if not keyword.startswith("mlflow.") or not exclude_system_tags
|
|
42
|
+
}
|
|
43
|
+
|
|
44
|
+
return True, tags
|
|
45
|
+
except:
|
|
46
|
+
crash_report(f"{NAME}.get_tags({object_name})")
|
|
47
|
+
return False, {}
|
|
48
|
+
|
|
49
|
+
|
|
50
|
+
# https://www.mlflow.org/docs/latest/search-experiments.html
|
|
51
|
+
def search(filter_string: str) -> List[str]:
|
|
52
|
+
client = MlflowClient()
|
|
53
|
+
|
|
54
|
+
return [
|
|
55
|
+
to_object_name(experiment.name)
|
|
56
|
+
for experiment in client.search_experiments(
|
|
57
|
+
filter_string=filter_string,
|
|
58
|
+
view_type=ViewType.ALL,
|
|
59
|
+
)
|
|
60
|
+
]
|
|
61
|
+
|
|
62
|
+
|
|
63
|
+
def set_tags(
|
|
64
|
+
object_name: str,
|
|
65
|
+
tags: Union[str, Dict[str, str]],
|
|
66
|
+
log: bool = True,
|
|
67
|
+
icon="#️⃣ ",
|
|
68
|
+
) -> bool:
|
|
69
|
+
experiment_name = to_experiment_name(object_name)
|
|
70
|
+
|
|
71
|
+
try:
|
|
72
|
+
tags = Options(tags)
|
|
73
|
+
|
|
74
|
+
client = MlflowClient()
|
|
75
|
+
|
|
76
|
+
experiment = client.get_experiment_by_name(experiment_name)
|
|
77
|
+
if experiment is None:
|
|
78
|
+
client.create_experiment(name=experiment_name)
|
|
79
|
+
experiment = client.get_experiment_by_name(experiment_name)
|
|
80
|
+
|
|
81
|
+
for key, value in tags.items():
|
|
82
|
+
client.set_experiment_tag(experiment.experiment_id, key, value)
|
|
83
|
+
if log:
|
|
84
|
+
logger.info("{} {}.{}={}".format(icon, object_name, key, value))
|
|
85
|
+
|
|
86
|
+
except:
|
|
87
|
+
crash_report(f"{NAME}.set_tags({object_name})")
|
|
88
|
+
return False
|
|
89
|
+
|
|
90
|
+
return True
|
|
@@ -0,0 +1,39 @@
|
|
|
1
|
+
import mlflow
|
|
2
|
+
|
|
3
|
+
from blueness import module
|
|
4
|
+
from blue_options import string
|
|
5
|
+
from blue_options.logger import crash_report
|
|
6
|
+
|
|
7
|
+
from bluer_objects import NAME, VERSION
|
|
8
|
+
from bluer_objects.mlflow.objects import get_id
|
|
9
|
+
from bluer_objects.logger import logger
|
|
10
|
+
|
|
11
|
+
NAME = module.name(__file__, NAME)
|
|
12
|
+
|
|
13
|
+
|
|
14
|
+
def test() -> bool:
|
|
15
|
+
object_name = string.pretty_date(
|
|
16
|
+
as_filename=True,
|
|
17
|
+
unique=True,
|
|
18
|
+
)
|
|
19
|
+
|
|
20
|
+
success, experiment_id = get_id(
|
|
21
|
+
object_name,
|
|
22
|
+
create=True,
|
|
23
|
+
)
|
|
24
|
+
if not success:
|
|
25
|
+
return success
|
|
26
|
+
|
|
27
|
+
try:
|
|
28
|
+
mlflow.start_run(
|
|
29
|
+
experiment_id=experiment_id,
|
|
30
|
+
tags={"purpose": "testing"},
|
|
31
|
+
)
|
|
32
|
+
mlflow.end_run()
|
|
33
|
+
|
|
34
|
+
logger.info(f"✅ {NAME}-{VERSION}-{mlflow.version.VERSION}")
|
|
35
|
+
except:
|
|
36
|
+
crash_report(f"{NAME}.test()")
|
|
37
|
+
return False
|
|
38
|
+
|
|
39
|
+
return True
|
|
@@ -0,0 +1,91 @@
|
|
|
1
|
+
import argparse
|
|
2
|
+
|
|
3
|
+
from blueness import module
|
|
4
|
+
from blueness.argparse.generic import sys_exit
|
|
5
|
+
|
|
6
|
+
from bluer_objects import NAME
|
|
7
|
+
from bluer_objects.mysql.cache.functions import create, clone, read, write, search
|
|
8
|
+
from bluer_objects.logger import logger
|
|
9
|
+
|
|
10
|
+
NAME = module.name(__file__, NAME)
|
|
11
|
+
|
|
12
|
+
|
|
13
|
+
parser = argparse.ArgumentParser(NAME)
|
|
14
|
+
parser.add_argument(
|
|
15
|
+
"task",
|
|
16
|
+
type=str,
|
|
17
|
+
default="read",
|
|
18
|
+
help="clone,create,read,search,write",
|
|
19
|
+
)
|
|
20
|
+
parser.add_argument(
|
|
21
|
+
"--all",
|
|
22
|
+
default=0,
|
|
23
|
+
type=int,
|
|
24
|
+
)
|
|
25
|
+
parser.add_argument(
|
|
26
|
+
"--dataframe",
|
|
27
|
+
default=0,
|
|
28
|
+
type=int,
|
|
29
|
+
)
|
|
30
|
+
parser.add_argument(
|
|
31
|
+
"--destination",
|
|
32
|
+
type=str,
|
|
33
|
+
default="",
|
|
34
|
+
)
|
|
35
|
+
parser.add_argument(
|
|
36
|
+
"--keyword",
|
|
37
|
+
type=str,
|
|
38
|
+
)
|
|
39
|
+
parser.add_argument(
|
|
40
|
+
"--like",
|
|
41
|
+
default=0,
|
|
42
|
+
type=int,
|
|
43
|
+
)
|
|
44
|
+
parser.add_argument(
|
|
45
|
+
"--source",
|
|
46
|
+
type=str,
|
|
47
|
+
default="",
|
|
48
|
+
)
|
|
49
|
+
parser.add_argument(
|
|
50
|
+
"--unique",
|
|
51
|
+
default=1,
|
|
52
|
+
type=int,
|
|
53
|
+
help="cache.read('unique')",
|
|
54
|
+
)
|
|
55
|
+
parser.add_argument(
|
|
56
|
+
"--value",
|
|
57
|
+
type=str,
|
|
58
|
+
default="unknown",
|
|
59
|
+
)
|
|
60
|
+
args = parser.parse_args()
|
|
61
|
+
|
|
62
|
+
success = False
|
|
63
|
+
if args.task == "clone":
|
|
64
|
+
success = clone(args.source, args.destination)
|
|
65
|
+
elif args.task == "create":
|
|
66
|
+
success = create()
|
|
67
|
+
elif args.task == "read":
|
|
68
|
+
output = read(
|
|
69
|
+
args.keyword,
|
|
70
|
+
all=args.all,
|
|
71
|
+
like=args.like,
|
|
72
|
+
dataframe=args.dataframe,
|
|
73
|
+
unique=args.unique,
|
|
74
|
+
)
|
|
75
|
+
|
|
76
|
+
print(
|
|
77
|
+
("None" if output.empty else output.drop(columns=["log_id"]))
|
|
78
|
+
if args.dataframe
|
|
79
|
+
else output
|
|
80
|
+
)
|
|
81
|
+
success = True
|
|
82
|
+
elif args.task == "search":
|
|
83
|
+
for keyword, value in search(args.keyword).items():
|
|
84
|
+
print(f"{keyword}: {value}")
|
|
85
|
+
success = True
|
|
86
|
+
elif args.task == "write":
|
|
87
|
+
success = write(args.keyword, args.value)
|
|
88
|
+
else:
|
|
89
|
+
success = None
|
|
90
|
+
|
|
91
|
+
sys_exit(logger, NAME, args.task, success)
|