ob-metaflow-extensions 1.1.151__py2.py3-none-any.whl → 1.6.2__py2.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 (92) hide show
  1. metaflow_extensions/outerbounds/__init__.py +1 -1
  2. metaflow_extensions/outerbounds/plugins/__init__.py +24 -3
  3. metaflow_extensions/outerbounds/plugins/apps/app_cli.py +0 -0
  4. metaflow_extensions/outerbounds/plugins/apps/core/__init__.py +16 -0
  5. metaflow_extensions/outerbounds/plugins/apps/core/_state_machine.py +506 -0
  6. metaflow_extensions/outerbounds/plugins/apps/core/_vendor/__init__.py +0 -0
  7. metaflow_extensions/outerbounds/plugins/apps/core/_vendor/spinner/__init__.py +4 -0
  8. metaflow_extensions/outerbounds/plugins/apps/core/_vendor/spinner/spinners.py +478 -0
  9. metaflow_extensions/outerbounds/plugins/apps/core/app_config.py +128 -0
  10. metaflow_extensions/outerbounds/plugins/apps/core/app_deploy_decorator.py +333 -0
  11. metaflow_extensions/outerbounds/plugins/apps/core/artifacts.py +0 -0
  12. metaflow_extensions/outerbounds/plugins/apps/core/capsule.py +1029 -0
  13. metaflow_extensions/outerbounds/plugins/apps/core/click_importer.py +24 -0
  14. metaflow_extensions/outerbounds/plugins/apps/core/code_package/__init__.py +3 -0
  15. metaflow_extensions/outerbounds/plugins/apps/core/code_package/code_packager.py +618 -0
  16. metaflow_extensions/outerbounds/plugins/apps/core/code_package/examples.py +125 -0
  17. metaflow_extensions/outerbounds/plugins/apps/core/config/__init__.py +15 -0
  18. metaflow_extensions/outerbounds/plugins/apps/core/config/cli_generator.py +165 -0
  19. metaflow_extensions/outerbounds/plugins/apps/core/config/config_utils.py +966 -0
  20. metaflow_extensions/outerbounds/plugins/apps/core/config/schema_export.py +299 -0
  21. metaflow_extensions/outerbounds/plugins/apps/core/config/typed_configs.py +233 -0
  22. metaflow_extensions/outerbounds/plugins/apps/core/config/typed_init_generator.py +537 -0
  23. metaflow_extensions/outerbounds/plugins/apps/core/config/unified_config.py +1125 -0
  24. metaflow_extensions/outerbounds/plugins/apps/core/config_schema.yaml +337 -0
  25. metaflow_extensions/outerbounds/plugins/apps/core/dependencies.py +115 -0
  26. metaflow_extensions/outerbounds/plugins/apps/core/deployer.py +1300 -0
  27. metaflow_extensions/outerbounds/plugins/apps/core/exceptions.py +341 -0
  28. metaflow_extensions/outerbounds/plugins/apps/core/experimental/__init__.py +89 -0
  29. metaflow_extensions/outerbounds/plugins/apps/core/perimeters.py +123 -0
  30. metaflow_extensions/outerbounds/plugins/apps/core/secrets.py +164 -0
  31. metaflow_extensions/outerbounds/plugins/apps/core/utils.py +233 -0
  32. metaflow_extensions/outerbounds/plugins/apps/core/validations.py +17 -0
  33. metaflow_extensions/outerbounds/plugins/aws/__init__.py +4 -0
  34. metaflow_extensions/outerbounds/plugins/aws/assume_role.py +3 -0
  35. metaflow_extensions/outerbounds/plugins/aws/assume_role_decorator.py +118 -0
  36. metaflow_extensions/outerbounds/plugins/checkpoint_datastores/coreweave.py +9 -77
  37. metaflow_extensions/outerbounds/plugins/checkpoint_datastores/external_chckpt.py +85 -0
  38. metaflow_extensions/outerbounds/plugins/checkpoint_datastores/nebius.py +7 -78
  39. metaflow_extensions/outerbounds/plugins/fast_bakery/baker.py +119 -0
  40. metaflow_extensions/outerbounds/plugins/fast_bakery/docker_environment.py +17 -3
  41. metaflow_extensions/outerbounds/plugins/fast_bakery/fast_bakery.py +1 -0
  42. metaflow_extensions/outerbounds/plugins/kubernetes/kubernetes_client.py +18 -44
  43. metaflow_extensions/outerbounds/plugins/kubernetes/pod_killer.py +374 -0
  44. metaflow_extensions/outerbounds/plugins/nim/card.py +1 -6
  45. metaflow_extensions/outerbounds/plugins/nim/{__init__.py → nim_decorator.py} +13 -49
  46. metaflow_extensions/outerbounds/plugins/nim/nim_manager.py +294 -233
  47. metaflow_extensions/outerbounds/plugins/nim/utils.py +36 -0
  48. metaflow_extensions/outerbounds/plugins/nvcf/constants.py +2 -2
  49. metaflow_extensions/outerbounds/plugins/nvct/nvct_decorator.py +32 -8
  50. metaflow_extensions/outerbounds/plugins/nvct/nvct_runner.py +1 -1
  51. metaflow_extensions/outerbounds/plugins/ollama/__init__.py +171 -16
  52. metaflow_extensions/outerbounds/plugins/ollama/constants.py +1 -0
  53. metaflow_extensions/outerbounds/plugins/ollama/exceptions.py +22 -0
  54. metaflow_extensions/outerbounds/plugins/ollama/ollama.py +1710 -114
  55. metaflow_extensions/outerbounds/plugins/ollama/status_card.py +292 -0
  56. metaflow_extensions/outerbounds/plugins/optuna/__init__.py +49 -0
  57. metaflow_extensions/outerbounds/plugins/profilers/simple_card_decorator.py +96 -0
  58. metaflow_extensions/outerbounds/plugins/s3_proxy/__init__.py +7 -0
  59. metaflow_extensions/outerbounds/plugins/s3_proxy/binary_caller.py +132 -0
  60. metaflow_extensions/outerbounds/plugins/s3_proxy/constants.py +11 -0
  61. metaflow_extensions/outerbounds/plugins/s3_proxy/exceptions.py +13 -0
  62. metaflow_extensions/outerbounds/plugins/s3_proxy/proxy_bootstrap.py +59 -0
  63. metaflow_extensions/outerbounds/plugins/s3_proxy/s3_proxy_api.py +93 -0
  64. metaflow_extensions/outerbounds/plugins/s3_proxy/s3_proxy_decorator.py +250 -0
  65. metaflow_extensions/outerbounds/plugins/s3_proxy/s3_proxy_manager.py +225 -0
  66. metaflow_extensions/outerbounds/plugins/snowflake/snowflake.py +37 -7
  67. metaflow_extensions/outerbounds/plugins/snowpark/snowpark.py +18 -8
  68. metaflow_extensions/outerbounds/plugins/snowpark/snowpark_cli.py +6 -0
  69. metaflow_extensions/outerbounds/plugins/snowpark/snowpark_client.py +45 -18
  70. metaflow_extensions/outerbounds/plugins/snowpark/snowpark_decorator.py +18 -9
  71. metaflow_extensions/outerbounds/plugins/snowpark/snowpark_job.py +10 -4
  72. metaflow_extensions/outerbounds/plugins/torchtune/__init__.py +163 -0
  73. metaflow_extensions/outerbounds/plugins/vllm/__init__.py +255 -0
  74. metaflow_extensions/outerbounds/plugins/vllm/constants.py +1 -0
  75. metaflow_extensions/outerbounds/plugins/vllm/exceptions.py +1 -0
  76. metaflow_extensions/outerbounds/plugins/vllm/status_card.py +352 -0
  77. metaflow_extensions/outerbounds/plugins/vllm/vllm_manager.py +621 -0
  78. metaflow_extensions/outerbounds/remote_config.py +46 -9
  79. metaflow_extensions/outerbounds/toplevel/apps/__init__.py +9 -0
  80. metaflow_extensions/outerbounds/toplevel/apps/exceptions.py +11 -0
  81. metaflow_extensions/outerbounds/toplevel/global_aliases_for_metaflow_package.py +86 -2
  82. metaflow_extensions/outerbounds/toplevel/ob_internal.py +4 -0
  83. metaflow_extensions/outerbounds/toplevel/plugins/optuna/__init__.py +1 -0
  84. metaflow_extensions/outerbounds/toplevel/plugins/torchtune/__init__.py +1 -0
  85. metaflow_extensions/outerbounds/toplevel/plugins/vllm/__init__.py +1 -0
  86. metaflow_extensions/outerbounds/toplevel/s3_proxy.py +88 -0
  87. {ob_metaflow_extensions-1.1.151.dist-info → ob_metaflow_extensions-1.6.2.dist-info}/METADATA +2 -2
  88. ob_metaflow_extensions-1.6.2.dist-info/RECORD +136 -0
  89. metaflow_extensions/outerbounds/plugins/nim/utilities.py +0 -5
  90. ob_metaflow_extensions-1.1.151.dist-info/RECORD +0 -74
  91. {ob_metaflow_extensions-1.1.151.dist-info → ob_metaflow_extensions-1.6.2.dist-info}/WHEEL +0 -0
  92. {ob_metaflow_extensions-1.1.151.dist-info → ob_metaflow_extensions-1.6.2.dist-info}/top_level.txt +0 -0
@@ -0,0 +1,478 @@
1
+ # -*- coding: utf-8 -*-
2
+ """
3
+ Python wrapper for beautiful terminal spinner library.
4
+
5
+ Spinners are from:
6
+ * cli-spinners:
7
+ MIT License
8
+
9
+ Copyright (c) Sindre Sorhus <sindresorhus@gmail.com> (sindresorhus.com)
10
+
11
+ Permission is hereby granted, free of charge, to any person obtaining a copy
12
+ of this software and associated documentation files (the "Software"), to deal
13
+ in the Software without restriction, including without limitation the rights to
14
+ use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
15
+ the Software, and to permit persons to whom the Software is furnished to do so,
16
+ subject to the following conditions:
17
+
18
+ The above copyright notice and this permission notice shall be included
19
+ in all copies or substantial portions of the Software.
20
+
21
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED,
22
+ INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR
23
+ PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE
24
+ FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
25
+ ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
26
+ IN THE SOFTWARE.
27
+ """
28
+ from __future__ import unicode_literals
29
+
30
+ from enum import Enum
31
+
32
+ Spinners = Enum(
33
+ "Spinners",
34
+ {
35
+ "dots": {
36
+ "interval": 80,
37
+ "frames": ["⠋", "⠙", "⠹", "⠸", "⠼", "⠴", "⠦", "⠧", "⠇", "⠏"],
38
+ },
39
+ "dots2": {"interval": 80, "frames": ["⣾", "⣽", "⣻", "⢿", "⡿", "⣟", "⣯", "⣷"]},
40
+ "dots3": {
41
+ "interval": 80,
42
+ "frames": ["⠋", "⠙", "⠚", "⠞", "⠖", "⠦", "⠴", "⠲", "⠳", "⠓"],
43
+ },
44
+ "dots4": {
45
+ "interval": 80,
46
+ "frames": [
47
+ "⠄",
48
+ "⠆",
49
+ "⠇",
50
+ "⠋",
51
+ "⠙",
52
+ "⠸",
53
+ "⠰",
54
+ "⠠",
55
+ "⠰",
56
+ "⠸",
57
+ "⠙",
58
+ "⠋",
59
+ "⠇",
60
+ "⠆",
61
+ ],
62
+ },
63
+ "dots5": {
64
+ "interval": 80,
65
+ "frames": [
66
+ "⠋",
67
+ "⠙",
68
+ "⠚",
69
+ "⠒",
70
+ "⠂",
71
+ "⠂",
72
+ "⠒",
73
+ "⠲",
74
+ "⠴",
75
+ "⠦",
76
+ "⠖",
77
+ "⠒",
78
+ "⠐",
79
+ "⠐",
80
+ "⠒",
81
+ "⠓",
82
+ "⠋",
83
+ ],
84
+ },
85
+ "dots6": {
86
+ "interval": 80,
87
+ "frames": [
88
+ "⠁",
89
+ "⠉",
90
+ "⠙",
91
+ "⠚",
92
+ "⠒",
93
+ "⠂",
94
+ "⠂",
95
+ "⠒",
96
+ "⠲",
97
+ "⠴",
98
+ "⠤",
99
+ "⠄",
100
+ "⠄",
101
+ "⠤",
102
+ "⠴",
103
+ "⠲",
104
+ "⠒",
105
+ "⠂",
106
+ "⠂",
107
+ "⠒",
108
+ "⠚",
109
+ "⠙",
110
+ "⠉",
111
+ "⠁",
112
+ ],
113
+ },
114
+ "dots7": {
115
+ "interval": 80,
116
+ "frames": [
117
+ "⠈",
118
+ "⠉",
119
+ "⠋",
120
+ "⠓",
121
+ "⠒",
122
+ "⠐",
123
+ "⠐",
124
+ "⠒",
125
+ "⠖",
126
+ "⠦",
127
+ "⠤",
128
+ "⠠",
129
+ "⠠",
130
+ "⠤",
131
+ "⠦",
132
+ "⠖",
133
+ "⠒",
134
+ "⠐",
135
+ "⠐",
136
+ "⠒",
137
+ "⠓",
138
+ "⠋",
139
+ "⠉",
140
+ "⠈",
141
+ ],
142
+ },
143
+ "dots8": {
144
+ "interval": 80,
145
+ "frames": [
146
+ "⠁",
147
+ "⠁",
148
+ "⠉",
149
+ "⠙",
150
+ "⠚",
151
+ "⠒",
152
+ "⠂",
153
+ "⠂",
154
+ "⠒",
155
+ "⠲",
156
+ "⠴",
157
+ "⠤",
158
+ "⠄",
159
+ "⠄",
160
+ "⠤",
161
+ "⠠",
162
+ "⠠",
163
+ "⠤",
164
+ "⠦",
165
+ "⠖",
166
+ "⠒",
167
+ "⠐",
168
+ "⠐",
169
+ "⠒",
170
+ "⠓",
171
+ "⠋",
172
+ "⠉",
173
+ "⠈",
174
+ "⠈",
175
+ ],
176
+ },
177
+ "dots9": {"interval": 80, "frames": ["⢹", "⢺", "⢼", "⣸", "⣇", "⡧", "⡗", "⡏"]},
178
+ "dots10": {"interval": 80, "frames": ["⢄", "⢂", "⢁", "⡁", "⡈", "⡐", "⡠"]},
179
+ "dots11": {"interval": 100, "frames": ["⠁", "⠂", "⠄", "⡀", "⢀", "⠠", "⠐", "⠈"]},
180
+ "dots12": {
181
+ "interval": 80,
182
+ "frames": [
183
+ "⢀⠀",
184
+ "⡀⠀",
185
+ "⠄⠀",
186
+ "⢂⠀",
187
+ "⡂⠀",
188
+ "⠅⠀",
189
+ "⢃⠀",
190
+ "⡃⠀",
191
+ "⠍⠀",
192
+ "⢋⠀",
193
+ "⡋⠀",
194
+ "⠍⠁",
195
+ "⢋⠁",
196
+ "⡋⠁",
197
+ "⠍⠉",
198
+ "⠋⠉",
199
+ "⠋⠉",
200
+ "⠉⠙",
201
+ "⠉⠙",
202
+ "⠉⠩",
203
+ "⠈⢙",
204
+ "⠈⡙",
205
+ "⢈⠩",
206
+ "⡀⢙",
207
+ "⠄⡙",
208
+ "⢂⠩",
209
+ "⡂⢘",
210
+ "⠅⡘",
211
+ "⢃⠨",
212
+ "⡃⢐",
213
+ "⠍⡐",
214
+ "⢋⠠",
215
+ "⡋⢀",
216
+ "⠍⡁",
217
+ "⢋⠁",
218
+ "⡋⠁",
219
+ "⠍⠉",
220
+ "⠋⠉",
221
+ "⠋⠉",
222
+ "⠉⠙",
223
+ "⠉⠙",
224
+ "⠉⠩",
225
+ "⠈⢙",
226
+ "⠈⡙",
227
+ "⠈⠩",
228
+ "⠀⢙",
229
+ "⠀⡙",
230
+ "⠀⠩",
231
+ "⠀⢘",
232
+ "⠀⡘",
233
+ "⠀⠨",
234
+ "⠀⢐",
235
+ "⠀⡐",
236
+ "⠀⠠",
237
+ "⠀⢀",
238
+ "⠀⡀",
239
+ ],
240
+ },
241
+ "line": {"interval": 130, "frames": ["-", "\\", "|", "/"]},
242
+ "line2": {"interval": 100, "frames": ["⠂", "-", "–", "—", "–", "-"]},
243
+ "pipe": {"interval": 100, "frames": ["┤", "┘", "┴", "└", "├", "┌", "┬", "┐"]},
244
+ "simpleDots": {"interval": 400, "frames": [". ", ".. ", "...", " "]},
245
+ "simpleDotsScrolling": {
246
+ "interval": 200,
247
+ "frames": [". ", ".. ", "...", " ..", " .", " "],
248
+ },
249
+ "star": {"interval": 70, "frames": ["✶", "✸", "✹", "✺", "✹", "✷"]},
250
+ "star2": {"interval": 80, "frames": ["+", "x", "*"]},
251
+ "flip": {
252
+ "interval": 70,
253
+ "frames": ["_", "_", "_", "-", "`", "`", "'", "´", "-", "_", "_", "_"],
254
+ },
255
+ "hamburger": {"interval": 100, "frames": ["☱", "☲", "☴"]},
256
+ "growVertical": {
257
+ "interval": 120,
258
+ "frames": ["▁", "▃", "▄", "▅", "▆", "▇", "▆", "▅", "▄", "▃"],
259
+ },
260
+ "growHorizontal": {
261
+ "interval": 120,
262
+ "frames": ["▏", "▎", "▍", "▌", "▋", "▊", "▉", "▊", "▋", "▌", "▍", "▎"],
263
+ },
264
+ "balloon": {"interval": 140, "frames": [" ", ".", "o", "O", "@", "*", " "]},
265
+ "balloon2": {"interval": 120, "frames": [".", "o", "O", "°", "O", "o", "."]},
266
+ "noise": {"interval": 100, "frames": ["▓", "▒", "░"]},
267
+ "bounce": {"interval": 120, "frames": ["⠁", "⠂", "⠄", "⠂"]},
268
+ "boxBounce": {"interval": 120, "frames": ["▖", "▘", "▝", "▗"]},
269
+ "boxBounce2": {"interval": 100, "frames": ["▌", "▀", "▐", "▄"]},
270
+ "triangle": {"interval": 50, "frames": ["◢", "◣", "◤", "◥"]},
271
+ "arc": {"interval": 100, "frames": ["◜", "◠", "◝", "◞", "◡", "◟"]},
272
+ "circle": {"interval": 120, "frames": ["◡", "⊙", "◠"]},
273
+ "squareCorners": {"interval": 180, "frames": ["◰", "◳", "◲", "◱"]},
274
+ "circleQuarters": {"interval": 120, "frames": ["◴", "◷", "◶", "◵"]},
275
+ "circleHalves": {"interval": 50, "frames": ["◐", "◓", "◑", "◒"]},
276
+ "squish": {"interval": 100, "frames": ["╫", "╪"]},
277
+ "toggle": {"interval": 250, "frames": ["⊶", "⊷"]},
278
+ "toggle2": {"interval": 80, "frames": ["▫", "▪"]},
279
+ "toggle3": {"interval": 120, "frames": ["□", "■"]},
280
+ "toggle4": {"interval": 100, "frames": ["■", "□", "▪", "▫"]},
281
+ "toggle5": {"interval": 100, "frames": ["▮", "▯"]},
282
+ "toggle6": {"interval": 300, "frames": ["ဝ", "၀"]},
283
+ "toggle7": {"interval": 80, "frames": ["⦾", "⦿"]},
284
+ "toggle8": {"interval": 100, "frames": ["◍", "◌"]},
285
+ "toggle9": {"interval": 100, "frames": ["◉", "◎"]},
286
+ "toggle10": {"interval": 100, "frames": ["㊂", "㊀", "㊁"]},
287
+ "toggle11": {"interval": 50, "frames": ["⧇", "⧆"]},
288
+ "toggle12": {"interval": 120, "frames": ["☗", "☖"]},
289
+ "toggle13": {"interval": 80, "frames": ["=", "*", "-"]},
290
+ "arrow": {"interval": 100, "frames": ["←", "↖", "↑", "↗", "→", "↘", "↓", "↙"]},
291
+ "arrow2": {
292
+ "interval": 80,
293
+ "frames": ["⬆️ ", "↗️ ", "➡️ ", "↘️ ", "⬇️ ", "↙️ ", "⬅️ ", "↖️ "],
294
+ },
295
+ "arrow3": {
296
+ "interval": 120,
297
+ "frames": ["▹▹▹▹▹", "▸▹▹▹▹", "▹▸▹▹▹", "▹▹▸▹▹", "▹▹▹▸▹", "▹▹▹▹▸"],
298
+ },
299
+ "bouncingBar": {
300
+ "interval": 80,
301
+ "frames": [
302
+ "[ ]",
303
+ "[= ]",
304
+ "[== ]",
305
+ "[=== ]",
306
+ "[ ===]",
307
+ "[ ==]",
308
+ "[ =]",
309
+ "[ ]",
310
+ "[ =]",
311
+ "[ ==]",
312
+ "[ ===]",
313
+ "[====]",
314
+ "[=== ]",
315
+ "[== ]",
316
+ "[= ]",
317
+ ],
318
+ },
319
+ "bouncingBall": {
320
+ "interval": 80,
321
+ "frames": [
322
+ "( ● )",
323
+ "( ● )",
324
+ "( ● )",
325
+ "( ● )",
326
+ "( ●)",
327
+ "( ● )",
328
+ "( ● )",
329
+ "( ● )",
330
+ "( ● )",
331
+ "(● )",
332
+ ],
333
+ },
334
+ "smiley": {"interval": 200, "frames": ["😄 ", "😝 "]},
335
+ "monkey": {"interval": 300, "frames": ["🙈 ", "🙈 ", "🙉 ", "🙊 "]},
336
+ "hearts": {"interval": 100, "frames": ["💛 ", "💙 ", "💜 ", "💚 ", "❤️ "]},
337
+ "clock": {
338
+ "interval": 100,
339
+ "frames": [
340
+ "🕛 ",
341
+ "🕐 ",
342
+ "🕑 ",
343
+ "🕒 ",
344
+ "🕓 ",
345
+ "🕔 ",
346
+ "🕕 ",
347
+ "🕖 ",
348
+ "🕗 ",
349
+ "🕘 ",
350
+ "🕙 ",
351
+ "🕚 ",
352
+ ],
353
+ },
354
+ "earth": {"interval": 180, "frames": ["🌍 ", "🌎 ", "🌏 "]},
355
+ "moon": {
356
+ "interval": 80,
357
+ "frames": ["🌑 ", "🌒 ", "🌓 ", "🌔 ", "🌕 ", "🌖 ", "🌗 ", "🌘 "],
358
+ },
359
+ "runner": {"interval": 140, "frames": ["🚶 ", "🏃 "]},
360
+ "pong": {
361
+ "interval": 80,
362
+ "frames": [
363
+ "▐⠂ ▌",
364
+ "▐⠈ ▌",
365
+ "▐ ⠂ ▌",
366
+ "▐ ⠠ ▌",
367
+ "▐ ⡀ ▌",
368
+ "▐ ⠠ ▌",
369
+ "▐ ⠂ ▌",
370
+ "▐ ⠈ ▌",
371
+ "▐ ⠂ ▌",
372
+ "▐ ⠠ ▌",
373
+ "▐ ⡀ ▌",
374
+ "▐ ⠠ ▌",
375
+ "▐ ⠂ ▌",
376
+ "▐ ⠈ ▌",
377
+ "▐ ⠂▌",
378
+ "▐ ⠠▌",
379
+ "▐ ⡀▌",
380
+ "▐ ⠠ ▌",
381
+ "▐ ⠂ ▌",
382
+ "▐ ⠈ ▌",
383
+ "▐ ⠂ ▌",
384
+ "▐ ⠠ ▌",
385
+ "▐ ⡀ ▌",
386
+ "▐ ⠠ ▌",
387
+ "▐ ⠂ ▌",
388
+ "▐ ⠈ ▌",
389
+ "▐ ⠂ ▌",
390
+ "▐ ⠠ ▌",
391
+ "▐ ⡀ ▌",
392
+ "▐⠠ ▌",
393
+ ],
394
+ },
395
+ "shark": {
396
+ "interval": 120,
397
+ "frames": [
398
+ "▐|\\____________▌",
399
+ "▐_|\\___________▌",
400
+ "▐__|\\__________▌",
401
+ "▐___|\\_________▌",
402
+ "▐____|\\________▌",
403
+ "▐_____|\\_______▌",
404
+ "▐______|\\______▌",
405
+ "▐_______|\\_____▌",
406
+ "▐________|\\____▌",
407
+ "▐_________|\\___▌",
408
+ "▐__________|\\__▌",
409
+ "▐___________|\\_▌",
410
+ "▐____________|\\▌",
411
+ "▐____________/|▌",
412
+ "▐___________/|_▌",
413
+ "▐__________/|__▌",
414
+ "▐_________/|___▌",
415
+ "▐________/|____▌",
416
+ "▐_______/|_____▌",
417
+ "▐______/|______▌",
418
+ "▐_____/|_______▌",
419
+ "▐____/|________▌",
420
+ "▐___/|_________▌",
421
+ "▐__/|__________▌",
422
+ "▐_/|___________▌",
423
+ "▐/|____________▌",
424
+ ],
425
+ },
426
+ "dqpb": {"interval": 100, "frames": ["d", "q", "p", "b"]},
427
+ "weather": {
428
+ "interval": 100,
429
+ "frames": [
430
+ "☀️ ",
431
+ "☀️ ",
432
+ "☀️ ",
433
+ "🌤 ",
434
+ "⛅️ ",
435
+ "🌥 ",
436
+ "☁️ ",
437
+ "🌧 ",
438
+ "🌨 ",
439
+ "🌧 ",
440
+ "🌨 ",
441
+ "🌧 ",
442
+ "🌨 ",
443
+ "⛈ ",
444
+ "🌨 ",
445
+ "🌧 ",
446
+ "🌨 ",
447
+ "☁️ ",
448
+ "🌥 ",
449
+ "⛅️ ",
450
+ "🌤 ",
451
+ "☀️ ",
452
+ "☀️ ",
453
+ ],
454
+ },
455
+ "christmas": {"interval": 400, "frames": ["🌲", "🎄"]},
456
+ "grenade": {
457
+ "interval": 80,
458
+ "frames": [
459
+ "، ",
460
+ "′ ",
461
+ " ´ ",
462
+ " ‾ ",
463
+ " ⸌",
464
+ " ⸊",
465
+ " |",
466
+ " ⁎",
467
+ " ⁕",
468
+ " ෴ ",
469
+ " ⁓",
470
+ " ",
471
+ " ",
472
+ " ",
473
+ ],
474
+ },
475
+ "point": {"interval": 125, "frames": ["∙∙∙", "●∙∙", "∙●∙", "∙∙●", "∙∙∙"]},
476
+ "layer": {"interval": 150, "frames": ["-", "=", "≡"]},
477
+ },
478
+ )
@@ -0,0 +1,128 @@
1
+ import json
2
+ import os
3
+
4
+ from typing import Dict, Any
5
+ from .config import (
6
+ CoreConfig,
7
+ AuthType,
8
+ MergingNotAllowedFieldsException,
9
+ ConfigValidationFailedException,
10
+ RequiredFieldMissingException,
11
+ )
12
+
13
+ CODE_PACKAGE_PREFIX = "mf.obp-apps"
14
+
15
+ CAPSULE_DEBUG = os.environ.get("OUTERBOUNDS_CAPSULE_DEBUG", False)
16
+
17
+
18
+ class AppConfigError(Exception):
19
+ """Exception raised when app configuration is invalid."""
20
+
21
+ pass
22
+
23
+
24
+ def _try_loading_yaml(file):
25
+ try:
26
+ import yaml
27
+
28
+ return yaml.safe_load(file)
29
+ except ImportError:
30
+ pass
31
+
32
+ try:
33
+ from outerbounds._vendor import yaml
34
+
35
+ return yaml.safe_load(file)
36
+ except ImportError:
37
+ pass
38
+ return None
39
+
40
+
41
+ class AppConfig:
42
+ """Class representing an Outerbounds App configuration."""
43
+
44
+ def __init__(self, core_config: CoreConfig):
45
+ """Initialize configuration from a dictionary."""
46
+ self._core_config = core_config
47
+ self._final_state: Dict[str, Any] = {}
48
+ self.config = {}
49
+
50
+ def set_state(self, key, value):
51
+ self._final_state[key] = value
52
+ return self
53
+
54
+ def get_state(self, key, default=None):
55
+ return self._final_state.get(key, self.get(key, default))
56
+
57
+ def dump_state(self):
58
+ x = {k: v for k, v in self.config.items()}
59
+ for k, v in self._final_state.items():
60
+ x[k] = v
61
+ return x
62
+
63
+ def commit(self):
64
+ try:
65
+ self._core_config.commit()
66
+ self.config = self._core_config.to_dict()
67
+ except RequiredFieldMissingException as e:
68
+ raise AppConfigError(
69
+ "The configuration is missing the following required fields: %s. \n\tException: %s"
70
+ % (e.field_name, e.message)
71
+ )
72
+ except ConfigValidationFailedException as e:
73
+ raise AppConfigError(
74
+ "The configuration is invalid. \n\n\tException: %s" % (e.message)
75
+ )
76
+
77
+ def get(self, key: str, default: Any = None) -> Any:
78
+ """Get a configuration value by key."""
79
+ config_value = self.config.get(key, default)
80
+ if config_value is None:
81
+ return default
82
+ return config_value
83
+
84
+ def to_json(self):
85
+ return json.dumps(self.config, indent=2)
86
+
87
+ def to_yaml(self):
88
+ return self.to_json()
89
+
90
+ def to_dict(self):
91
+ return self.config
92
+
93
+ @classmethod
94
+ def from_file(cls, file_path: str) -> "AppConfig":
95
+ """Create a configuration from a file."""
96
+ if not os.path.exists(file_path):
97
+ raise AppConfigError(f"Configuration file '{file_path}' does not exist.")
98
+
99
+ with open(file_path, "r") as f:
100
+ try:
101
+ config_dict = _try_loading_yaml(f)
102
+ if config_dict is None:
103
+ config_dict = json.load(f)
104
+ except json.JSONDecodeError as e:
105
+ raise AppConfigError(
106
+ "The PyYAML package is not available as a dependency and JSON parsing of the configuration file also failed %s: \n%s"
107
+ % (file_path, str(e))
108
+ )
109
+ except Exception as e:
110
+ raise AppConfigError(f"Failed to parse configuration file: {e}")
111
+
112
+ return cls(CoreConfig.from_dict(config_dict))
113
+
114
+ @classmethod
115
+ def from_cli(cls, options: Dict[str, Any]):
116
+ return cls(CoreConfig.from_cli(options))
117
+
118
+ def update_from_cli_options(self, options):
119
+ cli_options_config = CoreConfig.from_cli(options)
120
+ try:
121
+ self._core_config = CoreConfig.merge_configs(
122
+ self._core_config, cli_options_config
123
+ )
124
+ except MergingNotAllowedFieldsException as e:
125
+ raise AppConfigError(
126
+ "CLI Overrides are not allowed for the following fields: %s. \n\tException: %s"
127
+ % (e.field_name, e.message)
128
+ )