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.

Files changed (149) hide show
  1. bluer_objects/.abcli/abcli.sh +9 -0
  2. bluer_objects/.abcli/actions.sh +11 -0
  3. bluer_objects/.abcli/aka.sh +3 -0
  4. bluer_objects/.abcli/alias.sh +36 -0
  5. bluer_objects/.abcli/blue_objects.sh +11 -0
  6. bluer_objects/.abcli/cache.sh +5 -0
  7. bluer_objects/.abcli/clone.sh +94 -0
  8. bluer_objects/.abcli/download.sh +53 -0
  9. bluer_objects/.abcli/file.sh +8 -0
  10. bluer_objects/.abcli/gif.sh +27 -0
  11. bluer_objects/.abcli/host.sh +29 -0
  12. bluer_objects/.abcli/ls.sh +24 -0
  13. bluer_objects/.abcli/metadata/get.sh +24 -0
  14. bluer_objects/.abcli/metadata/post.sh +22 -0
  15. bluer_objects/.abcli/metadata.sh +16 -0
  16. bluer_objects/.abcli/mlflow/browse.sh +36 -0
  17. bluer_objects/.abcli/mlflow/cache.sh +31 -0
  18. bluer_objects/.abcli/mlflow/list_registered_models.sh +9 -0
  19. bluer_objects/.abcli/mlflow/log_artifacts.sh +10 -0
  20. bluer_objects/.abcli/mlflow/log_run.sh +10 -0
  21. bluer_objects/.abcli/mlflow/run.sh +11 -0
  22. bluer_objects/.abcli/mlflow/tags/clone.sh +15 -0
  23. bluer_objects/.abcli/mlflow/tags/get.sh +10 -0
  24. bluer_objects/.abcli/mlflow/tags/search.sh +12 -0
  25. bluer_objects/.abcli/mlflow/tags/set.sh +13 -0
  26. bluer_objects/.abcli/mlflow/tags.sh +16 -0
  27. bluer_objects/.abcli/mlflow/test.sh +11 -0
  28. bluer_objects/.abcli/mlflow/transition.sh +20 -0
  29. bluer_objects/.abcli/mlflow.sh +29 -0
  30. bluer_objects/.abcli/mysql/cache.sh +65 -0
  31. bluer_objects/.abcli/mysql/relations.sh +83 -0
  32. bluer_objects/.abcli/mysql/tags.sh +85 -0
  33. bluer_objects/.abcli/mysql.sh +16 -0
  34. bluer_objects/.abcli/object.sh +54 -0
  35. bluer_objects/.abcli/publish.sh +58 -0
  36. bluer_objects/.abcli/select.sh +34 -0
  37. bluer_objects/.abcli/storage/clear.sh +45 -0
  38. bluer_objects/.abcli/storage/download_file.sh +9 -0
  39. bluer_objects/.abcli/storage/exists.sh +8 -0
  40. bluer_objects/.abcli/storage/list.sh +8 -0
  41. bluer_objects/.abcli/storage/rm.sh +11 -0
  42. bluer_objects/.abcli/storage/status.sh +11 -0
  43. bluer_objects/.abcli/storage.sh +15 -0
  44. bluer_objects/.abcli/tags.sh +5 -0
  45. bluer_objects/.abcli/tests/README.sh +8 -0
  46. bluer_objects/.abcli/tests/clone.sh +32 -0
  47. bluer_objects/.abcli/tests/help.sh +85 -0
  48. bluer_objects/.abcli/tests/host.sh +7 -0
  49. bluer_objects/.abcli/tests/ls.sh +13 -0
  50. bluer_objects/.abcli/tests/metadata.sh +53 -0
  51. bluer_objects/.abcli/tests/mlflow_cache.sh +14 -0
  52. bluer_objects/.abcli/tests/mlflow_logging.sh +12 -0
  53. bluer_objects/.abcli/tests/mlflow_tags.sh +29 -0
  54. bluer_objects/.abcli/tests/mlflow_test.sh +7 -0
  55. bluer_objects/.abcli/tests/mysql_cache.sh +15 -0
  56. bluer_objects/.abcli/tests/mysql_relations.sh +20 -0
  57. bluer_objects/.abcli/tests/mysql_tags.sh +16 -0
  58. bluer_objects/.abcli/tests/test_gif.sh +13 -0
  59. bluer_objects/.abcli/tests/version.sh +10 -0
  60. bluer_objects/.abcli/upload.sh +73 -0
  61. bluer_objects/README/__init__.py +29 -0
  62. bluer_objects/README/functions.py +285 -0
  63. bluer_objects/README/items.py +30 -0
  64. bluer_objects/__init__.py +19 -0
  65. bluer_objects/__main__.py +16 -0
  66. bluer_objects/config.env +22 -0
  67. bluer_objects/env.py +72 -0
  68. bluer_objects/file/__init__.py +41 -0
  69. bluer_objects/file/__main__.py +51 -0
  70. bluer_objects/file/classes.py +38 -0
  71. bluer_objects/file/functions.py +290 -0
  72. bluer_objects/file/load.py +219 -0
  73. bluer_objects/file/save.py +280 -0
  74. bluer_objects/graphics/__init__.py +4 -0
  75. bluer_objects/graphics/__main__.py +84 -0
  76. bluer_objects/graphics/frame.py +15 -0
  77. bluer_objects/graphics/gif.py +86 -0
  78. bluer_objects/graphics/screen.py +63 -0
  79. bluer_objects/graphics/signature.py +97 -0
  80. bluer_objects/graphics/text.py +165 -0
  81. bluer_objects/help/__init__.py +0 -0
  82. bluer_objects/help/__main__.py +10 -0
  83. bluer_objects/help/functions.py +5 -0
  84. bluer_objects/host/__init__.py +1 -0
  85. bluer_objects/host/__main__.py +84 -0
  86. bluer_objects/host/functions.py +66 -0
  87. bluer_objects/logger/__init__.py +4 -0
  88. bluer_objects/logger/matrix.py +209 -0
  89. bluer_objects/markdown.py +43 -0
  90. bluer_objects/metadata/__init__.py +8 -0
  91. bluer_objects/metadata/__main__.py +110 -0
  92. bluer_objects/metadata/enums.py +29 -0
  93. bluer_objects/metadata/get.py +89 -0
  94. bluer_objects/metadata/post.py +101 -0
  95. bluer_objects/mlflow/__init__.py +28 -0
  96. bluer_objects/mlflow/__main__.py +271 -0
  97. bluer_objects/mlflow/cache.py +13 -0
  98. bluer_objects/mlflow/logging.py +81 -0
  99. bluer_objects/mlflow/models.py +57 -0
  100. bluer_objects/mlflow/objects.py +76 -0
  101. bluer_objects/mlflow/runs.py +100 -0
  102. bluer_objects/mlflow/tags.py +90 -0
  103. bluer_objects/mlflow/testing.py +39 -0
  104. bluer_objects/mysql/cache/__init__.py +8 -0
  105. bluer_objects/mysql/cache/__main__.py +91 -0
  106. bluer_objects/mysql/cache/functions.py +181 -0
  107. bluer_objects/mysql/relations/__init__.py +9 -0
  108. bluer_objects/mysql/relations/__main__.py +138 -0
  109. bluer_objects/mysql/relations/functions.py +180 -0
  110. bluer_objects/mysql/table.py +144 -0
  111. bluer_objects/mysql/tags/__init__.py +1 -0
  112. bluer_objects/mysql/tags/__main__.py +130 -0
  113. bluer_objects/mysql/tags/functions.py +203 -0
  114. bluer_objects/objects.py +167 -0
  115. bluer_objects/path.py +194 -0
  116. bluer_objects/sample.env +16 -0
  117. bluer_objects/storage/__init__.py +3 -0
  118. bluer_objects/storage/__main__.py +114 -0
  119. bluer_objects/storage/classes.py +237 -0
  120. bluer_objects/tests/__init__.py +0 -0
  121. bluer_objects/tests/test_README.py +5 -0
  122. bluer_objects/tests/test_env.py +27 -0
  123. bluer_objects/tests/test_file_load_save.py +105 -0
  124. bluer_objects/tests/test_fullname.py +5 -0
  125. bluer_objects/tests/test_graphics.py +28 -0
  126. bluer_objects/tests/test_graphics_frame.py +11 -0
  127. bluer_objects/tests/test_graphics_gif.py +29 -0
  128. bluer_objects/tests/test_graphics_screen.py +8 -0
  129. bluer_objects/tests/test_graphics_signature.py +80 -0
  130. bluer_objects/tests/test_graphics_text.py +14 -0
  131. bluer_objects/tests/test_logger.py +5 -0
  132. bluer_objects/tests/test_logger_matrix.py +73 -0
  133. bluer_objects/tests/test_markdown.py +10 -0
  134. bluer_objects/tests/test_metadata.py +204 -0
  135. bluer_objects/tests/test_mlflow.py +60 -0
  136. bluer_objects/tests/test_mysql_cache.py +14 -0
  137. bluer_objects/tests/test_mysql_relations.py +16 -0
  138. bluer_objects/tests/test_mysql_table.py +9 -0
  139. bluer_objects/tests/test_mysql_tags.py +13 -0
  140. bluer_objects/tests/test_objects.py +180 -0
  141. bluer_objects/tests/test_path.py +7 -0
  142. bluer_objects/tests/test_storage.py +7 -0
  143. bluer_objects/tests/test_version.py +5 -0
  144. bluer_objects/urls.py +3 -0
  145. bluer_objects-6.3.1.dist-info/METADATA +57 -0
  146. bluer_objects-6.3.1.dist-info/RECORD +149 -0
  147. bluer_objects-6.3.1.dist-info/WHEEL +5 -0
  148. bluer_objects-6.3.1.dist-info/licenses/LICENSE +121 -0
  149. 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,8 @@
1
+ from bluer_objects.mysql.cache.functions import (
2
+ create,
3
+ clone,
4
+ read,
5
+ write,
6
+ search,
7
+ search_value,
8
+ )
@@ -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)