outerbounds 0.3.55rc3__py3-none-any.whl → 0.3.133__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 (56) hide show
  1. outerbounds/_vendor/PyYAML.LICENSE +20 -0
  2. outerbounds/_vendor/__init__.py +0 -0
  3. outerbounds/_vendor/_yaml/__init__.py +34 -0
  4. outerbounds/_vendor/click/__init__.py +73 -0
  5. outerbounds/_vendor/click/_compat.py +626 -0
  6. outerbounds/_vendor/click/_termui_impl.py +717 -0
  7. outerbounds/_vendor/click/_textwrap.py +49 -0
  8. outerbounds/_vendor/click/_winconsole.py +279 -0
  9. outerbounds/_vendor/click/core.py +2998 -0
  10. outerbounds/_vendor/click/decorators.py +497 -0
  11. outerbounds/_vendor/click/exceptions.py +287 -0
  12. outerbounds/_vendor/click/formatting.py +301 -0
  13. outerbounds/_vendor/click/globals.py +68 -0
  14. outerbounds/_vendor/click/parser.py +529 -0
  15. outerbounds/_vendor/click/py.typed +0 -0
  16. outerbounds/_vendor/click/shell_completion.py +580 -0
  17. outerbounds/_vendor/click/termui.py +787 -0
  18. outerbounds/_vendor/click/testing.py +479 -0
  19. outerbounds/_vendor/click/types.py +1073 -0
  20. outerbounds/_vendor/click/utils.py +580 -0
  21. outerbounds/_vendor/click.LICENSE +28 -0
  22. outerbounds/_vendor/vendor_any.txt +2 -0
  23. outerbounds/_vendor/yaml/__init__.py +471 -0
  24. outerbounds/_vendor/yaml/_yaml.cpython-311-darwin.so +0 -0
  25. outerbounds/_vendor/yaml/composer.py +146 -0
  26. outerbounds/_vendor/yaml/constructor.py +862 -0
  27. outerbounds/_vendor/yaml/cyaml.py +177 -0
  28. outerbounds/_vendor/yaml/dumper.py +138 -0
  29. outerbounds/_vendor/yaml/emitter.py +1239 -0
  30. outerbounds/_vendor/yaml/error.py +94 -0
  31. outerbounds/_vendor/yaml/events.py +104 -0
  32. outerbounds/_vendor/yaml/loader.py +62 -0
  33. outerbounds/_vendor/yaml/nodes.py +51 -0
  34. outerbounds/_vendor/yaml/parser.py +629 -0
  35. outerbounds/_vendor/yaml/reader.py +208 -0
  36. outerbounds/_vendor/yaml/representer.py +378 -0
  37. outerbounds/_vendor/yaml/resolver.py +245 -0
  38. outerbounds/_vendor/yaml/scanner.py +1555 -0
  39. outerbounds/_vendor/yaml/serializer.py +127 -0
  40. outerbounds/_vendor/yaml/tokens.py +129 -0
  41. outerbounds/command_groups/apps_cli.py +450 -0
  42. outerbounds/command_groups/cli.py +9 -5
  43. outerbounds/command_groups/local_setup_cli.py +249 -33
  44. outerbounds/command_groups/perimeters_cli.py +231 -33
  45. outerbounds/command_groups/tutorials_cli.py +111 -0
  46. outerbounds/command_groups/workstations_cli.py +88 -15
  47. outerbounds/utils/kubeconfig.py +2 -2
  48. outerbounds/utils/metaflowconfig.py +111 -21
  49. outerbounds/utils/schema.py +8 -2
  50. outerbounds/utils/utils.py +19 -0
  51. outerbounds/vendor.py +159 -0
  52. {outerbounds-0.3.55rc3.dist-info → outerbounds-0.3.133.dist-info}/METADATA +17 -6
  53. outerbounds-0.3.133.dist-info/RECORD +59 -0
  54. {outerbounds-0.3.55rc3.dist-info → outerbounds-0.3.133.dist-info}/WHEEL +1 -1
  55. outerbounds-0.3.55rc3.dist-info/RECORD +0 -15
  56. {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 requests
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
- def init_config(config_dir="", profile="") -> dict:
9
- profile = profile or os.environ.get("METAFLOW_PROFILE")
10
- config_dir = config_dir or os.path.expanduser(
11
- os.environ.get("METAFLOW_HOME", "~/.metaflowconfig")
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
@@ -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 = "We found one or more errors with your installation."
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 = "We found one or more warnings with your installation."
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.55rc3
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,<4.0
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
- Requires-Dist: PyYAML (>=6.0,<7.0)
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: ob-metaflow (==2.11.0.4)
27
- Requires-Dist: ob-metaflow-extensions (==1.1.45rc2)
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,4 +1,4 @@
1
1
  Wheel-Version: 1.0
2
- Generator: poetry-core 1.4.0
2
+ Generator: poetry-core 1.9.0
3
3
  Root-Is-Purelib: true
4
4
  Tag: py3-none-any
@@ -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,,