ob-metaflow-extensions 1.1.171rc1__py2.py3-none-any.whl → 1.4.35__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 (64) hide show
  1. metaflow_extensions/outerbounds/plugins/__init__.py +6 -3
  2. metaflow_extensions/outerbounds/plugins/apps/app_cli.py +0 -29
  3. metaflow_extensions/outerbounds/plugins/apps/app_deploy_decorator.py +146 -0
  4. metaflow_extensions/outerbounds/plugins/apps/core/__init__.py +10 -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_cli.py +1200 -0
  10. metaflow_extensions/outerbounds/plugins/apps/core/app_config.py +146 -0
  11. metaflow_extensions/outerbounds/plugins/apps/core/artifacts.py +0 -0
  12. metaflow_extensions/outerbounds/plugins/apps/core/capsule.py +958 -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 +12 -0
  18. metaflow_extensions/outerbounds/plugins/apps/core/config/cli_generator.py +161 -0
  19. metaflow_extensions/outerbounds/plugins/apps/core/config/config_utils.py +868 -0
  20. metaflow_extensions/outerbounds/plugins/apps/core/config/schema_export.py +288 -0
  21. metaflow_extensions/outerbounds/plugins/apps/core/config/typed_configs.py +139 -0
  22. metaflow_extensions/outerbounds/plugins/apps/core/config/typed_init_generator.py +398 -0
  23. metaflow_extensions/outerbounds/plugins/apps/core/config/unified_config.py +1088 -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 +303 -0
  27. metaflow_extensions/outerbounds/plugins/apps/core/experimental/__init__.py +89 -0
  28. metaflow_extensions/outerbounds/plugins/apps/core/perimeters.py +87 -0
  29. metaflow_extensions/outerbounds/plugins/apps/core/secrets.py +164 -0
  30. metaflow_extensions/outerbounds/plugins/apps/core/utils.py +233 -0
  31. metaflow_extensions/outerbounds/plugins/apps/core/validations.py +17 -0
  32. metaflow_extensions/outerbounds/plugins/aws/assume_role_decorator.py +25 -12
  33. metaflow_extensions/outerbounds/plugins/checkpoint_datastores/coreweave.py +9 -77
  34. metaflow_extensions/outerbounds/plugins/checkpoint_datastores/external_chckpt.py +85 -0
  35. metaflow_extensions/outerbounds/plugins/checkpoint_datastores/nebius.py +7 -78
  36. metaflow_extensions/outerbounds/plugins/fast_bakery/docker_environment.py +6 -2
  37. metaflow_extensions/outerbounds/plugins/fast_bakery/fast_bakery.py +1 -0
  38. metaflow_extensions/outerbounds/plugins/nvct/nvct_decorator.py +8 -8
  39. metaflow_extensions/outerbounds/plugins/optuna/__init__.py +48 -0
  40. metaflow_extensions/outerbounds/plugins/profilers/simple_card_decorator.py +96 -0
  41. metaflow_extensions/outerbounds/plugins/s3_proxy/__init__.py +7 -0
  42. metaflow_extensions/outerbounds/plugins/s3_proxy/binary_caller.py +132 -0
  43. metaflow_extensions/outerbounds/plugins/s3_proxy/constants.py +11 -0
  44. metaflow_extensions/outerbounds/plugins/s3_proxy/exceptions.py +13 -0
  45. metaflow_extensions/outerbounds/plugins/s3_proxy/proxy_bootstrap.py +59 -0
  46. metaflow_extensions/outerbounds/plugins/s3_proxy/s3_proxy_api.py +93 -0
  47. metaflow_extensions/outerbounds/plugins/s3_proxy/s3_proxy_decorator.py +250 -0
  48. metaflow_extensions/outerbounds/plugins/s3_proxy/s3_proxy_manager.py +225 -0
  49. metaflow_extensions/outerbounds/plugins/snowpark/snowpark_client.py +6 -3
  50. metaflow_extensions/outerbounds/plugins/snowpark/snowpark_decorator.py +13 -7
  51. metaflow_extensions/outerbounds/plugins/snowpark/snowpark_job.py +8 -2
  52. metaflow_extensions/outerbounds/plugins/torchtune/__init__.py +4 -0
  53. metaflow_extensions/outerbounds/plugins/vllm/__init__.py +173 -95
  54. metaflow_extensions/outerbounds/plugins/vllm/status_card.py +9 -9
  55. metaflow_extensions/outerbounds/plugins/vllm/vllm_manager.py +159 -9
  56. metaflow_extensions/outerbounds/remote_config.py +8 -3
  57. metaflow_extensions/outerbounds/toplevel/global_aliases_for_metaflow_package.py +62 -1
  58. metaflow_extensions/outerbounds/toplevel/ob_internal.py +2 -0
  59. metaflow_extensions/outerbounds/toplevel/plugins/optuna/__init__.py +1 -0
  60. metaflow_extensions/outerbounds/toplevel/s3_proxy.py +88 -0
  61. {ob_metaflow_extensions-1.1.171rc1.dist-info → ob_metaflow_extensions-1.4.35.dist-info}/METADATA +2 -2
  62. {ob_metaflow_extensions-1.1.171rc1.dist-info → ob_metaflow_extensions-1.4.35.dist-info}/RECORD +64 -22
  63. {ob_metaflow_extensions-1.1.171rc1.dist-info → ob_metaflow_extensions-1.4.35.dist-info}/WHEEL +0 -0
  64. {ob_metaflow_extensions-1.1.171rc1.dist-info → ob_metaflow_extensions-1.4.35.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,12 @@
1
+ from .unified_config import CoreConfig
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
+ )
11
+ from . import schema_export
12
+ from .typed_configs import TypedCoreConfig, TypedDict
@@ -0,0 +1,161 @@
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
+ if ConfigMeta.is_instance(field_info.field_type):
58
+ _subfield_options = _options_from_cfg_cls(field_info.field_type)
59
+ options.extend(_subfield_options)
60
+ continue
61
+
62
+ cli_meta = field_info.cli_meta
63
+ if not cli_meta or cli_meta.hidden:
64
+ continue
65
+
66
+ option = self._create_option(field_name, field_info, cli_meta)
67
+ if option:
68
+ options.append(option)
69
+ return options
70
+
71
+ return _options_from_cfg_cls(config_class)
72
+
73
+ def _create_option(self, field_name: str, field_info, cli_meta: CLIOption):
74
+ """Create a Click option from field info and CLI metadata."""
75
+ # Use the cli_option_str from the CLIOption
76
+ option_str = cli_meta.cli_option_str
77
+ param_name = cli_meta.name
78
+
79
+ # Determine Click type
80
+ click_type = self._get_click_type(field_info, cli_meta)
81
+
82
+ # Build option parameters
83
+ help_text = cli_meta.help or field_info.help or f"Set {field_name}"
84
+ option_params = {
85
+ "help": help_text,
86
+ "default": cli_meta.default if cli_meta.default is not None else None,
87
+ "type": click_type,
88
+ }
89
+
90
+ # Handle multiple values
91
+ if cli_meta.multiple:
92
+ option_params["multiple"] = True
93
+
94
+ # Handle choices
95
+ if cli_meta.choices:
96
+ option_params["type"] = click.Choice(cli_meta.choices)
97
+
98
+ # Handle flags
99
+ if cli_meta.is_flag:
100
+ option_params["is_flag"] = True
101
+ option_params.pop("type", None)
102
+
103
+ # Handle special flag patterns (e.g., --public-access/--private-access)
104
+ return click.option(option_str, param_name, **option_params)
105
+
106
+ def _get_click_type(self, field_info, cli_meta: CLIOption) -> Any:
107
+ """Determine the appropriate Click type for a field."""
108
+ if cli_meta.click_type:
109
+ return cli_meta.click_type
110
+
111
+ # Get the field type
112
+ field_type = field_info.field_type
113
+
114
+ # Handle basic types
115
+ if field_type == list:
116
+ return CommaSeparatedListType
117
+ elif field_type == dict:
118
+ return JsonFriendlyKeyValuePairType
119
+ elif field_type == str:
120
+ return str
121
+ elif field_type == int:
122
+ return int
123
+ elif field_type == bool:
124
+ return bool
125
+ elif field_type == float:
126
+ return float
127
+
128
+ # Handle custom config types
129
+ if hasattr(field_type, "__name__") and field_type.__name__.endswith("Config"):
130
+ return str # Default to string for complex types
131
+
132
+ # Use type mapping
133
+ return self._type_mapping.get(field_type, str)
134
+
135
+ def create_decorator(self, command_type: str = "deploy") -> callable:
136
+ """Create a decorator that applies all CLI options to a command."""
137
+
138
+ def decorator(func):
139
+ # Apply options in reverse order since decorators are applied bottom-up
140
+ for option in reversed(self.generate_options()):
141
+ func = option(func)
142
+ return func
143
+
144
+ return decorator
145
+
146
+
147
+ def auto_cli_options(config_class: type = CoreConfig, command_type: str = "deploy"):
148
+ """
149
+ Decorator that automatically adds CLI options from CoreConfig.
150
+
151
+ Args:
152
+ command_type: Type of command (e.g., "deploy", "list", "delete")
153
+
154
+ Usage:
155
+ @auto_cli_options("deploy")
156
+ def deploy_command(**kwargs):
157
+ config = CoreConfig.from_cli(kwargs)
158
+ # ... use config
159
+ """
160
+ generator = CLIGenerator(config_class)
161
+ return generator.create_decorator(command_type)