dbos 1.8.0a1__py3-none-any.whl → 1.8.0a3__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 dbos might be problematic. Click here for more details.

dbos/_context.py CHANGED
@@ -10,7 +10,7 @@ from enum import Enum
10
10
  from types import TracebackType
11
11
  from typing import List, Literal, Optional, Type, TypedDict
12
12
 
13
- from opentelemetry.trace import Span, Status, StatusCode
13
+ from opentelemetry.trace import Span, Status, StatusCode, use_span
14
14
  from sqlalchemy.orm import Session
15
15
 
16
16
  from dbos._utils import GlobalParams
@@ -68,6 +68,20 @@ class StepStatus:
68
68
  max_attempts: Optional[int]
69
69
 
70
70
 
71
+ @dataclass
72
+ class ContextSpan:
73
+ """
74
+ A span that is used to track the context of a workflow or step execution.
75
+
76
+ Attributes:
77
+ span: The OpenTelemetry span object.
78
+ context_manager: The context manager that is used to manage the span's lifecycle.
79
+ """
80
+
81
+ span: Span
82
+ context_manager: AbstractContextManager[Span]
83
+
84
+
71
85
  class DBOSContext:
72
86
  def __init__(self) -> None:
73
87
  self.executor_id = GlobalParams.executor_id
@@ -86,7 +100,7 @@ class DBOSContext:
86
100
  self.curr_step_function_id: int = -1
87
101
  self.curr_tx_function_id: int = -1
88
102
  self.sql_session: Optional[Session] = None
89
- self.spans: list[Span] = []
103
+ self.context_spans: list[ContextSpan] = []
90
104
 
91
105
  self.authenticated_user: Optional[str] = None
92
106
  self.authenticated_roles: Optional[List[str]] = None
@@ -202,8 +216,8 @@ class DBOSContext:
202
216
  self._end_span(exc_value)
203
217
 
204
218
  def get_current_span(self) -> Optional[Span]:
205
- if len(self.spans):
206
- return self.spans[-1]
219
+ if len(self.context_spans) > 0:
220
+ return self.context_spans[-1].span
207
221
  return None
208
222
 
209
223
  def _start_span(self, attributes: TracedAttributes) -> None:
@@ -218,27 +232,38 @@ class DBOSContext:
218
232
  )
219
233
  attributes["authenticatedUserAssumedRole"] = self.assumed_role
220
234
  span = dbos_tracer.start_span(
221
- attributes, parent=self.spans[-1] if len(self.spans) > 0 else None
235
+ attributes,
236
+ parent=self.context_spans[-1].span if len(self.context_spans) > 0 else None,
237
+ )
238
+ # Activate the current span
239
+ cm = use_span(
240
+ span,
241
+ end_on_exit=False,
242
+ record_exception=False,
243
+ set_status_on_exception=False,
222
244
  )
223
- self.spans.append(span)
245
+ self.context_spans.append(ContextSpan(span, cm))
246
+ cm.__enter__()
224
247
 
225
248
  def _end_span(self, exc_value: Optional[BaseException]) -> None:
249
+ context_span = self.context_spans.pop()
226
250
  if exc_value is None:
227
- self.spans[-1].set_status(Status(StatusCode.OK))
251
+ context_span.span.set_status(Status(StatusCode.OK))
228
252
  else:
229
- self.spans[-1].set_status(
253
+ context_span.span.set_status(
230
254
  Status(StatusCode.ERROR, description=str(exc_value))
231
255
  )
232
- dbos_tracer.end_span(self.spans.pop())
256
+ dbos_tracer.end_span(context_span.span)
257
+ context_span.context_manager.__exit__(None, None, None)
233
258
 
234
259
  def set_authentication(
235
260
  self, user: Optional[str], roles: Optional[List[str]]
236
261
  ) -> None:
237
262
  self.authenticated_user = user
238
263
  self.authenticated_roles = roles
239
- if user is not None and len(self.spans) > 0:
240
- self.spans[-1].set_attribute("authenticatedUser", user)
241
- self.spans[-1].set_attribute(
264
+ if user is not None and len(self.context_spans) > 0:
265
+ self.context_spans[-1].span.set_attribute("authenticatedUser", user)
266
+ self.context_spans[-1].span.set_attribute(
242
267
  "authenticatedUserRoles", json.dumps(roles) if roles is not None else ""
243
268
  )
244
269
 
dbos/_error.py CHANGED
@@ -126,7 +126,7 @@ class DBOSDeadLetterQueueError(DBOSException):
126
126
 
127
127
  def __init__(self, wf_id: str, max_retries: int):
128
128
  super().__init__(
129
- f"Workflow {wf_id} has been moved to the dead-letter queue after exceeding the maximum of ${max_retries} retries",
129
+ f"Workflow {wf_id} has been moved to the dead-letter queue after exceeding the maximum of {max_retries} retries",
130
130
  dbos_error_code=DBOSErrorCode.DeadLetterQueueError.value,
131
131
  )
132
132
 
dbos/_sys_db.py CHANGED
@@ -437,7 +437,14 @@ class SystemDatabase:
437
437
 
438
438
  # Values to update when a row already exists for this workflow
439
439
  update_values: dict[str, Any] = {
440
- "recovery_attempts": SystemSchema.workflow_status.c.recovery_attempts + 1,
440
+ "recovery_attempts": sa.case(
441
+ (
442
+ SystemSchema.workflow_status.c.status
443
+ != WorkflowStatusString.ENQUEUED.value,
444
+ SystemSchema.workflow_status.c.recovery_attempts + 1,
445
+ ),
446
+ else_=SystemSchema.workflow_status.c.recovery_attempts,
447
+ ),
441
448
  "updated_at": func.extract("epoch", func.now()) * 1000,
442
449
  }
443
450
  # Don't update an existing executor ID when enqueueing a workflow.
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.1
2
2
  Name: dbos
3
- Version: 1.8.0a1
3
+ Version: 1.8.0a3
4
4
  Summary: Ultra-lightweight durable execution in Python
5
5
  Author-Email: "DBOS, Inc." <contact@dbos.dev>
6
6
  License: MIT
@@ -1,7 +1,7 @@
1
- dbos-1.8.0a1.dist-info/METADATA,sha256=YxpqtPtDVv28hgyqDg9sbsNWZ5pRr7mbOOCPVZ1IsRA,13267
2
- dbos-1.8.0a1.dist-info/WHEEL,sha256=tSfRZzRHthuv7vxpI4aehrdN9scLjk-dCJkPLzkHxGg,90
3
- dbos-1.8.0a1.dist-info/entry_points.txt,sha256=_QOQ3tVfEjtjBlr1jS4sHqHya9lI2aIEIWkz8dqYp14,58
4
- dbos-1.8.0a1.dist-info/licenses/LICENSE,sha256=VGZit_a5-kdw9WT6fY5jxAWVwGQzgLFyPWrcVVUhVNU,1067
1
+ dbos-1.8.0a3.dist-info/METADATA,sha256=Eo7YKx6NXFQxjbLzrfUNs7AiHsUQqogTMQZNi1SNSmg,13267
2
+ dbos-1.8.0a3.dist-info/WHEEL,sha256=9P2ygRxDrTJz3gsagc0Z96ukrxjr-LFBGOgv3AuKlCA,90
3
+ dbos-1.8.0a3.dist-info/entry_points.txt,sha256=_QOQ3tVfEjtjBlr1jS4sHqHya9lI2aIEIWkz8dqYp14,58
4
+ dbos-1.8.0a3.dist-info/licenses/LICENSE,sha256=VGZit_a5-kdw9WT6fY5jxAWVwGQzgLFyPWrcVVUhVNU,1067
5
5
  dbos/__init__.py,sha256=NssPCubaBxdiKarOWa-wViz1hdJSkmBGcpLX_gQ4NeA,891
6
6
  dbos/__main__.py,sha256=G7Exn-MhGrVJVDbgNlpzhfh8WMX_72t3_oJaFT9Lmt8,653
7
7
  dbos/_admin_server.py,sha256=e8ELhcDWqR3_PNobnNgUvLGh5lzZq0yFSF6dvtzoQRI,16267
@@ -10,14 +10,14 @@ dbos/_classproperty.py,sha256=f0X-_BySzn3yFDRKB2JpCbLYQ9tLwt1XftfshvY7CBs,626
10
10
  dbos/_client.py,sha256=KD38fNX-u8hCyjcED3-Q7B6RrCNDeO9YZraAoi2nzrI,15194
11
11
  dbos/_conductor/conductor.py,sha256=3E_hL3c9g9yWqKZkvI6KA0-ZzPMPRo06TOzT1esMiek,24114
12
12
  dbos/_conductor/protocol.py,sha256=q3rgLxINFtWFigdOONc-4gX4vn66UmMlJQD6Kj8LnL4,7420
13
- dbos/_context.py,sha256=zhje6jObpBcRALYfHyyIEumHtk_enl_PxLl01j4oDME,24897
13
+ dbos/_context.py,sha256=0vFtLAk3WF5BQYIYNFImDRBppKO2CTKOSy51zQC-Cu8,25723
14
14
  dbos/_core.py,sha256=kRY2PXVryfpwjbOCmgzPA_-qNsFmRMLi-CxYCnyp1V8,49495
15
15
  dbos/_croniter.py,sha256=XHAyUyibs_59sJQfSNWkP7rqQY6_XrlfuuCxk4jYqek,47559
16
16
  dbos/_dbos.py,sha256=2fvnTLnHAXcI8FTXBiMrsnjxqg8sbTSKxYBDKG7LZ1g,48361
17
17
  dbos/_dbos_config.py,sha256=JUG4V1rrP0p1AYESgih4ea80qOH_13UsgoIIm8X84pw,20562
18
18
  dbos/_debug.py,sha256=99j2SChWmCPAlZoDmjsJGe77tpU2LEa8E2TtLAnnh7o,1831
19
19
  dbos/_docker_pg_helper.py,sha256=tLJXWqZ4S-ExcaPnxg_i6cVxL6ZxrYlZjaGsklY-s2I,6115
20
- dbos/_error.py,sha256=nS7KuXJHhuNXZRErxdEUGT38Hb0VPyxNwSyADiVpHcE,8581
20
+ dbos/_error.py,sha256=MAHBjo2MLoaHBtRL1pOPNKqAM3IdNPPV11n7-meSF54,8580
21
21
  dbos/_event_loop.py,sha256=cvaFN9-II3MsHEOq8QoICc_8qSKrjikMlLfuhC3Y8Dk,2923
22
22
  dbos/_fastapi.py,sha256=T7YlVY77ASqyTqq0aAPclZ9YzlXdGTT0lEYSwSgt1EE,3151
23
23
  dbos/_flask.py,sha256=Npnakt-a3W5OykONFRkDRnumaDhTQmA0NPdUCGRYKXE,1652
@@ -49,7 +49,7 @@ dbos/_schemas/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
49
49
  dbos/_schemas/application_database.py,sha256=SypAS9l9EsaBHFn9FR8jmnqt01M74d9AF1AMa4m2hhI,1040
50
50
  dbos/_schemas/system_database.py,sha256=rbFKggONdvvbb45InvGz0TM6a7c-Ux9dcaL-h_7Z7pU,4438
51
51
  dbos/_serialization.py,sha256=bWuwhXSQcGmiazvhJHA5gwhrRWxtmFmcCFQSDJnqqkU,3666
52
- dbos/_sys_db.py,sha256=Eh9ghQzwmcDsYDu9mFO8HHIbqOWGXy1IxaX8dIODWK0,81270
52
+ dbos/_sys_db.py,sha256=862gEhgQ1l_yLDMoYrux4Ri8Hv6aQH-c_BHFAeDVTvE,81541
53
53
  dbos/_templates/dbos-db-starter/README.md,sha256=GhxhBj42wjTt1fWEtwNriHbJuKb66Vzu89G4pxNHw2g,930
54
54
  dbos/_templates/dbos-db-starter/__package/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
55
55
  dbos/_templates/dbos-db-starter/__package/main.py.dbos,sha256=aQnBPSSQpkB8ERfhf7gB7P9tsU6OPKhZscfeh0yiaD8,2702
@@ -69,4 +69,4 @@ dbos/cli/cli.py,sha256=IcfaX4rrSrk6f24S2jrlR33snYMyNyEIx_lNQtuVr2E,22081
69
69
  dbos/dbos-config.schema.json,sha256=CjaspeYmOkx6Ip_pcxtmfXJTn_YGdSx_0pcPBF7KZmo,6060
70
70
  dbos/py.typed,sha256=QfzXT1Ktfk3Rj84akygc7_42z0lRpCq0Ilh8OXI6Zas,44
71
71
  version/__init__.py,sha256=L4sNxecRuqdtSFdpUGX3TtBi9KL3k7YsZVIvv-fv9-A,1678
72
- dbos-1.8.0a1.dist-info/RECORD,,
72
+ dbos-1.8.0a3.dist-info/RECORD,,
@@ -1,4 +1,4 @@
1
1
  Wheel-Version: 1.0
2
- Generator: pdm-backend (2.4.4)
2
+ Generator: pdm-backend (2.4.5)
3
3
  Root-Is-Purelib: true
4
4
  Tag: py3-none-any