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.

Files changed (19) hide show
  1. metaflow_extensions/outerbounds/config/__init__.py +28 -0
  2. metaflow_extensions/outerbounds/plugins/__init__.py +17 -3
  3. metaflow_extensions/outerbounds/plugins/fast_bakery/__init__.py +0 -0
  4. metaflow_extensions/outerbounds/plugins/fast_bakery/docker_environment.py +268 -0
  5. metaflow_extensions/outerbounds/plugins/fast_bakery/fast_bakery.py +160 -0
  6. metaflow_extensions/outerbounds/plugins/fast_bakery/fast_bakery_cli.py +54 -0
  7. metaflow_extensions/outerbounds/plugins/fast_bakery/fast_bakery_decorator.py +50 -0
  8. metaflow_extensions/outerbounds/plugins/snowpark/__init__.py +0 -0
  9. metaflow_extensions/outerbounds/plugins/snowpark/snowpark.py +299 -0
  10. metaflow_extensions/outerbounds/plugins/snowpark/snowpark_cli.py +271 -0
  11. metaflow_extensions/outerbounds/plugins/snowpark/snowpark_client.py +123 -0
  12. metaflow_extensions/outerbounds/plugins/snowpark/snowpark_decorator.py +264 -0
  13. metaflow_extensions/outerbounds/plugins/snowpark/snowpark_exceptions.py +13 -0
  14. metaflow_extensions/outerbounds/plugins/snowpark/snowpark_job.py +235 -0
  15. metaflow_extensions/outerbounds/plugins/snowpark/snowpark_service_spec.py +259 -0
  16. {ob_metaflow_extensions-1.1.78.dist-info → ob_metaflow_extensions-1.1.80.dist-info}/METADATA +2 -2
  17. {ob_metaflow_extensions-1.1.78.dist-info → ob_metaflow_extensions-1.1.80.dist-info}/RECORD +19 -6
  18. {ob_metaflow_extensions-1.1.78.dist-info → ob_metaflow_extensions-1.1.80.dist-info}/WHEEL +0 -0
  19. {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")
@@ -1,13 +1,13 @@
1
1
  Metadata-Version: 2.1
2
2
  Name: ob-metaflow-extensions
3
- Version: 1.1.78
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.11.0)
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=mYo95obHU1IE1wbPkeVz_pfTzNqlNabp1QBEMTGllbE,112
4
- metaflow_extensions/outerbounds/plugins/__init__.py,sha256=pylEqgeO7KpE3tu7gGYkScLKwBPPkCAvNEiQ7biK9kk,9671
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.78.dist-info/METADATA,sha256=46nNd5NpYJRzNhcbc9MEE9w760iwAFsN2vFG10J1hLY,520
23
- ob_metaflow_extensions-1.1.78.dist-info/WHEEL,sha256=bb2Ot9scclHKMOLDEHY6B2sicWOgugjFKaJsT7vwMQo,110
24
- ob_metaflow_extensions-1.1.78.dist-info/top_level.txt,sha256=NwG0ukwjygtanDETyp_BUdtYtqIA_lOjzFFh1TsnxvI,20
25
- ob_metaflow_extensions-1.1.78.dist-info/RECORD,,
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,,