vellum-workflow-server 1.8.2__py3-none-any.whl → 1.10.7__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.
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.1
2
2
  Name: vellum-workflow-server
3
- Version: 1.8.2
3
+ Version: 1.10.7
4
4
  Summary:
5
5
  License: AGPL
6
6
  Requires-Python: >=3.9.0,<4
@@ -26,10 +26,10 @@ Requires-Dist: gunicorn (==23.0.0)
26
26
  Requires-Dist: orderly-set (==5.2.2)
27
27
  Requires-Dist: pebble (==5.0.7)
28
28
  Requires-Dist: pyjwt (==2.10.0)
29
- Requires-Dist: python-dotenv (==1.0.1)
29
+ Requires-Dist: python-dotenv (==1.2.1)
30
30
  Requires-Dist: retrying (==1.3.4)
31
31
  Requires-Dist: sentry-sdk[flask] (==2.20.0)
32
- Requires-Dist: vellum-ai (==1.8.2)
32
+ Requires-Dist: vellum-ai (==1.10.7)
33
33
  Description-Content-Type: text/markdown
34
34
 
35
35
  # Vellum Workflow Runner Server
@@ -1,25 +1,27 @@
1
1
  workflow_server/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
2
2
  workflow_server/api/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
3
- workflow_server/api/auth_middleware.py,sha256=IlZaCiwZ5nwQqk5sYQorvOFj7lt0p1ZSSEqUxfiFaW0,2458
3
+ workflow_server/api/auth_middleware.py,sha256=qHsMZFYtZyaR7dvkJ6xI6ZYdYw2-2y8X4JyfIQqQTSw,2495
4
4
  workflow_server/api/healthz_view.py,sha256=itiRvBDBXncrw8Kbbc73UZLwqMAhgHOR3uSre_dAfgY,404
5
+ workflow_server/api/status_view.py,sha256=Jah8dBAVL4uOcRfsjKAOyfVONFyk9HQjXeRfjcIqhmA,514
5
6
  workflow_server/api/tests/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
6
7
  workflow_server/api/tests/test_input_display_mapping.py,sha256=drBZqMudFyB5wgiUOcMgRXz7E7ge-Qgxbstw4E4f0zE,2211
7
- workflow_server/api/tests/test_workflow_view.py,sha256=_9SHdK1t-wwWILZFrnoYe5NhkoLazJnt7K1oH4bnJU0,30355
8
- workflow_server/api/tests/test_workflow_view_stream_workflow_route.py,sha256=GpOBFnbc54KotEAwwXaCSM2CQMnvXCl64v5IwN_ZVm0,38658
9
- workflow_server/api/workflow_view.py,sha256=tSepIRP0LcJUKae_wSHGw6P5Ho8K20_YTj3J-9ZL6bs,20463
8
+ workflow_server/api/tests/test_workflow_view.py,sha256=B6B8mCirt3FvpPKRP_AyzPJ199k_gwLzAcQuWRkzEfA,32343
9
+ workflow_server/api/tests/test_workflow_view_async_exec.py,sha256=eP_H2xI9SRfJdoJ6HPeynQecnxR50I_8aDCooF-YzIw,11952
10
+ workflow_server/api/tests/test_workflow_view_stream_workflow_route.py,sha256=16ZxP_nuAIP1Cg4-4z6EQttn07SRY1GkVq2m53z6XaE,42389
11
+ workflow_server/api/workflow_view.py,sha256=RiRO0Z_gCIbdcG9XX_PcB9j8Qx5K_2dXxxtkib6fezY,24601
10
12
  workflow_server/code_exec_runner.py,sha256=DLNNrinCRbnkSvlqVvSZ1wv_etI7r_kKAXNPGMj3jBk,2196
11
- workflow_server/config.py,sha256=cUdI_lEovV7e7lwCkGJ1eM9R4OZVJw5R5zT1eG1SzQQ,2122
13
+ workflow_server/config.py,sha256=I4hfTsjIbHxoSKylPCjKnrysPV0jO5nfRKwpKvEcfAE,2193
12
14
  workflow_server/core/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
13
15
  workflow_server/core/cancel_workflow.py,sha256=QcEeYUIrxq4pub-z9BlGi5fLI3gVRml-56rMCW7j5Hc,2212
14
16
  workflow_server/core/events.py,sha256=24MA66DVQuaLJJcZrS8IL1Zq4Ohi9CoouKZ5VgoH3Cs,1402
15
- workflow_server/core/executor.py,sha256=8EDEyAFonQ5cIV9-orbgSbDErPTe7sj5-fN4WKZR2VM,17426
16
- workflow_server/core/utils.py,sha256=si0NB4Suurc-mn8NYdn59xM9CkPrfOP1aWEVrZvifDI,1929
17
- workflow_server/core/workflow_executor_context.py,sha256=7Vp714LNVx_J5ERbgRHy5pJo_MaXsccIePWEW3IBshw,3234
17
+ workflow_server/core/executor.py,sha256=xbySFdb9KHoqFDfiKMR77fViFVo3XEQ5ER54C1PlS8c,16948
18
+ workflow_server/core/utils.py,sha256=mecVPqQkthrC4mpop3r8J3IWnBmKbDgqfCrSagyzVEg,2021
19
+ workflow_server/core/workflow_executor_context.py,sha256=8faOdpU4cBeIbmOvg9VzD3eS5i_PKcH7tyNGzx_rehg,3899
18
20
  workflow_server/logging_config.py,sha256=Hvx1t8uhqMMinl-5qcef7ufUvzs6x14VRnCb7YZxEAg,1206
19
- workflow_server/server.py,sha256=UnldeFS6iINBc-Kxl8LQcdAB2SGV6u-Xi5gy5EN466E,1729
20
- workflow_server/start.py,sha256=xSIobowtSLoZI86bbMkmEw3pqJHQaFdDyNffk4kGYL8,2544
21
+ workflow_server/server.py,sha256=pBl0OQmrLE-PbTDwTgsVmxgz_Ai3TVhFRaMnr6PX6Yk,1849
22
+ workflow_server/start.py,sha256=dvV8EKUH_oaTbOzNmUolF7RpkPWW8IkFwlgqOV9BhZQ,2842
21
23
  workflow_server/utils/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
22
- workflow_server/utils/exit_handler.py,sha256=_FacDVi4zc3bfTA3D2mJsISePlJ8jpLrnGVo5-xZQFs,743
24
+ workflow_server/utils/exit_handler.py,sha256=PzRpzmia4Ki33sJTWjsvjD5oLP4_qfS5SZg2uXnyqxE,1767
23
25
  workflow_server/utils/log_proxy.py,sha256=nugi6fOgAYKX2X9DIc39TG366rsmmDUPoEtG3gzma_Y,3088
24
26
  workflow_server/utils/oom_killer.py,sha256=dzaqSzi0jQ3MvALwwiYIO9r6VWLa5Ln9AY6l11WEexo,3050
25
27
  workflow_server/utils/sentry.py,sha256=pmGDoaFhJwUprjP_Vmz6bETitqKQulJ0vwRP-gYb2w4,2145
@@ -29,7 +31,7 @@ workflow_server/utils/tests/test_sentry_integration.py,sha256=14PfuW8AaQNNtqLmBs
29
31
  workflow_server/utils/tests/test_system_utils.py,sha256=_4GwXvVvU5BrATxUEWwQIPg0bzQXMWBtiBmjP8MTxJM,4314
30
32
  workflow_server/utils/tests/test_utils.py,sha256=0Nq6du8o-iBtTrip9_wgHES53JSiJbVdSXaBnPobw3s,6930
31
33
  workflow_server/utils/utils.py,sha256=m7iMJtor5SQLWu7jlJw-X5Q3nmbq69BCxTMv6qnFYrA,4835
32
- vellum_workflow_server-1.8.2.dist-info/METADATA,sha256=iBsFz2wqk0GYbvqUyCxS6F7K4JY_UhFc2ct_pvsm6kc,2267
33
- vellum_workflow_server-1.8.2.dist-info/WHEEL,sha256=sP946D7jFCHeNz5Iq4fL4Lu-PrWrFsgfLXbbkciIZwg,88
34
- vellum_workflow_server-1.8.2.dist-info/entry_points.txt,sha256=uB_0yPkr7YV6RhEXzvFReUM8P4OQBlVXD6TN6eb9-oc,277
35
- vellum_workflow_server-1.8.2.dist-info/RECORD,,
34
+ vellum_workflow_server-1.10.7.dist-info/METADATA,sha256=fmGtKTAbZbiiO93Cw18heCPbkQUjjicY2bEXEg2TB5U,2269
35
+ vellum_workflow_server-1.10.7.dist-info/WHEEL,sha256=sP946D7jFCHeNz5Iq4fL4Lu-PrWrFsgfLXbbkciIZwg,88
36
+ vellum_workflow_server-1.10.7.dist-info/entry_points.txt,sha256=uB_0yPkr7YV6RhEXzvFReUM8P4OQBlVXD6TN6eb9-oc,277
37
+ vellum_workflow_server-1.10.7.dist-info/RECORD,,
@@ -5,7 +5,7 @@ from flask import Flask, Request, Response
5
5
  import jwt
6
6
  from jwt import ExpiredSignatureError
7
7
 
8
- from workflow_server.config import IS_VPC, NAMESPACE, VEMBDA_PUBLIC_KEY, is_development
8
+ from workflow_server.config import IS_ASYNC_MODE, IS_VPC, NAMESPACE, VEMBDA_PUBLIC_KEY, is_development
9
9
 
10
10
 
11
11
  class AuthMiddleware:
@@ -15,7 +15,7 @@ class AuthMiddleware:
15
15
  def __call__(self, environ: Dict[str, Any], start_response: Any) -> Any:
16
16
  try:
17
17
  request = Request(environ)
18
- if not request.path.startswith("/healthz") and not is_development() and not IS_VPC:
18
+ if not request.path.startswith("/healthz") and not is_development() and not IS_VPC and not IS_ASYNC_MODE:
19
19
  token = request.headers.get("X-Vembda-Signature")
20
20
  if token:
21
21
  decoded = jwt.decode(token, VEMBDA_PUBLIC_KEY, algorithms=["RS256"])
@@ -0,0 +1,19 @@
1
+ from typing import Tuple
2
+
3
+ from flask import Blueprint, Response, jsonify
4
+
5
+ from workflow_server.config import CONCURRENCY
6
+ from workflow_server.utils.system_utils import get_active_process_count
7
+
8
+ bp = Blueprint("status", __name__)
9
+
10
+
11
+ @bp.route("/is_available", methods=["GET"])
12
+ def is_available() -> Tuple[Response, int]:
13
+ resp = jsonify(
14
+ available=get_active_process_count() < CONCURRENCY,
15
+ process_count=get_active_process_count(),
16
+ max_concurrency=CONCURRENCY,
17
+ )
18
+
19
+ return resp, 200
@@ -63,11 +63,11 @@ class TestNode(BaseNode):
63
63
  "comment": {"expanded": True, "value": "A test node for processing data."},
64
64
  "position": {"x": 0.0, "y": 0.0},
65
65
  },
66
- "id": "7a8b251d-f5ca-462a-b293-071d219460fb",
66
+ "id": "6f4c9178-9f46-4723-bcb7-0bd59db54eca",
67
67
  "label": "Test Node",
68
68
  "outputs": [],
69
- "ports": [{"id": "a3a0eefd-45d0-4f13-8c58-a836a9f7f9ed", "name": "default", "type": "DEFAULT"}],
70
- "trigger": {"id": "a022e36c-9852-4772-9be3-3c6c147fd811", "merge_behavior": "AWAIT_ATTRIBUTES"},
69
+ "ports": [{"id": "4394823f-79a8-4dbc-99ae-06a1df6c7408", "name": "default", "type": "DEFAULT"}],
70
+ "trigger": {"id": "07240af1-67c6-4460-b53d-53f0b0f1b90e", "merge_behavior": "AWAIT_ATTRIBUTES"},
71
71
  "type": "GENERIC",
72
72
  }
73
73
 
@@ -127,11 +127,11 @@ class SomeOtherNode(BaseNode):
127
127
  "comment": {"expanded": True, "value": "This is Some Node."},
128
128
  "position": {"x": 0.0, "y": 0.0},
129
129
  },
130
- "id": "1e559c2e-db82-41f0-9ceb-5e89b0c5a0a3",
130
+ "id": "89e84bac-5a5f-4f64-8083-7d3ebec98be1",
131
131
  "label": "Some Node",
132
132
  "outputs": [],
133
- "ports": [{"id": "48e39e97-5fd4-471e-b4f2-51d3baf06456", "name": "default", "type": "DEFAULT"}],
134
- "trigger": {"id": "e3381fb7-61fc-4c46-ae8e-51fc463b6a59", "merge_behavior": "AWAIT_ATTRIBUTES"},
133
+ "ports": [{"id": "2983ea5c-1d29-483a-b896-53098f5de4f1", "name": "default", "type": "DEFAULT"}],
134
+ "trigger": {"id": "6996efb0-5a20-4719-8835-34fe6552764a", "merge_behavior": "AWAIT_ATTRIBUTES"},
135
135
  "type": "GENERIC",
136
136
  }
137
137
 
@@ -150,11 +150,11 @@ class SomeOtherNode(BaseNode):
150
150
  "comment": {"expanded": True, "value": "This is Some Other Node."},
151
151
  "position": {"x": 0.0, "y": 0.0},
152
152
  },
153
- "id": "7aee541b-b245-4c8a-9137-3e4631d5100c",
153
+ "id": "3cdbba02-8a34-4e0f-8b94-770a944dcaa3",
154
154
  "label": "Some Other Node",
155
155
  "outputs": [],
156
- "ports": [{"id": "fb66b46a-d970-4bc9-83ea-70c154c57ddd", "name": "default", "type": "DEFAULT"}],
157
- "trigger": {"id": "13fa2714-20b3-4bc3-ab79-621a188e3bfa", "merge_behavior": "AWAIT_ATTRIBUTES"},
156
+ "ports": [{"id": "1839bde5-2ad4-4723-b21b-2c55fa833a7a", "name": "default", "type": "DEFAULT"}],
157
+ "trigger": {"id": "c36df8a8-5624-45be-99c9-826cf511a951", "merge_behavior": "AWAIT_ATTRIBUTES"},
158
158
  "type": "GENERIC",
159
159
  }
160
160
 
@@ -222,11 +222,11 @@ class HelperClass:
222
222
  "comment": {"expanded": True, "value": "Processes input data."},
223
223
  "position": {"x": 0.0, "y": 0.0},
224
224
  },
225
- "id": "f92c09f0-0434-46cb-829d-a73f801d6343",
225
+ "id": "7121bcb9-98a1-4907-bf9b-9734d773fd15",
226
226
  "label": "Processing Node",
227
227
  "outputs": [],
228
- "ports": [{"id": "abaa2984-b312-4491-b069-e689759f72c8", "name": "default", "type": "DEFAULT"}],
229
- "trigger": {"id": "35378c2b-f089-44af-ac37-efe4ea42c817", "merge_behavior": "AWAIT_ATTRIBUTES"},
228
+ "ports": [{"id": "de27da74-30e9-4e7b-95c2-92bdfc5bf042", "name": "default", "type": "DEFAULT"}],
229
+ "trigger": {"id": "e02bd85e-8b03-4b21-8b3e-f411042334ce", "merge_behavior": "AWAIT_ATTRIBUTES"},
230
230
  "type": "GENERIC",
231
231
  }
232
232
 
@@ -240,11 +240,11 @@ class HelperClass:
240
240
  "comment": {"expanded": True, "value": "Transforms data format."},
241
241
  "position": {"x": 0.0, "y": 0.0},
242
242
  },
243
- "id": "09ca32f7-c8f2-4469-97e5-1f288f85127a",
243
+ "id": "6a785cb0-f631-4f03-94c6-e82331c14c1a",
244
244
  "label": "Transformation Node",
245
245
  "outputs": [],
246
- "ports": [{"id": "88778117-fbfc-4b44-964b-5a4994aa2f24", "name": "default", "type": "DEFAULT"}],
247
- "trigger": {"id": "5d096263-7fbf-490a-83b7-e441852b5fb6", "merge_behavior": "AWAIT_ATTRIBUTES"},
246
+ "ports": [{"id": "67a13ea0-fd6b-44dc-af46-c72da06aa11f", "name": "default", "type": "DEFAULT"}],
247
+ "trigger": {"id": "08d4e317-baa8-478f-b278-99362e50e6b4", "merge_behavior": "AWAIT_ATTRIBUTES"},
248
248
  "type": "GENERIC",
249
249
  }
250
250
 
@@ -306,11 +306,11 @@ class BrokenNode(BaseNode)
306
306
  "comment": {"expanded": True, "value": "This is Some Node."},
307
307
  "position": {"x": 0.0, "y": 0.0},
308
308
  },
309
- "id": "1e559c2e-db82-41f0-9ceb-5e89b0c5a0a3",
309
+ "id": "a2706730-074b-4ea3-968a-25e68af1caed",
310
310
  "label": "Some Node",
311
311
  "outputs": [],
312
- "ports": [{"id": "48e39e97-5fd4-471e-b4f2-51d3baf06456", "name": "default", "type": "DEFAULT"}],
313
- "trigger": {"id": "e3381fb7-61fc-4c46-ae8e-51fc463b6a59", "merge_behavior": "AWAIT_ATTRIBUTES"},
312
+ "ports": [{"id": "e0ee3653-e071-4b91-9dfc-5e1dca9c665b", "name": "default", "type": "DEFAULT"}],
313
+ "trigger": {"id": "8d931b01-30ca-4c0d-b1b7-7c18379c83e6", "merge_behavior": "AWAIT_ATTRIBUTES"},
314
314
  "type": "GENERIC",
315
315
  }
316
316
 
@@ -371,12 +371,12 @@ class MyAdditionNode(BaseNode):
371
371
  "adornments": None,
372
372
  "attributes": [
373
373
  {
374
- "id": "aed3bcbb-d243-4a77-bb5e-409e9a28e868",
374
+ "id": "4223b340-447f-46c2-b35d-30ef16c5ae17",
375
375
  "name": "arg1",
376
376
  "value": None,
377
377
  },
378
378
  {
379
- "id": "9225d225-a41b-4642-8964-f28f58dcf4bf",
379
+ "id": "1de0f46a-95f6-4cd0-bb0f-e2414054d507",
380
380
  "name": "arg2",
381
381
  "value": None,
382
382
  },
@@ -387,11 +387,11 @@ class MyAdditionNode(BaseNode):
387
387
  "comment": {"expanded": True, "value": "Custom node that performs simple addition."},
388
388
  "position": {"x": 0.0, "y": 0.0},
389
389
  },
390
- "id": "195cd69d-3d2d-41e4-a432-16c433cb8d34",
390
+ "id": "2464b610-fb6d-495b-b17c-933ee147f19f",
391
391
  "label": "My Addition Node",
392
- "outputs": [{"id": "3d8e40cb-2aa8-44bd-ae6a-708a9fbc4779", "name": "result", "type": "NUMBER", "value": None}],
393
- "ports": [{"id": "9a9e4ef6-febf-4093-a515-217bbb1373db", "name": "default", "type": "DEFAULT"}],
394
- "trigger": {"id": "a5298668-d808-4a45-a62e-790943948e8a", "merge_behavior": "AWAIT_ATTRIBUTES"},
392
+ "outputs": [{"id": "f39d85c9-e7bf-45e1-bb67-f16225db0118", "name": "result", "type": "NUMBER", "value": None}],
393
+ "ports": [{"id": "bc489295-cd8a-4aa2-88bb-34446374100d", "name": "default", "type": "DEFAULT"}],
394
+ "trigger": {"id": "ff580cad-73d6-44fe-8f2c-4b8dc990ee70", "merge_behavior": "AWAIT_ATTRIBUTES"},
395
395
  "type": "GENERIC",
396
396
  "should_file_merge": True,
397
397
  }
@@ -537,6 +537,57 @@ def test_serialize_route__with_invalid_workspace_api_key():
537
537
  assert "exec_config" in response.json
538
538
 
539
539
 
540
+ def test_serialize_route__with_is_new_server_header():
541
+ """
542
+ Tests that the serialize route returns the is_new_server header.
543
+ """
544
+ # GIVEN a Flask application
545
+ flask_app = create_app()
546
+
547
+ workflow_files = {
548
+ "__init__.py": "",
549
+ "workflow.py": (
550
+ "from vellum.workflows import BaseWorkflow\n\n"
551
+ "class Workflow(BaseWorkflow):\n"
552
+ " class Outputs(BaseWorkflow.Outputs):\n"
553
+ " foo = 'hello'\n"
554
+ ),
555
+ }
556
+
557
+ # WHEN we make a request with is_new_server=True
558
+ with flask_app.test_client() as test_client:
559
+ response = test_client.post("/workflow/serialize", json={"files": workflow_files, "is_new_server": True})
560
+
561
+ # THEN we should get a successful response
562
+ assert response.status_code == 200
563
+
564
+ # AND the response should contain the is_new_server header set to true
565
+ assert "X-Vellum-Is-New-Server" in response.headers
566
+ assert response.headers["X-Vellum-Is-New-Server"] == "true"
567
+
568
+ # WHEN we make a request with is_new_server=False
569
+ with flask_app.test_client() as test_client:
570
+ response = test_client.post("/workflow/serialize", json={"files": workflow_files, "is_new_server": False})
571
+
572
+ # THEN we should get a successful response
573
+ assert response.status_code == 200
574
+
575
+ # AND the response should contain the is_new_server header set to false
576
+ assert "X-Vellum-Is-New-Server" in response.headers
577
+ assert response.headers["X-Vellum-Is-New-Server"] == "false"
578
+
579
+ # WHEN we make a request without is_new_server
580
+ with flask_app.test_client() as test_client:
581
+ response = test_client.post("/workflow/serialize", json={"files": workflow_files})
582
+
583
+ # THEN we should get a successful response
584
+ assert response.status_code == 200
585
+
586
+ # AND the response should contain the is_new_server header set to false (default)
587
+ assert "X-Vellum-Is-New-Server" in response.headers
588
+ assert response.headers["X-Vellum-Is-New-Server"] == "false"
589
+
590
+
540
591
  def test_stream_node_route__with_node_id():
541
592
  """
542
593
  Tests that the stream-node endpoint works with node_id.