vellum-workflow-server 1.7.0__tar.gz → 1.7.0.post2__tar.gz

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 vellum-workflow-server might be problematic. Click here for more details.

Files changed (33) hide show
  1. {vellum_workflow_server-1.7.0 → vellum_workflow_server-1.7.0.post2}/PKG-INFO +1 -1
  2. {vellum_workflow_server-1.7.0 → vellum_workflow_server-1.7.0.post2}/pyproject.toml +1 -1
  3. {vellum_workflow_server-1.7.0 → vellum_workflow_server-1.7.0.post2}/src/workflow_server/api/tests/test_workflow_view.py +43 -1
  4. {vellum_workflow_server-1.7.0 → vellum_workflow_server-1.7.0.post2}/src/workflow_server/api/workflow_view.py +16 -30
  5. {vellum_workflow_server-1.7.0 → vellum_workflow_server-1.7.0.post2}/README.md +0 -0
  6. {vellum_workflow_server-1.7.0 → vellum_workflow_server-1.7.0.post2}/src/workflow_server/__init__.py +0 -0
  7. {vellum_workflow_server-1.7.0 → vellum_workflow_server-1.7.0.post2}/src/workflow_server/api/__init__.py +0 -0
  8. {vellum_workflow_server-1.7.0 → vellum_workflow_server-1.7.0.post2}/src/workflow_server/api/auth_middleware.py +0 -0
  9. {vellum_workflow_server-1.7.0 → vellum_workflow_server-1.7.0.post2}/src/workflow_server/api/healthz_view.py +0 -0
  10. {vellum_workflow_server-1.7.0 → vellum_workflow_server-1.7.0.post2}/src/workflow_server/api/tests/__init__.py +0 -0
  11. {vellum_workflow_server-1.7.0 → vellum_workflow_server-1.7.0.post2}/src/workflow_server/api/tests/test_input_display_mapping.py +0 -0
  12. {vellum_workflow_server-1.7.0 → vellum_workflow_server-1.7.0.post2}/src/workflow_server/api/tests/test_workflow_view_stream_workflow_route.py +0 -0
  13. {vellum_workflow_server-1.7.0 → vellum_workflow_server-1.7.0.post2}/src/workflow_server/code_exec_runner.py +0 -0
  14. {vellum_workflow_server-1.7.0 → vellum_workflow_server-1.7.0.post2}/src/workflow_server/config.py +0 -0
  15. {vellum_workflow_server-1.7.0 → vellum_workflow_server-1.7.0.post2}/src/workflow_server/core/__init__.py +0 -0
  16. {vellum_workflow_server-1.7.0 → vellum_workflow_server-1.7.0.post2}/src/workflow_server/core/cancel_workflow.py +0 -0
  17. {vellum_workflow_server-1.7.0 → vellum_workflow_server-1.7.0.post2}/src/workflow_server/core/events.py +0 -0
  18. {vellum_workflow_server-1.7.0 → vellum_workflow_server-1.7.0.post2}/src/workflow_server/core/executor.py +0 -0
  19. {vellum_workflow_server-1.7.0 → vellum_workflow_server-1.7.0.post2}/src/workflow_server/core/utils.py +0 -0
  20. {vellum_workflow_server-1.7.0 → vellum_workflow_server-1.7.0.post2}/src/workflow_server/core/workflow_executor_context.py +0 -0
  21. {vellum_workflow_server-1.7.0 → vellum_workflow_server-1.7.0.post2}/src/workflow_server/server.py +0 -0
  22. {vellum_workflow_server-1.7.0 → vellum_workflow_server-1.7.0.post2}/src/workflow_server/start.py +0 -0
  23. {vellum_workflow_server-1.7.0 → vellum_workflow_server-1.7.0.post2}/src/workflow_server/utils/__init__.py +0 -0
  24. {vellum_workflow_server-1.7.0 → vellum_workflow_server-1.7.0.post2}/src/workflow_server/utils/exit_handler.py +0 -0
  25. {vellum_workflow_server-1.7.0 → vellum_workflow_server-1.7.0.post2}/src/workflow_server/utils/log_proxy.py +0 -0
  26. {vellum_workflow_server-1.7.0 → vellum_workflow_server-1.7.0.post2}/src/workflow_server/utils/oom_killer.py +0 -0
  27. {vellum_workflow_server-1.7.0 → vellum_workflow_server-1.7.0.post2}/src/workflow_server/utils/sentry.py +0 -0
  28. {vellum_workflow_server-1.7.0 → vellum_workflow_server-1.7.0.post2}/src/workflow_server/utils/system_utils.py +0 -0
  29. {vellum_workflow_server-1.7.0 → vellum_workflow_server-1.7.0.post2}/src/workflow_server/utils/tests/__init__.py +0 -0
  30. {vellum_workflow_server-1.7.0 → vellum_workflow_server-1.7.0.post2}/src/workflow_server/utils/tests/test_sentry_integration.py +0 -0
  31. {vellum_workflow_server-1.7.0 → vellum_workflow_server-1.7.0.post2}/src/workflow_server/utils/tests/test_system_utils.py +0 -0
  32. {vellum_workflow_server-1.7.0 → vellum_workflow_server-1.7.0.post2}/src/workflow_server/utils/tests/test_utils.py +0 -0
  33. {vellum_workflow_server-1.7.0 → vellum_workflow_server-1.7.0.post2}/src/workflow_server/utils/utils.py +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.1
2
2
  Name: vellum-workflow-server
3
- Version: 1.7.0
3
+ Version: 1.7.0.post2
4
4
  Summary:
5
5
  License: AGPL
6
6
  Requires-Python: >=3.9.0,<4
@@ -3,7 +3,7 @@ name = "vellum-workflow-server"
3
3
 
4
4
  [tool.poetry]
5
5
  name = "vellum-workflow-server"
6
- version = "1.7.0"
6
+ version = "1.7.0.post2"
7
7
  description = ""
8
8
  readme = "README.md"
9
9
  authors = []
@@ -429,7 +429,7 @@ class BrokenNode(BaseNode) # Missing colon
429
429
  with flask_app.test_client() as test_client:
430
430
  response = test_client.post("/workflow/serialize", json={"files": {"broken_node.py": invalid_content}})
431
431
 
432
- # THEN we should get a 4xx response
432
+ # THEN we should get a 400 response
433
433
  assert response.status_code == 400
434
434
 
435
435
  # AND the response should contain an error message
@@ -729,3 +729,45 @@ class Workflow(BaseWorkflow):
729
729
  assert events[0]["name"] == "vembda.execution.initiated"
730
730
  assert events[1]["name"] == "vembda.execution.fulfilled"
731
731
  assert len(events) == 2
732
+
733
+
734
+ def test_serialize_route__with_invalid_nested_set_graph():
735
+ """
736
+ Tests that a workflow with an invalid nested set graph structure raises a clear user-facing exception.
737
+ """
738
+ # GIVEN a Flask application
739
+ flask_app = create_app()
740
+
741
+ invalid_workflow_content = """
742
+ from vellum.workflows import BaseWorkflow
743
+ from vellum.workflows.nodes import BaseNode
744
+
745
+ class TestNode(BaseNode):
746
+ class Outputs(BaseNode.Outputs):
747
+ value = "test"
748
+
749
+ class InvalidWorkflow(BaseWorkflow):
750
+ graph = {TestNode, {TestNode}}
751
+
752
+ class Outputs(BaseWorkflow.Outputs):
753
+ result = TestNode.Outputs.value
754
+ """
755
+
756
+ workflow_files = {
757
+ "__init__.py": "",
758
+ "workflow.py": invalid_workflow_content,
759
+ }
760
+
761
+ # WHEN we make a request to the serialize route
762
+ with flask_app.test_client() as test_client:
763
+ response = test_client.post("/workflow/serialize", json={"files": workflow_files})
764
+
765
+ # THEN we should get a 400 response
766
+ assert response.status_code == 400
767
+
768
+ # AND the response should contain a user-friendly error message
769
+ assert "detail" in response.json
770
+ error_detail = response.json["detail"]
771
+ assert "Serialization failed" in error_detail
772
+ assert "Invalid graph structure detected" in error_detail
773
+ assert "contact Vellum support" in error_detail
@@ -23,7 +23,6 @@ from vellum_ee.workflows.display.types import WorkflowDisplayContext
23
23
  from vellum_ee.workflows.display.workflows import BaseWorkflowDisplay
24
24
  from vellum_ee.workflows.server.virtual_file_loader import VirtualFileFinder
25
25
 
26
- from vellum.workflows import BaseWorkflow
27
26
  from vellum.workflows.exceptions import WorkflowInitializationException
28
27
  from vellum.workflows.nodes import BaseNode
29
28
  from workflow_server.config import ENABLE_PROCESS_WRAPPER, MEMORY_LIMIT_MB
@@ -432,37 +431,20 @@ def serialize_route() -> Response:
432
431
  content_type="application/json",
433
432
  )
434
433
 
435
- try:
436
- client = None
437
- if workspace_api_key:
438
- try:
439
- client = create_vellum_client(api_key=workspace_api_key)
440
- except Exception as e:
441
- logger.warning(f"Failed to create VellumClient with provided workspace_api_key: {str(e)}")
434
+ client = create_vellum_client(api_key=workspace_api_key)
442
435
 
443
- # Generate a unique namespace for this serialization request
444
- namespace = "".join(random.choice(string.ascii_letters + string.digits) for i in range(14))
445
- virtual_finder = VirtualFileFinder(files, namespace)
446
-
447
- try:
448
- sys.meta_path.append(virtual_finder)
449
- try:
450
- result = BaseWorkflowDisplay.serialize_module(namespace, client=client)
451
- except Exception as e:
452
- raise WorkflowInitializationException(
453
- message=str(e),
454
- workflow_definition=BaseWorkflow,
455
- ) from e
456
-
457
- return Response(
458
- json.dumps(result.model_dump()),
459
- status=200,
460
- content_type="application/json",
461
- )
436
+ # Generate a unique namespace for this serialization request
437
+ namespace = "".join(random.choice(string.ascii_letters + string.digits) for i in range(14))
438
+ virtual_finder = VirtualFileFinder(files, namespace)
439
+ try:
440
+ sys.meta_path.append(virtual_finder)
441
+ result = BaseWorkflowDisplay.serialize_module(namespace, client=client, dry_run=True)
462
442
 
463
- finally:
464
- if virtual_finder in sys.meta_path:
465
- sys.meta_path.remove(virtual_finder)
443
+ return Response(
444
+ json.dumps(result.model_dump()),
445
+ status=200,
446
+ content_type="application/json",
447
+ )
466
448
 
467
449
  except WorkflowInitializationException as e:
468
450
  error_message = f"Serialization failed: {str(e)}"
@@ -481,6 +463,10 @@ def serialize_route() -> Response:
481
463
  content_type="application/json",
482
464
  )
483
465
 
466
+ finally:
467
+ if virtual_finder in sys.meta_path:
468
+ sys.meta_path.remove(virtual_finder)
469
+
484
470
 
485
471
  @bp.route("/version", methods=["GET"])
486
472
  def get_version_route() -> tuple[dict, int]: