ob-metaflow-extensions 1.1.78__py2.py3-none-any.whl → 1.1.80__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.
- metaflow_extensions/outerbounds/config/__init__.py +28 -0
- metaflow_extensions/outerbounds/plugins/__init__.py +17 -3
- metaflow_extensions/outerbounds/plugins/fast_bakery/__init__.py +0 -0
- metaflow_extensions/outerbounds/plugins/fast_bakery/docker_environment.py +268 -0
- metaflow_extensions/outerbounds/plugins/fast_bakery/fast_bakery.py +160 -0
- metaflow_extensions/outerbounds/plugins/fast_bakery/fast_bakery_cli.py +54 -0
- metaflow_extensions/outerbounds/plugins/fast_bakery/fast_bakery_decorator.py +50 -0
- metaflow_extensions/outerbounds/plugins/snowpark/__init__.py +0 -0
- metaflow_extensions/outerbounds/plugins/snowpark/snowpark.py +299 -0
- metaflow_extensions/outerbounds/plugins/snowpark/snowpark_cli.py +271 -0
- metaflow_extensions/outerbounds/plugins/snowpark/snowpark_client.py +123 -0
- metaflow_extensions/outerbounds/plugins/snowpark/snowpark_decorator.py +264 -0
- metaflow_extensions/outerbounds/plugins/snowpark/snowpark_exceptions.py +13 -0
- metaflow_extensions/outerbounds/plugins/snowpark/snowpark_job.py +235 -0
- metaflow_extensions/outerbounds/plugins/snowpark/snowpark_service_spec.py +259 -0
- {ob_metaflow_extensions-1.1.78.dist-info → ob_metaflow_extensions-1.1.80.dist-info}/METADATA +2 -2
- {ob_metaflow_extensions-1.1.78.dist-info → ob_metaflow_extensions-1.1.80.dist-info}/RECORD +19 -6
- {ob_metaflow_extensions-1.1.78.dist-info → ob_metaflow_extensions-1.1.80.dist-info}/WHEEL +0 -0
- {ob_metaflow_extensions-1.1.78.dist-info → ob_metaflow_extensions-1.1.80.dist-info}/top_level.txt +0 -0
|
@@ -0,0 +1,259 @@
|
|
|
1
|
+
import json
|
|
2
|
+
from collections import defaultdict
|
|
3
|
+
from typing import List, Dict, Optional
|
|
4
|
+
|
|
5
|
+
|
|
6
|
+
class Container:
|
|
7
|
+
def __init__(self, name: str, image: str):
|
|
8
|
+
self.payload = defaultdict(lambda: defaultdict(dict))
|
|
9
|
+
self.payload["name"] = name
|
|
10
|
+
self.payload["image"] = image
|
|
11
|
+
|
|
12
|
+
def command(self, command: List[str]) -> "Container":
|
|
13
|
+
self.payload["command"] = command
|
|
14
|
+
return self
|
|
15
|
+
|
|
16
|
+
def args(self, args: List[str]) -> "Container":
|
|
17
|
+
self.payload["args"] = args
|
|
18
|
+
return self
|
|
19
|
+
|
|
20
|
+
def env(self, env: Dict[str, str]) -> "Container":
|
|
21
|
+
self.payload["env"] = env
|
|
22
|
+
return self
|
|
23
|
+
|
|
24
|
+
def readiness_probe(self, readiness_probe: "ReadinessProbe") -> "Container":
|
|
25
|
+
self.payload["readiness_probe"] = (
|
|
26
|
+
readiness_probe.to_dict() if readiness_probe else None
|
|
27
|
+
)
|
|
28
|
+
return self
|
|
29
|
+
|
|
30
|
+
def volume_mounts(self, volume_mounts: List["VolumeMount"]) -> "Container":
|
|
31
|
+
self.payload["volume_mounts"] = [vm.to_dict() for vm in volume_mounts]
|
|
32
|
+
return self
|
|
33
|
+
|
|
34
|
+
def resources(self, resources: "Resources") -> "Container":
|
|
35
|
+
self.payload["resources"] = resources.to_dict() if resources else None
|
|
36
|
+
return self
|
|
37
|
+
|
|
38
|
+
def secrets(self, secrets: List["Secrets"]) -> "Container":
|
|
39
|
+
self.payload["secrets"] = [secret.to_dict() for secret in secrets]
|
|
40
|
+
return self
|
|
41
|
+
|
|
42
|
+
def to_dict(self) -> Dict:
|
|
43
|
+
result = {"name": self.payload["name"], "image": self.payload["image"]}
|
|
44
|
+
if "command" in self.payload and self.payload["command"]:
|
|
45
|
+
result["command"] = self.payload["command"]
|
|
46
|
+
if "args" in self.payload and self.payload["args"]:
|
|
47
|
+
result["args"] = self.payload["args"]
|
|
48
|
+
if "env" in self.payload and self.payload["env"]:
|
|
49
|
+
result["env"] = self.payload["env"]
|
|
50
|
+
if "readiness_probe" in self.payload and self.payload["readiness_probe"]:
|
|
51
|
+
result["readiness_probe"] = self.payload["readiness_probe"]
|
|
52
|
+
if "volume_mounts" in self.payload and self.payload["volume_mounts"]:
|
|
53
|
+
result["volume_mounts"] = self.payload["volume_mounts"]
|
|
54
|
+
if "resources" in self.payload and self.payload["resources"]:
|
|
55
|
+
result["resources"] = self.payload["resources"]
|
|
56
|
+
if "secrets" in self.payload and self.payload["secrets"]:
|
|
57
|
+
result["secrets"] = self.payload["secrets"]
|
|
58
|
+
return result
|
|
59
|
+
|
|
60
|
+
|
|
61
|
+
class ReadinessProbe:
|
|
62
|
+
def __init__(self, port: int, path: str):
|
|
63
|
+
self.payload = defaultdict(dict)
|
|
64
|
+
self.payload["port"] = port
|
|
65
|
+
self.payload["path"] = path
|
|
66
|
+
|
|
67
|
+
def to_dict(self) -> Dict:
|
|
68
|
+
return dict(self.payload)
|
|
69
|
+
|
|
70
|
+
|
|
71
|
+
class VolumeMount:
|
|
72
|
+
def __init__(self, name: str, mount_path: str):
|
|
73
|
+
self.payload = defaultdict(dict)
|
|
74
|
+
self.payload["name"] = name
|
|
75
|
+
self.payload["mount_path"] = mount_path
|
|
76
|
+
|
|
77
|
+
def to_dict(self) -> Dict:
|
|
78
|
+
return dict(self.payload)
|
|
79
|
+
|
|
80
|
+
|
|
81
|
+
class Resources:
|
|
82
|
+
def __init__(
|
|
83
|
+
self,
|
|
84
|
+
requests: Optional[Dict[str, str]] = None,
|
|
85
|
+
limits: Optional[Dict[str, str]] = None,
|
|
86
|
+
):
|
|
87
|
+
self.payload = defaultdict(dict)
|
|
88
|
+
if requests:
|
|
89
|
+
self.payload["requests"] = requests
|
|
90
|
+
if limits:
|
|
91
|
+
self.payload["limits"] = limits
|
|
92
|
+
|
|
93
|
+
def to_dict(self) -> Dict:
|
|
94
|
+
result = {}
|
|
95
|
+
if "requests" in self.payload and self.payload["requests"]:
|
|
96
|
+
result["requests"] = self.payload["requests"]
|
|
97
|
+
if "limits" in self.payload and self.payload["limits"]:
|
|
98
|
+
result["limits"] = self.payload["limits"]
|
|
99
|
+
return result
|
|
100
|
+
|
|
101
|
+
|
|
102
|
+
class Secrets:
|
|
103
|
+
def __init__(self, snowflake_secret: str):
|
|
104
|
+
self.payload = {"snowflake_secret": snowflake_secret}
|
|
105
|
+
|
|
106
|
+
def secret_key_ref(self, secret_key_ref: str) -> "Secrets":
|
|
107
|
+
self.payload["secret_key_ref"] = secret_key_ref
|
|
108
|
+
return self
|
|
109
|
+
|
|
110
|
+
def env_var_name(self, env_var_name: str) -> "Secrets":
|
|
111
|
+
self.payload["env_var_name"] = env_var_name
|
|
112
|
+
return self
|
|
113
|
+
|
|
114
|
+
def directory_path(self, directory_path: str) -> "Secrets":
|
|
115
|
+
self.payload["directory_path"] = directory_path
|
|
116
|
+
return self
|
|
117
|
+
|
|
118
|
+
def to_dict(self) -> Dict:
|
|
119
|
+
return {k: v for k, v in self.payload.items() if v}
|
|
120
|
+
|
|
121
|
+
|
|
122
|
+
class Endpoint:
|
|
123
|
+
def __init__(self, name: str, port: int):
|
|
124
|
+
self.payload = defaultdict(dict)
|
|
125
|
+
self.payload["name"] = name
|
|
126
|
+
self.payload["port"] = port
|
|
127
|
+
|
|
128
|
+
def public(self, public: bool) -> "Endpoint":
|
|
129
|
+
self.payload["public"] = public
|
|
130
|
+
return self
|
|
131
|
+
|
|
132
|
+
def protocol(self, protocol: str) -> "Endpoint":
|
|
133
|
+
self.payload["protocol"] = protocol
|
|
134
|
+
return self
|
|
135
|
+
|
|
136
|
+
def to_dict(self) -> Dict:
|
|
137
|
+
return dict(self.payload)
|
|
138
|
+
|
|
139
|
+
|
|
140
|
+
class Volume:
|
|
141
|
+
def __init__(self, name: str, source: str):
|
|
142
|
+
self.payload = defaultdict(dict)
|
|
143
|
+
self.payload["name"] = name
|
|
144
|
+
self.payload["source"] = source
|
|
145
|
+
|
|
146
|
+
def size(self, size: str) -> "Volume":
|
|
147
|
+
self.payload["size"] = size
|
|
148
|
+
return self
|
|
149
|
+
|
|
150
|
+
def block_config(self, block_config: Dict) -> "Volume":
|
|
151
|
+
self.payload["block_config"] = block_config
|
|
152
|
+
return self
|
|
153
|
+
|
|
154
|
+
def uid(self, uid: int) -> "Volume":
|
|
155
|
+
self.payload["uid"] = uid
|
|
156
|
+
return self
|
|
157
|
+
|
|
158
|
+
def gid(self, gid: int) -> "Volume":
|
|
159
|
+
self.payload["gid"] = gid
|
|
160
|
+
return self
|
|
161
|
+
|
|
162
|
+
def to_dict(self) -> Dict:
|
|
163
|
+
result = {"name": self.payload["name"], "source": self.payload["source"]}
|
|
164
|
+
if "size" in self.payload:
|
|
165
|
+
result["size"] = self.payload["size"]
|
|
166
|
+
if "block_config" in self.payload:
|
|
167
|
+
result["block_config"] = self.payload["block_config"]
|
|
168
|
+
if "uid" in self.payload:
|
|
169
|
+
result["uid"] = self.payload["uid"]
|
|
170
|
+
if "gid" in self.payload:
|
|
171
|
+
result["gid"] = self.payload["gid"]
|
|
172
|
+
return result
|
|
173
|
+
|
|
174
|
+
|
|
175
|
+
class LogExporters:
|
|
176
|
+
def __init__(self):
|
|
177
|
+
self.payload = {}
|
|
178
|
+
|
|
179
|
+
def event_table_config(self, log_level: str) -> "LogExporters":
|
|
180
|
+
self.payload["eventTableConfig"] = {"logLevel": log_level}
|
|
181
|
+
return self
|
|
182
|
+
|
|
183
|
+
def to_dict(self) -> Dict:
|
|
184
|
+
return dict(self.payload)
|
|
185
|
+
|
|
186
|
+
|
|
187
|
+
class ServiceRole:
|
|
188
|
+
def __init__(self, name: str):
|
|
189
|
+
self.payload = {"name": name}
|
|
190
|
+
|
|
191
|
+
def endpoints(self, endpoints: List[str]) -> "ServiceRole":
|
|
192
|
+
self.payload["endpoints"] = endpoints
|
|
193
|
+
return self
|
|
194
|
+
|
|
195
|
+
def to_dict(self) -> Dict:
|
|
196
|
+
return dict(self.payload)
|
|
197
|
+
|
|
198
|
+
|
|
199
|
+
class SnowparkServiceSpec:
|
|
200
|
+
def __init__(self):
|
|
201
|
+
self.payload = defaultdict(lambda: defaultdict(list))
|
|
202
|
+
|
|
203
|
+
def containers(self, containers: List[Container]) -> "SnowparkServiceSpec":
|
|
204
|
+
self.payload["containers"] = [container.to_dict() for container in containers]
|
|
205
|
+
return self
|
|
206
|
+
|
|
207
|
+
def endpoints(self, endpoints: List[Endpoint]) -> "SnowparkServiceSpec":
|
|
208
|
+
self.payload["endpoints"] = [endpoint.to_dict() for endpoint in endpoints]
|
|
209
|
+
return self
|
|
210
|
+
|
|
211
|
+
def volumes(self, volumes: List[Volume]) -> "SnowparkServiceSpec":
|
|
212
|
+
self.payload["volumes"] = [volume.to_dict() for volume in volumes]
|
|
213
|
+
return self
|
|
214
|
+
|
|
215
|
+
def log_exporters(self, log_exporters: LogExporters) -> "SnowparkServiceSpec":
|
|
216
|
+
self.payload["logExporters"] = log_exporters.to_dict()
|
|
217
|
+
return self
|
|
218
|
+
|
|
219
|
+
def service_roles(self, service_roles: List[ServiceRole]) -> "SnowparkServiceSpec":
|
|
220
|
+
self.payload["serviceRoles"] = [role.to_dict() for role in service_roles]
|
|
221
|
+
return self
|
|
222
|
+
|
|
223
|
+
def to_dict(self) -> Dict:
|
|
224
|
+
return {"spec": dict(self.payload)}
|
|
225
|
+
|
|
226
|
+
|
|
227
|
+
def generate_spec_file(spec: SnowparkServiceSpec, filename: str, format: str = "yaml"):
|
|
228
|
+
import yaml
|
|
229
|
+
|
|
230
|
+
spec_dict = spec.to_dict()
|
|
231
|
+
with open(filename, "w") as file:
|
|
232
|
+
if format == "json":
|
|
233
|
+
json.dump(spec_dict, file, indent=2)
|
|
234
|
+
elif format == "yaml":
|
|
235
|
+
yaml.dump(spec_dict, file, default_flow_style=False)
|
|
236
|
+
|
|
237
|
+
|
|
238
|
+
if __name__ == "__main__":
|
|
239
|
+
# Example usage
|
|
240
|
+
container = (
|
|
241
|
+
Container(name="example-container", image="example-image")
|
|
242
|
+
.command(["python3", "app.py"])
|
|
243
|
+
.env({"ENV_VARIABLE": "value"})
|
|
244
|
+
.readiness_probe(ReadinessProbe(port=8080, path="/health"))
|
|
245
|
+
.resources(
|
|
246
|
+
Resources(requests={"memory": "2G", "cpu": "1"}, limits={"memory": "4G"})
|
|
247
|
+
)
|
|
248
|
+
)
|
|
249
|
+
|
|
250
|
+
endpoint = Endpoint(name="example-endpoint", port=8080).public(True)
|
|
251
|
+
volume = Volume(name="example-volume", source="local")
|
|
252
|
+
spec = (
|
|
253
|
+
SnowparkServiceSpec()
|
|
254
|
+
.containers([container])
|
|
255
|
+
.endpoints([endpoint])
|
|
256
|
+
.volumes([volume])
|
|
257
|
+
)
|
|
258
|
+
|
|
259
|
+
generate_spec_file(spec, "service_spec.yaml", format="yaml")
|
{ob_metaflow_extensions-1.1.78.dist-info → ob_metaflow_extensions-1.1.80.dist-info}/METADATA
RENAMED
|
@@ -1,13 +1,13 @@
|
|
|
1
1
|
Metadata-Version: 2.1
|
|
2
2
|
Name: ob-metaflow-extensions
|
|
3
|
-
Version: 1.1.
|
|
3
|
+
Version: 1.1.80
|
|
4
4
|
Summary: Outerbounds Platform Extensions for Metaflow
|
|
5
5
|
Author: Outerbounds, Inc.
|
|
6
6
|
License: Commercial
|
|
7
7
|
Description-Content-Type: text/markdown
|
|
8
8
|
Requires-Dist: boto3
|
|
9
9
|
Requires-Dist: kubernetes
|
|
10
|
-
Requires-Dist: ob-metaflow (==2.12.
|
|
10
|
+
Requires-Dist: ob-metaflow (==2.12.15.1)
|
|
11
11
|
|
|
12
12
|
# Outerbounds platform package
|
|
13
13
|
|
|
@@ -1,9 +1,14 @@
|
|
|
1
1
|
metaflow_extensions/outerbounds/__init__.py,sha256=TRGvIUMjkfneWtYUFSWoubu_Kf2ekAL4WLbV3IxOj9k,499
|
|
2
2
|
metaflow_extensions/outerbounds/remote_config.py,sha256=Zpfpjgz68_ZgxlXezjzlsDLo4840rkWuZgwDB_5H57U,4059
|
|
3
|
-
metaflow_extensions/outerbounds/config/__init__.py,sha256=
|
|
4
|
-
metaflow_extensions/outerbounds/plugins/__init__.py,sha256=
|
|
3
|
+
metaflow_extensions/outerbounds/config/__init__.py,sha256=MwC9dK3A5waKt-DOdHJMw-7sA5Zrl89uLmYJiM3mucc,1057
|
|
4
|
+
metaflow_extensions/outerbounds/plugins/__init__.py,sha256=Y6Y2RlZFW5RwZjXa5QrKptht-u1p8faJxFFaA2n9Jy8,10074
|
|
5
5
|
metaflow_extensions/outerbounds/plugins/auth_server.py,sha256=1v2GBqoMBxp5E7Lejz139w-jxJtPnLDvvHXP0HhEIHI,2361
|
|
6
6
|
metaflow_extensions/outerbounds/plugins/perimeters.py,sha256=QXh3SFP7GQbS-RAIxUOPbhPzQ7KDFVxZkTdKqFKgXjI,2697
|
|
7
|
+
metaflow_extensions/outerbounds/plugins/fast_bakery/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
8
|
+
metaflow_extensions/outerbounds/plugins/fast_bakery/docker_environment.py,sha256=P8AOdQYz6T0D4Uj0_hUF91MF0FkRHBU9P7Wgihouk20,9852
|
|
9
|
+
metaflow_extensions/outerbounds/plugins/fast_bakery/fast_bakery.py,sha256=7ppPwnwb_b2bRdZnmxnZXsnDlysLe2Ah4o0vxJdrP6Q,4621
|
|
10
|
+
metaflow_extensions/outerbounds/plugins/fast_bakery/fast_bakery_cli.py,sha256=kqFyu2bJSnc9_9aYfBpz5xK6L6luWFZK_NMuh8f1eVk,1494
|
|
11
|
+
metaflow_extensions/outerbounds/plugins/fast_bakery/fast_bakery_decorator.py,sha256=EZDbyrfZ7fgcU-P9dMS_hpCxsdDeUE0K5VU3uNM4aW4,1506
|
|
7
12
|
metaflow_extensions/outerbounds/plugins/kubernetes/__init__.py,sha256=5zG8gShSj8m7rgF4xgWBZFuY3GDP5n1T0ktjRpGJLHA,69
|
|
8
13
|
metaflow_extensions/outerbounds/plugins/kubernetes/kubernetes_client.py,sha256=gj6Iaz26bGbZm3aQuNS18Mqh_80iJp5PgFwFSlJRcn8,1968
|
|
9
14
|
metaflow_extensions/outerbounds/plugins/nim/__init__.py,sha256=GVnvSTjqYVj5oG2yh8KJFt7iZ33cEadDD5HbdmC9hJ0,1457
|
|
@@ -12,6 +17,14 @@ metaflow_extensions/outerbounds/plugins/nvcf/__init__.py,sha256=47DEQpj8HBSa-_TI
|
|
|
12
17
|
metaflow_extensions/outerbounds/plugins/nvcf/nvcf.py,sha256=ftxC5SCo64P5Ycpv5vudluTnQi3-VCZW0umdsPP326A,7926
|
|
13
18
|
metaflow_extensions/outerbounds/plugins/nvcf/nvcf_cli.py,sha256=ow3lonclEDoZEUQCDV_L8lEr6HopXqjNXzubRrfdIm4,7219
|
|
14
19
|
metaflow_extensions/outerbounds/plugins/nvcf/nvcf_decorator.py,sha256=0xNA4aRTPJ4SKpRIFKZzlL9a7lf367KGTrVWVXd-uGE,6052
|
|
20
|
+
metaflow_extensions/outerbounds/plugins/snowpark/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
21
|
+
metaflow_extensions/outerbounds/plugins/snowpark/snowpark.py,sha256=vzgpVLCKvHjzHNfJvmH0jcxefYNsVggw_vof_y_U_a8,10643
|
|
22
|
+
metaflow_extensions/outerbounds/plugins/snowpark/snowpark_cli.py,sha256=ErsVoCQLa33byiykOQzDEeEkRKk0mgffZme43f3jxn4,8747
|
|
23
|
+
metaflow_extensions/outerbounds/plugins/snowpark/snowpark_client.py,sha256=JEW0EUxj_mNZXo9OFkJFmWfg-P7_CEgvNbgsMTCBTAE,4273
|
|
24
|
+
metaflow_extensions/outerbounds/plugins/snowpark/snowpark_decorator.py,sha256=3A9LKg7EarWM8WQ0PTGLUetjxzemQeUiJivvv_4uzr0,9886
|
|
25
|
+
metaflow_extensions/outerbounds/plugins/snowpark/snowpark_exceptions.py,sha256=FTfYlJu-sn9DkPOs2R1V1ChWb1vZthOgeq0BZdT1ucY,296
|
|
26
|
+
metaflow_extensions/outerbounds/plugins/snowpark/snowpark_job.py,sha256=d_5UhXqZ_12rCvatH1capPQZYGLx1FVqq_rtW65OXyk,6874
|
|
27
|
+
metaflow_extensions/outerbounds/plugins/snowpark/snowpark_service_spec.py,sha256=AI_kcm1hZV3JRxJkookcH6twiGnAYjk9Dx-MeoYz60Y,8511
|
|
15
28
|
metaflow_extensions/outerbounds/profilers/__init__.py,sha256=wa_jhnCBr82TBxoS0e8b6_6sLyZX0fdHicuGJZNTqKw,29
|
|
16
29
|
metaflow_extensions/outerbounds/profilers/gpu.py,sha256=a5YZAepujuP0uDqG9UpXBlZS3wjUt4Yv8CjybXqeT2c,24342
|
|
17
30
|
metaflow_extensions/outerbounds/toplevel/__init__.py,sha256=qWUJSv_r5hXJ7jV_On4nEasKIfUCm6_UjkjXWA_A1Ts,90
|
|
@@ -19,7 +32,7 @@ metaflow_extensions/outerbounds/toplevel/global_aliases_for_metaflow_package.py,
|
|
|
19
32
|
metaflow_extensions/outerbounds/toplevel/plugins/azure/__init__.py,sha256=WUuhz2YQfI4fz7nIcipwwWq781eaoHEk7n4GAn1npDg,63
|
|
20
33
|
metaflow_extensions/outerbounds/toplevel/plugins/gcp/__init__.py,sha256=BbZiaH3uILlEZ6ntBLKeNyqn3If8nIXZFq_Apd7Dhco,70
|
|
21
34
|
metaflow_extensions/outerbounds/toplevel/plugins/kubernetes/__init__.py,sha256=5zG8gShSj8m7rgF4xgWBZFuY3GDP5n1T0ktjRpGJLHA,69
|
|
22
|
-
ob_metaflow_extensions-1.1.
|
|
23
|
-
ob_metaflow_extensions-1.1.
|
|
24
|
-
ob_metaflow_extensions-1.1.
|
|
25
|
-
ob_metaflow_extensions-1.1.
|
|
35
|
+
ob_metaflow_extensions-1.1.80.dist-info/METADATA,sha256=WxObfrqrbhEeFqDktCqP8hrCZsyfqkcDCrlnAo-UP58,520
|
|
36
|
+
ob_metaflow_extensions-1.1.80.dist-info/WHEEL,sha256=bb2Ot9scclHKMOLDEHY6B2sicWOgugjFKaJsT7vwMQo,110
|
|
37
|
+
ob_metaflow_extensions-1.1.80.dist-info/top_level.txt,sha256=NwG0ukwjygtanDETyp_BUdtYtqIA_lOjzFFh1TsnxvI,20
|
|
38
|
+
ob_metaflow_extensions-1.1.80.dist-info/RECORD,,
|
|
File without changes
|
{ob_metaflow_extensions-1.1.78.dist-info → ob_metaflow_extensions-1.1.80.dist-info}/top_level.txt
RENAMED
|
File without changes
|