vellum-ai 0.14.79__py3-none-any.whl → 0.14.81__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.
@@ -18,7 +18,7 @@ class BaseClientWrapper:
18
18
  headers: typing.Dict[str, str] = {
19
19
  "X-Fern-Language": "Python",
20
20
  "X-Fern-SDK-Name": "vellum-ai",
21
- "X-Fern-SDK-Version": "0.14.79",
21
+ "X-Fern-SDK-Version": "0.14.81",
22
22
  }
23
23
  headers["X-API-KEY"] = self.api_key
24
24
  return headers
@@ -109,6 +109,7 @@ def main(word: str) -> int:
109
109
  CodeExecutionPackage(
110
110
  name="openai",
111
111
  version="1.0.0",
112
+ repository="test-repo",
112
113
  )
113
114
  ]
114
115
 
@@ -150,6 +151,7 @@ def main(word: str) -> int:
150
151
  CodeExecutionPackage(
151
152
  name="openai",
152
153
  version="1.0.0",
154
+ repository="test-repo",
153
155
  )
154
156
  ],
155
157
  request_options=None,
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.1
2
2
  Name: vellum-ai
3
- Version: 0.14.79
3
+ Version: 0.14.81
4
4
  Summary:
5
5
  License: MIT
6
6
  Requires-Python: >=3.9,<4.0
@@ -3,7 +3,7 @@ vellum_cli/README.md,sha256=2NudRoLzWxNKqnuVy1JuQ7DerIaxWGYkrH8kMd-asIE,90
3
3
  vellum_cli/__init__.py,sha256=50dYVkBzGUS1i-UKf_9zv1JMif1lLClriNUSs-Z7i4E,12678
4
4
  vellum_cli/aliased_group.py,sha256=ugW498j0yv4ALJ8vS9MsO7ctDW7Jlir9j6nE_uHAP8c,3363
5
5
  vellum_cli/config.py,sha256=v5BmZ-t_v4Jmqd7KVuQMZF2pRI-rbMspSkVYXIRoTmI,9448
6
- vellum_cli/image_push.py,sha256=rPeSfTlFpdTzwTdnXRL82OVd61qMoGFGLxnLjZLU98Q,10596
6
+ vellum_cli/image_push.py,sha256=eeOBqKtKkPu6Kgm_jQCVCivogzAcdlIlkv61-QxH67c,11006
7
7
  vellum_cli/init.py,sha256=WpnMXPItPmh0f0bBGIer3p-e5gu8DUGwSArT_FuoMEw,5093
8
8
  vellum_cli/logger.py,sha256=dcM_OmgqXLo93vDYswO5ylyUQQcTfnA5GTd5tbIt3wM,1446
9
9
  vellum_cli/ping.py,sha256=p_BCCRjgPhng6JktuECtkDQLbhopt6JpmrtGoLnLJT8,1161
@@ -12,8 +12,8 @@ vellum_cli/push.py,sha256=sUo0d7lm7saGxQciH-JW2FB_gWfP2gwoEHO1wGnNQR0,10933
12
12
  vellum_cli/tests/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
13
13
  vellum_cli/tests/conftest.py,sha256=wx3PlJjVB0HRf5dr2b_idOIw27WPPl0J0FNbhIJJaVk,1689
14
14
  vellum_cli/tests/test_config.py,sha256=uvKGDc8BoVyT9_H0Z-g8469zVxomn6Oi3Zj-vK7O_wU,2631
15
- vellum_cli/tests/test_image_push.py,sha256=qrlSZVMkPYc0ieqYaY2HCI8bBzwwL_Sx1G2nLb9_pSo,9199
16
- vellum_cli/tests/test_image_push_error_handling.py,sha256=_Wjfkn1orI2K4Ahzqz4u8T13or7NOX01K4BtcTuTIOM,7107
15
+ vellum_cli/tests/test_image_push.py,sha256=X0YOPdoaAnWtK9IQTxaN_wWpw08-5G3v76k1Wu53JpU,12801
16
+ vellum_cli/tests/test_image_push_error_handling.py,sha256=QRH0eYNEEIkD2-EVFQWYexOKlhMB6puh1GouovrE-VU,7647
17
17
  vellum_cli/tests/test_init.py,sha256=8UOc_ThfouR4ja5cCl_URuLk7ohr9JXfCnG4yka1OUQ,18754
18
18
  vellum_cli/tests/test_main.py,sha256=qDZG-aQauPwBwM6A2DIu1494n47v3pL28XakTbLGZ-k,272
19
19
  vellum_cli/tests/test_ping.py,sha256=178EJHxPZtnnPMNXXynsQt8DIFhsrdc2bL17_YsG17M,2580
@@ -78,7 +78,7 @@ vellum_ee/workflows/display/tests/workflow_serialization/generic_nodes/test_outp
78
78
  vellum_ee/workflows/display/tests/workflow_serialization/generic_nodes/test_ports_serialization.py,sha256=PkSgghJDz0fpDB72HHPjLjo8LkZk-HpUkCQzRLX-iVw,40611
79
79
  vellum_ee/workflows/display/tests/workflow_serialization/generic_nodes/test_trigger_serialization.py,sha256=dsJr8I9AdPwMOGszirfNDzZP2Ychd94aAKuPXAzknMk,4632
80
80
  vellum_ee/workflows/display/tests/workflow_serialization/test_basic_api_node_serialization.py,sha256=Q3QOzzF7KE_9EukJ9yNFgYL7Qio_vTqDVd-6kc40wd4,15834
81
- vellum_ee/workflows/display/tests/workflow_serialization/test_basic_code_execution_node_serialization.py,sha256=SrpLTehz__k9DFGMTWQfTKxuzDxY2rLi8TJ27-h0UKE,29681
81
+ vellum_ee/workflows/display/tests/workflow_serialization/test_basic_code_execution_node_serialization.py,sha256=B4DC2e5nqEk5NZeUwR4vKmBoEyToHkAuq4cCqbsidFo,29708
82
82
  vellum_ee/workflows/display/tests/workflow_serialization/test_basic_conditional_node_serialization.py,sha256=cBHGuY-DeyqQlLbpRZrrQyDh7em8rPkB7bV9Vi0EFoE,53608
83
83
  vellum_ee/workflows/display/tests/workflow_serialization/test_basic_default_state_serialization.py,sha256=E1ww97BFoGbnRkxf84TScat5NQhP8nLVrdaOlpGnSKU,8615
84
84
  vellum_ee/workflows/display/tests/workflow_serialization/test_basic_error_node_serialization.py,sha256=w1BYEZXIMjWmcKGQXzhelHnKFlEAXmsgjkI9fcgqKXA,5850
@@ -144,7 +144,7 @@ vellum/client/README.md,sha256=CuGUYnaE0Imt0KqQ4sIPaUghCjLHkF3DdEvZWu14-8s,4807
144
144
  vellum/client/__init__.py,sha256=AYopGv2ZRVn3zsU8_km6KOvEHDbXiTPCVuYVI7bWvdA,120166
145
145
  vellum/client/core/__init__.py,sha256=SQ85PF84B9MuKnBwHNHWemSGuy-g_515gFYNFhvEE0I,1438
146
146
  vellum/client/core/api_error.py,sha256=RE8LELok2QCjABadECTvtDp7qejA1VmINCh6TbqPwSE,426
147
- vellum/client/core/client_wrapper.py,sha256=Q1F5IAmbUhtpL6ilvnpt5ixi8uWvRrlgvSV3JXJyybU,1869
147
+ vellum/client/core/client_wrapper.py,sha256=RGItlYpaVjeK3lxB5PIvrtQu08YDkuzJF7ACN4HgnNk,1869
148
148
  vellum/client/core/datetime_utils.py,sha256=nBys2IsYrhPdszxGKCNRPSOCwa-5DWOHG95FB8G9PKo,1047
149
149
  vellum/client/core/file.py,sha256=d4NNbX8XvXP32z8KpK2Xovv33nFfruIrpz0QWxlgpZk,2663
150
150
  vellum/client/core/http_client.py,sha256=Z77OIxIbL4OAB2IDqjRq_sYa5yNYAWfmdhdCSSvh6Y4,19552
@@ -1629,7 +1629,7 @@ vellum/workflows/nodes/displayable/code_execution_node/node.py,sha256=Qh4SPafzdR
1629
1629
  vellum/workflows/nodes/displayable/code_execution_node/tests/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
1630
1630
  vellum/workflows/nodes/displayable/code_execution_node/tests/fixtures/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
1631
1631
  vellum/workflows/nodes/displayable/code_execution_node/tests/fixtures/main.py,sha256=5QsbmkzSlSbcbWTG_JmIqcP-JNJzOPTKxGzdHos19W4,79
1632
- vellum/workflows/nodes/displayable/code_execution_node/tests/test_node.py,sha256=47W5fPLpDcaKhCVuauKOwcivx1NfhpbsRMPrs-WBnlY,38441
1632
+ vellum/workflows/nodes/displayable/code_execution_node/tests/test_node.py,sha256=0lxmU-XXie6qu35qAEfZJ3vKZ1XGvWV4eq9y2RMelOE,38521
1633
1633
  vellum/workflows/nodes/displayable/code_execution_node/utils.py,sha256=VRTKms59vrSR9mDk99cojParZVAP4lzjEeDwDNXU1tk,3837
1634
1634
  vellum/workflows/nodes/displayable/conditional_node/__init__.py,sha256=AS_EIqFdU1F9t8aLmbZU-rLh9ry6LCJ0uj0D8F0L5Uw,72
1635
1635
  vellum/workflows/nodes/displayable/conditional_node/node.py,sha256=71ZUNfTiD7t2Kai2ypw0tmv1lSf1brQaHAQD-SeUrGE,1101
@@ -1745,8 +1745,8 @@ vellum/workflows/workflows/event_filters.py,sha256=GSxIgwrX26a1Smfd-6yss2abGCnad
1745
1745
  vellum/workflows/workflows/tests/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
1746
1746
  vellum/workflows/workflows/tests/test_base_workflow.py,sha256=fROqff6AZpCIzaSwOKSdtYy4XR0UZQ6ejxL3RJOSJVs,20447
1747
1747
  vellum/workflows/workflows/tests/test_context.py,sha256=VJBUcyWVtMa_lE5KxdhgMu0WYNYnUQUDvTF7qm89hJ0,2333
1748
- vellum_ai-0.14.79.dist-info/LICENSE,sha256=hOypcdt481qGNISA784bnAGWAE6tyIf9gc2E78mYC3E,1574
1749
- vellum_ai-0.14.79.dist-info/METADATA,sha256=UodF9npSWC-UMqf_F0L-rKwUk-q97JFdxaojQo7pF-8,5556
1750
- vellum_ai-0.14.79.dist-info/WHEEL,sha256=sP946D7jFCHeNz5Iq4fL4Lu-PrWrFsgfLXbbkciIZwg,88
1751
- vellum_ai-0.14.79.dist-info/entry_points.txt,sha256=HCH4yc_V3J_nDv3qJzZ_nYS8llCHZViCDP1ejgCc5Ak,42
1752
- vellum_ai-0.14.79.dist-info/RECORD,,
1748
+ vellum_ai-0.14.81.dist-info/LICENSE,sha256=hOypcdt481qGNISA784bnAGWAE6tyIf9gc2E78mYC3E,1574
1749
+ vellum_ai-0.14.81.dist-info/METADATA,sha256=ly3BaXiiN3s_NvoL-gREFI-QYc0sqnBrV6wdC3G9tWU,5556
1750
+ vellum_ai-0.14.81.dist-info/WHEEL,sha256=sP946D7jFCHeNz5Iq4fL4Lu-PrWrFsgfLXbbkciIZwg,88
1751
+ vellum_ai-0.14.81.dist-info/entry_points.txt,sha256=HCH4yc_V3J_nDv3qJzZ_nYS8llCHZViCDP1ejgCc5Ak,42
1752
+ vellum_ai-0.14.81.dist-info/RECORD,,
vellum_cli/image_push.py CHANGED
@@ -24,6 +24,16 @@ def image_push_command(
24
24
  logger = load_cli_logger()
25
25
  config = load_vellum_cli_config()
26
26
 
27
+ logger.info("Cleaning up unused Docker images...")
28
+ try:
29
+ subprocess.run(
30
+ ["docker", "image", "prune", "--all", "-f", "--filter", "label=image-type=python-workflow-runtime"],
31
+ check=True,
32
+ )
33
+ logger.info("Docker image pruning completed successfully")
34
+ except subprocess.CalledProcessError as e:
35
+ logger.warning(f"Docker image pruning failed: {e}")
36
+
27
37
  if source:
28
38
  logger.info(f"Building Docker image from Dockerfile: {source}")
29
39
 
@@ -48,6 +48,7 @@ def test_image_push__self_hosted_happy_path(mock_docker_from_env, mock_subproces
48
48
  mock_docker_from_env.return_value = mock_docker_client
49
49
 
50
50
  mock_subprocess_run.side_effect = [
51
+ subprocess.CompletedProcess(args="", returncode=0, stdout=b"Pruning successful"),
51
52
  subprocess.CompletedProcess(
52
53
  args="", returncode=0, stdout=b'{"manifests": [{"platform": {"architecture": "amd64"}}]}'
53
54
  ),
@@ -100,6 +101,7 @@ def test_image_push__self_hosted_happy_path__workspace_option(
100
101
  mock_docker_from_env.return_value = mock_docker_client
101
102
 
102
103
  mock_subprocess_run.side_effect = [
104
+ subprocess.CompletedProcess(args="", returncode=0, stdout=b"Pruning successful"),
103
105
  subprocess.CompletedProcess(
104
106
  args="", returncode=0, stdout=b'{"manifests": [{"platform": {"architecture": "amd64"}}]}'
105
107
  ),
@@ -189,6 +191,7 @@ def test_image_push_with_source_success(
189
191
  mock_docker_client.images.push.return_value = [b'{"status": "Pushed"}']
190
192
 
191
193
  mock_subprocess_run.side_effect = [
194
+ subprocess.CompletedProcess(args="", returncode=0, stdout=b"Pruning successful"),
192
195
  subprocess.CompletedProcess(args="", returncode=0, stdout=b"Build successful"),
193
196
  subprocess.CompletedProcess(
194
197
  args="", returncode=0, stdout=b'{"manifests": [{"platform": {"architecture": "amd64"}}]}'
@@ -205,7 +208,7 @@ def test_image_push_with_source_success(
205
208
 
206
209
  assert result.exit_code == 0, result.output
207
210
 
208
- build_call = mock_subprocess_run.call_args_list[0]
211
+ build_call = mock_subprocess_run.call_args_list[1]
209
212
  assert build_call[0][0] == [
210
213
  "docker",
211
214
  "buildx",
@@ -246,6 +249,7 @@ def test_image_push_with_source_build_fails(mock_subprocess_run, monkeypatch, mo
246
249
  f.write("FROM alpine:latest\n")
247
250
 
248
251
  mock_subprocess_run.side_effect = [
252
+ subprocess.CompletedProcess(args="", returncode=0, stdout=b"Pruning successful"),
249
253
  subprocess.CompletedProcess(args="", returncode=1, stderr=b"Build failed: missing dependency"),
250
254
  ]
251
255
 
@@ -255,3 +259,85 @@ def test_image_push_with_source_build_fails(mock_subprocess_run, monkeypatch, mo
255
259
  assert result.exit_code == 1
256
260
  assert "Docker build failed" in result.output
257
261
  assert "Build failed: missing dependency" in result.output
262
+
263
+
264
+ @pytest.mark.usefixtures("vellum_client", "info_log_level")
265
+ def test_image_push_includes_docker_prune(mock_docker_from_env, mock_subprocess_run, monkeypatch):
266
+ """
267
+ Tests that image_push_command calls docker image prune before validation.
268
+ """
269
+ # GIVEN a self hosted vellum api URL env var
270
+ monkeypatch.setenv("VELLUM_API_URL", "mycompany.api.com")
271
+ monkeypatch.setenv("VELLUM_API_KEY", "123456abcdef")
272
+
273
+ # AND a mock Docker client
274
+ mock_docker_client = MagicMock()
275
+ mock_docker_from_env.return_value = mock_docker_client
276
+
277
+ mock_subprocess_run.side_effect = [
278
+ subprocess.CompletedProcess(args="", returncode=0, stdout=b"Pruning successful"),
279
+ subprocess.CompletedProcess(
280
+ args="", returncode=0, stdout=b'{"manifests": [{"platform": {"architecture": "amd64"}}]}'
281
+ ),
282
+ subprocess.CompletedProcess(args="", returncode=0, stdout=b"manifest"),
283
+ subprocess.CompletedProcess(args="", returncode=0, stdout=b"sha256:hellosha"),
284
+ ]
285
+
286
+ # WHEN the user runs the image push command with any image
287
+ runner = CliRunner()
288
+ result = runner.invoke(cli_main, ["image", "push", "myrepo.net/myimage:latest"])
289
+
290
+ # THEN the command exits successfully
291
+ assert result.exit_code == 0, result.output
292
+
293
+ prune_call = mock_subprocess_run.call_args_list[0]
294
+ assert prune_call[0][0] == [
295
+ "docker",
296
+ "image",
297
+ "prune",
298
+ "--all",
299
+ "-f",
300
+ "--filter",
301
+ "label=image-type=python-workflow-runtime",
302
+ ]
303
+
304
+ # AND the success message includes pruning completion
305
+ assert "Docker image pruning completed successfully" in result.output
306
+
307
+
308
+ @pytest.mark.usefixtures("vellum_client", "info_log_level")
309
+ def test_image_push_continues_if_prune_fails(mock_docker_from_env, mock_subprocess_run, monkeypatch):
310
+ """
311
+ Tests that image_push_command continues if docker image prune fails.
312
+ """
313
+ # GIVEN a self hosted vellum api URL env var
314
+ monkeypatch.setenv("VELLUM_API_URL", "mycompany.api.com")
315
+ monkeypatch.setenv("VELLUM_API_KEY", "123456abcdef")
316
+
317
+ # AND a mock Docker client
318
+ mock_docker_client = MagicMock()
319
+ mock_docker_from_env.return_value = mock_docker_client
320
+
321
+ mock_subprocess_run.side_effect = [
322
+ subprocess.CalledProcessError(
323
+ 1, ["docker", "image", "prune", "--all", "-f", "--filter", "label=image-type=python-workflow-runtime"]
324
+ ),
325
+ subprocess.CompletedProcess(
326
+ args="", returncode=0, stdout=b'{"manifests": [{"platform": {"architecture": "amd64"}}]}'
327
+ ),
328
+ subprocess.CompletedProcess(args="", returncode=0, stdout=b"manifest"),
329
+ subprocess.CompletedProcess(args="", returncode=0, stdout=b"sha256:hellosha"),
330
+ ]
331
+
332
+ # WHEN the user runs the image push command with any image
333
+ runner = CliRunner()
334
+ result = runner.invoke(cli_main, ["image", "push", "myrepo.net/myimage:latest"])
335
+
336
+ # THEN the command exits successfully despite pruning failure
337
+ assert result.exit_code == 0, result.output
338
+
339
+ # AND the warning message about pruning failure is shown
340
+ assert "Docker image pruning failed" in result.output
341
+
342
+ # AND the success message is still shown
343
+ assert "Image successfully pushed" in result.output
@@ -18,6 +18,7 @@ def test_image_push_docker_service_token_401_error(mock_docker_from_env, mock_ru
18
18
  mock_docker_client.images.get.return_value.id = "test-image-id"
19
19
 
20
20
  mock_run.side_effect = [
21
+ subprocess.CompletedProcess(args="", returncode=0, stdout=b"Pruning successful"),
21
22
  subprocess.CompletedProcess(
22
23
  args="", returncode=0, stdout=b'{"manifests": [{"platform": {"architecture": "amd64"}}]}'
23
24
  ),
@@ -43,6 +44,7 @@ def test_image_push_docker_service_token_500_error(mock_docker_from_env, mock_ru
43
44
  mock_docker_client.images.get.return_value.id = "test-image-id"
44
45
 
45
46
  mock_run.side_effect = [
47
+ subprocess.CompletedProcess(args="", returncode=0, stdout=b"Pruning successful"),
46
48
  subprocess.CompletedProcess(
47
49
  args="", returncode=0, stdout=b'{"manifests": [{"platform": {"architecture": "amd64"}}]}'
48
50
  ),
@@ -70,6 +72,7 @@ def test_image_push_docker_service_token_other_error(mock_docker_from_env, mock_
70
72
  mock_docker_client.images.get.return_value.id = "test-image-id"
71
73
 
72
74
  mock_run.side_effect = [
75
+ subprocess.CompletedProcess(args="", returncode=0, stdout=b"Pruning successful"),
73
76
  subprocess.CompletedProcess(
74
77
  args="", returncode=0, stdout=b'{"manifests": [{"platform": {"architecture": "amd64"}}]}'
75
78
  ),
@@ -98,6 +101,7 @@ def test_image_push_container_image_401_error(mock_docker_from_env, mock_run, ve
98
101
  mock_docker_client.images.push.return_value = ["pushed"]
99
102
 
100
103
  mock_run.side_effect = [
104
+ subprocess.CompletedProcess(args="", returncode=0, stdout=b"Pruning successful"),
101
105
  subprocess.CompletedProcess(
102
106
  args="", returncode=0, stdout=b'{"manifests": [{"platform": {"architecture": "amd64"}}]}'
103
107
  ),
@@ -129,6 +133,7 @@ def test_image_push_container_image_500_error(mock_docker_from_env, mock_run, ve
129
133
  mock_docker_client.images.push.return_value = ["pushed"]
130
134
 
131
135
  mock_run.side_effect = [
136
+ subprocess.CompletedProcess(args="", returncode=0, stdout=b"Pruning successful"),
132
137
  subprocess.CompletedProcess(
133
138
  args="", returncode=0, stdout=b'{"manifests": [{"platform": {"architecture": "amd64"}}]}'
134
139
  ),
@@ -162,6 +167,7 @@ def test_image_push_container_image_other_error(mock_docker_from_env, mock_run,
162
167
  mock_docker_client.images.push.return_value = ["pushed"]
163
168
 
164
169
  mock_run.side_effect = [
170
+ subprocess.CompletedProcess(args="", returncode=0, stdout=b"Pruning successful"),
165
171
  subprocess.CompletedProcess(
166
172
  args="", returncode=0, stdout=b'{"manifests": [{"platform": {"architecture": "amd64"}}]}'
167
173
  ),
@@ -561,7 +561,7 @@ def test_serialize_workflow__try_wrapped():
561
561
  "code_input_id": "f2e8a4fa-b54e-41e9-b314-0e5443519ac7",
562
562
  "runtime_input_id": "19d64948-f22b-4103-a7f5-3add184b31cc",
563
563
  "output_type": "NUMBER",
564
- "packages": [{"name": "openai", "version": "1.0.0"}],
564
+ "packages": [{"name": "openai", "version": "1.0.0", "repository": "test-repo"}],
565
565
  "output_id": "0fde9607-353f-42c2-85c4-20f720ebc1ec",
566
566
  "log_output_id": "7cac05e3-b7c3-475e-8df8-422b496c3398",
567
567
  },