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.
- bluer_objects/.abcli/abcli.sh +6 -0
- bluer_objects/.abcli/alias.sh +11 -0
- bluer_objects/.abcli/assets/cd.sh +20 -0
- bluer_objects/.abcli/assets/mv.sh +34 -0
- bluer_objects/.abcli/assets/publish.sh +37 -0
- bluer_objects/.abcli/assets.sh +15 -0
- bluer_objects/.abcli/create_test_asset.sh +10 -0
- bluer_objects/.abcli/download.sh +3 -1
- bluer_objects/.abcli/file.sh +15 -4
- bluer_objects/.abcli/gif.sh +18 -0
- bluer_objects/.abcli/host.sh +23 -7
- bluer_objects/.abcli/ls.sh +19 -8
- bluer_objects/.abcli/metadata/download.sh +9 -0
- bluer_objects/.abcli/metadata/edit.sh +15 -0
- bluer_objects/.abcli/metadata/upload.sh +9 -0
- bluer_objects/.abcli/mlflow/browse.sh +2 -0
- bluer_objects/.abcli/mlflow/deploy.sh +21 -5
- bluer_objects/.abcli/mlflow/lock/lock.sh +11 -0
- bluer_objects/.abcli/mlflow/lock/unlock.sh +12 -0
- bluer_objects/.abcli/mlflow/lock.sh +15 -0
- bluer_objects/.abcli/mlflow.sh +0 -2
- bluer_objects/.abcli/pdf/convert.sh +92 -0
- bluer_objects/.abcli/pdf.sh +15 -0
- bluer_objects/.abcli/storage/clear.sh +2 -0
- bluer_objects/.abcli/tests/clone.sh +2 -3
- bluer_objects/.abcli/tests/create_test_asset.sh +16 -0
- bluer_objects/.abcli/tests/file.sh +64 -0
- bluer_objects/.abcli/tests/gif.sh +3 -3
- bluer_objects/.abcli/tests/help.sh +27 -4
- bluer_objects/.abcli/tests/ls.sh +11 -4
- bluer_objects/.abcli/tests/metadata.sh +35 -0
- bluer_objects/.abcli/tests/mlflow_lock.sh +30 -0
- bluer_objects/.abcli/tests/open.sh +11 -0
- bluer_objects/.abcli/tests/open_gif_open.sh +14 -0
- bluer_objects/.abcli/tests/pdf.sh +31 -0
- bluer_objects/.abcli/tests/storage_clear.sh +11 -0
- bluer_objects/.abcli/tests/storage_public_upload.sh +25 -0
- bluer_objects/.abcli/tests/storage_status.sh +12 -0
- bluer_objects/.abcli/tests/{storage.sh → storage_upload_download.sh} +26 -8
- bluer_objects/.abcli/tests/web_is_accessible.sh +17 -0
- bluer_objects/.abcli/tests/web_where_am_ai.sh +5 -0
- bluer_objects/.abcli/upload.sh +26 -2
- bluer_objects/.abcli/url.sh +15 -0
- bluer_objects/.abcli/web/is_accessible.sh +13 -0
- bluer_objects/.abcli/web/where_am_i.sh +5 -0
- bluer_objects/README/__init__.py +24 -9
- bluer_objects/README/alias.py +56 -0
- bluer_objects/README/consts.py +39 -0
- bluer_objects/README/functions.py +127 -205
- bluer_objects/README/items.py +78 -6
- bluer_objects/README/utils.py +275 -0
- bluer_objects/__init__.py +1 -1
- bluer_objects/assets/__init__.py +0 -0
- bluer_objects/assets/__main__.py +57 -0
- bluer_objects/assets/functions.py +62 -0
- bluer_objects/config.env +9 -1
- bluer_objects/env.py +23 -0
- bluer_objects/file/__main__.py +52 -7
- bluer_objects/file/functions.py +13 -3
- bluer_objects/file/load.py +2 -9
- bluer_objects/file/save.py +17 -24
- bluer_objects/graphics/__main__.py +7 -0
- bluer_objects/graphics/gif.py +11 -7
- bluer_objects/graphics/screen.py +9 -8
- bluer_objects/help/assets.py +96 -0
- bluer_objects/help/create_test_asset.py +22 -0
- bluer_objects/help/download.py +17 -3
- bluer_objects/help/file.py +59 -0
- bluer_objects/help/functions.py +11 -1
- bluer_objects/help/gif.py +25 -0
- bluer_objects/help/host.py +6 -4
- bluer_objects/help/ls.py +26 -3
- bluer_objects/help/metadata.py +51 -0
- bluer_objects/help/mlflow/__init__.py +23 -2
- bluer_objects/help/mlflow/lock.py +52 -0
- bluer_objects/help/pdf.py +67 -0
- bluer_objects/help/upload.py +10 -3
- bluer_objects/help/web.py +38 -0
- bluer_objects/host/functions.py +4 -1
- bluer_objects/logger/confusion_matrix.py +76 -0
- bluer_objects/logger/image.py +110 -0
- bluer_objects/logger/stitch.py +107 -0
- bluer_objects/markdown.py +8 -6
- bluer_objects/metadata/__init__.py +1 -0
- bluer_objects/metadata/flatten.py +27 -0
- bluer_objects/mlflow/lock/__init__.py +1 -0
- bluer_objects/mlflow/lock/__main__.py +58 -0
- bluer_objects/mlflow/lock/functions.py +121 -0
- bluer_objects/mlflow/logging.py +47 -41
- bluer_objects/pdf/__init__.py +1 -0
- bluer_objects/pdf/__main__.py +78 -0
- bluer_objects/pdf/convert/__init__.py +0 -0
- bluer_objects/pdf/convert/batch.py +54 -0
- bluer_objects/pdf/convert/combination.py +32 -0
- bluer_objects/pdf/convert/convert.py +111 -0
- bluer_objects/pdf/convert/image.py +53 -0
- bluer_objects/pdf/convert/md.py +97 -0
- bluer_objects/pdf/convert/missing.py +96 -0
- bluer_objects/pdf/convert/pdf.py +37 -0
- bluer_objects/sample.env +6 -0
- bluer_objects/storage/WebDAV.py +11 -7
- bluer_objects/storage/WebDAVrequest.py +360 -0
- bluer_objects/storage/WebDAVzip.py +26 -29
- bluer_objects/storage/__init__.py +28 -1
- bluer_objects/storage/__main__.py +40 -6
- bluer_objects/storage/base.py +84 -5
- bluer_objects/storage/policies.py +7 -0
- bluer_objects/storage/s3.py +367 -0
- bluer_objects/testing/__main__.py +6 -0
- bluer_objects/tests/test_README_consts.py +71 -0
- bluer_objects/tests/test_README_items.py +128 -0
- bluer_objects/tests/test_alias.py +33 -0
- bluer_objects/tests/test_env.py +25 -2
- bluer_objects/tests/test_file_download.py +25 -0
- bluer_objects/tests/test_file_load_save.py +1 -2
- bluer_objects/tests/test_file_load_save_text.py +46 -0
- bluer_objects/tests/test_graphics_gif.py +2 -0
- bluer_objects/tests/test_log_image_grid.py +29 -0
- bluer_objects/tests/test_logger_confusion_matrix.py +18 -0
- bluer_objects/tests/test_logger_matrix.py +2 -2
- bluer_objects/tests/test_logger_stitch_images.py +47 -0
- bluer_objects/tests/test_metadata.py +12 -6
- bluer_objects/tests/test_metadata_flatten.py +109 -0
- bluer_objects/tests/test_mlflow.py +2 -2
- bluer_objects/tests/test_mlflow_lock.py +26 -0
- bluer_objects/tests/test_objects.py +2 -0
- bluer_objects/tests/test_shell.py +34 -0
- bluer_objects/tests/test_storage.py +8 -21
- bluer_objects/tests/test_storage_base.py +39 -0
- bluer_objects/tests/test_storage_s3.py +67 -0
- bluer_objects/tests/test_storage_webdav_request.py +75 -0
- bluer_objects/tests/test_storage_webdav_zip.py +42 -0
- bluer_objects/tests/test_web_is_accessible.py +11 -0
- bluer_objects/web/__init__.py +1 -0
- bluer_objects/web/__main__.py +31 -0
- bluer_objects/web/functions.py +9 -0
- {bluer_objects-6.104.1.dist-info → bluer_objects-6.377.1.dist-info}/METADATA +6 -3
- bluer_objects-6.377.1.dist-info/RECORD +217 -0
- {bluer_objects-6.104.1.dist-info → bluer_objects-6.377.1.dist-info}/WHEEL +1 -1
- bluer_objects/.abcli/storage/download_file.sh +0 -9
- bluer_objects/.abcli/storage/exists.sh +0 -8
- bluer_objects/.abcli/storage/list.sh +0 -8
- bluer_objects/.abcli/storage/rm.sh +0 -11
- bluer_objects-6.104.1.dist-info/RECORD +0 -143
- {bluer_objects-6.104.1.dist-info → bluer_objects-6.377.1.dist-info}/licenses/LICENSE +0 -0
- {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
|
+
"".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("<", "<")
|
|
173
|
+
.replace(">", ">")
|
|
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"[](https://github.com/kamangir/{REPO_NAME}/actions/workflows/pylint.yml)",
|
|
259
|
+
f"[](https://github.com/kamangir/{REPO_NAME}/actions/workflows/pytest.yml)",
|
|
260
|
+
f"[](https://github.com/kamangir/{REPO_NAME}/actions/workflows/bashtest.yml)",
|
|
261
|
+
f"[](https://pypi.org/project/{MODULE_NAME}/)",
|
|
262
|
+
f"[](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
|
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
|
-
|
|
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")
|
bluer_objects/file/__main__.py
CHANGED
|
@@ -31,24 +31,69 @@ parser.add_argument(
|
|
|
31
31
|
help="<that-1+that-2+that-3>",
|
|
32
32
|
)
|
|
33
33
|
parser.add_argument(
|
|
34
|
-
"--
|
|
34
|
+
"--pretty",
|
|
35
35
|
type=int,
|
|
36
|
-
default=
|
|
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(
|
|
67
|
+
logger.info(
|
|
68
|
+
f'{NAME}.{args.task}: "{args.this}" -> "{args.that}" in {args.filename}'
|
|
69
|
+
)
|
|
43
70
|
|
|
44
|
-
success, content = file.load_text(
|
|
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
|
-
|
|
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
|
-
|
|
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
|
bluer_objects/file/functions.py
CHANGED
|
@@ -117,25 +117,29 @@ def copy(
|
|
|
117
117
|
return False
|
|
118
118
|
|
|
119
119
|
if log:
|
|
120
|
-
logger.info(f"{
|
|
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
|
|
bluer_objects/file/load.py
CHANGED
|
@@ -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
|
-
|
|
160
|
-
|
|
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:
|