outerbounds 0.3.183rc0__py3-none-any.whl → 0.3.183rc1__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.
@@ -245,7 +245,7 @@ class DEPLOYMENT_READY_CONDITIONS:
245
245
  - ATLEAST_ONE_RUNNING: At least one worker is running and update is not in progress
246
246
  - ALL_RUNNING: All required workers are running and update is not in progress
247
247
  - FULLY_FINISHED: All workers running with no pending/crashlooping workers and update is not in progress
248
- - ASYNC: Deployment ready when update is no longer in progress
248
+ - ASYNC: Deployment is ready when the backend registers the current serving version in the capsule's status.
249
249
 
250
250
  Returns
251
251
  -------
@@ -278,7 +278,11 @@ class DEPLOYMENT_READY_CONDITIONS:
278
278
  and not capsule_status["updateInProgress"]
279
279
  )
280
280
  elif readiness_condition == cls.ASYNC:
281
- _readiness_condition_satisfied = not capsule_status["updateInProgress"]
281
+ # The async readiness condition is satisfied when the currently served version is the same as the final version.
282
+ _readiness_condition_satisfied = (
283
+ capsule_status["currentlyServedVersion"]
284
+ == worker_semantic_status["final_version"]
285
+ )
282
286
  _worker_readiness_check = False
283
287
  else:
284
288
  raise ValueError(f"Invalid readiness condition: {readiness_condition}")
@@ -295,6 +299,7 @@ class DEPLOYMENT_READY_CONDITIONS:
295
299
  cls.ATLEAST_ONE_RUNNING,
296
300
  cls.ALL_RUNNING,
297
301
  cls.FULLY_FINISHED,
302
+ cls.ASYNC,
298
303
  ]
299
304
 
300
305
 
@@ -21,8 +21,6 @@ from typing import Dict, List, Any, Optional, Union
21
21
  # way to figure the right import of click dynamically. a neat way to handle that would be
22
22
  # to have a function that can import the correct click based on the context in which stuff is being loaded.
23
23
  from .click_importer import click
24
- from outerbounds._vendor import yaml
25
- from outerbounds.utils import metaflowconfig
26
24
  from .app_config import (
27
25
  AppConfig,
28
26
  AppConfigError,
@@ -299,7 +297,7 @@ def _pre_create_debug(
299
297
  ):
300
298
  if CAPSULE_DEBUG:
301
299
  os.makedirs(state_dir, exist_ok=True)
302
- debug_path = os.path.join(state_dir, f"debug_{time.time()}.yaml")
300
+ debug_path = os.path.join(state_dir, f"debug_{time.time()}.json")
303
301
  with open(
304
302
  debug_path,
305
303
  "w",
@@ -322,14 +320,10 @@ def _pre_create_debug(
322
320
  def _post_create_debug(capsule: CapsuleDeployer, state_dir: str):
323
321
  if CAPSULE_DEBUG:
324
322
  debug_path = os.path.join(
325
- state_dir, f"debug_deploy_response_{time.time()}.yaml"
323
+ state_dir, f"debug_deploy_response_{time.time()}.json"
326
324
  )
327
325
  with open(debug_path, "w") as f:
328
- f.write(
329
- yaml.dump(
330
- capsule._capsule_deploy_response, default_flow_style=False, indent=2
331
- )
332
- )
326
+ f.write(json.dumps(capsule._capsule_deploy_response, indent=2, default=str))
333
327
 
334
328
 
335
329
  def _bake_image(app_config: AppConfig, cache_dir: str, logger):
@@ -719,7 +713,7 @@ def deploy(
719
713
 
720
714
  if not ctx.obj.perimeter:
721
715
  raise AppConfigError("OB_CURRENT_PERIMETER is not set")
722
-
716
+ _current_instance_debug_dir = None
723
717
  logger = partial(_logger, timestamp=True)
724
718
  try:
725
719
  _cli_parsed_config = build_config_from_options(options)
@@ -850,6 +844,21 @@ def deploy(
850
844
 
851
845
  capsule_spinner = None
852
846
  capsule_logger = _non_spinner_logger
847
+ # 2. Convert to the IR that the backend accepts
848
+ capsule = CapsuleDeployer(
849
+ app_config,
850
+ ctx.obj.api_url,
851
+ debug_dir=_current_instance_debug_dir,
852
+ success_terminal_state_condition=readiness_condition,
853
+ create_timeout=max_wait_time,
854
+ readiness_wait_time=readiness_wait_time,
855
+ logger_fn=capsule_logger,
856
+ )
857
+ _current_instance_debug_dir = os.path.join(
858
+ cache_dir, f"debug_deployment_instance_{time.time()}"
859
+ )
860
+ if CAPSULE_DEBUG:
861
+ os.makedirs(_current_instance_debug_dir, exist_ok=True)
853
862
  if not no_loader:
854
863
  capsule_spinner = MultiStepSpinner(
855
864
  text=lambda: _logger_styled(
@@ -862,21 +871,6 @@ def deploy(
862
871
  capsule_logger = partial(_spinner_logger, capsule_spinner)
863
872
  capsule_spinner.start()
864
873
 
865
- _current_instance_debug_dir = os.path.join(
866
- cache_dir, f"debug_deployment_instance_{time.time()}"
867
- )
868
- if CAPSULE_DEBUG:
869
- os.makedirs(_current_instance_debug_dir, exist_ok=True)
870
- # 2. Convert to the IR that the backend accepts
871
- capsule = CapsuleDeployer(
872
- app_config,
873
- ctx.obj.api_url,
874
- debug_dir=_current_instance_debug_dir,
875
- success_terminal_state_condition=readiness_condition,
876
- create_timeout=max_wait_time,
877
- readiness_wait_time=readiness_wait_time,
878
- logger_fn=capsule_logger,
879
- )
880
874
  currently_present_capsules = list_and_filter_capsules(
881
875
  capsule.capsule_api,
882
876
  None,
@@ -957,12 +951,18 @@ def deploy(
957
951
  )
958
952
 
959
953
  except Exception as e:
954
+ message = getattr(e, "message", str(e))
960
955
  logger(
961
- f"Deployment failed: [{e.__class__.__name__}]: {e}",
956
+ f"Deployment failed: [{e.__class__.__name__}]: {message}",
962
957
  bad=True,
963
958
  system_msg=True,
964
959
  )
965
960
  if CAPSULE_DEBUG:
961
+ if _current_instance_debug_dir is not None:
962
+ logger(
963
+ f"[debug] 💊 debug info saved to `{_current_instance_debug_dir}`",
964
+ color=ColorTheme.DEBUG_COLOR,
965
+ )
966
966
  raise e
967
967
  exit(1)
968
968
 
@@ -1,5 +1,7 @@
1
1
  import json
2
2
  import os
3
+
4
+ # TODO: remove vendor'd dependency where.
3
5
  from outerbounds._vendor import yaml
4
6
  from typing import Dict, Any
5
7
  from .cli_to_config import build_config_from_options
@@ -58,6 +60,7 @@ class AppConfig:
58
60
  @staticmethod
59
61
  def _load_schema():
60
62
  """Load the configuration schema from the YAML file."""
63
+ # TODO: Make it easier.
61
64
  schema_path = os.path.join(os.path.dirname(__file__), "config_schema.yaml")
62
65
  with open(schema_path, "r") as f:
63
66
  return yaml.safe_load(f)
@@ -5,6 +5,11 @@ description: |
5
5
  How to read this schema:
6
6
  1. If the a property has `allow_union`:true then it will allow overrides from the cli.
7
7
  2. If a property has `experimental` set to true then a lot its validations may-be skipped and parsing handled somewhere else.
8
+
9
+ The YAML based schema file is for Humans to change and consume. The JSON based schema file is what gets autogenerated based on pre-commit
10
+ hooks so that we can use within the outerbounds package. The reasons for two distinct types of files it that YAML provides the ability to
11
+ add comments and make readability easier. While JSON is so that we can reduce the dependency on YAML when working with apps within both
12
+ Metaflow and OB package.
8
13
  version: 1.0.0
9
14
  type: object
10
15
  required:
@@ -0,0 +1,336 @@
1
+ {
2
+ "title": "Outerbounds App Configuration Schema",
3
+ "description": "Schema for defining Outerbounds Apps configuration. This schema is what we will end up using on the CLI/programmatic interface.\nHow to read this schema:\n 1. If the a property has `allow_union`:true then it will allow overrides from the cli.\n 2. If a property has `experimental` set to true then a lot its validations may-be skipped and parsing handled somewhere else.\n\nThe YAML based schema file is for Humans to change and consume. The JSON based schema file is what gets autogenerated based on pre-commit\nhooks so that we can use within the outerbounds package. The reasons for two distinct types of files it that YAML provides the ability to\nadd comments and make readability easier. While JSON is so that we can reduce the dependency on YAML when working with apps within both\nMetaflow and OB package.\n",
4
+ "version": "1.0.0",
5
+ "type": "object",
6
+ "required": [
7
+ "name",
8
+ "port"
9
+ ],
10
+ "properties": {
11
+ "name": {
12
+ "allow_union": true,
13
+ "type": "string",
14
+ "description": "The name of the app to deploy.",
15
+ "maxLength": 20,
16
+ "example": "myapp"
17
+ },
18
+ "port": {
19
+ "allow_union": false,
20
+ "type": "integer",
21
+ "description": "Port where the app is hosted. When deployed this will be port on which we will deploy the app.",
22
+ "minimum": 1,
23
+ "maximum": 65535,
24
+ "example": 8000
25
+ },
26
+ "tags": {
27
+ "allow_union": true,
28
+ "type": "array",
29
+ "description": "The tags of the app to deploy.",
30
+ "items": {
31
+ "type": "object"
32
+ },
33
+ "example": [
34
+ {
35
+ "foo": "bar"
36
+ },
37
+ {
38
+ "x": "y"
39
+ }
40
+ ]
41
+ },
42
+ "description": {
43
+ "allow_union": true,
44
+ "type": "string",
45
+ "description": "The description of the app to deploy.",
46
+ "example": "This is a description of my app."
47
+ },
48
+ "force_upgrade": {
49
+ "allow_union": true,
50
+ "type": "boolean",
51
+ "description": "Whether to force upgrade the app even if it is currently being upgraded.",
52
+ "example": true
53
+ },
54
+ "app_type": {
55
+ "allow_union": true,
56
+ "type": "string",
57
+ "description": "The User defined type of app to deploy. Its only used for bookkeeping purposes.",
58
+ "example": "MyCustomAgent"
59
+ },
60
+ "image": {
61
+ "allow_union": true,
62
+ "type": "string",
63
+ "description": "The Docker image to deploy with the App."
64
+ },
65
+ "secrets": {
66
+ "allow_union": true,
67
+ "type": "array",
68
+ "description": "Outerbounds integrations to attach to the app. You can use the value you set in the `@secrets` decorator in your code.",
69
+ "items": {
70
+ "type": "string"
71
+ },
72
+ "example": [
73
+ "hf-token"
74
+ ]
75
+ },
76
+ "environment": {
77
+ "allow_union": true,
78
+ "type": "object",
79
+ "description": "Environment variables to deploy with the App.",
80
+ "additionalProperties": {
81
+ "oneOf": [
82
+ {
83
+ "type": "string"
84
+ },
85
+ {
86
+ "type": "number"
87
+ },
88
+ {
89
+ "type": "boolean"
90
+ },
91
+ {
92
+ "type": "object"
93
+ },
94
+ {
95
+ "type": "array"
96
+ }
97
+ ]
98
+ },
99
+ "example": {
100
+ "DEBUG": true,
101
+ "DATABASE_CONFIG": {
102
+ "host": "localhost",
103
+ "port": 5432
104
+ },
105
+ "ALLOWED_ORIGINS": [
106
+ "http://localhost:3000",
107
+ "https://myapp.com"
108
+ ]
109
+ }
110
+ },
111
+ "dependencies": {
112
+ "allow_union": false,
113
+ "type": "object",
114
+ "description": "The dependencies to attach to the app. Only one of the properties can be specified.\n",
115
+ "properties": {
116
+ "from_requirements_file": {
117
+ "type": "string",
118
+ "description": "The path to the requirements.txt file to attach to the app.",
119
+ "example": "requirements.txt"
120
+ },
121
+ "from_pyproject_toml": {
122
+ "type": "string",
123
+ "description": "The path to the pyproject.toml file to attach to the app.",
124
+ "example": "pyproject.toml"
125
+ },
126
+ "python": {
127
+ "type": "string",
128
+ "description": "The Python version to use for the app.\n",
129
+ "example": "3.10"
130
+ },
131
+ "pypi": {
132
+ "type": "object",
133
+ "description": "A dictionary of pypi dependencies to attach to the app.\nThe key is the package name and the value is the version.\n",
134
+ "example": {
135
+ "numpy": "1.23.0",
136
+ "pandas": ""
137
+ }
138
+ },
139
+ "conda": {
140
+ "type": "object",
141
+ "description": "A dictionary of pypi dependencies to attach to the app.\nThe key is the package name and the value is the version.\n",
142
+ "example": {
143
+ "numpy": "1.23.0",
144
+ "pandas": ""
145
+ }
146
+ }
147
+ }
148
+ },
149
+ "package": {
150
+ "allow_union": false,
151
+ "type": "object",
152
+ "description": "Configurations associated with packaging the app.\n",
153
+ "properties": {
154
+ "src_path": {
155
+ "type": "string",
156
+ "description": "The path to the source code to deploy with the App.",
157
+ "example": "./"
158
+ },
159
+ "suffixes": {
160
+ "type": "array",
161
+ "description": "A list of suffixes to add to the source code to deploy with the App.\n",
162
+ "items": {
163
+ "type": "string"
164
+ },
165
+ "example": [
166
+ ".py",
167
+ ".ipynb"
168
+ ]
169
+ }
170
+ }
171
+ },
172
+ "commands": {
173
+ "allow_union": false,
174
+ "type": "array",
175
+ "description": "A list of commands to run the app with. Cannot be configured from the CLI. Only used in `run` command.",
176
+ "items": {
177
+ "type": "string"
178
+ },
179
+ "example": [
180
+ "python app.py",
181
+ "python app.py --foo bar"
182
+ ]
183
+ },
184
+ "resources": {
185
+ "allow_union": true,
186
+ "type": "object",
187
+ "properties": {
188
+ "cpu": {
189
+ "type": "string",
190
+ "description": "CPU resource request and limit.",
191
+ "example": "500m",
192
+ "default": "1"
193
+ },
194
+ "memory": {
195
+ "type": "string",
196
+ "description": "Memory resource request and limit.",
197
+ "example": "512Mi",
198
+ "default": "4Gi"
199
+ },
200
+ "gpu": {
201
+ "type": "string",
202
+ "description": "GPU resource request and limit.",
203
+ "example": "1"
204
+ },
205
+ "storage": {
206
+ "type": "string",
207
+ "description": "Storage resource request and limit.",
208
+ "example": "1Gi",
209
+ "default": "10Gi"
210
+ }
211
+ }
212
+ },
213
+ "replicas": {
214
+ "allow_union": true,
215
+ "type": "object",
216
+ "description": "The number of replicas to deploy the app with.\n",
217
+ "properties": {
218
+ "min": {
219
+ "type": "integer",
220
+ "description": "The minimum number of replicas to deploy the app with.",
221
+ "example": 1
222
+ },
223
+ "max": {
224
+ "type": "integer",
225
+ "description": "The maximum number of replicas to deploy the app with.",
226
+ "example": 10
227
+ }
228
+ }
229
+ },
230
+ "health_check": {
231
+ "type": "object",
232
+ "allow_union": false,
233
+ "properties": {
234
+ "enabled": {
235
+ "type": "boolean",
236
+ "description": "Whether to enable health checks.",
237
+ "example": true,
238
+ "default": false
239
+ },
240
+ "path": {
241
+ "type": "string",
242
+ "description": "The path for health checks.",
243
+ "example": "/health"
244
+ },
245
+ "initial_delay_seconds": {
246
+ "type": "integer",
247
+ "description": "Number of seconds to wait before performing the first health check.",
248
+ "example": 10
249
+ },
250
+ "period_seconds": {
251
+ "type": "integer",
252
+ "description": "How often to perform the health check.",
253
+ "example": 30
254
+ }
255
+ }
256
+ },
257
+ "compute_pools": {
258
+ "allow_union": true,
259
+ "type": "array",
260
+ "description": "A list of compute pools to deploy the app to.\n",
261
+ "items": {
262
+ "type": "string"
263
+ },
264
+ "example": [
265
+ "default",
266
+ "large"
267
+ ]
268
+ },
269
+ "auth": {
270
+ "allow_union": false,
271
+ "type": "object",
272
+ "description": "Auth related configurations.\n",
273
+ "properties": {
274
+ "type": {
275
+ "type": "string",
276
+ "description": "The type of authentication to use for the app.\n",
277
+ "enum": [
278
+ "API",
279
+ "Browser"
280
+ ]
281
+ },
282
+ "public": {
283
+ "type": "boolean",
284
+ "description": "Whether the app is public or not.\n",
285
+ "default": true
286
+ }
287
+ }
288
+ },
289
+ "project": {
290
+ "type": "string",
291
+ "description": "The project name to deploy the app to.",
292
+ "experimental": true,
293
+ "allow_union": true
294
+ },
295
+ "branch": {
296
+ "type": "string",
297
+ "description": "The branch name to deploy the app to.",
298
+ "experimental": true,
299
+ "allow_union": true
300
+ },
301
+ "models": {
302
+ "type": "array",
303
+ "description": "model asset ids to include with the deployment. NO CLI Option for this Now.",
304
+ "experimental": true,
305
+ "allow_union": true,
306
+ "items": {
307
+ "type": "object",
308
+ "properties": {
309
+ "asset_id": {
310
+ "type": "string"
311
+ },
312
+ "asset_instance_id": {
313
+ "type": "string"
314
+ }
315
+ }
316
+ }
317
+ },
318
+ "data": {
319
+ "type": "array",
320
+ "description": "data asset ids to include with the deployment.",
321
+ "experimental": true,
322
+ "allow_union": true,
323
+ "items": {
324
+ "type": "object",
325
+ "properties": {
326
+ "asset_id": {
327
+ "type": "string"
328
+ },
329
+ "asset_instance_id": {
330
+ "type": "string"
331
+ }
332
+ }
333
+ }
334
+ }
335
+ }
336
+ }
outerbounds/apps/utils.py CHANGED
@@ -17,6 +17,7 @@ import logging
17
17
  import itertools
18
18
  from typing import Union, Callable, Any, List
19
19
 
20
+ # TODO: remove vendor'd dependency where.
20
21
  from outerbounds._vendor.spinner import (
21
22
  Spinners,
22
23
  )
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.1
2
2
  Name: outerbounds
3
- Version: 0.3.183rc0
3
+ Version: 0.3.183rc1
4
4
  Summary: More Data Science, Less Administration
5
5
  License: Proprietary
6
6
  Keywords: data science,machine learning,MLOps
@@ -29,8 +29,8 @@ Requires-Dist: google-cloud-secret-manager (>=2.20.0,<3.0.0) ; extra == "gcp"
29
29
  Requires-Dist: google-cloud-storage (>=2.14.0,<3.0.0) ; extra == "gcp"
30
30
  Requires-Dist: metaflow-checkpoint (==0.2.1)
31
31
  Requires-Dist: ob-metaflow (==2.15.18.1)
32
- Requires-Dist: ob-metaflow-extensions (==1.1.171rc0)
33
- Requires-Dist: ob-metaflow-stubs (==6.0.3.183rc0)
32
+ Requires-Dist: ob-metaflow-extensions (==1.1.171rc1)
33
+ Requires-Dist: ob-metaflow-stubs (==6.0.3.183rc1)
34
34
  Requires-Dist: opentelemetry-distro (>=0.41b0) ; extra == "otel"
35
35
  Requires-Dist: opentelemetry-exporter-otlp-proto-http (>=1.20.0) ; extra == "otel"
36
36
  Requires-Dist: opentelemetry-instrumentation-requests (>=0.41b0) ; extra == "otel"
@@ -43,9 +43,9 @@ outerbounds/_vendor/yaml/scanner.py,sha256=ZcI8IngR56PaQ0m27WU2vxCqmDCuRjz-hr7pi
43
43
  outerbounds/_vendor/yaml/serializer.py,sha256=8wFZRy9SsQSktF_f9OOroroqsh4qVUe53ry07P9UgCc,4368
44
44
  outerbounds/_vendor/yaml/tokens.py,sha256=JBSu38wihGr4l73JwbfMA7Ks1-X84g8-NskTz7KwPmA,2578
45
45
  outerbounds/apps/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
46
- outerbounds/apps/_state_machine.py,sha256=PaegyxSxNZxyLTxU9_kekd3MPM9sW76RZPkibeMTMfY,18314
47
- outerbounds/apps/app_cli.py,sha256=n_NABDjdgY4ApgNvdQMmpJfPGzCwJxr_G0w6-5LZ85I,51940
48
- outerbounds/apps/app_config.py,sha256=UHVK8JLIuW-OcGg5WxDm4QHeImPGtohD4KpJryZntC4,11307
46
+ outerbounds/apps/_state_machine.py,sha256=uv3tGOWxqY0NdQdsjg3uvPpBu0JeniE41AE9_H7El5c,18601
47
+ outerbounds/apps/app_cli.py,sha256=bblWHLC9h6VCaXYnVndrrpmcuahapbsR9NzeU4rX84I,52107
48
+ outerbounds/apps/app_config.py,sha256=ixxeOlZD0AB2TFoN-mzeqEqduGriTSCsdFFm23bVpqw,11382
49
49
  outerbounds/apps/artifacts.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
50
50
  outerbounds/apps/capsule.py,sha256=NC9ajD06y6U-COi-8Qw6k_N1ltbQAio2O_Xs2RTrAVA,32857
51
51
  outerbounds/apps/cli_to_config.py,sha256=Thc5jXRxoU6Pr8kAVVOX-5Es5ha6y6Vh_GBzL__oI7Q,3299
@@ -53,13 +53,14 @@ outerbounds/apps/click_importer.py,sha256=nnkPOR6TKrtIpc3a5Fna1zVJoQqDZvUXlNA9Cd
53
53
  outerbounds/apps/code_package/__init__.py,sha256=8McF7pgx8ghvjRnazp2Qktlxi9yYwNiwESSQrk-2oW8,68
54
54
  outerbounds/apps/code_package/code_packager.py,sha256=RWvM5BKjgLhu7icsO_n5SSYC57dwyST0dWpoWF88ovU,22881
55
55
  outerbounds/apps/code_package/examples.py,sha256=aF8qKIJxCVv_ugcShQjqUsXKKKMsm1oMkQIl8w3QKuw,4016
56
- outerbounds/apps/config_schema.yaml,sha256=j_mysTAPkIMSocItTg3aduMDfBs2teIhAErvpF0Elus,8826
56
+ outerbounds/apps/config_schema.yaml,sha256=85g2khmkZg5pduilcOXMgn5m2I3DF_2WrRMjo5WsojM,9272
57
+ outerbounds/apps/config_schema_autogen.json,sha256=Mu9y6n-ophJ-48M9kBU4_tL6I9Y5nl06lMyufGMfOF8,9855
57
58
  outerbounds/apps/dependencies.py,sha256=03pZY-JRN-dYN-iyZ73zoEIEKmrOvbY4qld7RlRXYuw,3976
58
59
  outerbounds/apps/deployer.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
59
60
  outerbounds/apps/experimental/__init__.py,sha256=RUZBAyqFnX3pRQxTjNmS1-qpgQcc9xQGQD2yJh4MA_M,3349
60
61
  outerbounds/apps/perimeters.py,sha256=1J1_-5legFPskv3HTRwQMpzTytE3TO8KRT2IvVOrWcQ,1584
61
62
  outerbounds/apps/secrets.py,sha256=aWzcAayQEJghQgFP_qp9w6jyvan_hoL4_ceqZ0ZjLd4,6126
62
- outerbounds/apps/utils.py,sha256=C-4GLU5GHwwWHbW962Qac-wecvtdiBXezq0c8i9aJvs,7908
63
+ outerbounds/apps/utils.py,sha256=Yvoj1NFoIBqqaWQ32530saCb66B_juSiDOanH0CJJDE,7950
63
64
  outerbounds/apps/validations.py,sha256=kR2eXckx0XJ4kUOOLkMRepbTh0INtL1Z8aV4-fZpfc8,678
64
65
  outerbounds/cli_main.py,sha256=e9UMnPysmc7gbrimq2I4KfltggyU7pw59Cn9aEguVcU,74
65
66
  outerbounds/command_groups/__init__.py,sha256=QPWtj5wDRTINDxVUL7XPqG3HoxHNvYOg08EnuSZB2Hc,21
@@ -78,7 +79,7 @@ outerbounds/utils/metaflowconfig.py,sha256=l2vJbgPkLISU-XPGZFaC8ZKmYFyJemlD6bwB-
78
79
  outerbounds/utils/schema.py,sha256=lMUr9kNgn9wy-sO_t_Tlxmbt63yLeN4b0xQXbDUDj4A,2331
79
80
  outerbounds/utils/utils.py,sha256=4Z8cszNob_8kDYCLNTrP-wWads_S_MdL3Uj3ju4mEsk,501
80
81
  outerbounds/vendor.py,sha256=gRLRJNXtZBeUpPEog0LOeIsl6GosaFFbCxUvR4bW6IQ,5093
81
- outerbounds-0.3.183rc0.dist-info/METADATA,sha256=wY0FgePmu807U8X1eBnglevz656zQgPuAjooGlbNpMU,1846
82
- outerbounds-0.3.183rc0.dist-info/WHEEL,sha256=sP946D7jFCHeNz5Iq4fL4Lu-PrWrFsgfLXbbkciIZwg,88
83
- outerbounds-0.3.183rc0.dist-info/entry_points.txt,sha256=AP6rZg7y5SK9e9a9iVq0Fi9Q2KPjPZSwtZ6R98rLw-8,56
84
- outerbounds-0.3.183rc0.dist-info/RECORD,,
82
+ outerbounds-0.3.183rc1.dist-info/METADATA,sha256=Szdy_WqZjvdilRX2b-KlnLVKg6T3bGlmGCOQzlHNyRw,1846
83
+ outerbounds-0.3.183rc1.dist-info/WHEEL,sha256=sP946D7jFCHeNz5Iq4fL4Lu-PrWrFsgfLXbbkciIZwg,88
84
+ outerbounds-0.3.183rc1.dist-info/entry_points.txt,sha256=AP6rZg7y5SK9e9a9iVq0Fi9Q2KPjPZSwtZ6R98rLw-8,56
85
+ outerbounds-0.3.183rc1.dist-info/RECORD,,