ob-metaflow-extensions 1.1.130__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 (105) hide show
  1. metaflow_extensions/outerbounds/__init__.py +1 -1
  2. metaflow_extensions/outerbounds/plugins/__init__.py +34 -4
  3. metaflow_extensions/outerbounds/plugins/apps/__init__.py +0 -0
  4. metaflow_extensions/outerbounds/plugins/apps/app_cli.py +0 -0
  5. metaflow_extensions/outerbounds/plugins/apps/app_utils.py +187 -0
  6. metaflow_extensions/outerbounds/plugins/apps/consts.py +3 -0
  7. metaflow_extensions/outerbounds/plugins/apps/core/__init__.py +15 -0
  8. metaflow_extensions/outerbounds/plugins/apps/core/_state_machine.py +506 -0
  9. metaflow_extensions/outerbounds/plugins/apps/core/_vendor/__init__.py +0 -0
  10. metaflow_extensions/outerbounds/plugins/apps/core/_vendor/spinner/__init__.py +4 -0
  11. metaflow_extensions/outerbounds/plugins/apps/core/_vendor/spinner/spinners.py +478 -0
  12. metaflow_extensions/outerbounds/plugins/apps/core/app_config.py +128 -0
  13. metaflow_extensions/outerbounds/plugins/apps/core/app_deploy_decorator.py +330 -0
  14. metaflow_extensions/outerbounds/plugins/apps/core/artifacts.py +0 -0
  15. metaflow_extensions/outerbounds/plugins/apps/core/capsule.py +958 -0
  16. metaflow_extensions/outerbounds/plugins/apps/core/click_importer.py +24 -0
  17. metaflow_extensions/outerbounds/plugins/apps/core/code_package/__init__.py +3 -0
  18. metaflow_extensions/outerbounds/plugins/apps/core/code_package/code_packager.py +618 -0
  19. metaflow_extensions/outerbounds/plugins/apps/core/code_package/examples.py +125 -0
  20. metaflow_extensions/outerbounds/plugins/apps/core/config/__init__.py +15 -0
  21. metaflow_extensions/outerbounds/plugins/apps/core/config/cli_generator.py +165 -0
  22. metaflow_extensions/outerbounds/plugins/apps/core/config/config_utils.py +966 -0
  23. metaflow_extensions/outerbounds/plugins/apps/core/config/schema_export.py +299 -0
  24. metaflow_extensions/outerbounds/plugins/apps/core/config/typed_configs.py +233 -0
  25. metaflow_extensions/outerbounds/plugins/apps/core/config/typed_init_generator.py +537 -0
  26. metaflow_extensions/outerbounds/plugins/apps/core/config/unified_config.py +1125 -0
  27. metaflow_extensions/outerbounds/plugins/apps/core/config_schema.yaml +337 -0
  28. metaflow_extensions/outerbounds/plugins/apps/core/dependencies.py +115 -0
  29. metaflow_extensions/outerbounds/plugins/apps/core/deployer.py +959 -0
  30. metaflow_extensions/outerbounds/plugins/apps/core/experimental/__init__.py +89 -0
  31. metaflow_extensions/outerbounds/plugins/apps/core/perimeters.py +87 -0
  32. metaflow_extensions/outerbounds/plugins/apps/core/secrets.py +164 -0
  33. metaflow_extensions/outerbounds/plugins/apps/core/utils.py +233 -0
  34. metaflow_extensions/outerbounds/plugins/apps/core/validations.py +17 -0
  35. metaflow_extensions/outerbounds/plugins/apps/deploy_decorator.py +201 -0
  36. metaflow_extensions/outerbounds/plugins/apps/supervisord_utils.py +243 -0
  37. metaflow_extensions/outerbounds/plugins/aws/__init__.py +4 -0
  38. metaflow_extensions/outerbounds/plugins/aws/assume_role.py +3 -0
  39. metaflow_extensions/outerbounds/plugins/aws/assume_role_decorator.py +118 -0
  40. metaflow_extensions/outerbounds/plugins/card_utilities/injector.py +1 -1
  41. metaflow_extensions/outerbounds/plugins/checkpoint_datastores/__init__.py +2 -0
  42. metaflow_extensions/outerbounds/plugins/checkpoint_datastores/coreweave.py +71 -0
  43. metaflow_extensions/outerbounds/plugins/checkpoint_datastores/external_chckpt.py +85 -0
  44. metaflow_extensions/outerbounds/plugins/checkpoint_datastores/nebius.py +73 -0
  45. metaflow_extensions/outerbounds/plugins/fast_bakery/baker.py +110 -0
  46. metaflow_extensions/outerbounds/plugins/fast_bakery/docker_environment.py +43 -9
  47. metaflow_extensions/outerbounds/plugins/fast_bakery/fast_bakery.py +12 -0
  48. metaflow_extensions/outerbounds/plugins/kubernetes/kubernetes_client.py +18 -44
  49. metaflow_extensions/outerbounds/plugins/kubernetes/pod_killer.py +374 -0
  50. metaflow_extensions/outerbounds/plugins/nim/card.py +2 -16
  51. metaflow_extensions/outerbounds/plugins/nim/{__init__.py → nim_decorator.py} +13 -49
  52. metaflow_extensions/outerbounds/plugins/nim/nim_manager.py +294 -233
  53. metaflow_extensions/outerbounds/plugins/nim/utils.py +36 -0
  54. metaflow_extensions/outerbounds/plugins/nvcf/constants.py +2 -2
  55. metaflow_extensions/outerbounds/plugins/nvcf/nvcf.py +100 -19
  56. metaflow_extensions/outerbounds/plugins/nvcf/nvcf_decorator.py +6 -1
  57. metaflow_extensions/outerbounds/plugins/nvct/__init__.py +0 -0
  58. metaflow_extensions/outerbounds/plugins/nvct/exceptions.py +71 -0
  59. metaflow_extensions/outerbounds/plugins/nvct/nvct.py +131 -0
  60. metaflow_extensions/outerbounds/plugins/nvct/nvct_cli.py +289 -0
  61. metaflow_extensions/outerbounds/plugins/nvct/nvct_decorator.py +286 -0
  62. metaflow_extensions/outerbounds/plugins/nvct/nvct_runner.py +218 -0
  63. metaflow_extensions/outerbounds/plugins/nvct/utils.py +29 -0
  64. metaflow_extensions/outerbounds/plugins/ollama/__init__.py +225 -0
  65. metaflow_extensions/outerbounds/plugins/ollama/constants.py +1 -0
  66. metaflow_extensions/outerbounds/plugins/ollama/exceptions.py +22 -0
  67. metaflow_extensions/outerbounds/plugins/ollama/ollama.py +1924 -0
  68. metaflow_extensions/outerbounds/plugins/ollama/status_card.py +292 -0
  69. metaflow_extensions/outerbounds/plugins/optuna/__init__.py +48 -0
  70. metaflow_extensions/outerbounds/plugins/profilers/simple_card_decorator.py +96 -0
  71. metaflow_extensions/outerbounds/plugins/s3_proxy/__init__.py +7 -0
  72. metaflow_extensions/outerbounds/plugins/s3_proxy/binary_caller.py +132 -0
  73. metaflow_extensions/outerbounds/plugins/s3_proxy/constants.py +11 -0
  74. metaflow_extensions/outerbounds/plugins/s3_proxy/exceptions.py +13 -0
  75. metaflow_extensions/outerbounds/plugins/s3_proxy/proxy_bootstrap.py +59 -0
  76. metaflow_extensions/outerbounds/plugins/s3_proxy/s3_proxy_api.py +93 -0
  77. metaflow_extensions/outerbounds/plugins/s3_proxy/s3_proxy_decorator.py +250 -0
  78. metaflow_extensions/outerbounds/plugins/s3_proxy/s3_proxy_manager.py +225 -0
  79. metaflow_extensions/outerbounds/plugins/secrets/secrets.py +38 -2
  80. metaflow_extensions/outerbounds/plugins/snowflake/snowflake.py +81 -11
  81. metaflow_extensions/outerbounds/plugins/snowpark/snowpark.py +18 -8
  82. metaflow_extensions/outerbounds/plugins/snowpark/snowpark_cli.py +6 -0
  83. metaflow_extensions/outerbounds/plugins/snowpark/snowpark_client.py +45 -18
  84. metaflow_extensions/outerbounds/plugins/snowpark/snowpark_decorator.py +18 -9
  85. metaflow_extensions/outerbounds/plugins/snowpark/snowpark_job.py +10 -4
  86. metaflow_extensions/outerbounds/plugins/torchtune/__init__.py +163 -0
  87. metaflow_extensions/outerbounds/plugins/vllm/__init__.py +255 -0
  88. metaflow_extensions/outerbounds/plugins/vllm/constants.py +1 -0
  89. metaflow_extensions/outerbounds/plugins/vllm/exceptions.py +1 -0
  90. metaflow_extensions/outerbounds/plugins/vllm/status_card.py +352 -0
  91. metaflow_extensions/outerbounds/plugins/vllm/vllm_manager.py +621 -0
  92. metaflow_extensions/outerbounds/remote_config.py +46 -9
  93. metaflow_extensions/outerbounds/toplevel/global_aliases_for_metaflow_package.py +94 -2
  94. metaflow_extensions/outerbounds/toplevel/ob_internal.py +4 -0
  95. metaflow_extensions/outerbounds/toplevel/plugins/ollama/__init__.py +1 -0
  96. metaflow_extensions/outerbounds/toplevel/plugins/optuna/__init__.py +1 -0
  97. metaflow_extensions/outerbounds/toplevel/plugins/torchtune/__init__.py +1 -0
  98. metaflow_extensions/outerbounds/toplevel/plugins/vllm/__init__.py +1 -0
  99. metaflow_extensions/outerbounds/toplevel/s3_proxy.py +88 -0
  100. {ob_metaflow_extensions-1.1.130.dist-info → ob_metaflow_extensions-1.5.1.dist-info}/METADATA +2 -2
  101. ob_metaflow_extensions-1.5.1.dist-info/RECORD +133 -0
  102. metaflow_extensions/outerbounds/plugins/nim/utilities.py +0 -5
  103. ob_metaflow_extensions-1.1.130.dist-info/RECORD +0 -56
  104. {ob_metaflow_extensions-1.1.130.dist-info → ob_metaflow_extensions-1.5.1.dist-info}/WHEEL +0 -0
  105. {ob_metaflow_extensions-1.1.130.dist-info → ob_metaflow_extensions-1.5.1.dist-info}/top_level.txt +0 -0
@@ -0,0 +1,125 @@
1
+ """
2
+ Examples demonstrating how to use the code packager abstraction.
3
+
4
+ This file provides usage examples for the code packager classes.
5
+ These examples are for documentation purposes and are not meant to be run directly.
6
+ """
7
+
8
+ import os
9
+ import sys
10
+ from io import BytesIO
11
+ from typing import List, Dict, Any, Callable, Optional
12
+
13
+ from .code_packager import CodePackager
14
+
15
+
16
+ def basic_usage_example(datastore_type: str = "s3") -> None:
17
+ """
18
+ Basic usage example with ContentAddressedStore.
19
+
20
+ This example shows how to:
21
+ 1. Define paths to include in a package
22
+ 2. Create a package using CodePackager's default packaging
23
+ 3. Store the package using ContentAddressedStore directly
24
+ 4. Generate a download command
25
+
26
+ Parameters
27
+ ----------
28
+ datastore_type : str, default "s3"
29
+ The type of datastore to use: "s3", "azure", "gs", or "local"
30
+ """
31
+ # Define the paths to include in the package
32
+ paths_to_include = ["./"]
33
+
34
+ # Define which file suffixes to include
35
+ file_suffixes = [".py", ".md"]
36
+
37
+ # Create metadata for the package
38
+ metadata = {"example": True, "timestamp": "2023-01-01T00:00:00Z"}
39
+
40
+ # Initialize the packager with datastore configuration
41
+ packager = CodePackager(
42
+ datastore_type=datastore_type,
43
+ code_package_prefix="my-custom-prefix", # Optional
44
+ )
45
+
46
+ # Store the package with packaging parameters
47
+ package_url, package_key = packager.store(
48
+ paths_to_include=paths_to_include,
49
+ file_suffixes=file_suffixes,
50
+ metadata=metadata,
51
+ )
52
+
53
+ # Generate a download command
54
+ download_cmd = CodePackager.get_download_cmd(
55
+ package_url=package_url,
56
+ datastore_type=datastore_type,
57
+ target_file="my_package.tar",
58
+ )
59
+
60
+ # Generate complete package commands for downloading and setup
61
+ package_commands = packager.get_package_commands(
62
+ code_package_url=package_url,
63
+ target_file="my_package.tar",
64
+ working_dir="my_app",
65
+ )
66
+
67
+ # Print some information
68
+ print(f"Package URL: {package_url}")
69
+ print(f"Package Key: {package_key}")
70
+ print(f"Download Command: {download_cmd}")
71
+ print(f"Complete package commands: {package_commands}")
72
+
73
+
74
+ def usage_with_custom_package_function(datastore_type: str = "s3") -> None:
75
+ """
76
+ Example of using the CodePackager with a custom package creation function.
77
+
78
+ Parameters
79
+ ----------
80
+ datastore_type : str, default "s3"
81
+ The type of datastore to use: "s3", "azure", "gs", or "local"
82
+ """
83
+
84
+ # Define a custom package function
85
+ def create_custom_package():
86
+ # This is a simple example - in real use, you might create a more complex package
87
+ from io import BytesIO
88
+ import tarfile
89
+ import time
90
+
91
+ buf = BytesIO()
92
+ with tarfile.open(fileobj=buf, mode="w:gz") as tar:
93
+ # Add a simple file to the tarball
94
+ content = b"print('Hello, custom package!')"
95
+ info = tarfile.TarInfo(name="hello.py")
96
+ info.size = len(content)
97
+ info.mtime = int(time.time())
98
+ file_object = BytesIO(content)
99
+ tar.addfile(info, file_object)
100
+
101
+ return bytearray(buf.getvalue())
102
+
103
+ # Initialize the packager with datastore configuration
104
+ packager = CodePackager(datastore_type=datastore_type)
105
+
106
+ # Store the package with the custom package function
107
+ package_url, package_key = packager.store(package_create_fn=create_custom_package)
108
+
109
+ # Generate a download command
110
+ download_cmd = CodePackager.get_download_cmd(
111
+ package_url=package_url,
112
+ datastore_type=datastore_type,
113
+ target_file="custom_package.tar",
114
+ )
115
+
116
+ # Generate complete package commands
117
+ package_commands = packager.get_package_commands(
118
+ code_package_url=package_url,
119
+ )
120
+
121
+ # Print some information
122
+ print(f"Package URL: {package_url}")
123
+ print(f"Package Key: {package_key}")
124
+ print(f"Download Command: {download_cmd}")
125
+ print(f"Complete commands: {package_commands}")
@@ -0,0 +1,15 @@
1
+ from .unified_config import CoreConfig, PackagedCode, BakedImage, AuthType
2
+ from .cli_generator import auto_cli_options
3
+ from .config_utils import (
4
+ PureStringKVPairType,
5
+ JsonFriendlyKeyValuePairType,
6
+ CommaSeparatedListType,
7
+ MergingNotAllowedFieldsException,
8
+ ConfigValidationFailedException,
9
+ RequiredFieldMissingException,
10
+ ConfigFieldContext,
11
+ ConfigField,
12
+ FieldBehavior,
13
+ )
14
+ from . import schema_export
15
+ from .typed_configs import TypedCoreConfig, TypedDict
@@ -0,0 +1,165 @@
1
+ """
2
+ CLI Generator for Unified Configuration System
3
+
4
+ This module automatically generates Click CLI options from the CoreConfig,
5
+ eliminating the need for manual CLI option definitions and ensuring consistency
6
+ between configuration structure and CLI interface.
7
+
8
+ It also provides machinery for merging configurations from different sources
9
+ (CLI options, config files) with proper precedence and behavior handling.
10
+ """
11
+
12
+ from typing import Any, List, Optional
13
+ import json
14
+
15
+ from ..click_importer import click
16
+ from .unified_config import (
17
+ CoreConfig,
18
+ CLIOption,
19
+ ConfigMeta,
20
+ )
21
+ from .config_utils import (
22
+ PureStringKVPairType,
23
+ JsonFriendlyKeyValuePairType,
24
+ CommaSeparatedListType,
25
+ )
26
+
27
+
28
+ class CLIGenerator:
29
+ """Generates Click CLI options from CoreConfig dataclass."""
30
+
31
+ def __init__(self, config_class: type = CoreConfig):
32
+ self.config_class = config_class
33
+ self._type_mapping = {
34
+ str: str,
35
+ int: int,
36
+ float: float,
37
+ bool: bool,
38
+ list: CommaSeparatedListType,
39
+ dict: JsonFriendlyKeyValuePairType,
40
+ }
41
+
42
+ def generate_options(self):
43
+ """Generate all CLI options from the configuration class."""
44
+ options = []
45
+
46
+ # Generate options for all fields automatically
47
+ options.extend(self._generate_all_options(self.config_class))
48
+
49
+ return options
50
+
51
+ def _generate_all_options(self, config_class: type):
52
+ """Generate all options from a config class. Returns a list of click.Options"""
53
+
54
+ def _options_from_cfg_cls(_config_class):
55
+ options = []
56
+ for field_name, field_info in _config_class._fields.items():
57
+ # Skip fields not available in CLI context
58
+ if not field_info.is_available_in_cli():
59
+ continue
60
+
61
+ if ConfigMeta.is_instance(field_info.field_type):
62
+ _subfield_options = _options_from_cfg_cls(field_info.field_type)
63
+ options.extend(_subfield_options)
64
+ continue
65
+
66
+ cli_meta = field_info.cli_meta
67
+ if not cli_meta or cli_meta.hidden:
68
+ continue
69
+
70
+ option = self._create_option(field_name, field_info, cli_meta)
71
+ if option:
72
+ options.append(option)
73
+ return options
74
+
75
+ return _options_from_cfg_cls(config_class)
76
+
77
+ def _create_option(self, field_name: str, field_info, cli_meta: CLIOption):
78
+ """Create a Click option from field info and CLI metadata."""
79
+ # Use the cli_option_str from the CLIOption
80
+ option_str = cli_meta.cli_option_str
81
+ param_name = cli_meta.name
82
+
83
+ # Determine Click type
84
+ click_type = self._get_click_type(field_info, cli_meta)
85
+
86
+ # Build option parameters
87
+ help_text = cli_meta.help or field_info.help or f"Set {field_name}"
88
+ option_params = {
89
+ "help": help_text,
90
+ "default": cli_meta.default if cli_meta.default is not None else None,
91
+ "type": click_type,
92
+ }
93
+
94
+ # Handle multiple values
95
+ if cli_meta.multiple:
96
+ option_params["multiple"] = True
97
+
98
+ # Handle choices
99
+ if cli_meta.choices:
100
+ option_params["type"] = click.Choice(cli_meta.choices)
101
+
102
+ # Handle flags
103
+ if cli_meta.is_flag:
104
+ option_params["is_flag"] = True
105
+ option_params.pop("type", None)
106
+
107
+ # Handle special flag patterns (e.g., --public-access/--private-access)
108
+ return click.option(option_str, param_name, **option_params)
109
+
110
+ def _get_click_type(self, field_info, cli_meta: CLIOption) -> Any:
111
+ """Determine the appropriate Click type for a field."""
112
+ if cli_meta.click_type:
113
+ return cli_meta.click_type
114
+
115
+ # Get the field type
116
+ field_type = field_info.field_type
117
+
118
+ # Handle basic types
119
+ if field_type == list:
120
+ return CommaSeparatedListType
121
+ elif field_type == dict:
122
+ return JsonFriendlyKeyValuePairType
123
+ elif field_type == str:
124
+ return str
125
+ elif field_type == int:
126
+ return int
127
+ elif field_type == bool:
128
+ return bool
129
+ elif field_type == float:
130
+ return float
131
+
132
+ # Handle custom config types
133
+ if hasattr(field_type, "__name__") and field_type.__name__.endswith("Config"):
134
+ return str # Default to string for complex types
135
+
136
+ # Use type mapping
137
+ return self._type_mapping.get(field_type, str)
138
+
139
+ def create_decorator(self, command_type: str = "deploy") -> callable:
140
+ """Create a decorator that applies all CLI options to a command."""
141
+
142
+ def decorator(func):
143
+ # Apply options in reverse order since decorators are applied bottom-up
144
+ for option in reversed(self.generate_options()):
145
+ func = option(func)
146
+ return func
147
+
148
+ return decorator
149
+
150
+
151
+ def auto_cli_options(config_class: type = CoreConfig, command_type: str = "deploy"):
152
+ """
153
+ Decorator that automatically adds CLI options from CoreConfig.
154
+
155
+ Args:
156
+ command_type: Type of command (e.g., "deploy", "list", "delete")
157
+
158
+ Usage:
159
+ @auto_cli_options("deploy")
160
+ def deploy_command(**kwargs):
161
+ config = CoreConfig.from_cli(kwargs)
162
+ # ... use config
163
+ """
164
+ generator = CLIGenerator(config_class)
165
+ return generator.create_decorator(command_type)