ob-metaflow-extensions 1.1.45rc3__py2.py3-none-any.whl → 1.5.1__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.

Potentially problematic release.


This version of ob-metaflow-extensions might be problematic. Click here for more details.

Files changed (128) hide show
  1. metaflow_extensions/outerbounds/__init__.py +1 -7
  2. metaflow_extensions/outerbounds/config/__init__.py +35 -0
  3. metaflow_extensions/outerbounds/plugins/__init__.py +186 -57
  4. metaflow_extensions/outerbounds/plugins/apps/__init__.py +0 -0
  5. metaflow_extensions/outerbounds/plugins/apps/app_cli.py +0 -0
  6. metaflow_extensions/outerbounds/plugins/apps/app_utils.py +187 -0
  7. metaflow_extensions/outerbounds/plugins/apps/consts.py +3 -0
  8. metaflow_extensions/outerbounds/plugins/apps/core/__init__.py +15 -0
  9. metaflow_extensions/outerbounds/plugins/apps/core/_state_machine.py +506 -0
  10. metaflow_extensions/outerbounds/plugins/apps/core/_vendor/__init__.py +0 -0
  11. metaflow_extensions/outerbounds/plugins/apps/core/_vendor/spinner/__init__.py +4 -0
  12. metaflow_extensions/outerbounds/plugins/apps/core/_vendor/spinner/spinners.py +478 -0
  13. metaflow_extensions/outerbounds/plugins/apps/core/app_config.py +128 -0
  14. metaflow_extensions/outerbounds/plugins/apps/core/app_deploy_decorator.py +330 -0
  15. metaflow_extensions/outerbounds/plugins/apps/core/artifacts.py +0 -0
  16. metaflow_extensions/outerbounds/plugins/apps/core/capsule.py +958 -0
  17. metaflow_extensions/outerbounds/plugins/apps/core/click_importer.py +24 -0
  18. metaflow_extensions/outerbounds/plugins/apps/core/code_package/__init__.py +3 -0
  19. metaflow_extensions/outerbounds/plugins/apps/core/code_package/code_packager.py +618 -0
  20. metaflow_extensions/outerbounds/plugins/apps/core/code_package/examples.py +125 -0
  21. metaflow_extensions/outerbounds/plugins/apps/core/config/__init__.py +15 -0
  22. metaflow_extensions/outerbounds/plugins/apps/core/config/cli_generator.py +165 -0
  23. metaflow_extensions/outerbounds/plugins/apps/core/config/config_utils.py +966 -0
  24. metaflow_extensions/outerbounds/plugins/apps/core/config/schema_export.py +299 -0
  25. metaflow_extensions/outerbounds/plugins/apps/core/config/typed_configs.py +233 -0
  26. metaflow_extensions/outerbounds/plugins/apps/core/config/typed_init_generator.py +537 -0
  27. metaflow_extensions/outerbounds/plugins/apps/core/config/unified_config.py +1125 -0
  28. metaflow_extensions/outerbounds/plugins/apps/core/config_schema.yaml +337 -0
  29. metaflow_extensions/outerbounds/plugins/apps/core/dependencies.py +115 -0
  30. metaflow_extensions/outerbounds/plugins/apps/core/deployer.py +959 -0
  31. metaflow_extensions/outerbounds/plugins/apps/core/experimental/__init__.py +89 -0
  32. metaflow_extensions/outerbounds/plugins/apps/core/perimeters.py +87 -0
  33. metaflow_extensions/outerbounds/plugins/apps/core/secrets.py +164 -0
  34. metaflow_extensions/outerbounds/plugins/apps/core/utils.py +233 -0
  35. metaflow_extensions/outerbounds/plugins/apps/core/validations.py +17 -0
  36. metaflow_extensions/outerbounds/plugins/apps/deploy_decorator.py +201 -0
  37. metaflow_extensions/outerbounds/plugins/apps/supervisord_utils.py +243 -0
  38. metaflow_extensions/outerbounds/plugins/auth_server.py +28 -8
  39. metaflow_extensions/outerbounds/plugins/aws/__init__.py +4 -0
  40. metaflow_extensions/outerbounds/plugins/aws/assume_role.py +3 -0
  41. metaflow_extensions/outerbounds/plugins/aws/assume_role_decorator.py +118 -0
  42. metaflow_extensions/outerbounds/plugins/card_utilities/__init__.py +0 -0
  43. metaflow_extensions/outerbounds/plugins/card_utilities/async_cards.py +142 -0
  44. metaflow_extensions/outerbounds/plugins/card_utilities/extra_components.py +545 -0
  45. metaflow_extensions/outerbounds/plugins/card_utilities/injector.py +70 -0
  46. metaflow_extensions/outerbounds/plugins/checkpoint_datastores/__init__.py +2 -0
  47. metaflow_extensions/outerbounds/plugins/checkpoint_datastores/coreweave.py +71 -0
  48. metaflow_extensions/outerbounds/plugins/checkpoint_datastores/external_chckpt.py +85 -0
  49. metaflow_extensions/outerbounds/plugins/checkpoint_datastores/nebius.py +73 -0
  50. metaflow_extensions/outerbounds/plugins/fast_bakery/__init__.py +0 -0
  51. metaflow_extensions/outerbounds/plugins/fast_bakery/baker.py +110 -0
  52. metaflow_extensions/outerbounds/plugins/fast_bakery/docker_environment.py +391 -0
  53. metaflow_extensions/outerbounds/plugins/fast_bakery/fast_bakery.py +188 -0
  54. metaflow_extensions/outerbounds/plugins/fast_bakery/fast_bakery_cli.py +54 -0
  55. metaflow_extensions/outerbounds/plugins/fast_bakery/fast_bakery_decorator.py +50 -0
  56. metaflow_extensions/outerbounds/plugins/kubernetes/kubernetes_client.py +79 -0
  57. metaflow_extensions/outerbounds/plugins/kubernetes/pod_killer.py +374 -0
  58. metaflow_extensions/outerbounds/plugins/nim/card.py +140 -0
  59. metaflow_extensions/outerbounds/plugins/nim/nim_decorator.py +101 -0
  60. metaflow_extensions/outerbounds/plugins/nim/nim_manager.py +379 -0
  61. metaflow_extensions/outerbounds/plugins/nim/utils.py +36 -0
  62. metaflow_extensions/outerbounds/plugins/nvcf/__init__.py +0 -0
  63. metaflow_extensions/outerbounds/plugins/nvcf/constants.py +3 -0
  64. metaflow_extensions/outerbounds/plugins/nvcf/exceptions.py +94 -0
  65. metaflow_extensions/outerbounds/plugins/nvcf/heartbeat_store.py +178 -0
  66. metaflow_extensions/outerbounds/plugins/nvcf/nvcf.py +417 -0
  67. metaflow_extensions/outerbounds/plugins/nvcf/nvcf_cli.py +280 -0
  68. metaflow_extensions/outerbounds/plugins/nvcf/nvcf_decorator.py +242 -0
  69. metaflow_extensions/outerbounds/plugins/nvcf/utils.py +6 -0
  70. metaflow_extensions/outerbounds/plugins/nvct/__init__.py +0 -0
  71. metaflow_extensions/outerbounds/plugins/nvct/exceptions.py +71 -0
  72. metaflow_extensions/outerbounds/plugins/nvct/nvct.py +131 -0
  73. metaflow_extensions/outerbounds/plugins/nvct/nvct_cli.py +289 -0
  74. metaflow_extensions/outerbounds/plugins/nvct/nvct_decorator.py +286 -0
  75. metaflow_extensions/outerbounds/plugins/nvct/nvct_runner.py +218 -0
  76. metaflow_extensions/outerbounds/plugins/nvct/utils.py +29 -0
  77. metaflow_extensions/outerbounds/plugins/ollama/__init__.py +225 -0
  78. metaflow_extensions/outerbounds/plugins/ollama/constants.py +1 -0
  79. metaflow_extensions/outerbounds/plugins/ollama/exceptions.py +22 -0
  80. metaflow_extensions/outerbounds/plugins/ollama/ollama.py +1924 -0
  81. metaflow_extensions/outerbounds/plugins/ollama/status_card.py +292 -0
  82. metaflow_extensions/outerbounds/plugins/optuna/__init__.py +48 -0
  83. metaflow_extensions/outerbounds/plugins/perimeters.py +19 -5
  84. metaflow_extensions/outerbounds/plugins/profilers/deco_injector.py +70 -0
  85. metaflow_extensions/outerbounds/plugins/profilers/gpu_profile_decorator.py +88 -0
  86. metaflow_extensions/outerbounds/plugins/profilers/simple_card_decorator.py +96 -0
  87. metaflow_extensions/outerbounds/plugins/s3_proxy/__init__.py +7 -0
  88. metaflow_extensions/outerbounds/plugins/s3_proxy/binary_caller.py +132 -0
  89. metaflow_extensions/outerbounds/plugins/s3_proxy/constants.py +11 -0
  90. metaflow_extensions/outerbounds/plugins/s3_proxy/exceptions.py +13 -0
  91. metaflow_extensions/outerbounds/plugins/s3_proxy/proxy_bootstrap.py +59 -0
  92. metaflow_extensions/outerbounds/plugins/s3_proxy/s3_proxy_api.py +93 -0
  93. metaflow_extensions/outerbounds/plugins/s3_proxy/s3_proxy_decorator.py +250 -0
  94. metaflow_extensions/outerbounds/plugins/s3_proxy/s3_proxy_manager.py +225 -0
  95. metaflow_extensions/outerbounds/plugins/secrets/__init__.py +0 -0
  96. metaflow_extensions/outerbounds/plugins/secrets/secrets.py +204 -0
  97. metaflow_extensions/outerbounds/plugins/snowflake/__init__.py +3 -0
  98. metaflow_extensions/outerbounds/plugins/snowflake/snowflake.py +378 -0
  99. metaflow_extensions/outerbounds/plugins/snowpark/__init__.py +0 -0
  100. metaflow_extensions/outerbounds/plugins/snowpark/snowpark.py +309 -0
  101. metaflow_extensions/outerbounds/plugins/snowpark/snowpark_cli.py +277 -0
  102. metaflow_extensions/outerbounds/plugins/snowpark/snowpark_client.py +150 -0
  103. metaflow_extensions/outerbounds/plugins/snowpark/snowpark_decorator.py +273 -0
  104. metaflow_extensions/outerbounds/plugins/snowpark/snowpark_exceptions.py +13 -0
  105. metaflow_extensions/outerbounds/plugins/snowpark/snowpark_job.py +241 -0
  106. metaflow_extensions/outerbounds/plugins/snowpark/snowpark_service_spec.py +259 -0
  107. metaflow_extensions/outerbounds/plugins/tensorboard/__init__.py +50 -0
  108. metaflow_extensions/outerbounds/plugins/torchtune/__init__.py +163 -0
  109. metaflow_extensions/outerbounds/plugins/vllm/__init__.py +255 -0
  110. metaflow_extensions/outerbounds/plugins/vllm/constants.py +1 -0
  111. metaflow_extensions/outerbounds/plugins/vllm/exceptions.py +1 -0
  112. metaflow_extensions/outerbounds/plugins/vllm/status_card.py +352 -0
  113. metaflow_extensions/outerbounds/plugins/vllm/vllm_manager.py +621 -0
  114. metaflow_extensions/outerbounds/profilers/gpu.py +131 -47
  115. metaflow_extensions/outerbounds/remote_config.py +53 -16
  116. metaflow_extensions/outerbounds/toplevel/global_aliases_for_metaflow_package.py +138 -2
  117. metaflow_extensions/outerbounds/toplevel/ob_internal.py +4 -0
  118. metaflow_extensions/outerbounds/toplevel/plugins/ollama/__init__.py +1 -0
  119. metaflow_extensions/outerbounds/toplevel/plugins/optuna/__init__.py +1 -0
  120. metaflow_extensions/outerbounds/toplevel/plugins/snowflake/__init__.py +1 -0
  121. metaflow_extensions/outerbounds/toplevel/plugins/torchtune/__init__.py +1 -0
  122. metaflow_extensions/outerbounds/toplevel/plugins/vllm/__init__.py +1 -0
  123. metaflow_extensions/outerbounds/toplevel/s3_proxy.py +88 -0
  124. {ob_metaflow_extensions-1.1.45rc3.dist-info → ob_metaflow_extensions-1.5.1.dist-info}/METADATA +2 -2
  125. ob_metaflow_extensions-1.5.1.dist-info/RECORD +133 -0
  126. ob_metaflow_extensions-1.1.45rc3.dist-info/RECORD +0 -19
  127. {ob_metaflow_extensions-1.1.45rc3.dist-info → ob_metaflow_extensions-1.5.1.dist-info}/WHEEL +0 -0
  128. {ob_metaflow_extensions-1.1.45rc3.dist-info → ob_metaflow_extensions-1.5.1.dist-info}/top_level.txt +0 -0
@@ -0,0 +1,299 @@
1
+ """
2
+ Schema Export Module for Unified Configuration System
3
+
4
+ This module provides standalone functions to export configuration schemas in various formats:
5
+ - OpenAPI schemas in YAML or JSON format
6
+ - JSON schemas in YAML or JSON format
7
+
8
+ Usage:
9
+ from schema_export import export_schema, to_openapi_schema, to_json_schema, to_dict
10
+
11
+ # Export schema to file
12
+ export_schema(CoreConfig, "schema.yaml")
13
+ export_schema(CoreConfig, "schema.json", schema_type="json", format="json")
14
+
15
+ # Generate schema in memory
16
+ openapi_schema = to_openapi_schema(CoreConfig)
17
+ json_schema = to_json_schema(CoreConfig)
18
+
19
+ # Export config instance to dict
20
+ config_instance = CoreConfig(name="myapp", port=8000)
21
+ config_dict = to_dict(config_instance)
22
+
23
+ No external dependencies required for basic functionality.
24
+ PyYAML is optional for YAML export support.
25
+ """
26
+
27
+ import json
28
+ import textwrap
29
+ from collections import OrderedDict
30
+ from typing import Any, Dict
31
+
32
+ try:
33
+ import yaml
34
+
35
+ HAS_YAML = True
36
+ except ImportError:
37
+ HAS_YAML = False
38
+
39
+
40
+ def to_openapi_schema(config_class) -> Dict[str, Any]:
41
+ """Generate OpenAPI schema for a configuration class.
42
+
43
+ Args:
44
+ config_class: The configuration class to generate schema for
45
+
46
+ Returns:
47
+ OpenAPI schema dictionary
48
+ """
49
+ return _generate_openapi_schema(config_class)
50
+
51
+
52
+ def to_json_schema(config_class) -> Dict[str, Any]:
53
+ """Generate JSON schema for a configuration class.
54
+
55
+ Args:
56
+ config_class: The configuration class to generate schema for
57
+
58
+ Returns:
59
+ JSON schema dictionary
60
+ """
61
+ return _generate_json_schema(config_class)
62
+
63
+
64
+ def export_schema(
65
+ config_class, filepath: str, schema_type: str = "openapi", format: str = "yaml"
66
+ ) -> None:
67
+ """Export configuration schema to file.
68
+
69
+ Args:
70
+ config_class: The configuration class to export schema for
71
+ filepath: Path to save the schema file
72
+ schema_type: Type of schema to generate ('openapi' or 'json')
73
+ format: Output format ('yaml' or 'json')
74
+
75
+ Examples:
76
+ # Export OpenAPI schema as YAML (default)
77
+ export_schema(CoreConfig, "schema.yaml")
78
+
79
+ # Export JSON schema as YAML
80
+ export_schema(CoreConfig, "schema.yaml", schema_type="json")
81
+
82
+ # Export OpenAPI schema as JSON
83
+ export_schema(CoreConfig, "schema.json", schema_type="openapi", format="json")
84
+
85
+ # Export JSON schema as JSON
86
+ export_schema(CoreConfig, "schema.json", schema_type="json", format="json")
87
+ """
88
+ # Validate inputs
89
+ if schema_type.lower() not in ["openapi", "json"]:
90
+ raise ValueError(
91
+ f"Unsupported schema type: {schema_type}. Use 'openapi' or 'json'."
92
+ )
93
+
94
+ if format.lower() not in ["yaml", "json"]:
95
+ raise ValueError(f"Unsupported format: {format}. Use 'yaml' or 'json'.")
96
+
97
+ # Generate the appropriate schema
98
+ if schema_type.lower() == "openapi":
99
+ base_schema = _generate_openapi_schema(config_class)
100
+ # Wrap in OpenAPI document structure with proper ordering
101
+ schema_data = OrderedDict(
102
+ [
103
+ ("openapi", "3.0.0"),
104
+ (
105
+ "info",
106
+ OrderedDict(
107
+ [
108
+ ("title", f"{config_class.__name__} Configuration Schema"),
109
+ ("version", "1.0.0"),
110
+ ]
111
+ ),
112
+ ),
113
+ (
114
+ "components",
115
+ OrderedDict(
116
+ [
117
+ (
118
+ "schemas",
119
+ OrderedDict([(config_class.__name__, base_schema)]),
120
+ )
121
+ ]
122
+ ),
123
+ ),
124
+ ]
125
+ )
126
+ else: # json schema
127
+ schema_data = _generate_json_schema(config_class)
128
+
129
+ # Export in the requested format
130
+ if format.lower() == "yaml":
131
+ if not HAS_YAML:
132
+ raise ImportError(
133
+ "PyYAML is required for YAML export. Install with: pip install pyyaml"
134
+ )
135
+
136
+ # Custom YAML representer for multiline strings
137
+ def multiline_representer(dumper, data):
138
+ if "\n" in data or len(data) > 80:
139
+ style = "|" # use literal block
140
+ else:
141
+ style = None # normal flow
142
+ return dumper.represent_scalar("tag:yaml.org,2002:str", data, style=style)
143
+
144
+ # Custom YAML representer for OrderedDict to preserve order
145
+ def ordered_dict_representer(dumper, data):
146
+ return dumper.represent_dict(data.items())
147
+
148
+ yaml.add_representer(str, multiline_representer)
149
+ yaml.add_representer(OrderedDict, ordered_dict_representer)
150
+
151
+ with open(filepath, "w") as f:
152
+ yaml.dump(
153
+ schema_data,
154
+ f,
155
+ default_flow_style=False,
156
+ sort_keys=False,
157
+ allow_unicode=True,
158
+ width=120,
159
+ indent=2,
160
+ )
161
+ else: # json format
162
+ with open(filepath, "w") as f:
163
+ json.dump(schema_data, f, indent=2)
164
+
165
+
166
+ # Private helper functions
167
+ def _generate_openapi_schema(cls) -> Dict[str, Any]:
168
+ """Generate OpenAPI schema for a configuration class.
169
+
170
+ Note: Schema is intended for CLI/config file usage, so PROGRAMMATIC-only
171
+ fields are excluded.
172
+ """
173
+ # Clean up class docstring for better YAML formatting
174
+ description = f"{cls.__name__} configuration"
175
+ get_description = getattr(cls, "SCHEMA_DOC", None)
176
+ if get_description:
177
+ description = get_description
178
+ elif cls.__doc__:
179
+ # Remove common indentation and clean up whitespace
180
+ cleaned_doc = textwrap.dedent(cls.__doc__).strip()
181
+ # Replace multiple spaces with single spaces but preserve line breaks
182
+ lines = [line.strip() for line in cleaned_doc.split("\n") if line.strip()]
183
+ description = "\n".join(lines)
184
+
185
+ # Create ordered schema with specific order: title, description, type, required, then properties
186
+ schema = OrderedDict(
187
+ [
188
+ ("title", cls.__name__),
189
+ ("description", description),
190
+ ("type", "object"),
191
+ ("required", []),
192
+ ("properties", OrderedDict()),
193
+ ]
194
+ )
195
+
196
+ for field_name, field_info in cls._fields.items():
197
+ if field_name.startswith("_"):
198
+ continue
199
+
200
+ # Skip PROGRAMMATIC-only fields - schema is for CLI/config file usage
201
+ if (
202
+ hasattr(field_info, "is_available_in_cli")
203
+ and not field_info.is_available_in_cli()
204
+ ):
205
+ continue
206
+
207
+ field_schema = _get_field_schema(field_info)
208
+ schema["properties"][field_name] = field_schema
209
+
210
+ # Add to required if field is required
211
+ if field_info.required:
212
+ schema["required"].append(field_name)
213
+
214
+ return schema
215
+
216
+
217
+ def _generate_json_schema(cls) -> Dict[str, Any]:
218
+ """Generate JSON schema for a configuration class."""
219
+ openapi_schema = _generate_openapi_schema(cls)
220
+
221
+ # Create ordered JSON schema with $schema first
222
+ schema = OrderedDict(
223
+ [
224
+ ("$schema", "https://json-schema.org/draft/2020-12/schema"),
225
+ ("title", openapi_schema["title"]),
226
+ ("description", openapi_schema["description"]),
227
+ ("type", openapi_schema["type"]),
228
+ ("required", openapi_schema["required"]),
229
+ ("properties", openapi_schema["properties"]),
230
+ ]
231
+ )
232
+
233
+ return schema
234
+
235
+
236
+ def _get_field_schema(field_info) -> Dict[str, Any]:
237
+ """Generate schema for a single field."""
238
+ field_schema = OrderedDict()
239
+
240
+ # Get description from ConfigField.help first, then CLI metadata
241
+ description = field_info.help or (
242
+ field_info.cli_meta.help if field_info.cli_meta else None
243
+ )
244
+ if description:
245
+ field_schema["description"] = description
246
+
247
+ # Handle field type
248
+ if field_info.field_type == str:
249
+ field_schema["type"] = "string"
250
+ elif field_info.field_type == int:
251
+ field_schema["type"] = "integer"
252
+ elif field_info.field_type == float:
253
+ field_schema["type"] = "number"
254
+ elif field_info.field_type == bool:
255
+ field_schema["type"] = "boolean"
256
+ elif field_info.field_type == list:
257
+ field_schema["type"] = "array"
258
+ field_schema["items"] = {"type": "string"} # Default to string items
259
+ elif field_info.field_type == dict:
260
+ field_schema["type"] = "object"
261
+ field_schema["additionalProperties"] = True
262
+ elif hasattr(field_info.field_type, "_fields"):
263
+ # Nested configuration object
264
+ field_schema = _generate_openapi_schema(field_info.field_type)
265
+ else:
266
+ # Fallback to string for unknown types
267
+ field_schema["type"] = "string"
268
+
269
+ # Add default value
270
+ if field_info.default is not None and not callable(field_info.default):
271
+ field_schema["default"] = field_info.default
272
+
273
+ # Handle choices from CLI metadata
274
+ if field_info.cli_meta and field_info.cli_meta.choices:
275
+ if "type" in field_schema:
276
+ field_schema["enum"] = field_info.cli_meta.choices
277
+
278
+ # Add examples from ConfigField
279
+ if field_info.example is not None:
280
+ field_schema["example"] = field_info.example
281
+
282
+ # Add experimental flag
283
+ if field_info.is_experimental:
284
+ field_schema["experimental"] = True
285
+
286
+ # Add Field Behavior
287
+ if field_info.behavior:
288
+ field_schema["mutation_behavior"] = field_info.behavior
289
+
290
+ if field_info.cli_meta is not None:
291
+ field_schema["cli_option"] = field_info.cli_meta.cli_option_str
292
+
293
+ # Handle validation from CLI metadata
294
+ if field_info.cli_meta and field_info.validation_fn:
295
+ # Add validation hints in description
296
+ if "description" in field_schema:
297
+ field_schema["description"] += " (validation applied)"
298
+
299
+ return field_schema
@@ -0,0 +1,233 @@
1
+ """
2
+ Auto-generated typed classes for ConfigMeta classes.
3
+
4
+ This module provides IDE-friendly typed interfaces for all configuration classes.
5
+ The reason we auto-generate this file is because we want to provide a bridge between what is the ConfigMeta classes and the typed programmatic interface.
6
+ The CoreConfig class is setup in a way that if any additionally params are missed out from being auto-generated then it will not affect the core functionality of the programmatic API.
7
+ The new parameters will just not show up in IDE autocompletions.
8
+ It is fine if this file is not regularly updated by running the script in the .pre-commit-config.app-changes.yaml
9
+ but it is recommended that this file not be deleted or manually edited.
10
+
11
+ """
12
+
13
+ from typing import Optional, List, Dict, Any
14
+ from .unified_config import CoreConfig
15
+
16
+ import sys
17
+ from typing import TYPE_CHECKING
18
+
19
+ # on 3.8+ use the stdlib TypedDict;
20
+ # in TYPE_CHECKING blocks mypy/pyright still pick it up on older Pythons
21
+ if sys.version_info >= (3, 8):
22
+ from typing import TypedDict
23
+ else:
24
+ if TYPE_CHECKING:
25
+ # for the benefit of type-checkers
26
+ from typing import TypedDict # noqa: F401
27
+ # runtime no-op TypedDict shim
28
+ class _TypedDictMeta(type):
29
+ def __new__(cls, name, bases, namespace, total=True):
30
+ # ignore total at runtime
31
+ return super().__new__(cls, name, bases, namespace)
32
+
33
+ class TypedDict(dict, metaclass=_TypedDictMeta):
34
+ # Runtime stand-in for typing.TypedDict on <3.8.
35
+ pass
36
+
37
+
38
+ class ResourceConfigDict(TypedDict, total=False):
39
+ cpu: Optional[str]
40
+ memory: Optional[str]
41
+ gpu: Optional[str]
42
+ disk: Optional[str]
43
+ shared_memory: Optional[str]
44
+
45
+
46
+ class AuthConfigDict(TypedDict, total=False):
47
+ type: Optional[str]
48
+ public: Optional[bool]
49
+
50
+
51
+ class ReplicaConfigDict(TypedDict, total=False):
52
+ fixed: Optional[int]
53
+ min: Optional[int]
54
+ max: Optional[int]
55
+ scaling_policy: Optional["ScalingPolicyConfigDict"]
56
+
57
+
58
+ class ScalingPolicyConfigDict(TypedDict, total=False):
59
+ rpm: Optional[int]
60
+
61
+
62
+ class DependencyConfigDict(TypedDict, total=False):
63
+ from_requirements_file: Optional[str]
64
+ from_pyproject_toml: Optional[str]
65
+ python: Optional[str]
66
+ pypi: Optional[dict]
67
+ conda: Optional[dict]
68
+
69
+
70
+ class PackageConfigDict(TypedDict, total=False):
71
+ src_paths: Optional[list]
72
+ suffixes: Optional[list]
73
+
74
+
75
+ class TypedCoreConfig:
76
+ """
77
+ Parameters
78
+ ----------
79
+ name : str, optional
80
+ The name of the app to deploy.
81
+
82
+ port : int, optional
83
+ Port where the app is hosted. When deployed this will be port on which we will deploy the app.
84
+
85
+ description : str, optional
86
+ The description of the app to deploy.
87
+
88
+ app_type : str, optional
89
+ The User defined type of app to deploy. Its only used for bookkeeping purposes.
90
+
91
+ image : str, optional
92
+ The Docker image to deploy with the App.
93
+
94
+ tags : list, optional
95
+ The tags of the app to deploy.
96
+
97
+ secrets : list, optional
98
+ Outerbounds integrations to attach to the app. You can use the value you set in the `@secrets` decorator in your code.
99
+
100
+ compute_pools : list, optional
101
+ A list of compute pools to deploy the app to.
102
+
103
+ environment : dict, optional
104
+ Environment variables to deploy with the App.
105
+
106
+ commands : list, optional
107
+ A list of commands to run the app with.
108
+
109
+ resources : ResourceConfigDict, optional
110
+ Resource configuration for the app.
111
+ - cpu (str)
112
+ CPU requests
113
+ - memory (str)
114
+ Memory requests
115
+ - gpu (str)
116
+ GPU requests
117
+ - disk (str)
118
+ Storage disk size.
119
+ - shared_memory (str)
120
+ Shared memory
121
+
122
+ auth : AuthConfigDict, optional
123
+ Auth related configurations.
124
+ - type (str)
125
+ The type of authentication to use for the app.
126
+ - public (bool)
127
+ Whether the app is public or not.
128
+
129
+ replicas : ReplicaConfigDict, optional
130
+ The number of replicas to deploy the app with.
131
+ - fixed (int)
132
+ The fixed number of replicas to deploy the app with. If min and max are set, this will raise an error.
133
+ - min (int)
134
+ The minimum number of replicas to deploy the app with.
135
+ - max (int)
136
+ The maximum number of replicas to deploy the app with.
137
+ - scaling_policy (ScalingPolicyConfigDict)
138
+ Scaling policy defines the the metric based on which the replicas will horizontally scale. If min and max replicas are set and are not the same, then a scaling policy will be applied. Default scaling policies can be 60 rpm (ie 1 rps).
139
+ - rpm (int)
140
+ Scale up replicas when the requests per minute crosses this threshold. If nothing is provided and the replicas.max and replicas.min is set then the default rpm would be 60.
141
+
142
+ code_package : tuple, optional
143
+ Pre-packaged code from package_code(). A PackagedCode namedtuple containing url and key.
144
+
145
+ force_upgrade : bool, optional
146
+ Force upgrade the app even if it is currently being upgraded.
147
+
148
+ persistence : str, optional
149
+ The persistence mode to deploy the app with.
150
+ [Experimental] May change in the future.
151
+
152
+ project : str, optional
153
+ The project name to deploy the app to.
154
+ [Experimental] May change in the future.
155
+
156
+ branch : str, optional
157
+ The branch name to deploy the app to.
158
+ [Experimental] May change in the future.
159
+
160
+ models : list, optional
161
+ [Experimental] May change in the future.
162
+
163
+ data : list, optional
164
+ [Experimental] May change in the future.
165
+
166
+ generate_static_url : bool, optional
167
+ Generate a static URL for the app based on its name.
168
+ """
169
+
170
+ def __init__(
171
+ self,
172
+ name: Optional[str] = None,
173
+ port: Optional[int] = None,
174
+ description: Optional[str] = None,
175
+ app_type: Optional[str] = None,
176
+ image: Optional[str] = None,
177
+ tags: Optional[list] = None,
178
+ secrets: Optional[list] = None,
179
+ compute_pools: Optional[list] = None,
180
+ environment: Optional[dict] = None,
181
+ commands: Optional[list] = None,
182
+ resources: Optional[ResourceConfigDict] = None,
183
+ auth: Optional[AuthConfigDict] = None,
184
+ replicas: Optional[ReplicaConfigDict] = None,
185
+ code_package: Optional[tuple] = None,
186
+ force_upgrade: Optional[bool] = None,
187
+ persistence: Optional[str] = None,
188
+ project: Optional[str] = None,
189
+ branch: Optional[str] = None,
190
+ models: Optional[list] = None,
191
+ data: Optional[list] = None,
192
+ generate_static_url: Optional[bool] = None,
193
+ **kwargs
194
+ ) -> None:
195
+ self._kwargs = {
196
+ "name": name,
197
+ "port": port,
198
+ "description": description,
199
+ "app_type": app_type,
200
+ "image": image,
201
+ "tags": tags,
202
+ "secrets": secrets,
203
+ "compute_pools": compute_pools,
204
+ "environment": environment,
205
+ "commands": commands,
206
+ "resources": resources,
207
+ "auth": auth,
208
+ "replicas": replicas,
209
+ "code_package": code_package,
210
+ "force_upgrade": force_upgrade,
211
+ "persistence": persistence,
212
+ "project": project,
213
+ "branch": branch,
214
+ "models": models,
215
+ "data": data,
216
+ "generate_static_url": generate_static_url,
217
+ }
218
+ # Add any additional kwargs
219
+ self._kwargs.update(kwargs)
220
+ # Remove None values
221
+ self._kwargs = {k: v for k, v in self._kwargs.items() if v is not None}
222
+ self._config_class = CoreConfig
223
+ self._config = self.create_config()
224
+ self._init()
225
+
226
+ def create_config(self) -> CoreConfig:
227
+ return CoreConfig.from_dict(self._kwargs)
228
+
229
+ def to_dict(self) -> Dict[str, Any]:
230
+ return self._config.to_dict()
231
+
232
+ def _init(self):
233
+ raise NotImplementedError