bluer-objects 6.104.1__py3-none-any.whl → 6.377.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.
Files changed (146) hide show
  1. bluer_objects/.abcli/abcli.sh +6 -0
  2. bluer_objects/.abcli/alias.sh +11 -0
  3. bluer_objects/.abcli/assets/cd.sh +20 -0
  4. bluer_objects/.abcli/assets/mv.sh +34 -0
  5. bluer_objects/.abcli/assets/publish.sh +37 -0
  6. bluer_objects/.abcli/assets.sh +15 -0
  7. bluer_objects/.abcli/create_test_asset.sh +10 -0
  8. bluer_objects/.abcli/download.sh +3 -1
  9. bluer_objects/.abcli/file.sh +15 -4
  10. bluer_objects/.abcli/gif.sh +18 -0
  11. bluer_objects/.abcli/host.sh +23 -7
  12. bluer_objects/.abcli/ls.sh +19 -8
  13. bluer_objects/.abcli/metadata/download.sh +9 -0
  14. bluer_objects/.abcli/metadata/edit.sh +15 -0
  15. bluer_objects/.abcli/metadata/upload.sh +9 -0
  16. bluer_objects/.abcli/mlflow/browse.sh +2 -0
  17. bluer_objects/.abcli/mlflow/deploy.sh +21 -5
  18. bluer_objects/.abcli/mlflow/lock/lock.sh +11 -0
  19. bluer_objects/.abcli/mlflow/lock/unlock.sh +12 -0
  20. bluer_objects/.abcli/mlflow/lock.sh +15 -0
  21. bluer_objects/.abcli/mlflow.sh +0 -2
  22. bluer_objects/.abcli/pdf/convert.sh +92 -0
  23. bluer_objects/.abcli/pdf.sh +15 -0
  24. bluer_objects/.abcli/storage/clear.sh +2 -0
  25. bluer_objects/.abcli/tests/clone.sh +2 -3
  26. bluer_objects/.abcli/tests/create_test_asset.sh +16 -0
  27. bluer_objects/.abcli/tests/file.sh +64 -0
  28. bluer_objects/.abcli/tests/gif.sh +3 -3
  29. bluer_objects/.abcli/tests/help.sh +27 -4
  30. bluer_objects/.abcli/tests/ls.sh +11 -4
  31. bluer_objects/.abcli/tests/metadata.sh +35 -0
  32. bluer_objects/.abcli/tests/mlflow_lock.sh +30 -0
  33. bluer_objects/.abcli/tests/open.sh +11 -0
  34. bluer_objects/.abcli/tests/open_gif_open.sh +14 -0
  35. bluer_objects/.abcli/tests/pdf.sh +31 -0
  36. bluer_objects/.abcli/tests/storage_clear.sh +11 -0
  37. bluer_objects/.abcli/tests/storage_public_upload.sh +25 -0
  38. bluer_objects/.abcli/tests/storage_status.sh +12 -0
  39. bluer_objects/.abcli/tests/{storage.sh → storage_upload_download.sh} +26 -8
  40. bluer_objects/.abcli/tests/web_is_accessible.sh +17 -0
  41. bluer_objects/.abcli/tests/web_where_am_ai.sh +5 -0
  42. bluer_objects/.abcli/upload.sh +26 -2
  43. bluer_objects/.abcli/url.sh +15 -0
  44. bluer_objects/.abcli/web/is_accessible.sh +13 -0
  45. bluer_objects/.abcli/web/where_am_i.sh +5 -0
  46. bluer_objects/README/__init__.py +24 -9
  47. bluer_objects/README/alias.py +56 -0
  48. bluer_objects/README/consts.py +39 -0
  49. bluer_objects/README/functions.py +127 -205
  50. bluer_objects/README/items.py +78 -6
  51. bluer_objects/README/utils.py +275 -0
  52. bluer_objects/__init__.py +1 -1
  53. bluer_objects/assets/__init__.py +0 -0
  54. bluer_objects/assets/__main__.py +57 -0
  55. bluer_objects/assets/functions.py +62 -0
  56. bluer_objects/config.env +9 -1
  57. bluer_objects/env.py +23 -0
  58. bluer_objects/file/__main__.py +52 -7
  59. bluer_objects/file/functions.py +13 -3
  60. bluer_objects/file/load.py +2 -9
  61. bluer_objects/file/save.py +17 -24
  62. bluer_objects/graphics/__main__.py +7 -0
  63. bluer_objects/graphics/gif.py +11 -7
  64. bluer_objects/graphics/screen.py +9 -8
  65. bluer_objects/help/assets.py +96 -0
  66. bluer_objects/help/create_test_asset.py +22 -0
  67. bluer_objects/help/download.py +17 -3
  68. bluer_objects/help/file.py +59 -0
  69. bluer_objects/help/functions.py +11 -1
  70. bluer_objects/help/gif.py +25 -0
  71. bluer_objects/help/host.py +6 -4
  72. bluer_objects/help/ls.py +26 -3
  73. bluer_objects/help/metadata.py +51 -0
  74. bluer_objects/help/mlflow/__init__.py +23 -2
  75. bluer_objects/help/mlflow/lock.py +52 -0
  76. bluer_objects/help/pdf.py +67 -0
  77. bluer_objects/help/upload.py +10 -3
  78. bluer_objects/help/web.py +38 -0
  79. bluer_objects/host/functions.py +4 -1
  80. bluer_objects/logger/confusion_matrix.py +76 -0
  81. bluer_objects/logger/image.py +110 -0
  82. bluer_objects/logger/stitch.py +107 -0
  83. bluer_objects/markdown.py +8 -6
  84. bluer_objects/metadata/__init__.py +1 -0
  85. bluer_objects/metadata/flatten.py +27 -0
  86. bluer_objects/mlflow/lock/__init__.py +1 -0
  87. bluer_objects/mlflow/lock/__main__.py +58 -0
  88. bluer_objects/mlflow/lock/functions.py +121 -0
  89. bluer_objects/mlflow/logging.py +47 -41
  90. bluer_objects/pdf/__init__.py +1 -0
  91. bluer_objects/pdf/__main__.py +78 -0
  92. bluer_objects/pdf/convert/__init__.py +0 -0
  93. bluer_objects/pdf/convert/batch.py +54 -0
  94. bluer_objects/pdf/convert/combination.py +32 -0
  95. bluer_objects/pdf/convert/convert.py +111 -0
  96. bluer_objects/pdf/convert/image.py +53 -0
  97. bluer_objects/pdf/convert/md.py +97 -0
  98. bluer_objects/pdf/convert/missing.py +96 -0
  99. bluer_objects/pdf/convert/pdf.py +37 -0
  100. bluer_objects/sample.env +6 -0
  101. bluer_objects/storage/WebDAV.py +11 -7
  102. bluer_objects/storage/WebDAVrequest.py +360 -0
  103. bluer_objects/storage/WebDAVzip.py +26 -29
  104. bluer_objects/storage/__init__.py +28 -1
  105. bluer_objects/storage/__main__.py +40 -6
  106. bluer_objects/storage/base.py +84 -5
  107. bluer_objects/storage/policies.py +7 -0
  108. bluer_objects/storage/s3.py +367 -0
  109. bluer_objects/testing/__main__.py +6 -0
  110. bluer_objects/tests/test_README_consts.py +71 -0
  111. bluer_objects/tests/test_README_items.py +128 -0
  112. bluer_objects/tests/test_alias.py +33 -0
  113. bluer_objects/tests/test_env.py +25 -2
  114. bluer_objects/tests/test_file_download.py +25 -0
  115. bluer_objects/tests/test_file_load_save.py +1 -2
  116. bluer_objects/tests/test_file_load_save_text.py +46 -0
  117. bluer_objects/tests/test_graphics_gif.py +2 -0
  118. bluer_objects/tests/test_log_image_grid.py +29 -0
  119. bluer_objects/tests/test_logger_confusion_matrix.py +18 -0
  120. bluer_objects/tests/test_logger_matrix.py +2 -2
  121. bluer_objects/tests/test_logger_stitch_images.py +47 -0
  122. bluer_objects/tests/test_metadata.py +12 -6
  123. bluer_objects/tests/test_metadata_flatten.py +109 -0
  124. bluer_objects/tests/test_mlflow.py +2 -2
  125. bluer_objects/tests/test_mlflow_lock.py +26 -0
  126. bluer_objects/tests/test_objects.py +2 -0
  127. bluer_objects/tests/test_shell.py +34 -0
  128. bluer_objects/tests/test_storage.py +8 -21
  129. bluer_objects/tests/test_storage_base.py +39 -0
  130. bluer_objects/tests/test_storage_s3.py +67 -0
  131. bluer_objects/tests/test_storage_webdav_request.py +75 -0
  132. bluer_objects/tests/test_storage_webdav_zip.py +42 -0
  133. bluer_objects/tests/test_web_is_accessible.py +11 -0
  134. bluer_objects/web/__init__.py +1 -0
  135. bluer_objects/web/__main__.py +31 -0
  136. bluer_objects/web/functions.py +9 -0
  137. {bluer_objects-6.104.1.dist-info → bluer_objects-6.377.1.dist-info}/METADATA +6 -3
  138. bluer_objects-6.377.1.dist-info/RECORD +217 -0
  139. {bluer_objects-6.104.1.dist-info → bluer_objects-6.377.1.dist-info}/WHEEL +1 -1
  140. bluer_objects/.abcli/storage/download_file.sh +0 -9
  141. bluer_objects/.abcli/storage/exists.sh +0 -8
  142. bluer_objects/.abcli/storage/list.sh +0 -8
  143. bluer_objects/.abcli/storage/rm.sh +0 -11
  144. bluer_objects-6.104.1.dist-info/RECORD +0 -143
  145. {bluer_objects-6.104.1.dist-info → bluer_objects-6.377.1.dist-info}/licenses/LICENSE +0 -0
  146. {bluer_objects-6.104.1.dist-info → bluer_objects-6.377.1.dist-info}/top_level.txt +0 -0
@@ -0,0 +1,275 @@
1
+ import os
2
+ from typing import List, Dict, Union, Callable, Tuple
3
+
4
+ from bluer_options.env import get_env
5
+ from bluer_objects import file
6
+ from bluer_objects import env
7
+ from bluer_objects import NAME as MY_NAME, ICON as MY_ICON
8
+
9
+ from bluer_objects.logger import logger
10
+
11
+
12
+ variables: Dict[str, str] = {}
13
+
14
+
15
+ def apply_legacy_on_line(line: str) -> str:
16
+ for before, after in {
17
+ "yaml:::": "metadata:::",
18
+ "--help--": "help:::",
19
+ "--include": "include:::",
20
+ "--table--": "items:::",
21
+ "--signature--": "signature:::",
22
+ }.items():
23
+ line = line.replace(before, after)
24
+ return line
25
+
26
+
27
+ def apply_legacy(template: List[str]) -> List[str]:
28
+ logger.info("applying legacy conversions...")
29
+ template = [apply_legacy_on_line(line) for line in template]
30
+ return template
31
+
32
+
33
+ def process_assets(
34
+ template_line: str,
35
+ assets_repo: str,
36
+ ) -> str:
37
+ if "assets:::" in template_line:
38
+ template_line = " ".join(
39
+ [
40
+ (
41
+ (
42
+ "![image](https://github.com/{}/blob/main/{}?raw=true)".format(
43
+ assets_repo,
44
+ token.split(":::")[1].strip(),
45
+ )
46
+ if any(
47
+ token.endswith(extension)
48
+ for extension in ["png", "jpg", "jpeg", "gif"]
49
+ )
50
+ else "[{}](https://github.com/{}/blob/main/{})".format(
51
+ file.name_and_extension(token.split(":::")[1].strip()),
52
+ assets_repo,
53
+ token.split(":::")[1].strip(),
54
+ )
55
+ )
56
+ if token.startswith("assets:::")
57
+ else token
58
+ )
59
+ for token in template_line.split(" ")
60
+ ]
61
+ )
62
+
63
+ return template_line
64
+
65
+
66
+ def process_details(template_line: str) -> List[str]:
67
+ suffix = template_line.split(":::", 1)[1]
68
+ if suffix:
69
+ content_section = [
70
+ "",
71
+ "<details>",
72
+ f"<summary>{suffix}</summary>",
73
+ "",
74
+ ]
75
+ else:
76
+ content_section = [
77
+ "",
78
+ "</details>",
79
+ "",
80
+ ]
81
+
82
+ return content_section
83
+
84
+
85
+ def process_envs(template_line: str) -> str:
86
+ while "env:::" in template_line:
87
+ env_name = template_line.split("env:::", 1)[1]
88
+ if " " in env_name:
89
+ env_name = env_name.split(" ", 1)[0]
90
+ else:
91
+ if ":::" in env_name:
92
+ env_name = env_name.split(":::", 1)[0]
93
+
94
+ env_value = get_env(env_name)
95
+
96
+ template_line = template_line.replace(
97
+ f"env:::{env_name}",
98
+ env_value,
99
+ )
100
+ logger.info(f"{env_name} -> {env_value}")
101
+
102
+ return template_line
103
+
104
+
105
+ def process_help(
106
+ template_line: str,
107
+ help_function: Union[Callable[[List[str]], str], None] = None,
108
+ ) -> Tuple[bool, List[str]]:
109
+ help_command = template_line.split("help:::")[1].strip()
110
+
111
+ tokens = help_command.strip().split(" ")[1:]
112
+
113
+ help_content = help_function(tokens)
114
+ if not help_content:
115
+ logger.error(f"help not found: {help_command}: {tokens}")
116
+ return False, []
117
+
118
+ logger.info(f"+= help: {help_command}")
119
+ print(help_content)
120
+ content_section = [
121
+ "```bash",
122
+ help_content,
123
+ "```",
124
+ ]
125
+
126
+ return True, content_section
127
+
128
+
129
+ def process_include(
130
+ template_line: str,
131
+ template_path: str,
132
+ ) -> List[str]:
133
+ include_filename_relative = template_line.split(" ")[1].strip()
134
+ include_filename = file.absolute(
135
+ include_filename_relative,
136
+ template_path,
137
+ )
138
+
139
+ success, content_section = file.load_text(include_filename)
140
+ if not success:
141
+ return success
142
+
143
+ content_section = [
144
+ line for line in content_section if not line.startswith("used by:")
145
+ ]
146
+
147
+ include_title = (template_line.split(" ", 2) + ["", "", ""])[2]
148
+ if include_title:
149
+ content_section = [f"## {include_title}"] + content_section[1:]
150
+
151
+ if "include:::noref" not in template_line:
152
+ content_section += [
153
+ "using [{}]({}).".format(
154
+ file.name(include_filename),
155
+ include_filename_relative,
156
+ )
157
+ ]
158
+
159
+ logger.info(f"{MY_NAME}.build: including {include_filename} ...")
160
+
161
+ return content_section
162
+
163
+
164
+ def process_mermaid(template_line: str) -> List[str]:
165
+ template_line_pieces = template_line.split('"')
166
+ if len(template_line_pieces) != 3:
167
+ logger.error(f"🧜🏽‍♀️ mermaid line not in expected format: {template_line}.")
168
+ return False
169
+
170
+ template_line_pieces[1] = (
171
+ template_line_pieces[1]
172
+ .replace("<", "&lt;")
173
+ .replace(">", "&gt;")
174
+ .replace(" ", "<br>")
175
+ .replace("~~", " ")
176
+ )
177
+
178
+ return ['"'.join(template_line_pieces)]
179
+
180
+
181
+ def process_objects(template_line: str) -> str:
182
+ if "object:::" in template_line:
183
+ template_line = " ".join(
184
+ [
185
+ (
186
+ "[{}](https://{}.{}/{}.tar.gz)".format(
187
+ token.split(":::")[1].strip(),
188
+ env.S3_PUBLIC_STORAGE_BUCKET,
189
+ env.S3_STORAGE_ENDPOINT_URL.split("https://", 1)[1],
190
+ token.split(":::")[1].strip(),
191
+ )
192
+ if token.startswith("object:::")
193
+ else token
194
+ )
195
+ for token in template_line.split(" ")
196
+ ]
197
+ )
198
+
199
+ return template_line
200
+
201
+
202
+ def process_title(
203
+ template_line: str,
204
+ filename: str,
205
+ ) -> Tuple[bool, List[str]]:
206
+ template_line_pieces = [
207
+ piece for piece in template_line.strip().split(":::") if piece
208
+ ]
209
+ reference = template_line_pieces[1] if len(template_line_pieces) >= 2 else "docs"
210
+
211
+ filename_path_pieces = file.path(filename).split(os.sep)
212
+ if reference not in filename_path_pieces:
213
+ logger.error(
214
+ "reference: {} not found in {}.".format(
215
+ reference,
216
+ template_line,
217
+ )
218
+ )
219
+ return False, []
220
+
221
+ title_pieces = filename_path_pieces[filename_path_pieces.index(reference) + 1 :]
222
+ filename_name = file.name(filename)
223
+ if filename_name != "README":
224
+ title_pieces.append(filename_name)
225
+
226
+ return True, [
227
+ "# {}".format(
228
+ ": ".join(
229
+ [
230
+ piece.replace(
231
+ "_",
232
+ "-",
233
+ )
234
+ for piece in title_pieces
235
+ ]
236
+ )
237
+ )
238
+ ]
239
+
240
+
241
+ def process_variable(template_line: str):
242
+ key, value = template_line.split("set:::", 1)[1].split(" ", 1)
243
+ variables[key] = value
244
+ logger.info(f"{key} = {value}")
245
+
246
+
247
+ def signature(
248
+ REPO_NAME: str,
249
+ NAME: str,
250
+ ICON: str,
251
+ MODULE_NAME: str,
252
+ VERSION: str,
253
+ ) -> List[str]:
254
+ return [
255
+ "",
256
+ " ".join(
257
+ [
258
+ f"[![pylint](https://github.com/kamangir/{REPO_NAME}/actions/workflows/pylint.yml/badge.svg)](https://github.com/kamangir/{REPO_NAME}/actions/workflows/pylint.yml)",
259
+ f"[![pytest](https://github.com/kamangir/{REPO_NAME}/actions/workflows/pytest.yml/badge.svg)](https://github.com/kamangir/{REPO_NAME}/actions/workflows/pytest.yml)",
260
+ f"[![bashtest](https://github.com/kamangir/{REPO_NAME}/actions/workflows/bashtest.yml/badge.svg)](https://github.com/kamangir/{REPO_NAME}/actions/workflows/bashtest.yml)",
261
+ f"[![PyPI version](https://img.shields.io/pypi/v/{MODULE_NAME}.svg)](https://pypi.org/project/{MODULE_NAME}/)",
262
+ f"[![PyPI - Downloads](https://img.shields.io/pypi/dd/{MODULE_NAME})](https://pypistats.org/packages/{MODULE_NAME})",
263
+ ]
264
+ ),
265
+ "",
266
+ "built by {} [`{}`]({}), based on {}[`{}-{}`]({}).".format(
267
+ MY_ICON,
268
+ "bluer README",
269
+ "https://github.com/kamangir/bluer-objects/tree/main/bluer_objects/README",
270
+ f"{ICON} " if ICON else "",
271
+ NAME,
272
+ VERSION,
273
+ f"https://github.com/kamangir/{REPO_NAME}",
274
+ ),
275
+ ]
bluer_objects/__init__.py CHANGED
@@ -4,7 +4,7 @@ ICON = "🌀"
4
4
 
5
5
  DESCRIPTION = f"{ICON} Object management in Bash."
6
6
 
7
- VERSION = "6.104.1"
7
+ VERSION = "6.377.1"
8
8
 
9
9
  REPO_NAME = "bluer-objects"
10
10
 
File without changes
@@ -0,0 +1,57 @@
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.assets.functions import publish
8
+ from bluer_objects.logger import logger
9
+
10
+ NAME = module.name(__file__, NAME)
11
+
12
+ parser = argparse.ArgumentParser(NAME)
13
+ parser.add_argument(
14
+ "task",
15
+ type=str,
16
+ help="publish",
17
+ )
18
+ parser.add_argument(
19
+ "--arg",
20
+ type=bool,
21
+ default=0,
22
+ help="0|1",
23
+ )
24
+ parser.add_argument(
25
+ "--object_name",
26
+ type=str,
27
+ )
28
+ parser.add_argument(
29
+ "--extensions",
30
+ type=str,
31
+ default="png",
32
+ help="png+txt",
33
+ )
34
+ parser.add_argument(
35
+ "--prefix",
36
+ type=str,
37
+ default="",
38
+ )
39
+ parser.add_argument(
40
+ "--asset_name",
41
+ type=str,
42
+ default="",
43
+ )
44
+ args = parser.parse_args()
45
+
46
+ success = False
47
+ if args.task == "publish":
48
+ success = publish(
49
+ object_name=args.object_name,
50
+ list_of_extensions=args.extensions.split("+"),
51
+ prefix=args.prefix,
52
+ asset_name=args.asset_name,
53
+ )
54
+ else:
55
+ success = None
56
+
57
+ sys_exit(logger, NAME, args.task, success)
@@ -0,0 +1,62 @@
1
+ import os
2
+ from typing import List
3
+ import glob
4
+ from tqdm import tqdm
5
+
6
+ from blueness import module
7
+
8
+ from bluer_objects import objects, file
9
+ from bluer_objects.env import abcli_path_git
10
+ from bluer_objects import NAME
11
+ from bluer_objects.logger import logger
12
+
13
+
14
+ NAME = module.name(__file__, NAME)
15
+
16
+
17
+ def publish(
18
+ object_name: str,
19
+ list_of_extensions: List[str],
20
+ prefix: str = "",
21
+ asset_name: str = "",
22
+ log: bool = True,
23
+ ) -> bool:
24
+ if not asset_name:
25
+ asset_name = object_name
26
+ logger.info(
27
+ "{}.publish: {}/{}.* for {} -> {}".format(
28
+ NAME,
29
+ object_name,
30
+ prefix,
31
+ ", ".join(list_of_extensions),
32
+ asset_name,
33
+ )
34
+ )
35
+
36
+ for extension in tqdm(list_of_extensions):
37
+ for filename in glob.glob(
38
+ objects.path_of(
39
+ filename=f"{prefix}*.{extension}",
40
+ object_name=object_name,
41
+ )
42
+ ):
43
+ published_filename = os.path.join(
44
+ abcli_path_git,
45
+ "assets",
46
+ asset_name,
47
+ file.name_and_extension(filename).replace(
48
+ object_name,
49
+ asset_name,
50
+ ),
51
+ )
52
+
53
+ if not file.copy(
54
+ filename,
55
+ published_filename,
56
+ log=log,
57
+ ):
58
+ return False
59
+
60
+ logger.info(f"🔗 https://github.com/kamangir/assets/tree/main/{asset_name}")
61
+
62
+ return True
bluer_objects/config.env CHANGED
@@ -1,3 +1,11 @@
1
1
  ABCLI_MLFLOW_EXPERIMENT_PREFIX=experiment/
2
2
 
3
- BLUER_OBJECTS_STORAGE_INTERFACE=webdavzip
3
+ MLFLOW_LOCK_WAIT_FOR_CLEARANCE=3
4
+ MLFLOW_LOCK_WAIT_FOR_EXCLUSIVITY=1
5
+
6
+ S3_STORAGE_BUCKET=kamangir
7
+ S3_PUBLIC_STORAGE_BUCKET=kamangir-public
8
+
9
+ BLUER_OBJECTS_STORAGE_INTERFACE=s3
10
+
11
+ BLUER_OBJECTS_TEST_OBJECT=2025-09-22-13-11-08-cjbb3q
bluer_objects/env.py CHANGED
@@ -35,8 +35,31 @@ DUMMY_TEXT = "This is some dummy text. This is some dummy text. This is some dum
35
35
 
36
36
  ABCLI_MLFLOW_EXPERIMENT_PREFIX = get_env("ABCLI_MLFLOW_EXPERIMENT_PREFIX")
37
37
 
38
+ S3_STORAGE_BUCKET = get_env("S3_STORAGE_BUCKET")
39
+ S3_PUBLIC_STORAGE_BUCKET = get_env("S3_PUBLIC_STORAGE_BUCKET")
40
+
41
+ S3_STORAGE_ENDPOINT_URL = get_env("S3_STORAGE_ENDPOINT_URL")
42
+ S3_STORAGE_AWS_ACCESS_KEY_ID = get_env("S3_STORAGE_AWS_ACCESS_KEY_ID")
43
+ S3_STORAGE_AWS_SECRET_ACCESS_KEY = get_env("S3_STORAGE_AWS_SECRET_ACCESS_KEY")
44
+
38
45
  BLUER_OBJECTS_STORAGE_INTERFACE = get_env("BLUER_OBJECTS_STORAGE_INTERFACE")
39
46
 
47
+ MLFLOW_DEPLOYMENT = get_env("MLFLOW_DEPLOYMENT", "local")
48
+ if MLFLOW_DEPLOYMENT == "local":
49
+ MLFLOW_TRACKING_URI = os.path.join(
50
+ os.environ.get("HOME"),
51
+ "mlflow",
52
+ )
53
+ else:
54
+ MLFLOW_TRACKING_URI = MLFLOW_DEPLOYMENT
55
+ os.environ["MLFLOW_TRACKING_URI"] = MLFLOW_TRACKING_URI
56
+ MLFLOW_LOG_ARTIFACTS = "arvan" not in MLFLOW_DEPLOYMENT
57
+
58
+ MLFLOW_LOCK_WAIT_FOR_CLEARANCE = get_env("MLFLOW_LOCK_WAIT_FOR_CLEARANCE", 3)
59
+ MLFLOW_LOCK_WAIT_FOR_EXCLUSIVITY = get_env("MLFLOW_LOCK_WAIT_FOR_EXCLUSIVITY", 1)
60
+
40
61
  WEBDAV_HOSTNAME = get_env("WEBDAV_HOSTNAME")
41
62
  WEBDAV_LOGIN = get_env("WEBDAV_LOGIN")
42
63
  WEBDAV_PASSWORD = get_env("WEBDAV_PASSWORD")
64
+
65
+ BLUER_OBJECTS_TEST_OBJECT = get_env("BLUER_OBJECTS_TEST_OBJECT")
@@ -31,24 +31,69 @@ parser.add_argument(
31
31
  help="<that-1+that-2+that-3>",
32
32
  )
33
33
  parser.add_argument(
34
- "--size",
34
+ "--pretty",
35
35
  type=int,
36
- default=16,
36
+ default=1,
37
+ help="0 | 1",
38
+ )
39
+ parser.add_argument(
40
+ "--save",
41
+ type=int,
42
+ default=1,
43
+ help="0 | 1",
44
+ )
45
+ parser.add_argument(
46
+ "--whole_line",
47
+ type=int,
48
+ default=0,
49
+ help="0 | 1",
50
+ )
51
+ parser.add_argument(
52
+ "--log",
53
+ type=int,
54
+ default=0,
55
+ help="0 | 1",
56
+ )
57
+ parser.add_argument(
58
+ "--cat",
59
+ type=int,
60
+ default=0,
61
+ help="0 | 1",
37
62
  )
38
63
  args = parser.parse_args()
39
64
 
40
65
  success = False
41
66
  if args.task == "replace":
42
- logger.info(f"{NAME}.{args.task}: {args.this} -> {args.that} in {args.filename}")
67
+ logger.info(
68
+ f'{NAME}.{args.task}: "{args.this}" -> "{args.that}" in {args.filename}'
69
+ )
43
70
 
44
- success, content = file.load_text(args.filename)
71
+ success, content = file.load_text(
72
+ args.filename,
73
+ log=args.log == 1,
74
+ )
45
75
  if success:
46
76
  for this, that in tqdm(zip(args.this.split("+"), args.that.split("+"))):
47
- content = [line.replace(this, that) for line in content]
77
+ if args.whole_line:
78
+ content = [that if line == this else line for line in content]
79
+ else:
80
+ content = [line.replace(this, that) for line in content]
81
+
82
+ if args.save == 1:
83
+ success = file.save_text(
84
+ args.filename,
85
+ content,
86
+ log=args.log == 1,
87
+ )
88
+
89
+ if success and args.cat:
90
+ for line in content:
91
+ if any(this in line for this in args.this.split("+")):
92
+ logger.info(line)
48
93
 
49
- success = file.save_text(args.filename, content)
50
94
  elif args.task == "size":
51
- print(string.pretty_bytes(file.size(args.filename)))
95
+ size = file.size(args.filename)
96
+ print(string.pretty_bytes(size) if args.pretty == 1 else size)
52
97
  success = True
53
98
  else:
54
99
  success = None
@@ -117,25 +117,29 @@ def copy(
117
117
  return False
118
118
 
119
119
  if log:
120
- logger.info(f"{NAME}: {source} -> {destination}")
120
+ logger.info(f"{source} -copy-> {destination}")
121
121
 
122
122
  return True
123
123
 
124
124
 
125
125
  def delete(
126
126
  filename: str,
127
+ log: bool = False,
127
128
  ) -> bool:
128
129
  if not os.path.isfile(filename):
129
130
  return True
130
131
 
131
132
  try:
132
133
  os.remove(filename)
133
-
134
- return True
135
134
  except:
136
135
  crash_report(f"{NAME}: delete({filename}): failed.")
137
136
  return False
138
137
 
138
+ if log:
139
+ logger.info(f"deleted {filename}.")
140
+
141
+ return True
142
+
139
143
 
140
144
  def download(
141
145
  url: str,
@@ -150,6 +154,8 @@ def download(
150
154
  return True
151
155
 
152
156
  try:
157
+ os.makedirs(path(filename), exist_ok=True)
158
+
153
159
  # https://stackoverflow.com/a/27406501
154
160
  with urllib3.PoolManager().request(
155
161
  "GET", url, preload_content=False
@@ -236,6 +242,7 @@ def list_of(
236
242
  def move(
237
243
  source: str,
238
244
  destination: str,
245
+ log: bool = True,
239
246
  ) -> bool:
240
247
  try:
241
248
  os.makedirs(path(destination), exist_ok=True)
@@ -246,6 +253,9 @@ def move(
246
253
  crash_report(f"{NAME}: move({source},{destination}): failed.")
247
254
  return False
248
255
 
256
+ if log:
257
+ logger.info(f"{source} -move-> {destination}")
258
+
249
259
  return True
250
260
 
251
261
 
@@ -149,21 +149,14 @@ def load_matrix(
149
149
  def load_text(
150
150
  filename,
151
151
  ignore_error=False,
152
- count=-1,
153
152
  log=False,
154
153
  ) -> Tuple[bool, List[str]]:
155
154
  success = True
156
155
  text = []
157
156
 
158
157
  try:
159
- if count == -1:
160
- with open(filename, "r") as fp:
161
- text = fp.read()
162
- text = text.split("\n")
163
- else:
164
- # https://stackoverflow.com/a/1767589/10917551
165
- with open(filename) as fp:
166
- text = [next(fp) for _ in range(count)]
158
+ with open(filename, "r") as fp:
159
+ text = fp.read().splitlines()
167
160
  except:
168
161
  success = False
169
162
  if not ignore_error: