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,130 @@
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.tags.functions import clone, create, get, search, set_
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="get",
18
+ help="clone|create|get|search|set",
19
+ )
20
+ parser.add_argument(
21
+ "--after",
22
+ type=str,
23
+ default="",
24
+ help="123-4-e",
25
+ )
26
+ parser.add_argument(
27
+ "--before",
28
+ type=str,
29
+ default="",
30
+ )
31
+ parser.add_argument(
32
+ "--count",
33
+ type=int,
34
+ default=-1,
35
+ )
36
+ parser.add_argument(
37
+ "--offset",
38
+ type=int,
39
+ default=0,
40
+ )
41
+ parser.add_argument(
42
+ "--delim",
43
+ type=str,
44
+ default=", ",
45
+ )
46
+ parser.add_argument(
47
+ "--host",
48
+ default=-1,
49
+ type=int,
50
+ help="0|1|-1",
51
+ )
52
+ parser.add_argument(
53
+ "--item_name",
54
+ default="object",
55
+ type=str,
56
+ )
57
+ parser.add_argument(
58
+ "--log",
59
+ default=1,
60
+ type=int,
61
+ help="0|1",
62
+ )
63
+ parser.add_argument(
64
+ "--object",
65
+ type=str,
66
+ default="",
67
+ )
68
+ parser.add_argument(
69
+ "--object_2",
70
+ type=str,
71
+ default="",
72
+ )
73
+ parser.add_argument(
74
+ "--shuffle",
75
+ default=0,
76
+ type=int,
77
+ help="0|1",
78
+ )
79
+ parser.add_argument(
80
+ "--tag",
81
+ type=str,
82
+ default="",
83
+ )
84
+ parser.add_argument(
85
+ "--tags",
86
+ type=str,
87
+ default="",
88
+ help="tag_1,~tag_2",
89
+ )
90
+ parser.add_argument(
91
+ "--type",
92
+ type=str,
93
+ default="",
94
+ )
95
+ args = parser.parse_args()
96
+
97
+ delim = " " if args.delim == "space" else args.delim
98
+
99
+ success = False
100
+ output = None
101
+ if args.task == "clone":
102
+ success = clone(args.object, args.object_2)
103
+ elif args.task == "create":
104
+ success = create()
105
+ elif args.task == "get":
106
+ output = get(args.object)
107
+ success = True
108
+ elif args.task == "search":
109
+ output = search(
110
+ args.tags,
111
+ after=args.after,
112
+ before=args.before,
113
+ count=args.count,
114
+ host=args.host,
115
+ shuffle=args.shuffle,
116
+ offset=args.offset,
117
+ )
118
+ success = True
119
+ elif args.task == "set":
120
+ success = set_(args.object, args.tags)
121
+ else:
122
+ success = None
123
+
124
+ if success is True and output is not None:
125
+ if args.log:
126
+ logger.info(f"{len(output):,} {args.item_name}(s): {delim.join(output)}")
127
+ else:
128
+ print(delim.join(output))
129
+
130
+ sys_exit(logger, NAME, args.task, success, log=args.log)
@@ -0,0 +1,203 @@
1
+ from typing import List
2
+ from functools import reduce
3
+ import random
4
+ import re
5
+
6
+ from blue_options.options import Options
7
+
8
+ from bluer_objects.mysql.table import Table
9
+ from bluer_objects.logger import logger
10
+
11
+
12
+ def clone(
13
+ object_1: str,
14
+ object_2: str,
15
+ ) -> bool:
16
+ return set_(object_2, get(object_1))
17
+
18
+
19
+ def create() -> bool:
20
+ return Table.Create(
21
+ "tags",
22
+ [
23
+ "keyword VARCHAR(256) NOT NULL",
24
+ "tag VARCHAR(4096) NOT NULL",
25
+ "value BIT NOT NULL",
26
+ ],
27
+ )
28
+
29
+
30
+ def get(keyword: str) -> List[str]:
31
+ table = Table(name="tags")
32
+
33
+ if not table.connect():
34
+ return []
35
+
36
+ success, output = table.execute(
37
+ "SELECT t.tag,t.value "
38
+ f"FROM {table.name} t "
39
+ "INNER JOIN ( "
40
+ "SELECT tag, MAX(timestamp) AS max_timestamp "
41
+ f"FROM {table.name} "
42
+ f'WHERE keyword="{keyword}" GROUP BY tag '
43
+ ") tm "
44
+ "ON t.tag=tm.tag AND t.timestamp=tm.max_timestamp "
45
+ f'WHERE keyword="{keyword}";',
46
+ )
47
+
48
+ if success:
49
+ success = table.disconnect()
50
+
51
+ if not success:
52
+ return []
53
+
54
+ return sorted([thing[0] for thing in output if thing[1] == b"\x01"])
55
+
56
+
57
+ def search(
58
+ tags: List[str],
59
+ after: str = "",
60
+ before: str = "",
61
+ count: int = -1,
62
+ host: int = -1, # limit to/exclude/ignore (1/0/-1) hosts.
63
+ return_timestamp: bool = False,
64
+ shuffle: bool = False,
65
+ offset: int = 0,
66
+ ) -> List[str]:
67
+ if isinstance(tags, str):
68
+ tags = tags.split(",")
69
+
70
+ included_tags = []
71
+ excluded_tags = []
72
+ for tag in tags:
73
+ if tag:
74
+ if tag[0] in "~-!":
75
+ excluded_tags += [tag[1:]]
76
+ else:
77
+ included_tags += [tag]
78
+
79
+ table = Table(name="tags")
80
+
81
+ table.connect()
82
+
83
+ list_of_keywords = None
84
+ timestamp = {}
85
+ for tag in included_tags:
86
+ success, output = table.execute(
87
+ "SELECT t.keyword,t.value,t.timestamp "
88
+ "FROM abcli.tags t "
89
+ "INNER JOIN ( "
90
+ "SELECT keyword, MAX(timestamp) AS max_timestamp "
91
+ "FROM abcli.tags "
92
+ f'WHERE tag="{tag}" GROUP BY keyword '
93
+ ") tm "
94
+ "ON t.keyword=tm.keyword AND t.timestamp=tm.max_timestamp "
95
+ f'WHERE tag="{tag}"; '
96
+ )
97
+ if not success:
98
+ list_of_keywords = []
99
+ break
100
+
101
+ list_of_keywords_ = [thing[0] for thing in output if thing[1] == b"\x01"]
102
+
103
+ if return_timestamp:
104
+ for thing in output:
105
+ if thing[1] == b"\x01":
106
+ timestamp[thing[0]] = thing[2]
107
+
108
+ list_of_keywords = (
109
+ list_of_keywords_
110
+ if list_of_keywords is None
111
+ else [
112
+ keyword for keyword in list_of_keywords if keyword in list_of_keywords_
113
+ ]
114
+ )
115
+
116
+ table.disconnect()
117
+
118
+ list_of_keywords = [] if list_of_keywords is None else sorted(list_of_keywords)
119
+
120
+ if after:
121
+ list_of_keywords = [keyword for keyword in list_of_keywords if keyword >= after]
122
+
123
+ if before:
124
+ list_of_keywords = [
125
+ keyword for keyword in list_of_keywords if keyword <= before
126
+ ]
127
+
128
+ excluded_keywords = reduce(
129
+ lambda x, y: x + y,
130
+ [
131
+ search(
132
+ tag,
133
+ after=after,
134
+ before=before,
135
+ count=-1,
136
+ host=host,
137
+ )
138
+ for tag in excluded_tags
139
+ ],
140
+ [],
141
+ )
142
+
143
+ list_of_keywords = [
144
+ keyword for keyword in list_of_keywords if keyword not in excluded_keywords
145
+ ]
146
+
147
+ if shuffle:
148
+ random.shuffle(list_of_keywords)
149
+ else:
150
+ list_of_keywords = list_of_keywords[::-1]
151
+
152
+ p = re.compile("([0-9]{13}|(0|1)[0-9,a-z]{15}|i-[0-9,a-z]{17})")
153
+ if host == 1:
154
+ list_of_keywords = [keyword for keyword in list_of_keywords if p.match(keyword)]
155
+ if host == 0:
156
+ list_of_keywords = [
157
+ keyword for keyword in list_of_keywords if not p.match(keyword)
158
+ ]
159
+
160
+ list_of_keywords = list_of_keywords[offset:]
161
+
162
+ list_of_keywords = (
163
+ list_of_keywords[:count]
164
+ if count > 0
165
+ else [] if count != -1 else list_of_keywords
166
+ )
167
+
168
+ return (list_of_keywords, timestamp) if return_timestamp else list_of_keywords
169
+
170
+
171
+ def set_(
172
+ keyword: str,
173
+ tags: List[str],
174
+ ) -> bool:
175
+ table = Table(name="tags")
176
+
177
+ if isinstance(tags, list):
178
+ tags = ",".join(tags)
179
+ if isinstance(tags, str):
180
+ tags = Options(tags)
181
+
182
+ if not table.connect():
183
+ return False
184
+
185
+ tags = {tag.strip(): value for tag, value in tags.items()}
186
+
187
+ success = True
188
+ for tag in tags:
189
+ if not table.insert(
190
+ "keyword,tag,value".split(","),
191
+ [keyword, tag, 1 if tags[tag] else 0],
192
+ ):
193
+ success = False
194
+ else:
195
+ if tags[tag]:
196
+ logger.info(f"{keyword} += #{tag}.")
197
+ else:
198
+ logger.info(f"{keyword} -= #{tag}.")
199
+
200
+ if not table.disconnect():
201
+ return False
202
+
203
+ return success
@@ -0,0 +1,167 @@
1
+ import os
2
+
3
+ from blue_options import string
4
+
5
+ from bluer_objects import file, path
6
+ from bluer_objects.env import (
7
+ ABCLI_OBJECT_ROOT,
8
+ abcli_object_name,
9
+ ABCLI_S3_OBJECT_PREFIX,
10
+ )
11
+ from bluer_objects.host import shell
12
+ from bluer_objects.logger import logger
13
+
14
+
15
+ def download(
16
+ object_name: str,
17
+ filename: str = "",
18
+ overwrite: bool = False,
19
+ ) -> bool:
20
+ if not ABCLI_S3_OBJECT_PREFIX:
21
+ logger.error("ABCLI_S3_OBJECT_PREFIX is not set.")
22
+ return False
23
+
24
+ if not object_name:
25
+ logger.error("object_name not found.")
26
+ return False
27
+
28
+ if (
29
+ filename
30
+ and not overwrite
31
+ and file.exists(
32
+ path_of(
33
+ object_name=object_name,
34
+ filename=filename,
35
+ )
36
+ )
37
+ ):
38
+ return True
39
+
40
+ return (
41
+ shell(
42
+ "aws s3 cp {}/{}/{} {}".format(
43
+ ABCLI_S3_OBJECT_PREFIX,
44
+ object_name,
45
+ filename,
46
+ object_path(object_name, create=True),
47
+ )
48
+ )
49
+ if filename
50
+ else shell(
51
+ "aws s3 sync {}/{}/ {}".format(
52
+ ABCLI_S3_OBJECT_PREFIX,
53
+ object_name,
54
+ object_path(object_name, create=True),
55
+ )
56
+ )
57
+ )
58
+
59
+
60
+ def list_of_files(
61
+ object_name: str,
62
+ cloud: bool = False,
63
+ **kwargs,
64
+ ):
65
+ if cloud:
66
+ from bluer_objects.storage import instance as storage
67
+
68
+ return storage.list_of_objects(
69
+ object_name,
70
+ **kwargs,
71
+ )
72
+
73
+ return file.list_of(
74
+ os.path.join(
75
+ ABCLI_OBJECT_ROOT,
76
+ object_name,
77
+ "*",
78
+ ),
79
+ **kwargs,
80
+ )
81
+
82
+
83
+ def object_path(
84
+ object_name=".",
85
+ create=False,
86
+ ):
87
+ output = os.path.join(
88
+ ABCLI_OBJECT_ROOT,
89
+ abcli_object_name if object_name == "." else object_name,
90
+ )
91
+
92
+ if create:
93
+ os.makedirs(output, exist_ok=True)
94
+
95
+ return output
96
+
97
+
98
+ def path_of(
99
+ filename,
100
+ object_name=".",
101
+ create=False,
102
+ ):
103
+ return os.path.join(
104
+ object_path(object_name, create),
105
+ filename,
106
+ )
107
+
108
+
109
+ def signature(info=None, object_name="."):
110
+ return [
111
+ "{}{}".format(
112
+ abcli_object_name if object_name == "." else object_name,
113
+ "" if info is None else f"/{str(info)}",
114
+ ),
115
+ string.pretty_date(include_time=False),
116
+ string.pretty_date(include_date=False, include_zone=True),
117
+ ]
118
+
119
+
120
+ def unique_object(
121
+ prefix: str = "",
122
+ include_time: bool = True,
123
+ ):
124
+ object_name = string.pretty_date(
125
+ as_filename=True,
126
+ include_time=include_time,
127
+ unique=True,
128
+ )
129
+ if prefix:
130
+ object_name = f"{prefix}-{object_name}"
131
+
132
+ path.create(object_path(object_name))
133
+
134
+ logger.info(f"📂 {object_name}")
135
+
136
+ return object_name
137
+
138
+
139
+ def upload(
140
+ object_name: str,
141
+ filename: str = "",
142
+ ) -> bool:
143
+ if not ABCLI_S3_OBJECT_PREFIX:
144
+ logger.error("ABCLI_S3_OBJECT_PREFIX is not set.")
145
+ return False
146
+
147
+ if not object_name:
148
+ logger.error("object_name not found.")
149
+ return False
150
+
151
+ return (
152
+ shell(
153
+ "aws s3 cp {} {}/{}/".format(
154
+ path_of(filename=filename, object_name=object_name),
155
+ ABCLI_S3_OBJECT_PREFIX,
156
+ object_name,
157
+ )
158
+ )
159
+ if filename
160
+ else shell(
161
+ "aws s3 sync {} {}/{}/".format(
162
+ object_path(object_name, create=True),
163
+ ABCLI_S3_OBJECT_PREFIX,
164
+ object_name,
165
+ )
166
+ )
167
+ )
bluer_objects/path.py ADDED
@@ -0,0 +1,194 @@
1
+ import os
2
+ from typing import Any, Union, List
3
+ import pathlib
4
+ import shutil
5
+
6
+ from blueness import module
7
+ from blue_options import string
8
+ from blue_options.logger import crash_report
9
+
10
+ from bluer_objects import NAME
11
+ from bluer_objects.logger import logger
12
+ from bluer_objects.env import abcli_object_path
13
+
14
+
15
+ NAME = module.name(__file__, NAME)
16
+
17
+
18
+ def absolute(
19
+ path: str,
20
+ reference: Union[None, str] = None,
21
+ ):
22
+ if reference is None:
23
+ reference = current()
24
+ assert isinstance(reference, str)
25
+
26
+ path = path.replace("/", os.sep)
27
+ reference = reference.replace("/", os.sep)
28
+
29
+ return (
30
+ reference
31
+ if not path
32
+ else (
33
+ path
34
+ if path[0] != "."
35
+ else str(pathlib.Path(os.path.join(reference, path)).resolve())
36
+ )
37
+ )
38
+
39
+
40
+ def auxiliary(
41
+ nickname: str,
42
+ add_timestamp: bool = True,
43
+ ):
44
+ path = os.path.join(
45
+ abcli_object_path,
46
+ "auxiliary",
47
+ "-".join(
48
+ [nickname]
49
+ + (
50
+ [
51
+ string.pretty_date(
52
+ as_filename=True,
53
+ squeeze=True,
54
+ unique=True,
55
+ )
56
+ ]
57
+ if add_timestamp
58
+ else []
59
+ )
60
+ ),
61
+ )
62
+
63
+ assert create(path)
64
+
65
+ return path
66
+
67
+
68
+ def copy(
69
+ source: str,
70
+ destination: str,
71
+ ) -> bool:
72
+ if not create(parent(destination)):
73
+ return False
74
+
75
+ try:
76
+ shutil.copytree(source, destination)
77
+ return True
78
+ except:
79
+ crash_report(f"{NAME}: copy({source},{destination}): failed.")
80
+ return False
81
+
82
+
83
+ def create(
84
+ path: str,
85
+ log: bool = False,
86
+ ) -> bool:
87
+ if not path or exists(path):
88
+ return True
89
+
90
+ try:
91
+ os.makedirs(path)
92
+ except:
93
+ crash_report(f"{NAME}: create({path}): failed.")
94
+ return False
95
+
96
+ if log:
97
+ logger.info(f"{NAME}.create({path})")
98
+
99
+ return True
100
+
101
+
102
+ def current() -> str:
103
+ return os.getcwd()
104
+
105
+
106
+ def delete(
107
+ path: str,
108
+ ) -> bool:
109
+ try:
110
+ # https://docs.python.org/3/library/shutil.html#shutil.rmtree
111
+ shutil.rmtree(path)
112
+ return True
113
+ except:
114
+ crash_report(f"{NAME}: delete({path}): failed.")
115
+ return False
116
+
117
+
118
+ def exists(path: str) -> bool:
119
+ return os.path.exists(path) and os.path.isdir(path)
120
+
121
+
122
+ def list_of(
123
+ path: str,
124
+ recursive: bool = False,
125
+ ) -> List[str]:
126
+ if not exists(path):
127
+ return []
128
+
129
+ # http://stackabuse.com/python-list-files-in-a-directory/
130
+ output = []
131
+ try:
132
+ for entry in os.scandir(path):
133
+ if entry.is_file():
134
+ continue
135
+
136
+ path_name = os.path.join(path, entry.name)
137
+
138
+ output.append(path_name)
139
+
140
+ if recursive:
141
+ output += list_of(path_name, recursive=recursive)
142
+ except:
143
+ crash_report(f"-{NAME}: list_of({path}): failed.")
144
+
145
+ return output
146
+
147
+
148
+ def move(
149
+ source: str,
150
+ destination: str,
151
+ ) -> bool:
152
+ if not create(parent(destination)):
153
+ return False
154
+
155
+ try:
156
+ shutil.move(source, destination)
157
+ return True
158
+ except:
159
+ crash_report(f"{NAME}: move({source},{destination}): failed.")
160
+ return False
161
+
162
+
163
+ def name(path: str) -> str:
164
+ if not path:
165
+ return path
166
+
167
+ if path[-1] == os.sep:
168
+ path = path[:-1]
169
+
170
+ path_components = path.split(os.sep)
171
+ return "" if not path_components else path_components[-1]
172
+
173
+
174
+ def parent(
175
+ path: str,
176
+ depth: int = 1,
177
+ ) -> str:
178
+ # Add os.sep at the end of path, if it already does not exist.
179
+ if path:
180
+ if path[-1] != os.sep:
181
+ path = path + os.sep
182
+
183
+ return os.sep.join(path.split(os.sep)[: -depth - 1]) + os.sep
184
+
185
+
186
+ def relative(
187
+ path: str,
188
+ reference: Union[Any, str] = None,
189
+ ):
190
+ # https://stackoverflow.com/a/918174
191
+ return os.path.relpath(
192
+ path,
193
+ current() if reference is None else reference,
194
+ )
@@ -0,0 +1,16 @@
1
+ # to complete the `rds` section create a database as follows:
2
+ # go to `AWS Management Console` -> `RDS` -> `Create database`.
3
+ # use `Standard Create` -> `MySQL` -> `MySQL 8.0.20` -> `Dev/Test`.
4
+ # set `DB instance identifier` to `abcli`.
5
+ # set `Credentials Settings` -> `Master username` and `Master Password` and update `host`, `username`, and `password` here.
6
+ # set `DB instance size` to `Burstable Classes` and select `db.t3.small`.
7
+ # set `Storage` to `20` and disable `Storage autoscaling`.
8
+ # in `Connectivity` set `Public Access` to `Yes`.
9
+ # in `Additional Configuration` set `initial database name` to `abcli`.
10
+ ABCLI_AWS_RDS_HOST=
11
+ ABCLI_AWS_RDS_PASSWORD=
12
+
13
+ # https://docs.databricks.com/en/mlflow/tracking.html
14
+ # https://docs.databricks.com/en/dev-tools/auth/pat.html#databricks-personal-access-tokens-for-workspace-users
15
+ DATABRICKS_HOST=
16
+ DATABRICKS_TOKEN=
@@ -0,0 +1,3 @@
1
+ from bluer_objects.storage.classes import Storage
2
+
3
+ instance = Storage()