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
|
@@ -3,6 +3,7 @@ from typing import List
|
|
|
3
3
|
from bluer_options.terminal import show_usage, xtra
|
|
4
4
|
|
|
5
5
|
from bluer_objects.help.mlflow.cache import help_functions as help_cache
|
|
6
|
+
from bluer_objects.help.mlflow.lock import help_functions as help_lock
|
|
6
7
|
from bluer_objects.help.mlflow.tags import help_functions as help_tags
|
|
7
8
|
from bluer_ai import env
|
|
8
9
|
|
|
@@ -29,7 +30,7 @@ def help_deploy(
|
|
|
29
30
|
tokens: List[str],
|
|
30
31
|
mono: bool,
|
|
31
32
|
) -> str:
|
|
32
|
-
options = xtra("dryrun
|
|
33
|
+
options = xtra("dryrun,port=<5001>", mono=mono)
|
|
33
34
|
|
|
34
35
|
return show_usage(
|
|
35
36
|
[
|
|
@@ -42,6 +43,22 @@ def help_deploy(
|
|
|
42
43
|
)
|
|
43
44
|
|
|
44
45
|
|
|
46
|
+
def help_deploy_set(
|
|
47
|
+
tokens: List[str],
|
|
48
|
+
mono: bool,
|
|
49
|
+
) -> str:
|
|
50
|
+
return show_usage(
|
|
51
|
+
[
|
|
52
|
+
"@mlflow",
|
|
53
|
+
"deploy",
|
|
54
|
+
"set",
|
|
55
|
+
"<url> | local",
|
|
56
|
+
],
|
|
57
|
+
"set mlflow deployment.",
|
|
58
|
+
mono=mono,
|
|
59
|
+
)
|
|
60
|
+
|
|
61
|
+
|
|
45
62
|
def help_get_id(
|
|
46
63
|
tokens: List[str],
|
|
47
64
|
mono: bool,
|
|
@@ -198,10 +215,14 @@ def help_transition(
|
|
|
198
215
|
help_functions = {
|
|
199
216
|
"browse": help_browse,
|
|
200
217
|
"cache": help_cache,
|
|
201
|
-
"deploy":
|
|
218
|
+
"deploy": {
|
|
219
|
+
"": help_deploy,
|
|
220
|
+
"set": help_deploy_set,
|
|
221
|
+
},
|
|
202
222
|
"get_id": help_get_id,
|
|
203
223
|
"get_run_id": help_get_run_id,
|
|
204
224
|
"list_registered_models": help_list_registered_models,
|
|
225
|
+
"lock": help_lock,
|
|
205
226
|
"log_artifacts": help_log_artifacts,
|
|
206
227
|
"log_run": help_log_run,
|
|
207
228
|
"rm": help_rm,
|
|
@@ -0,0 +1,52 @@
|
|
|
1
|
+
from typing import List
|
|
2
|
+
|
|
3
|
+
from bluer_options.terminal import show_usage, xtra
|
|
4
|
+
|
|
5
|
+
|
|
6
|
+
def help_lock(
|
|
7
|
+
tokens: List[str],
|
|
8
|
+
mono: bool,
|
|
9
|
+
) -> str:
|
|
10
|
+
args = [
|
|
11
|
+
"[--lock <lock-name>]",
|
|
12
|
+
"[--timeout <10>]",
|
|
13
|
+
"[--verbose 0]",
|
|
14
|
+
]
|
|
15
|
+
|
|
16
|
+
return show_usage(
|
|
17
|
+
[
|
|
18
|
+
"@lock",
|
|
19
|
+
"lock",
|
|
20
|
+
"[.|<object-name>]",
|
|
21
|
+
]
|
|
22
|
+
+ args,
|
|
23
|
+
"lock <object-name>.",
|
|
24
|
+
mono=mono,
|
|
25
|
+
)
|
|
26
|
+
|
|
27
|
+
|
|
28
|
+
def help_unlock(
|
|
29
|
+
tokens: List[str],
|
|
30
|
+
mono: bool,
|
|
31
|
+
) -> str:
|
|
32
|
+
args = [
|
|
33
|
+
"[--lock <lock-name>]",
|
|
34
|
+
"[--verbose 0]",
|
|
35
|
+
]
|
|
36
|
+
|
|
37
|
+
return show_usage(
|
|
38
|
+
[
|
|
39
|
+
"@lock",
|
|
40
|
+
"unlock",
|
|
41
|
+
"[.|<object-name>]",
|
|
42
|
+
]
|
|
43
|
+
+ args,
|
|
44
|
+
"unlock <object-name>.",
|
|
45
|
+
mono=mono,
|
|
46
|
+
)
|
|
47
|
+
|
|
48
|
+
|
|
49
|
+
help_functions = {
|
|
50
|
+
"lock": help_lock,
|
|
51
|
+
"unlock": help_unlock,
|
|
52
|
+
}
|
|
@@ -0,0 +1,67 @@
|
|
|
1
|
+
from typing import List
|
|
2
|
+
|
|
3
|
+
from bluer_options.terminal import show_usage, xtra
|
|
4
|
+
|
|
5
|
+
|
|
6
|
+
def help_convert(
|
|
7
|
+
tokens: List[str],
|
|
8
|
+
mono: bool,
|
|
9
|
+
) -> str:
|
|
10
|
+
options = "".join(
|
|
11
|
+
[
|
|
12
|
+
"combine",
|
|
13
|
+
xtra(",~compress,filename=<release.pdf>,install,", mono=mono),
|
|
14
|
+
"upload",
|
|
15
|
+
]
|
|
16
|
+
)
|
|
17
|
+
|
|
18
|
+
args = [
|
|
19
|
+
"[--count <2>]",
|
|
20
|
+
]
|
|
21
|
+
|
|
22
|
+
# ---
|
|
23
|
+
|
|
24
|
+
usage_1 = show_usage(
|
|
25
|
+
[
|
|
26
|
+
"@pdf",
|
|
27
|
+
"convert",
|
|
28
|
+
"[{}]".format(f"inline,{options}"),
|
|
29
|
+
"<module-name>",
|
|
30
|
+
"<.,this,this/that.md,this/that.jpg,this/that.pdf>",
|
|
31
|
+
"[-|<object-name>]",
|
|
32
|
+
]
|
|
33
|
+
+ args,
|
|
34
|
+
"md -> pdf.",
|
|
35
|
+
mono=mono,
|
|
36
|
+
)
|
|
37
|
+
|
|
38
|
+
# ---
|
|
39
|
+
|
|
40
|
+
usage_2 = show_usage(
|
|
41
|
+
[
|
|
42
|
+
"@pdf",
|
|
43
|
+
"convert",
|
|
44
|
+
f"[{options}]",
|
|
45
|
+
"[.|<object-name>]",
|
|
46
|
+
]
|
|
47
|
+
+ args
|
|
48
|
+
+ [
|
|
49
|
+
"[--list_missing 0]",
|
|
50
|
+
],
|
|
51
|
+
"md -> pdf.",
|
|
52
|
+
mono=mono,
|
|
53
|
+
)
|
|
54
|
+
|
|
55
|
+
# ---
|
|
56
|
+
|
|
57
|
+
return "\n".join(
|
|
58
|
+
[
|
|
59
|
+
usage_1,
|
|
60
|
+
usage_2,
|
|
61
|
+
]
|
|
62
|
+
)
|
|
63
|
+
|
|
64
|
+
|
|
65
|
+
help_functions = {
|
|
66
|
+
"convert": help_convert,
|
|
67
|
+
}
|
bluer_objects/help/upload.py
CHANGED
|
@@ -3,16 +3,23 @@ from typing import List
|
|
|
3
3
|
from bluer_options.terminal import show_usage, xtra
|
|
4
4
|
|
|
5
5
|
|
|
6
|
+
def options(mono: bool) -> str:
|
|
7
|
+
return "".join(
|
|
8
|
+
[
|
|
9
|
+
"filename=<filename>",
|
|
10
|
+
xtra(",public,zip", mono=mono),
|
|
11
|
+
]
|
|
12
|
+
)
|
|
13
|
+
|
|
14
|
+
|
|
6
15
|
def help_upload(
|
|
7
16
|
tokens: List[str],
|
|
8
17
|
mono: bool,
|
|
9
18
|
) -> str:
|
|
10
|
-
options = "filename=<filename>"
|
|
11
|
-
|
|
12
19
|
return show_usage(
|
|
13
20
|
[
|
|
14
21
|
"@upload",
|
|
15
|
-
f"[{options}]",
|
|
22
|
+
f"[{options(mono=mono)}]",
|
|
16
23
|
"[.|<object-name>]",
|
|
17
24
|
],
|
|
18
25
|
"upload <object-name>.",
|
|
@@ -0,0 +1,38 @@
|
|
|
1
|
+
from typing import List
|
|
2
|
+
|
|
3
|
+
from bluer_options.terminal import show_usage
|
|
4
|
+
|
|
5
|
+
|
|
6
|
+
def help_is_accessible(
|
|
7
|
+
tokens: List[str],
|
|
8
|
+
mono: bool,
|
|
9
|
+
) -> str:
|
|
10
|
+
return show_usage(
|
|
11
|
+
[
|
|
12
|
+
"@web",
|
|
13
|
+
"is_accessible",
|
|
14
|
+
"<url>",
|
|
15
|
+
],
|
|
16
|
+
"is <url> accessible?",
|
|
17
|
+
mono=mono,
|
|
18
|
+
)
|
|
19
|
+
|
|
20
|
+
|
|
21
|
+
def help_where_am_i(
|
|
22
|
+
tokens: List[str],
|
|
23
|
+
mono: bool,
|
|
24
|
+
) -> str:
|
|
25
|
+
return show_usage(
|
|
26
|
+
[
|
|
27
|
+
"@web",
|
|
28
|
+
"where_am_i",
|
|
29
|
+
],
|
|
30
|
+
"where am I?",
|
|
31
|
+
mono=mono,
|
|
32
|
+
)
|
|
33
|
+
|
|
34
|
+
|
|
35
|
+
help_functions = {
|
|
36
|
+
"is_accessible": help_is_accessible,
|
|
37
|
+
"where_am_i": help_where_am_i,
|
|
38
|
+
}
|
bluer_objects/host/functions.py
CHANGED
|
@@ -11,7 +11,7 @@ NAME = module.name(__file__, NAME)
|
|
|
11
11
|
|
|
12
12
|
|
|
13
13
|
def shell(
|
|
14
|
-
command: str,
|
|
14
|
+
command: Union[str, List[str]],
|
|
15
15
|
clean_after: bool = False,
|
|
16
16
|
return_output: bool = False,
|
|
17
17
|
work_dir: str = ".",
|
|
@@ -20,6 +20,9 @@ def shell(
|
|
|
20
20
|
bool,
|
|
21
21
|
Tuple[bool, List[str]],
|
|
22
22
|
]:
|
|
23
|
+
if isinstance(command, list):
|
|
24
|
+
command = " ".join(command)
|
|
25
|
+
|
|
23
26
|
if log:
|
|
24
27
|
logger.info(f"{NAME}.shell({command})")
|
|
25
28
|
|
|
@@ -0,0 +1,76 @@
|
|
|
1
|
+
import matplotlib.pyplot as plt
|
|
2
|
+
import numpy as np
|
|
3
|
+
from typing import List
|
|
4
|
+
|
|
5
|
+
from bluer_objects.graphics.signature import justify_text
|
|
6
|
+
from bluer_objects import file
|
|
7
|
+
|
|
8
|
+
|
|
9
|
+
def log_confusion_matrix(
|
|
10
|
+
confusion_matrix: np.ndarray,
|
|
11
|
+
filename: str,
|
|
12
|
+
header: List[str] = [],
|
|
13
|
+
footer: List[str] = [],
|
|
14
|
+
x_classes: List[str] = [],
|
|
15
|
+
y_classes: List[str] = [],
|
|
16
|
+
x_name: str = "prediction",
|
|
17
|
+
y_name: str = "label",
|
|
18
|
+
line_width: int = 80,
|
|
19
|
+
log: bool = True,
|
|
20
|
+
figsize: tuple = (10, 10),
|
|
21
|
+
) -> bool:
|
|
22
|
+
fig, ax = plt.subplots(figsize=figsize)
|
|
23
|
+
cax = ax.imshow(
|
|
24
|
+
confusion_matrix,
|
|
25
|
+
interpolation="nearest",
|
|
26
|
+
cmap=plt.cm.Blues,
|
|
27
|
+
)
|
|
28
|
+
fig.colorbar(cax)
|
|
29
|
+
ax.set_title(
|
|
30
|
+
justify_text(
|
|
31
|
+
" | ".join(header),
|
|
32
|
+
line_width=line_width,
|
|
33
|
+
return_str=True,
|
|
34
|
+
)
|
|
35
|
+
)
|
|
36
|
+
ax.set_xlabel(
|
|
37
|
+
justify_text(
|
|
38
|
+
" | ".join([x_name] + footer),
|
|
39
|
+
line_width=line_width,
|
|
40
|
+
return_str=True,
|
|
41
|
+
)
|
|
42
|
+
)
|
|
43
|
+
ax.set_ylabel(y_name)
|
|
44
|
+
|
|
45
|
+
if not x_classes:
|
|
46
|
+
x_classes = [f"class #{index}" for index in range(confusion_matrix.shape[1])]
|
|
47
|
+
if not y_classes:
|
|
48
|
+
y_classes = [f"class #{index}" for index in range(confusion_matrix.shape[0])]
|
|
49
|
+
|
|
50
|
+
ax.set_xticks(np.arange(confusion_matrix.shape[1]))
|
|
51
|
+
ax.set_yticks(np.arange(confusion_matrix.shape[0]))
|
|
52
|
+
ax.set_xticklabels(
|
|
53
|
+
x_classes,
|
|
54
|
+
rotation=45,
|
|
55
|
+
ha="right",
|
|
56
|
+
)
|
|
57
|
+
ax.set_yticklabels(y_classes)
|
|
58
|
+
|
|
59
|
+
threshold = confusion_matrix.max() / 2.0
|
|
60
|
+
for i in range(confusion_matrix.shape[0]):
|
|
61
|
+
for j in range(confusion_matrix.shape[1]):
|
|
62
|
+
ax.text(
|
|
63
|
+
j,
|
|
64
|
+
i,
|
|
65
|
+
f"{100*confusion_matrix[i, j]:.1f}%",
|
|
66
|
+
ha="center",
|
|
67
|
+
va="center",
|
|
68
|
+
color="white" if confusion_matrix[i, j] > threshold else "black",
|
|
69
|
+
)
|
|
70
|
+
|
|
71
|
+
plt.tight_layout()
|
|
72
|
+
|
|
73
|
+
return file.save_fig(
|
|
74
|
+
filename,
|
|
75
|
+
log=log,
|
|
76
|
+
)
|
|
@@ -0,0 +1,110 @@
|
|
|
1
|
+
import matplotlib.pyplot as plt
|
|
2
|
+
from typing import Dict, Any, Union, List
|
|
3
|
+
import pandas as pd
|
|
4
|
+
import random
|
|
5
|
+
import os
|
|
6
|
+
|
|
7
|
+
from bluer_options import string
|
|
8
|
+
|
|
9
|
+
from bluer_objects import file, objects, path
|
|
10
|
+
from bluer_objects.graphics.signature import sign_filename
|
|
11
|
+
|
|
12
|
+
LOG_IMAGE_GRID_COLS = 5
|
|
13
|
+
LOG_IMAGE_GRID_ROWS = 3
|
|
14
|
+
|
|
15
|
+
|
|
16
|
+
def log_image_grid(
|
|
17
|
+
items: Union[
|
|
18
|
+
List[Dict[str, Any]],
|
|
19
|
+
pd.DataFrame,
|
|
20
|
+
],
|
|
21
|
+
filename: str,
|
|
22
|
+
rows: int = LOG_IMAGE_GRID_ROWS,
|
|
23
|
+
cols: int = LOG_IMAGE_GRID_COLS,
|
|
24
|
+
log: bool = True,
|
|
25
|
+
verbose: bool = False,
|
|
26
|
+
scale: int = 2,
|
|
27
|
+
shuffle: bool = False,
|
|
28
|
+
header: List[str] = [],
|
|
29
|
+
footer: List[str] = [],
|
|
30
|
+
relative_path: bool = False,
|
|
31
|
+
) -> bool:
|
|
32
|
+
if isinstance(items, pd.DataFrame):
|
|
33
|
+
items = items.to_dict("records")
|
|
34
|
+
|
|
35
|
+
while len(items) < rows * cols:
|
|
36
|
+
items += [{"pass": True}]
|
|
37
|
+
if shuffle:
|
|
38
|
+
random.shuffle(items)
|
|
39
|
+
|
|
40
|
+
items = items[: rows * cols]
|
|
41
|
+
|
|
42
|
+
if relative_path:
|
|
43
|
+
root_path = file.path(filename)
|
|
44
|
+
for item in items:
|
|
45
|
+
if item.get("filename", ""):
|
|
46
|
+
item["filename"] = os.path.join(
|
|
47
|
+
root_path,
|
|
48
|
+
item["filename"],
|
|
49
|
+
)
|
|
50
|
+
|
|
51
|
+
_, axes = plt.subplots(
|
|
52
|
+
rows,
|
|
53
|
+
cols,
|
|
54
|
+
figsize=(
|
|
55
|
+
scale * cols,
|
|
56
|
+
scale * rows,
|
|
57
|
+
),
|
|
58
|
+
)
|
|
59
|
+
axes = axes.flatten()
|
|
60
|
+
|
|
61
|
+
image_shape = ""
|
|
62
|
+
for i, item in enumerate(items):
|
|
63
|
+
if item.get("pass", False):
|
|
64
|
+
axes[i].axis("off")
|
|
65
|
+
continue
|
|
66
|
+
|
|
67
|
+
if item.get("filename", ""):
|
|
68
|
+
success, item["image"] = file.load_image(
|
|
69
|
+
item.get("filename", ""),
|
|
70
|
+
log=verbose,
|
|
71
|
+
)
|
|
72
|
+
if not success:
|
|
73
|
+
return False
|
|
74
|
+
|
|
75
|
+
ax = axes[i]
|
|
76
|
+
image = item["image"]
|
|
77
|
+
image_shape = string.pretty_shape_of_matrix(image)
|
|
78
|
+
ax.imshow(
|
|
79
|
+
image,
|
|
80
|
+
cmap="gray" if image.ndim == 2 else None,
|
|
81
|
+
)
|
|
82
|
+
ax.set_title(
|
|
83
|
+
item.get("title", f"#{i}"),
|
|
84
|
+
color=item.get("color", "black"),
|
|
85
|
+
fontsize=10,
|
|
86
|
+
)
|
|
87
|
+
ax.axis("off")
|
|
88
|
+
|
|
89
|
+
plt.tight_layout()
|
|
90
|
+
|
|
91
|
+
if not file.save_fig(
|
|
92
|
+
filename,
|
|
93
|
+
log=verbose,
|
|
94
|
+
):
|
|
95
|
+
return False
|
|
96
|
+
|
|
97
|
+
return sign_filename(
|
|
98
|
+
filename,
|
|
99
|
+
[
|
|
100
|
+
" | ".join(
|
|
101
|
+
objects.signature(
|
|
102
|
+
info=file.name_and_extension(filename),
|
|
103
|
+
object_name=path.name(file.path(filename)),
|
|
104
|
+
)
|
|
105
|
+
+ [image_shape]
|
|
106
|
+
+ header
|
|
107
|
+
)
|
|
108
|
+
],
|
|
109
|
+
[" | ".join(footer)],
|
|
110
|
+
)
|
|
@@ -0,0 +1,107 @@
|
|
|
1
|
+
from typing import List
|
|
2
|
+
import numpy as np
|
|
3
|
+
|
|
4
|
+
from blueness import module
|
|
5
|
+
from bluer_options import string
|
|
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 stitch_images(
|
|
14
|
+
list_of_images: List[np.ndarray],
|
|
15
|
+
cols: int = -1,
|
|
16
|
+
rows: int = -1,
|
|
17
|
+
log: bool = False,
|
|
18
|
+
) -> np.ndarray:
|
|
19
|
+
if not list_of_images:
|
|
20
|
+
return np.zeros((1, 1, 3), dtype=np.uint8)
|
|
21
|
+
|
|
22
|
+
list_of_images = list_of_images.copy()
|
|
23
|
+
|
|
24
|
+
if rows == -1:
|
|
25
|
+
rows = int(np.floor(np.sqrt(len(list_of_images))))
|
|
26
|
+
cols = -1
|
|
27
|
+
|
|
28
|
+
if cols == -1:
|
|
29
|
+
cols = int(np.ceil(len(list_of_images) / rows))
|
|
30
|
+
|
|
31
|
+
if log:
|
|
32
|
+
logger.info(
|
|
33
|
+
"{}.stitch_images[{}x{}]({}): {}".format(
|
|
34
|
+
NAME,
|
|
35
|
+
rows,
|
|
36
|
+
cols,
|
|
37
|
+
len(list_of_images),
|
|
38
|
+
", ".join(
|
|
39
|
+
[string.pretty_shape_of_matrix(image) for image in list_of_images]
|
|
40
|
+
),
|
|
41
|
+
)
|
|
42
|
+
)
|
|
43
|
+
|
|
44
|
+
for image in list_of_images:
|
|
45
|
+
if len(image.shape) == 2:
|
|
46
|
+
image = np.stack([image, image, image], axis=2)
|
|
47
|
+
|
|
48
|
+
if rows == 1:
|
|
49
|
+
output = np.zeros(
|
|
50
|
+
(
|
|
51
|
+
max([image.shape[0] for image in list_of_images]),
|
|
52
|
+
sum([image.shape[1] for image in list_of_images]),
|
|
53
|
+
3,
|
|
54
|
+
),
|
|
55
|
+
dtype=np.uint8,
|
|
56
|
+
)
|
|
57
|
+
x: int = 0
|
|
58
|
+
for image in list_of_images:
|
|
59
|
+
x_new = x + image.shape[1]
|
|
60
|
+
|
|
61
|
+
output[
|
|
62
|
+
: image.shape[0],
|
|
63
|
+
x:x_new,
|
|
64
|
+
:,
|
|
65
|
+
] = image
|
|
66
|
+
|
|
67
|
+
x = x_new
|
|
68
|
+
|
|
69
|
+
return output
|
|
70
|
+
|
|
71
|
+
if cols == 1:
|
|
72
|
+
output = np.zeros(
|
|
73
|
+
(
|
|
74
|
+
sum([image.shape[0] for image in list_of_images]),
|
|
75
|
+
max([image.shape[1] for image in list_of_images]),
|
|
76
|
+
3,
|
|
77
|
+
),
|
|
78
|
+
dtype=np.uint8,
|
|
79
|
+
)
|
|
80
|
+
y: int = 0
|
|
81
|
+
for image in list_of_images:
|
|
82
|
+
y_new = y + image.shape[0]
|
|
83
|
+
|
|
84
|
+
output[
|
|
85
|
+
y:y_new,
|
|
86
|
+
: image.shape[1],
|
|
87
|
+
:,
|
|
88
|
+
] = image
|
|
89
|
+
|
|
90
|
+
y = y_new
|
|
91
|
+
|
|
92
|
+
return output
|
|
93
|
+
|
|
94
|
+
return stitch_images(
|
|
95
|
+
list_of_images=[
|
|
96
|
+
stitch_images(
|
|
97
|
+
list_of_images[row * cols : (row + 1) * cols],
|
|
98
|
+
cols=cols,
|
|
99
|
+
rows=1,
|
|
100
|
+
log=log,
|
|
101
|
+
)
|
|
102
|
+
for row in range(rows)
|
|
103
|
+
],
|
|
104
|
+
cols=1,
|
|
105
|
+
rows=rows,
|
|
106
|
+
log=log,
|
|
107
|
+
)
|
bluer_objects/markdown.py
CHANGED
|
@@ -12,6 +12,7 @@ NAME = module.name(__file__, NAME)
|
|
|
12
12
|
def generate_table(
|
|
13
13
|
items: List[str],
|
|
14
14
|
cols: int = 3,
|
|
15
|
+
log: bool = True,
|
|
15
16
|
) -> List[str]:
|
|
16
17
|
if not items:
|
|
17
18
|
return []
|
|
@@ -22,13 +23,14 @@ def generate_table(
|
|
|
22
23
|
|
|
23
24
|
row_count = int(math.ceil(len(items) / cols))
|
|
24
25
|
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
26
|
+
if log:
|
|
27
|
+
logger.info(
|
|
28
|
+
"{}.generate_table(): {} item(s), {} row(s)".format(
|
|
29
|
+
NAME,
|
|
30
|
+
len(items),
|
|
31
|
+
row_count,
|
|
32
|
+
)
|
|
30
33
|
)
|
|
31
|
-
)
|
|
32
34
|
|
|
33
35
|
return [
|
|
34
36
|
"| {} |".format(" | ".join(cols * [" "])),
|
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
from typing import Any
|
|
2
|
+
import numpy as np
|
|
3
|
+
|
|
4
|
+
|
|
5
|
+
def flatten(obj: Any) -> Any:
|
|
6
|
+
if isinstance(obj, dict):
|
|
7
|
+
return {k: flatten(v) for k, v in obj.items()}
|
|
8
|
+
|
|
9
|
+
if isinstance(obj, list):
|
|
10
|
+
return [flatten(x) for x in obj]
|
|
11
|
+
|
|
12
|
+
if isinstance(obj, tuple):
|
|
13
|
+
return tuple(flatten(x) for x in obj)
|
|
14
|
+
|
|
15
|
+
if isinstance(obj, np.ndarray):
|
|
16
|
+
return obj.tolist()
|
|
17
|
+
|
|
18
|
+
if hasattr(obj, "__dict__"):
|
|
19
|
+
return flatten(vars(obj))
|
|
20
|
+
|
|
21
|
+
if isinstance(obj, (int, float, str)):
|
|
22
|
+
return obj
|
|
23
|
+
|
|
24
|
+
try:
|
|
25
|
+
return str(obj)
|
|
26
|
+
except:
|
|
27
|
+
return obj.__class__.__name__
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
|
|
@@ -0,0 +1,58 @@
|
|
|
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.mlflow.lock.functions import lock, unlock
|
|
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="lock | unlock",
|
|
17
|
+
)
|
|
18
|
+
parser.add_argument(
|
|
19
|
+
"--object_name",
|
|
20
|
+
type=str,
|
|
21
|
+
)
|
|
22
|
+
parser.add_argument(
|
|
23
|
+
"--lock",
|
|
24
|
+
type=str,
|
|
25
|
+
default="lock",
|
|
26
|
+
)
|
|
27
|
+
parser.add_argument(
|
|
28
|
+
"--timeout",
|
|
29
|
+
type=int,
|
|
30
|
+
default=-1,
|
|
31
|
+
help="in seconds",
|
|
32
|
+
)
|
|
33
|
+
parser.add_argument(
|
|
34
|
+
"--verbose",
|
|
35
|
+
type=int,
|
|
36
|
+
default=1,
|
|
37
|
+
help="0 | 1",
|
|
38
|
+
)
|
|
39
|
+
args = parser.parse_args()
|
|
40
|
+
|
|
41
|
+
success = False
|
|
42
|
+
if args.task == "lock":
|
|
43
|
+
success = lock(
|
|
44
|
+
object_name=args.object_name,
|
|
45
|
+
lock_name=args.lock,
|
|
46
|
+
timeout=args.timeout,
|
|
47
|
+
verbose=args.verbose == 1,
|
|
48
|
+
)
|
|
49
|
+
elif args.task == "unlock":
|
|
50
|
+
success = unlock(
|
|
51
|
+
object_name=args.object_name,
|
|
52
|
+
lock_name=args.lock,
|
|
53
|
+
verbose=args.verbose == 1,
|
|
54
|
+
)
|
|
55
|
+
else:
|
|
56
|
+
success = None
|
|
57
|
+
|
|
58
|
+
sys_exit(logger, NAME, args.task, success)
|