vellum-workflow-server 1.7.5__py3-none-any.whl → 1.7.5.post2__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 vellum-workflow-server might be problematic. Click here for more details.

@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.1
2
2
  Name: vellum-workflow-server
3
- Version: 1.7.5
3
+ Version: 1.7.5.post2
4
4
  Summary:
5
5
  License: AGPL
6
6
  Requires-Python: >=3.9.0,<4
@@ -8,7 +8,7 @@ workflow_server/api/tests/test_workflow_view.py,sha256=XfsW8_hFKN5rzp2UFVviVoLW-
8
8
  workflow_server/api/tests/test_workflow_view_stream_workflow_route.py,sha256=l4sfma1uNB2CtFjxKTIQ2SSn-PpyxaSWJZyy7VYSDYM,37311
9
9
  workflow_server/api/workflow_view.py,sha256=WJC8wfdgqIDk5LLdRN2rom1M4qKvqHroxXpCjYczmjg,19859
10
10
  workflow_server/code_exec_runner.py,sha256=DLNNrinCRbnkSvlqVvSZ1wv_etI7r_kKAXNPGMj3jBk,2196
11
- workflow_server/config.py,sha256=qmmTr6ty3ZN5LDOFs3TfUxYshYe6Mmn_LanplHHeE9Q,1796
11
+ workflow_server/config.py,sha256=CKU7qKC5k1_M1AFOJn_nUqntA46KPk_Z7fblfQaGC-0,1877
12
12
  workflow_server/core/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
13
13
  workflow_server/core/cancel_workflow.py,sha256=QcEeYUIrxq4pub-z9BlGi5fLI3gVRml-56rMCW7j5Hc,2212
14
14
  workflow_server/core/events.py,sha256=24MA66DVQuaLJJcZrS8IL1Zq4Ohi9CoouKZ5VgoH3Cs,1402
@@ -21,14 +21,14 @@ workflow_server/utils/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3h
21
21
  workflow_server/utils/exit_handler.py,sha256=_FacDVi4zc3bfTA3D2mJsISePlJ8jpLrnGVo5-xZQFs,743
22
22
  workflow_server/utils/log_proxy.py,sha256=nugi6fOgAYKX2X9DIc39TG366rsmmDUPoEtG3gzma_Y,3088
23
23
  workflow_server/utils/oom_killer.py,sha256=dzaqSzi0jQ3MvALwwiYIO9r6VWLa5Ln9AY6l11WEexo,3050
24
- workflow_server/utils/sentry.py,sha256=pqx3X_4W3yOzmz8QMJYUEi39skIKWtrTN5nyFhaPkbk,1597
24
+ workflow_server/utils/sentry.py,sha256=pmGDoaFhJwUprjP_Vmz6bETitqKQulJ0vwRP-gYb2w4,2145
25
25
  workflow_server/utils/system_utils.py,sha256=3jNv113zRkKJ0928i2Vm6TqFHrDulteQu1kjseP2B0Y,3271
26
26
  workflow_server/utils/tests/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
27
- workflow_server/utils/tests/test_sentry_integration.py,sha256=LGmWiaLhFrx-jslrRjRq9JY6Z5ShLZyx_N_L0-FU6OI,2100
27
+ workflow_server/utils/tests/test_sentry_integration.py,sha256=14PfuW8AaQNNtqLmBs16EPe5T3f_iTI7YJMCRtiboZk,4502
28
28
  workflow_server/utils/tests/test_system_utils.py,sha256=_4GwXvVvU5BrATxUEWwQIPg0bzQXMWBtiBmjP8MTxJM,4314
29
29
  workflow_server/utils/tests/test_utils.py,sha256=0Nq6du8o-iBtTrip9_wgHES53JSiJbVdSXaBnPobw3s,6930
30
- workflow_server/utils/utils.py,sha256=ZPoM1Suhid22dpB8oEFLux8wx-9iyzmSfWuYxSCrgWk,4774
31
- vellum_workflow_server-1.7.5.dist-info/METADATA,sha256=c0tu-HEYmmswm9pjE4LMvPG7gNdS3lFKabBiw11zKqM,2267
32
- vellum_workflow_server-1.7.5.dist-info/WHEEL,sha256=sP946D7jFCHeNz5Iq4fL4Lu-PrWrFsgfLXbbkciIZwg,88
33
- vellum_workflow_server-1.7.5.dist-info/entry_points.txt,sha256=uB_0yPkr7YV6RhEXzvFReUM8P4OQBlVXD6TN6eb9-oc,277
34
- vellum_workflow_server-1.7.5.dist-info/RECORD,,
30
+ workflow_server/utils/utils.py,sha256=m7iMJtor5SQLWu7jlJw-X5Q3nmbq69BCxTMv6qnFYrA,4835
31
+ vellum_workflow_server-1.7.5.post2.dist-info/METADATA,sha256=5F0-6hoq-F-F3cYDh9j_pDxewl3jMAYee3J_DPUQxy8,2273
32
+ vellum_workflow_server-1.7.5.post2.dist-info/WHEEL,sha256=sP946D7jFCHeNz5Iq4fL4Lu-PrWrFsgfLXbbkciIZwg,88
33
+ vellum_workflow_server-1.7.5.post2.dist-info/entry_points.txt,sha256=uB_0yPkr7YV6RhEXzvFReUM8P4OQBlVXD6TN6eb9-oc,277
34
+ vellum_workflow_server-1.7.5.post2.dist-info/RECORD,,
workflow_server/config.py CHANGED
@@ -28,6 +28,7 @@ PORT = os.getenv("PORT", "8000")
28
28
  VELLUM_API_URL_HOST = os.getenv("VELLUM_API_URL_HOST", "localhost")
29
29
  VELLUM_API_URL_PORT = os.getenv("VELLUM_API_URL_PORT", 8000)
30
30
  CONCURRENCY = int(os.getenv("CONCURRENCY", "8"))
31
+ CONTAINER_IMAGE = os.getenv("CONTAINER_IMAGE", "python-workflow-runtime:latest")
31
32
  ENABLE_PROCESS_WRAPPER = os.getenv("ENABLE_PROCESS_WRAPPER", "true").lower() == "true"
32
33
 
33
34
  # This controls if we should just load a module already available in the py path for running
@@ -37,11 +37,32 @@ def _tag_trace_id(event: dict) -> None:
37
37
  event["tags"]["vellum_trace_id"] = trace_id
38
38
 
39
39
 
40
+ def _apply_custom_tags(event: dict, hint: dict) -> None:
41
+ """
42
+ Extracts 'sentry_tags' from logger exception's extra data and adds them to the event tags.
43
+
44
+ Modifies the event dictionary in place.
45
+ """
46
+ record = hint.get("log_record")
47
+ if not record:
48
+ return
49
+
50
+ sentry_tags = getattr(record, "sentry_tags", None)
51
+ if not sentry_tags or not isinstance(sentry_tags, dict):
52
+ return
53
+
54
+ if "tags" not in event:
55
+ event["tags"] = {}
56
+
57
+ event["tags"].update(sentry_tags)
58
+
59
+
40
60
  def before_send(event: dict, hint: dict) -> Optional[dict]:
41
61
  if "exc_info" in hint:
42
62
  _, _, _ = hint["exc_info"]
43
63
 
44
64
  _tag_trace_id(event)
65
+ _apply_custom_tags(event, hint)
45
66
 
46
67
  return event
47
68
 
@@ -1,4 +1,5 @@
1
1
  import pytest
2
+ import logging
2
3
  from uuid import uuid4
3
4
 
4
5
  from workflow_server.server import create_app
@@ -67,3 +68,76 @@ class Workflow(BaseWorkflow):
67
68
 
68
69
  # AND the trace_id is tagged
69
70
  assert event["tags"]["vellum_trace_id"] == trace_id
71
+
72
+
73
+ def test_sentry_integration_applies_custom_tags_from_logger_extra(monkeypatch, mock_sentry_capture_envelope):
74
+ """Test that Sentry events include custom tags from logger exception extra data."""
75
+
76
+ # GIVEN sentry is configured
77
+ monkeypatch.setenv("SENTRY_DSN", "https://test-dsn@sentry.io/1234567890")
78
+
79
+ # AND we have a function that will log with custom sentry_tags when called
80
+ def mock_get_version():
81
+ logger = logging.getLogger(__name__)
82
+ try:
83
+ raise Exception("Test exception with custom tags")
84
+ except Exception:
85
+ logger.exception(
86
+ "Failed during workflow execution",
87
+ extra={
88
+ "sentry_tags": {
89
+ "operation": "stream",
90
+ "test_tag": "test_value",
91
+ "numeric_tag": "12345",
92
+ }
93
+ },
94
+ )
95
+ raise
96
+
97
+ monkeypatch.setattr("workflow_server.api.workflow_view.get_version", mock_get_version)
98
+
99
+ # AND we have a valid request body
100
+ body = {
101
+ "execution_id": str(uuid4()),
102
+ "inputs": [],
103
+ "environment_api_key": "test",
104
+ "module": "workflow",
105
+ "timeout": 360,
106
+ "files": {
107
+ "__init__.py": "",
108
+ "workflow.py": """\
109
+ from vellum.workflows import BaseWorkflow
110
+
111
+ class Workflow(BaseWorkflow):
112
+ pass
113
+ """,
114
+ },
115
+ "execution_context": {
116
+ "trace_id": str(uuid4()),
117
+ "parent_context": {
118
+ "type": "API_REQUEST",
119
+ "span_id": str(uuid4()),
120
+ "parent": None,
121
+ },
122
+ },
123
+ }
124
+
125
+ # WHEN we call an endpoint that triggers the error
126
+ flask_app = create_app()
127
+
128
+ with flask_app.test_client() as test_client:
129
+ response = test_client.post("/workflow/stream", json=body)
130
+
131
+ # THEN we get a 500 error
132
+ assert response.status_code == 500
133
+
134
+ # AND sentry captures the error
135
+ assert mock_sentry_capture_envelope.call_count == 1
136
+ envelope = mock_sentry_capture_envelope.call_args[0][0]
137
+ event = envelope.get_event()
138
+
139
+ # AND the custom tags are included in the event
140
+ assert "tags" in event
141
+ assert event["tags"]["operation"] == "stream"
142
+ assert event["tags"]["test_tag"] == "test_value"
143
+ assert event["tags"]["numeric_tag"] == "12345"
@@ -15,7 +15,7 @@ from vellum import (
15
15
  VellumImage,
16
16
  VellumVideo,
17
17
  )
18
- from workflow_server.config import is_development
18
+ from workflow_server.config import CONTAINER_IMAGE, is_development
19
19
 
20
20
 
21
21
  def convert_json_inputs_to_vellum(inputs: List[dict]) -> dict:
@@ -62,6 +62,7 @@ def get_version() -> dict:
62
62
  return {
63
63
  "sdk_version": version("vellum-ai"),
64
64
  "server_version": "local" if is_development() else version("vellum-workflow-server"),
65
+ "container_image": CONTAINER_IMAGE,
65
66
  }
66
67
 
67
68