outerbounds 0.3.55rc3__py3-none-any.whl → 0.3.133__py3-none-any.whl
Sign up to get free protection for your applications and to get access to all the features.
- outerbounds/_vendor/PyYAML.LICENSE +20 -0
- outerbounds/_vendor/__init__.py +0 -0
- outerbounds/_vendor/_yaml/__init__.py +34 -0
- outerbounds/_vendor/click/__init__.py +73 -0
- outerbounds/_vendor/click/_compat.py +626 -0
- outerbounds/_vendor/click/_termui_impl.py +717 -0
- outerbounds/_vendor/click/_textwrap.py +49 -0
- outerbounds/_vendor/click/_winconsole.py +279 -0
- outerbounds/_vendor/click/core.py +2998 -0
- outerbounds/_vendor/click/decorators.py +497 -0
- outerbounds/_vendor/click/exceptions.py +287 -0
- outerbounds/_vendor/click/formatting.py +301 -0
- outerbounds/_vendor/click/globals.py +68 -0
- outerbounds/_vendor/click/parser.py +529 -0
- outerbounds/_vendor/click/py.typed +0 -0
- outerbounds/_vendor/click/shell_completion.py +580 -0
- outerbounds/_vendor/click/termui.py +787 -0
- outerbounds/_vendor/click/testing.py +479 -0
- outerbounds/_vendor/click/types.py +1073 -0
- outerbounds/_vendor/click/utils.py +580 -0
- outerbounds/_vendor/click.LICENSE +28 -0
- outerbounds/_vendor/vendor_any.txt +2 -0
- outerbounds/_vendor/yaml/__init__.py +471 -0
- outerbounds/_vendor/yaml/_yaml.cpython-311-darwin.so +0 -0
- outerbounds/_vendor/yaml/composer.py +146 -0
- outerbounds/_vendor/yaml/constructor.py +862 -0
- outerbounds/_vendor/yaml/cyaml.py +177 -0
- outerbounds/_vendor/yaml/dumper.py +138 -0
- outerbounds/_vendor/yaml/emitter.py +1239 -0
- outerbounds/_vendor/yaml/error.py +94 -0
- outerbounds/_vendor/yaml/events.py +104 -0
- outerbounds/_vendor/yaml/loader.py +62 -0
- outerbounds/_vendor/yaml/nodes.py +51 -0
- outerbounds/_vendor/yaml/parser.py +629 -0
- outerbounds/_vendor/yaml/reader.py +208 -0
- outerbounds/_vendor/yaml/representer.py +378 -0
- outerbounds/_vendor/yaml/resolver.py +245 -0
- outerbounds/_vendor/yaml/scanner.py +1555 -0
- outerbounds/_vendor/yaml/serializer.py +127 -0
- outerbounds/_vendor/yaml/tokens.py +129 -0
- outerbounds/command_groups/apps_cli.py +450 -0
- outerbounds/command_groups/cli.py +9 -5
- outerbounds/command_groups/local_setup_cli.py +249 -33
- outerbounds/command_groups/perimeters_cli.py +231 -33
- outerbounds/command_groups/tutorials_cli.py +111 -0
- outerbounds/command_groups/workstations_cli.py +88 -15
- outerbounds/utils/kubeconfig.py +2 -2
- outerbounds/utils/metaflowconfig.py +111 -21
- outerbounds/utils/schema.py +8 -2
- outerbounds/utils/utils.py +19 -0
- outerbounds/vendor.py +159 -0
- {outerbounds-0.3.55rc3.dist-info → outerbounds-0.3.133.dist-info}/METADATA +17 -6
- outerbounds-0.3.133.dist-info/RECORD +59 -0
- {outerbounds-0.3.55rc3.dist-info → outerbounds-0.3.133.dist-info}/WHEEL +1 -1
- outerbounds-0.3.55rc3.dist-info/RECORD +0 -15
- {outerbounds-0.3.55rc3.dist-info → outerbounds-0.3.133.dist-info}/entry_points.txt +0 -0
@@ -1,17 +1,66 @@
|
|
1
|
+
from outerbounds._vendor import click
|
1
2
|
import json
|
2
3
|
import os
|
3
4
|
import requests
|
4
5
|
from os import path
|
5
|
-
import
|
6
|
+
from typing import Dict, Union
|
7
|
+
import sys
|
8
|
+
|
9
|
+
"""
|
10
|
+
key: perimeter specific URL to fetch the remote metaflow config from
|
11
|
+
value: the remote metaflow config
|
12
|
+
"""
|
13
|
+
CACHED_REMOTE_METAFLOW_CONFIG: Dict[str, Dict[str, str]] = {}
|
14
|
+
|
15
|
+
|
16
|
+
CURRENT_PERIMETER_KEY = "OB_CURRENT_PERIMETER"
|
17
|
+
CURRENT_PERIMETER_URL = "OB_CURRENT_PERIMETER_MF_CONFIG_URL"
|
18
|
+
CURRENT_PERIMETER_URL_LEGACY_KEY = (
|
19
|
+
"OB_CURRENT_PERIMETER_URL" # For backwards compatibility with workstations.
|
20
|
+
)
|
21
|
+
|
22
|
+
|
23
|
+
def init_config(config_dir, profile) -> Dict[str, str]:
|
24
|
+
global CACHED_REMOTE_METAFLOW_CONFIG
|
25
|
+
config = read_metaflow_config_from_filesystem(config_dir, profile)
|
26
|
+
|
27
|
+
# Either user has an ob_config.json file with the perimeter URL
|
28
|
+
# or the default config on the filesystem has the config URL in it.
|
29
|
+
perimeter_specifc_url = get_perimeter_config_url_if_set_in_ob_config(
|
30
|
+
config_dir, profile
|
31
|
+
) or config.get("OBP_METAFLOW_CONFIG_URL", "")
|
32
|
+
|
33
|
+
if perimeter_specifc_url != "":
|
34
|
+
if perimeter_specifc_url in CACHED_REMOTE_METAFLOW_CONFIG:
|
35
|
+
return CACHED_REMOTE_METAFLOW_CONFIG[perimeter_specifc_url]
|
36
|
+
|
37
|
+
remote_config = init_config_from_url(config_dir, profile, perimeter_specifc_url)
|
38
|
+
remote_config["OBP_METAFLOW_CONFIG_URL"] = perimeter_specifc_url
|
6
39
|
|
40
|
+
CACHED_REMOTE_METAFLOW_CONFIG[perimeter_specifc_url] = remote_config
|
41
|
+
return remote_config
|
42
|
+
|
43
|
+
return config
|
44
|
+
|
45
|
+
|
46
|
+
def init_config_from_url(config_dir, profile, url) -> Dict[str, str]:
|
47
|
+
config = read_metaflow_config_from_filesystem(config_dir, profile)
|
7
48
|
|
8
|
-
|
9
|
-
|
10
|
-
|
11
|
-
|
49
|
+
if config is None or "METAFLOW_SERVICE_AUTH_KEY" not in config:
|
50
|
+
raise Exception("METAFLOW_SERVICE_AUTH_KEY not found in config file")
|
51
|
+
|
52
|
+
config_response = requests.get(
|
53
|
+
url,
|
54
|
+
headers={"x-api-key": f'{config["METAFLOW_SERVICE_AUTH_KEY"]}'},
|
12
55
|
)
|
56
|
+
config_response.raise_for_status()
|
57
|
+
remote_config = config_response.json()["config"]
|
58
|
+
return remote_config
|
59
|
+
|
13
60
|
|
61
|
+
def read_metaflow_config_from_filesystem(config_dir, profile) -> Dict[str, str]:
|
14
62
|
config_filename = f"config_{profile}.json" if profile else "config.json"
|
63
|
+
|
15
64
|
path_to_config = os.path.join(config_dir, config_filename)
|
16
65
|
|
17
66
|
if os.path.exists(path_to_config):
|
@@ -19,22 +68,6 @@ def init_config(config_dir="", profile="") -> dict:
|
|
19
68
|
config = json.load(json_file)
|
20
69
|
else:
|
21
70
|
raise Exception("Unable to locate metaflow config at '%s')" % (path_to_config))
|
22
|
-
|
23
|
-
# This is new remote-metaflow config; fetch it from the URL
|
24
|
-
if "OBP_METAFLOW_CONFIG_URL" in config:
|
25
|
-
if config is None or "METAFLOW_SERVICE_AUTH_KEY" not in config:
|
26
|
-
raise Exception("METAFLOW_SERVICE_AUTH_KEY not found in config file")
|
27
|
-
|
28
|
-
config_response = requests.get(
|
29
|
-
config["OBP_METAFLOW_CONFIG_URL"],
|
30
|
-
headers={"x-api-key": f'{config["METAFLOW_SERVICE_AUTH_KEY"]}'},
|
31
|
-
)
|
32
|
-
config_response.raise_for_status()
|
33
|
-
remote_config = config_response.json()["config"]
|
34
|
-
remote_config["METAFLOW_SERVICE_AUTH_KEY"] = config["METAFLOW_SERVICE_AUTH_KEY"]
|
35
|
-
return remote_config
|
36
|
-
|
37
|
-
# Legacy config, use from filesystem
|
38
71
|
return config
|
39
72
|
|
40
73
|
|
@@ -70,3 +103,60 @@ def get_sanitized_url_from_config(config_dir: str, profile: str, key: str) -> st
|
|
70
103
|
|
71
104
|
url_in_config = url_in_config.rstrip("/")
|
72
105
|
return url_in_config
|
106
|
+
|
107
|
+
|
108
|
+
def get_remote_metaflow_config_for_perimeter(
|
109
|
+
origin_token: str, perimeter: str, api_server: str
|
110
|
+
):
|
111
|
+
try:
|
112
|
+
response = requests.get(
|
113
|
+
f"{api_server}/v1/perimeters/{perimeter}/metaflowconfigs/default",
|
114
|
+
headers={"x-api-key": origin_token},
|
115
|
+
)
|
116
|
+
response.raise_for_status()
|
117
|
+
config = response.json()["config"]
|
118
|
+
config["METAFLOW_SERVICE_AUTH_KEY"] = origin_token
|
119
|
+
return config
|
120
|
+
except Exception as e:
|
121
|
+
click.secho(
|
122
|
+
f"Failed to get metaflow config from {api_server}. Error: {str(e)}",
|
123
|
+
fg="red",
|
124
|
+
)
|
125
|
+
sys.exit(1)
|
126
|
+
|
127
|
+
|
128
|
+
def get_ob_config_file_path(config_dir: str, profile: str) -> str:
|
129
|
+
# If OBP_CONFIG_DIR is set, use that, otherwise use METAFLOW_HOME
|
130
|
+
# If neither are set, use ~/.metaflowconfig
|
131
|
+
obp_config_dir = path.expanduser(os.environ.get("OBP_CONFIG_DIR", config_dir))
|
132
|
+
|
133
|
+
ob_config_filename = f"ob_config_{profile}.json" if profile else "ob_config.json"
|
134
|
+
return os.path.expanduser(os.path.join(obp_config_dir, ob_config_filename))
|
135
|
+
|
136
|
+
|
137
|
+
def get_perimeter_config_url_if_set_in_ob_config(
|
138
|
+
config_dir: str, profile: str
|
139
|
+
) -> Union[str, None]:
|
140
|
+
file_path = get_ob_config_file_path(config_dir, profile)
|
141
|
+
|
142
|
+
if os.path.exists(file_path):
|
143
|
+
with open(file_path, "r") as f:
|
144
|
+
ob_config = json.loads(f.read())
|
145
|
+
|
146
|
+
if CURRENT_PERIMETER_URL in ob_config:
|
147
|
+
return ob_config[CURRENT_PERIMETER_URL]
|
148
|
+
elif CURRENT_PERIMETER_URL_LEGACY_KEY in ob_config:
|
149
|
+
return ob_config[CURRENT_PERIMETER_URL_LEGACY_KEY]
|
150
|
+
else:
|
151
|
+
raise ValueError(
|
152
|
+
"{} does not contain the key {}".format(
|
153
|
+
file_path, CURRENT_PERIMETER_KEY
|
154
|
+
)
|
155
|
+
)
|
156
|
+
elif "OBP_CONFIG_DIR" in os.environ:
|
157
|
+
raise FileNotFoundError(
|
158
|
+
"Environment variable OBP_CONFIG_DIR is set to {} but this directory does not contain an ob_config.json file.".format(
|
159
|
+
os.environ["OBP_CONFIG_DIR"]
|
160
|
+
)
|
161
|
+
)
|
162
|
+
return None
|
outerbounds/utils/schema.py
CHANGED
@@ -5,6 +5,7 @@ class OuterboundsCommandStatus(Enum):
|
|
5
5
|
OK = "OK"
|
6
6
|
FAIL = "FAIL"
|
7
7
|
WARN = "WARN"
|
8
|
+
NOT_SUPPORTED = "NOT_SUPPORTED"
|
8
9
|
|
9
10
|
|
10
11
|
class CommandStatus:
|
@@ -39,6 +40,11 @@ class OuterboundsCommandResponse:
|
|
39
40
|
self.metadata = {}
|
40
41
|
self._data = {}
|
41
42
|
|
43
|
+
def update(self, status, code, message):
|
44
|
+
self.status = status
|
45
|
+
self._code = code
|
46
|
+
self._message = message
|
47
|
+
|
42
48
|
def add_or_update_metadata(self, key, value):
|
43
49
|
self.metadata[key] = value
|
44
50
|
|
@@ -53,14 +59,14 @@ class OuterboundsCommandResponse:
|
|
53
59
|
if step.status == OuterboundsCommandStatus.FAIL:
|
54
60
|
self.status = OuterboundsCommandStatus.FAIL
|
55
61
|
self._code = 500
|
56
|
-
self._message = "
|
62
|
+
self._message = "Encountered an error when trying to run command."
|
57
63
|
elif (
|
58
64
|
step.status == OuterboundsCommandStatus.WARN
|
59
65
|
and self.status != OuterboundsCommandStatus.FAIL
|
60
66
|
):
|
61
67
|
self.status = OuterboundsCommandStatus.WARN
|
62
68
|
self._code = 200
|
63
|
-
self._message = "
|
69
|
+
self._message = "Encountered one or more warnings when running the command."
|
64
70
|
|
65
71
|
def as_dict(self):
|
66
72
|
self._data["steps"] = [step.as_dict() for step in self._steps]
|
@@ -0,0 +1,19 @@
|
|
1
|
+
import tempfile
|
2
|
+
import os
|
3
|
+
|
4
|
+
"""
|
5
|
+
Writes the given data to file_loc. Ensures that the directory exists
|
6
|
+
and uses a temporary file to ensure that the file is written atomically.
|
7
|
+
"""
|
8
|
+
|
9
|
+
|
10
|
+
def safe_write_to_disk(file_loc, data):
|
11
|
+
# Ensure the directory exists
|
12
|
+
os.makedirs(os.path.dirname(file_loc), exist_ok=True)
|
13
|
+
|
14
|
+
with tempfile.NamedTemporaryFile(
|
15
|
+
"w", dir=os.path.dirname(file_loc), delete=False
|
16
|
+
) as f:
|
17
|
+
f.write(data)
|
18
|
+
tmp_file = f.name
|
19
|
+
os.rename(tmp_file, file_loc)
|
outerbounds/vendor.py
ADDED
@@ -0,0 +1,159 @@
|
|
1
|
+
import glob
|
2
|
+
import shutil
|
3
|
+
import subprocess
|
4
|
+
import re
|
5
|
+
|
6
|
+
from functools import partial
|
7
|
+
from itertools import chain
|
8
|
+
from pathlib import Path
|
9
|
+
|
10
|
+
WHITELIST = {
|
11
|
+
"README.txt",
|
12
|
+
"__init__.py",
|
13
|
+
"vendor_any.txt",
|
14
|
+
"pip.LICENSE",
|
15
|
+
}
|
16
|
+
|
17
|
+
# Borrowed from https://github.com/pypa/pip/tree/main/src/pip/_vendor
|
18
|
+
|
19
|
+
VENDOR_SUBDIR = re.compile(r"^_vendor/vendor_([a-zA-Z0-9_]+).txt$")
|
20
|
+
|
21
|
+
|
22
|
+
def delete_all(*paths, whitelist=frozenset()):
|
23
|
+
for item in paths:
|
24
|
+
if item.is_dir():
|
25
|
+
shutil.rmtree(item, ignore_errors=True)
|
26
|
+
elif item.is_file() and item.name not in whitelist:
|
27
|
+
item.unlink()
|
28
|
+
|
29
|
+
|
30
|
+
def iter_subtree(path):
|
31
|
+
"""Recursively yield all files in a subtree, depth-first"""
|
32
|
+
if not path.is_dir():
|
33
|
+
if path.is_file():
|
34
|
+
yield path
|
35
|
+
return
|
36
|
+
for item in path.iterdir():
|
37
|
+
if item.is_dir():
|
38
|
+
yield from iter_subtree(item)
|
39
|
+
elif item.is_file():
|
40
|
+
yield item
|
41
|
+
|
42
|
+
|
43
|
+
def patch_vendor_imports(file, replacements):
|
44
|
+
text = file.read_text("utf8")
|
45
|
+
for replacement in replacements:
|
46
|
+
text = replacement(text)
|
47
|
+
file.write_text(text, "utf8")
|
48
|
+
|
49
|
+
|
50
|
+
def find_vendored_libs(vendor_dir, whitelist, whitelist_dirs):
|
51
|
+
vendored_libs = []
|
52
|
+
paths = []
|
53
|
+
for item in vendor_dir.iterdir():
|
54
|
+
if item.is_dir() and item not in whitelist_dirs:
|
55
|
+
vendored_libs.append(item.name)
|
56
|
+
elif item.is_file() and item.name not in whitelist:
|
57
|
+
vendored_libs.append(item.stem) # without extension
|
58
|
+
else: # not a dir or a file not in the whitelist
|
59
|
+
continue
|
60
|
+
paths.append(item)
|
61
|
+
return vendored_libs, paths
|
62
|
+
|
63
|
+
|
64
|
+
def fetch_licenses(*info_dir, vendor_dir):
|
65
|
+
for file in chain.from_iterable(map(iter_subtree, info_dir)):
|
66
|
+
if "LICENSE" in file.name:
|
67
|
+
library = file.parent.name.split("-")[0]
|
68
|
+
shutil.copy(file, vendor_dir / ("%s.LICENSE" % library))
|
69
|
+
else:
|
70
|
+
continue
|
71
|
+
|
72
|
+
|
73
|
+
def vendor(vendor_dir):
|
74
|
+
# remove everything
|
75
|
+
delete_all(*vendor_dir.iterdir(), whitelist=WHITELIST)
|
76
|
+
|
77
|
+
exclude_subdirs = []
|
78
|
+
# Iterate on the vendor*.txt files
|
79
|
+
for vendor_file in glob.glob(f"{vendor_dir.name}/vendor*.txt"):
|
80
|
+
# We extract the subdirectory we are going to extract into
|
81
|
+
subdir = VENDOR_SUBDIR.match(vendor_file).group(1)
|
82
|
+
# Includes "any" but it doesn't really matter unless you install "any"
|
83
|
+
exclude_subdirs.append(subdir)
|
84
|
+
|
85
|
+
for subdir in exclude_subdirs:
|
86
|
+
create_init_file = False
|
87
|
+
if subdir == "any":
|
88
|
+
vendor_subdir = vendor_dir
|
89
|
+
# target package is <parent>.<vendor_dir>; foo/_vendor -> foo._vendor
|
90
|
+
pkgname = f"{vendor_dir.parent.name}.{vendor_dir.name}"
|
91
|
+
else:
|
92
|
+
create_init_file = True
|
93
|
+
vendor_subdir = vendor_dir / subdir
|
94
|
+
# target package is <parent>.<vendor_dir>; foo/_vendor -> foo._vendor
|
95
|
+
pkgname = f"{vendor_dir.parent.name}.{vendor_dir.name}.{vendor_subdir.name}"
|
96
|
+
|
97
|
+
# install with pip
|
98
|
+
subprocess.run(
|
99
|
+
[
|
100
|
+
"python3",
|
101
|
+
"-m",
|
102
|
+
"pip",
|
103
|
+
"install",
|
104
|
+
"-t",
|
105
|
+
str(vendor_subdir),
|
106
|
+
"-r",
|
107
|
+
"_vendor/vendor_%s.txt" % subdir,
|
108
|
+
"--no-compile",
|
109
|
+
]
|
110
|
+
)
|
111
|
+
|
112
|
+
# fetch licenses
|
113
|
+
fetch_licenses(*vendor_subdir.glob("*.dist-info"), vendor_dir=vendor_subdir)
|
114
|
+
|
115
|
+
# delete stuff that's not needed
|
116
|
+
delete_all(
|
117
|
+
*vendor_subdir.glob("*.dist-info"),
|
118
|
+
*vendor_subdir.glob("*.egg-info"),
|
119
|
+
vendor_subdir / "bin",
|
120
|
+
)
|
121
|
+
|
122
|
+
# Touch a __init__.py file
|
123
|
+
if create_init_file:
|
124
|
+
with open(
|
125
|
+
"%s/__init__.py" % str(vendor_subdir), "w+", encoding="utf-8"
|
126
|
+
) as f:
|
127
|
+
f.write("# Empty file")
|
128
|
+
|
129
|
+
vendored_libs, paths = find_vendored_libs(
|
130
|
+
vendor_subdir, WHITELIST, exclude_subdirs
|
131
|
+
)
|
132
|
+
|
133
|
+
replacements = []
|
134
|
+
for lib in vendored_libs:
|
135
|
+
replacements += (
|
136
|
+
partial( # import bar -> import foo._vendor.bar
|
137
|
+
re.compile(r"(^\s*)import {}\n".format(lib), flags=re.M).sub,
|
138
|
+
r"\1from {} import {}\n".format(pkgname, lib),
|
139
|
+
),
|
140
|
+
partial( # from bar -> from foo._vendor.bar
|
141
|
+
re.compile(r"(^\s*)from {}(\.|\s+)".format(lib), flags=re.M).sub,
|
142
|
+
r"\1from {}.{}\2".format(pkgname, lib),
|
143
|
+
),
|
144
|
+
)
|
145
|
+
|
146
|
+
for file in chain.from_iterable(map(iter_subtree, paths)):
|
147
|
+
if file.suffix == ".py":
|
148
|
+
patch_vendor_imports(file, replacements)
|
149
|
+
|
150
|
+
|
151
|
+
if __name__ == "__main__":
|
152
|
+
here = Path("__file__").resolve().parent
|
153
|
+
vendor_tl_dir = here / "_vendor"
|
154
|
+
has_vendor_file = len(glob.glob(f"{vendor_tl_dir.name}/vendor*.txt")) > 0
|
155
|
+
assert has_vendor_file, "_vendor/vendor*.txt file not found"
|
156
|
+
assert (
|
157
|
+
vendor_tl_dir / "__init__.py"
|
158
|
+
).exists(), "_vendor/__init__.py file not found"
|
159
|
+
vendor(vendor_tl_dir)
|
@@ -1,31 +1,42 @@
|
|
1
1
|
Metadata-Version: 2.1
|
2
2
|
Name: outerbounds
|
3
|
-
Version: 0.3.
|
3
|
+
Version: 0.3.133
|
4
4
|
Summary: More Data Science, Less Administration
|
5
5
|
License: Proprietary
|
6
6
|
Keywords: data science,machine learning,MLOps
|
7
7
|
Author: Outerbounds, Inc.
|
8
|
-
Requires-Python: >=3.
|
8
|
+
Requires-Python: >=3.7,<4.0
|
9
9
|
Classifier: Development Status :: 4 - Beta
|
10
10
|
Classifier: License :: Other/Proprietary License
|
11
11
|
Classifier: Programming Language :: Python :: 3
|
12
|
+
Classifier: Programming Language :: Python :: 3.7
|
12
13
|
Classifier: Programming Language :: Python :: 3.8
|
13
14
|
Classifier: Programming Language :: Python :: 3.9
|
14
15
|
Classifier: Programming Language :: Python :: 3.10
|
15
16
|
Classifier: Programming Language :: Python :: 3.11
|
17
|
+
Classifier: Programming Language :: Python :: 3.12
|
16
18
|
Provides-Extra: azure
|
17
19
|
Provides-Extra: gcp
|
18
|
-
|
20
|
+
Provides-Extra: snowflake
|
19
21
|
Requires-Dist: azure-identity (>=1.15.0,<2.0.0) ; extra == "azure"
|
22
|
+
Requires-Dist: azure-keyvault-secrets (>=4.7.0,<5.0.0) ; extra == "azure"
|
20
23
|
Requires-Dist: azure-storage-blob (>=12.9.0,<13.0.0) ; extra == "azure"
|
21
24
|
Requires-Dist: boto3
|
22
|
-
Requires-Dist: click (>=8.1.3,<9.0.0)
|
23
25
|
Requires-Dist: google-api-core (>=2.16.1,<3.0.0) ; extra == "gcp"
|
24
26
|
Requires-Dist: google-auth (>=2.27.0,<3.0.0) ; extra == "gcp"
|
27
|
+
Requires-Dist: google-cloud-secret-manager (>=2.20.0,<3.0.0) ; extra == "gcp"
|
25
28
|
Requires-Dist: google-cloud-storage (>=2.14.0,<3.0.0) ; extra == "gcp"
|
26
|
-
Requires-Dist:
|
27
|
-
Requires-Dist: ob-metaflow
|
29
|
+
Requires-Dist: metaflow-checkpoint (==0.1.6)
|
30
|
+
Requires-Dist: ob-metaflow (==2.13.4.1)
|
31
|
+
Requires-Dist: ob-metaflow-extensions (==1.1.121)
|
32
|
+
Requires-Dist: ob-metaflow-stubs (==6.0.3.133)
|
28
33
|
Requires-Dist: opentelemetry-distro (==0.41b0)
|
29
34
|
Requires-Dist: opentelemetry-exporter-otlp-proto-http (==1.20.0)
|
30
35
|
Requires-Dist: opentelemetry-instrumentation-requests (==0.41b0)
|
31
36
|
Project-URL: Documentation, https://docs.metaflow.org
|
37
|
+
Description-Content-Type: text/markdown
|
38
|
+
|
39
|
+
# Outerbounds
|
40
|
+
|
41
|
+
Main package for the Outerbounds platform.
|
42
|
+
|
@@ -0,0 +1,59 @@
|
|
1
|
+
outerbounds/__init__.py,sha256=GPdaubvAYF8pOFWJ3b-sPMKCpyfpteWVMZWkmaYhxRw,32
|
2
|
+
outerbounds/_vendor/PyYAML.LICENSE,sha256=jTko-dxEkP1jVwfLiOsmvXZBAqcoKVQwfT5RZ6V36KQ,1101
|
3
|
+
outerbounds/_vendor/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
4
|
+
outerbounds/_vendor/_yaml/__init__.py,sha256=nD985-g4Mrx97PhtSzI2L53o8sCHUJ4ZoBWcUd7o0PQ,1449
|
5
|
+
outerbounds/_vendor/click/__init__.py,sha256=rQBLutqg-z6m8nOzivIfigDn_emijB_dKv9BZ2FNi5s,3138
|
6
|
+
outerbounds/_vendor/click/_compat.py,sha256=JIHLYs7Jzz4KT9t-ds4o4jBzLjnwCiJQKqur-5iwCKI,18810
|
7
|
+
outerbounds/_vendor/click/_termui_impl.py,sha256=qK6Cfy4mRFxvxE8dya8RBhLpSC8HjF-lvBc6aNrPdwg,23451
|
8
|
+
outerbounds/_vendor/click/_textwrap.py,sha256=10fQ64OcBUMuK7mFvh8363_uoOxPlRItZBmKzRJDgoY,1353
|
9
|
+
outerbounds/_vendor/click/_winconsole.py,sha256=5ju3jQkcZD0W27WEMGqmEP4y_crUVzPCqsX_FYb7BO0,7860
|
10
|
+
outerbounds/_vendor/click/core.py,sha256=ici4JXpq5VWyQkFQQklE4GnUKR8wxSP1YAzqaVYAZ3Y,112862
|
11
|
+
outerbounds/_vendor/click/decorators.py,sha256=yo3zvzgUm5q7h5CXjyV6q3h_PJAiUaem178zXwdWUFI,16350
|
12
|
+
outerbounds/_vendor/click/exceptions.py,sha256=7gDaLGuFZBeCNwY9ERMsF2-Z3R9Fvq09Zc6IZSKjseo,9167
|
13
|
+
outerbounds/_vendor/click/formatting.py,sha256=Frf0-5W33-loyY_i9qrwXR8-STnW3m5gvyxLVUdyxyk,9706
|
14
|
+
outerbounds/_vendor/click/globals.py,sha256=TP-qM88STzc7f127h35TD_v920FgfOD2EwzqA0oE8XU,1961
|
15
|
+
outerbounds/_vendor/click/parser.py,sha256=cAEt1uQR8gq3-S9ysqbVU-fdAZNvilxw4ReJ_T1OQMk,19044
|
16
|
+
outerbounds/_vendor/click/py.typed,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
17
|
+
outerbounds/_vendor/click/shell_completion.py,sha256=qOp_BeC9esEOSZKyu5G7RIxEUaLsXUX-mTb7hB1r4QY,18018
|
18
|
+
outerbounds/_vendor/click/termui.py,sha256=ACBQVOvFCTSqtD5VREeCAdRtlHd-Imla-Lte4wSfMjA,28355
|
19
|
+
outerbounds/_vendor/click/testing.py,sha256=ptpMYgRY7dVfE3UDgkgwayu9ePw98sQI3D7zZXiCpj4,16063
|
20
|
+
outerbounds/_vendor/click/types.py,sha256=u8LK2CRcVw3jWDutzP_wgFV478TXhsjL8gYSFPjGKkE,35865
|
21
|
+
outerbounds/_vendor/click/utils.py,sha256=33D6E7poH_nrKB-xr-UyDEXnxOcCiQqxuRLtrqeVv6o,18682
|
22
|
+
outerbounds/_vendor/click.LICENSE,sha256=morRBqOU6FO_4h9C9OctWSgZoigF2ZG18ydQKSkrZY0,1475
|
23
|
+
outerbounds/_vendor/vendor_any.txt,sha256=9vi_h2zSBIx0sFM9i69xNEwe-HyeX0_sdtMjImmvgXo,27
|
24
|
+
outerbounds/_vendor/yaml/__init__.py,sha256=lPcXUknB0EUNfCL8MJOgq26y70nOQR_Eajqzycmtnhg,12569
|
25
|
+
outerbounds/_vendor/yaml/_yaml.cpython-311-darwin.so,sha256=YiF55JiadfOvw_mUH-lONNnsiMHj6C6o1SBfTCvvW54,362008
|
26
|
+
outerbounds/_vendor/yaml/composer.py,sha256=KI1ASnRYW7jWza4BxiHsjDdpV_AYR6wGKD_d3q5y1GY,4975
|
27
|
+
outerbounds/_vendor/yaml/constructor.py,sha256=a_QHcwgF8J3ius54IchRi50VSuX-tNZfL83JsRA9q9w,30058
|
28
|
+
outerbounds/_vendor/yaml/cyaml.py,sha256=pbSaKr0mn_yMEc4DuLbl38RGWVSkXBgA9NXHATnjfuE,4497
|
29
|
+
outerbounds/_vendor/yaml/dumper.py,sha256=ncn_DlBmKv_aTtkv9tBagK-8SQE9ETLIdwTYMO0_5WA,3507
|
30
|
+
outerbounds/_vendor/yaml/emitter.py,sha256=9jcV2QKdsHWAPJrqsWMEBCLCU56D25qLC1XiQFcU48A,44167
|
31
|
+
outerbounds/_vendor/yaml/error.py,sha256=1ImZXAcfUbnuVfkHYSeHakDojgwAjFs4pFUKfKNFLuw,2726
|
32
|
+
outerbounds/_vendor/yaml/events.py,sha256=VlHDUFXu2zAU6TFEQUBDIq8gU3s_1Q67vpNlYY645p4,2465
|
33
|
+
outerbounds/_vendor/yaml/loader.py,sha256=jX2YIC4HwJslE2DKVwLix2ne8qhJyFJzwjJz7CzVPOk,2060
|
34
|
+
outerbounds/_vendor/yaml/nodes.py,sha256=K0QBIan-NI8RqxiPyo6fLaR-GSTpmF_9eXtJ3uf6rEo,1422
|
35
|
+
outerbounds/_vendor/yaml/parser.py,sha256=BhbxGU0AjebJZIVFpBIPoP5YAGYOMVg7Vjmd-aFP5ts,26214
|
36
|
+
outerbounds/_vendor/yaml/reader.py,sha256=lR8yfw6FMasPB41qFrsBUOVtASViXnKd89tvJHQNsVc,7109
|
37
|
+
outerbounds/_vendor/yaml/representer.py,sha256=FK_yoIj_17GdgzVP8_yFBobV56PKqEkZ5AGtBdKjWDc,14088
|
38
|
+
outerbounds/_vendor/yaml/resolver.py,sha256=dPhU1d7G1JCMktPFvNhyqwj2oNvx1yf_Jfa35CydQXA,8992
|
39
|
+
outerbounds/_vendor/yaml/scanner.py,sha256=ZcI8IngR56PaQ0m27WU2vxCqmDCuRjz-hr7pirbMPuw,52982
|
40
|
+
outerbounds/_vendor/yaml/serializer.py,sha256=8wFZRy9SsQSktF_f9OOroroqsh4qVUe53ry07P9UgCc,4368
|
41
|
+
outerbounds/_vendor/yaml/tokens.py,sha256=JBSu38wihGr4l73JwbfMA7Ks1-X84g8-NskTz7KwPmA,2578
|
42
|
+
outerbounds/cli_main.py,sha256=e9UMnPysmc7gbrimq2I4KfltggyU7pw59Cn9aEguVcU,74
|
43
|
+
outerbounds/command_groups/__init__.py,sha256=QPWtj5wDRTINDxVUL7XPqG3HoxHNvYOg08EnuSZB2Hc,21
|
44
|
+
outerbounds/command_groups/apps_cli.py,sha256=8jmQufa0bK2sfRfs7DiWjoJ1oWiqZAixsL4Dte_KY4Y,17201
|
45
|
+
outerbounds/command_groups/cli.py,sha256=q0hdJO4biD3iEOdyJcxnRkeleA8AKAhx842kQ49I6kk,365
|
46
|
+
outerbounds/command_groups/local_setup_cli.py,sha256=tuuqJRXQ_guEwOuQSIf9wkUU0yg8yAs31myGViAK15s,36364
|
47
|
+
outerbounds/command_groups/perimeters_cli.py,sha256=iF_Uw7ROiSctf6FgoJEy30iDBLVE1j9FKuR3shgJRmc,19050
|
48
|
+
outerbounds/command_groups/tutorials_cli.py,sha256=UInFyiMqtscHFfi8YQwiY_6Sdw9quJOtRu5OukEBccw,3522
|
49
|
+
outerbounds/command_groups/workstations_cli.py,sha256=V5Jbj1cVb4IRllI7fOgNgL6OekRpuFDv6CEhDb4xC6w,22016
|
50
|
+
outerbounds/utils/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
51
|
+
outerbounds/utils/kubeconfig.py,sha256=yvcyRXGR4AhQuqUDqmbGxEOHw5ixMFV0AZIDg1LI_Qo,7981
|
52
|
+
outerbounds/utils/metaflowconfig.py,sha256=l2vJbgPkLISU-XPGZFaC8ZKmYFyJemlD6bwB-EKUsAw,5770
|
53
|
+
outerbounds/utils/schema.py,sha256=lMUr9kNgn9wy-sO_t_Tlxmbt63yLeN4b0xQXbDUDj4A,2331
|
54
|
+
outerbounds/utils/utils.py,sha256=4Z8cszNob_8kDYCLNTrP-wWads_S_MdL3Uj3ju4mEsk,501
|
55
|
+
outerbounds/vendor.py,sha256=gRLRJNXtZBeUpPEog0LOeIsl6GosaFFbCxUvR4bW6IQ,5093
|
56
|
+
outerbounds-0.3.133.dist-info/METADATA,sha256=q0HvciFfYuFHoyzBF7-2hnU7EkQIk47mtcxUOxtuWKs,1761
|
57
|
+
outerbounds-0.3.133.dist-info/WHEEL,sha256=sP946D7jFCHeNz5Iq4fL4Lu-PrWrFsgfLXbbkciIZwg,88
|
58
|
+
outerbounds-0.3.133.dist-info/entry_points.txt,sha256=7ye0281PKlvqxu15rjw60zKg2pMsXI49_A8BmGqIqBw,47
|
59
|
+
outerbounds-0.3.133.dist-info/RECORD,,
|
@@ -1,15 +0,0 @@
|
|
1
|
-
outerbounds/__init__.py,sha256=GPdaubvAYF8pOFWJ3b-sPMKCpyfpteWVMZWkmaYhxRw,32
|
2
|
-
outerbounds/cli_main.py,sha256=e9UMnPysmc7gbrimq2I4KfltggyU7pw59Cn9aEguVcU,74
|
3
|
-
outerbounds/command_groups/__init__.py,sha256=QPWtj5wDRTINDxVUL7XPqG3HoxHNvYOg08EnuSZB2Hc,21
|
4
|
-
outerbounds/command_groups/cli.py,sha256=H4LxcYTmsY9DQUrReSRLjvbg9s9Ro7s-eUrcMqEJ_9A,261
|
5
|
-
outerbounds/command_groups/local_setup_cli.py,sha256=0sEi3V0sqoCW0RI2z3xMLNnit0pCsigWQ07m1mhDBso,29524
|
6
|
-
outerbounds/command_groups/perimeters_cli.py,sha256=9tOql42d00KfHpZYkLLGEAOiy8iRbIzsknldCyICwU0,12063
|
7
|
-
outerbounds/command_groups/workstations_cli.py,sha256=f3gwHMZPHzeOcGj5VfC5tZZA18JQhFzy2LRGzqAosOk,19286
|
8
|
-
outerbounds/utils/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
9
|
-
outerbounds/utils/kubeconfig.py,sha256=l1mUP1j9VIq3fsffi5bJ1Nk-hYlwd1dIqkpj7DvVS1E,7936
|
10
|
-
outerbounds/utils/metaflowconfig.py,sha256=HgaDmK3F97rppfGUdysS1Zppe28ERTLV_HcB5IuPpV4,2631
|
11
|
-
outerbounds/utils/schema.py,sha256=Ht_Yf5uoKO0m36WXHZLSPmWPH6EFWXfZDQsiAUquc5k,2160
|
12
|
-
outerbounds-0.3.55rc3.dist-info/METADATA,sha256=ARhdx-T4KbMT1ri3AqRyA5vW4B_8dGHZGdRlcK-iBuI,1367
|
13
|
-
outerbounds-0.3.55rc3.dist-info/WHEEL,sha256=vVCvjcmxuUltf8cYhJ0sJMRDLr1XsPuxEId8YDzbyCY,88
|
14
|
-
outerbounds-0.3.55rc3.dist-info/entry_points.txt,sha256=7ye0281PKlvqxu15rjw60zKg2pMsXI49_A8BmGqIqBw,47
|
15
|
-
outerbounds-0.3.55rc3.dist-info/RECORD,,
|
File without changes
|