dbos 1.11.0a5__py3-none-any.whl → 1.12.0a1__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
@@ -753,3 +753,34 @@ class DBOSAssumeRole:
753
753
  assert ctx.assumed_role == self.assume_role
754
754
  ctx.assumed_role = self.prior_role
755
755
  return False # Did not handle
756
+
757
+
758
+ class UseLogAttributes:
759
+ """Temporarily set context attributes for logging"""
760
+
761
+ def __init__(self, *, workflow_id: str = "") -> None:
762
+ self.workflow_id = workflow_id
763
+ self.created_ctx = False
764
+
765
+ def __enter__(self) -> UseLogAttributes:
766
+ ctx = get_local_dbos_context()
767
+ if ctx is None:
768
+ self.created_ctx = True
769
+ _set_local_dbos_context(DBOSContext())
770
+ ctx = assert_current_dbos_context()
771
+ self.saved_workflow_id = ctx.workflow_id
772
+ ctx.workflow_id = self.workflow_id
773
+ return self
774
+
775
+ def __exit__(
776
+ self,
777
+ exc_type: Optional[Type[BaseException]],
778
+ exc_value: Optional[BaseException],
779
+ traceback: Optional[TracebackType],
780
+ ) -> Literal[False]:
781
+ ctx = assert_current_dbos_context()
782
+ ctx.workflow_id = self.saved_workflow_id
783
+ # Clean up the basic context if we created it
784
+ if self.created_ctx:
785
+ _clear_local_dbos_context()
786
+ return False # Did not handle
dbos/_core.py CHANGED
@@ -5,7 +5,6 @@ import json
5
5
  import sys
6
6
  import threading
7
7
  import time
8
- import traceback
9
8
  from concurrent.futures import Future
10
9
  from functools import wraps
11
10
  from typing import (
@@ -66,7 +65,6 @@ from ._registrations import (
66
65
  get_dbos_func_name,
67
66
  get_func_info,
68
67
  get_or_create_func_info,
69
- get_temp_workflow_type,
70
68
  set_dbos_func_name,
71
69
  set_func_info,
72
70
  set_temp_workflow_type,
@@ -452,7 +450,7 @@ def execute_workflow_by_id(dbos: "DBOS", workflow_id: str) -> "WorkflowHandle[An
452
450
  if not wf_func:
453
451
  raise DBOSWorkflowFunctionNotFoundError(
454
452
  workflow_id,
455
- f"Cannot execute workflow because {status['name']} is not a registered workflow function",
453
+ f"{status['name']} is not a registered workflow function",
456
454
  )
457
455
  with DBOSContextEnsure():
458
456
  # If this function belongs to a configured class, add that class instance as its first argument
@@ -463,7 +461,7 @@ def execute_workflow_by_id(dbos: "DBOS", workflow_id: str) -> "WorkflowHandle[An
463
461
  if iname not in dbos._registry.instance_info_map:
464
462
  raise DBOSWorkflowFunctionNotFoundError(
465
463
  workflow_id,
466
- f"Cannot execute workflow because instance '{iname}' is not registered",
464
+ f"configured class instance '{iname}' is not registered",
467
465
  )
468
466
  class_instance = dbos._registry.instance_info_map[iname]
469
467
  inputs["args"] = (class_instance,) + inputs["args"]
@@ -473,7 +471,7 @@ def execute_workflow_by_id(dbos: "DBOS", workflow_id: str) -> "WorkflowHandle[An
473
471
  if class_name not in dbos._registry.class_info_map:
474
472
  raise DBOSWorkflowFunctionNotFoundError(
475
473
  workflow_id,
476
- f"Cannot execute workflow because class '{class_name}' is not registered",
474
+ f"class '{class_name}' is not registered",
477
475
  )
478
476
  class_object = dbos._registry.class_info_map[class_name]
479
477
  inputs["args"] = (class_object,) + inputs["args"]
@@ -534,7 +532,7 @@ def start_workflow(
534
532
  if fi is None:
535
533
  raise DBOSWorkflowFunctionNotFoundError(
536
534
  "<NONE>",
537
- f"start_workflow: function {func.__name__} is not registered",
535
+ f"{func.__name__} is not a registered workflow function",
538
536
  )
539
537
 
540
538
  func = cast("Workflow[P, R]", func.__orig_func) # type: ignore
@@ -630,7 +628,7 @@ async def start_workflow_async(
630
628
  if fi is None:
631
629
  raise DBOSWorkflowFunctionNotFoundError(
632
630
  "<NONE>",
633
- f"start_workflow: function {func.__name__} is not registered",
631
+ f"{func.__name__} is not a registered workflow function",
634
632
  )
635
633
 
636
634
  func = cast("Workflow[P, R]", func.__orig_func) # type: ignore
@@ -1073,7 +1071,8 @@ def decorate_step(
1073
1071
 
1074
1072
  def on_exception(attempt: int, error: BaseException) -> float:
1075
1073
  dbos.logger.warning(
1076
- f"Step being automatically retried. (attempt {attempt + 1} of {attempts}). {traceback.format_exc()}"
1074
+ f"Step being automatically retried (attempt {attempt + 1} of {attempts})",
1075
+ exc_info=error,
1077
1076
  )
1078
1077
  ctx = assert_current_dbos_context()
1079
1078
  span = ctx.get_current_span()
dbos/_dbos.py CHANGED
@@ -211,6 +211,10 @@ class DBOSRegistry:
211
211
  def register_instance(self, inst: object) -> None:
212
212
  config_name = getattr(inst, "config_name")
213
213
  class_name = _class_fqn(inst.__class__)
214
+ if self.dbos and self.dbos._launched:
215
+ dbos_logger.warning(
216
+ f"Configured instance {config_name} of class {class_name} was registered after DBOS was launched. This may cause errors during workflow recovery. All configured instances should be instantiated before DBOS is launched."
217
+ )
214
218
  fn = f"{class_name}/{config_name}"
215
219
  if fn in self.instance_info_map:
216
220
  if self.instance_info_map[fn] is not inst:
dbos/_error.py CHANGED
@@ -106,7 +106,7 @@ class DBOSWorkflowFunctionNotFoundError(DBOSException):
106
106
 
107
107
  def __init__(self, workflow_id: str, message: Optional[str] = None):
108
108
  super().__init__(
109
- f"Workflow function not found for workflow ID {workflow_id}: {message}",
109
+ f"Could not execute workflow {workflow_id}: {message}",
110
110
  dbos_error_code=DBOSErrorCode.WorkflowFunctionNotFound.value,
111
111
  )
112
112
 
dbos/_recovery.py CHANGED
@@ -2,6 +2,7 @@ import threading
2
2
  import time
3
3
  from typing import TYPE_CHECKING, Any, List
4
4
 
5
+ from dbos._context import UseLogAttributes
5
6
  from dbos._utils import GlobalParams
6
7
 
7
8
  from ._core import execute_workflow_by_id
@@ -29,17 +30,19 @@ def startup_recovery_thread(
29
30
  stop_event = threading.Event()
30
31
  dbos.background_thread_stop_events.append(stop_event)
31
32
  while not stop_event.is_set() and len(pending_workflows) > 0:
32
- try:
33
- for pending_workflow in list(pending_workflows):
33
+ for pending_workflow in list(pending_workflows):
34
+ try:
34
35
  _recover_workflow(dbos, pending_workflow)
35
36
  pending_workflows.remove(pending_workflow)
36
- except DBOSWorkflowFunctionNotFoundError:
37
- time.sleep(1)
38
- except Exception as e:
39
- dbos.logger.error(
40
- f"Exception encountered when recovering workflows:", exc_info=e
41
- )
42
- raise
37
+ except DBOSWorkflowFunctionNotFoundError:
38
+ time.sleep(1)
39
+ except Exception as e:
40
+ with UseLogAttributes(workflow_id=pending_workflow.workflow_uuid):
41
+ dbos.logger.error(
42
+ f"Exception encountered when recovering workflow {pending_workflow.workflow_uuid}:",
43
+ exc_info=e,
44
+ )
45
+ raise
43
46
 
44
47
 
45
48
  def recover_pending_workflows(
@@ -56,9 +59,11 @@ def recover_pending_workflows(
56
59
  handle = _recover_workflow(dbos, pending_workflow)
57
60
  workflow_handles.append(handle)
58
61
  except Exception as e:
59
- dbos.logger.error(
60
- f"Exception encountered when recovering workflows:", exc_info=e
61
- )
62
+ with UseLogAttributes(workflow_id=pending_workflow.workflow_uuid):
63
+ dbos.logger.error(
64
+ f"Exception encountered when recovering workflow {pending_workflow.workflow_uuid}:",
65
+ exc_info=e,
66
+ )
62
67
  raise
63
68
  dbos.logger.info(
64
69
  f"Recovering {len(pending_workflows)} workflows for executor {executor_id} from version {GlobalParams.app_version}"
dbos/_registrations.py CHANGED
@@ -13,7 +13,7 @@ def get_dbos_func_name(f: Any) -> str:
13
13
  if hasattr(f, "dbos_function_name"):
14
14
  return str(getattr(f, "dbos_function_name"))
15
15
  raise DBOSWorkflowFunctionNotFoundError(
16
- "<NONE>", f"function {f.__name__} is not registered"
16
+ "<NONE>", f"{f.__name__} is not a registered workflow function"
17
17
  )
18
18
 
19
19
 
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.1
2
2
  Name: dbos
3
- Version: 1.11.0a5
3
+ Version: 1.12.0a1
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.11.0a5.dist-info/METADATA,sha256=O0d8QGDn5f_SGVxyu86jWTyP7ZgluPOf2nJsdNWX3bE,13268
2
- dbos-1.11.0a5.dist-info/WHEEL,sha256=9P2ygRxDrTJz3gsagc0Z96ukrxjr-LFBGOgv3AuKlCA,90
3
- dbos-1.11.0a5.dist-info/entry_points.txt,sha256=_QOQ3tVfEjtjBlr1jS4sHqHya9lI2aIEIWkz8dqYp14,58
4
- dbos-1.11.0a5.dist-info/licenses/LICENSE,sha256=VGZit_a5-kdw9WT6fY5jxAWVwGQzgLFyPWrcVVUhVNU,1067
1
+ dbos-1.12.0a1.dist-info/METADATA,sha256=C0KYncUnaBZoIUcbp8aiGYugvzqGDUYEejRyhriIUac,13268
2
+ dbos-1.12.0a1.dist-info/WHEEL,sha256=9P2ygRxDrTJz3gsagc0Z96ukrxjr-LFBGOgv3AuKlCA,90
3
+ dbos-1.12.0a1.dist-info/entry_points.txt,sha256=_QOQ3tVfEjtjBlr1jS4sHqHya9lI2aIEIWkz8dqYp14,58
4
+ dbos-1.12.0a1.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=_wMe4qnRSwiRZo74xdqTBetbHlIVy3vQifdSd7os1ZY,18213
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=0vFtLAk3WF5BQYIYNFImDRBppKO2CTKOSy51zQC-Cu8,25723
14
- dbos/_core.py,sha256=9S2w15zlxdHqX9bI7SK_DlrO1qzrAyCClIYn-ZXHQZo,49660
13
+ dbos/_context.py,sha256=8yZOTM1ehhk6URLa0EP9_20aOd6SZLhXBmcPwFEZDlA,26739
14
+ dbos/_core.py,sha256=KtIA7VZDeuKrrJT6Cy2z0YeT9dDDxelj69LIJ-4Gors,49536
15
15
  dbos/_croniter.py,sha256=XHAyUyibs_59sJQfSNWkP7rqQY6_XrlfuuCxk4jYqek,47559
16
- dbos/_dbos.py,sha256=h0ZtJNElMB4R2T1320jYD3PXKenn-xCLxnSkIiqpFVg,57386
16
+ dbos/_dbos.py,sha256=bn5S_T6HZnDipYEVqhLq_F2Zo904fjT3J5oO15Frhrs,57715
17
17
  dbos/_dbos_config.py,sha256=er8oF3e9zGlEG9KntX7uBSXrDuVvROtkzVidzXjOwUU,21746
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=2_2ve3qN0BLhFWMmd3aD9At54tIMCeh8TqHtVcEEVQo,8705
20
+ dbos/_error.py,sha256=GwO0Ng4d4iB52brY09-Ss6Cz_V28Xc0D0cRCzZ6XmNM,8688
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
@@ -42,8 +42,8 @@ dbos/_migrations/versions/eab0cc1d9a14_job_queue.py,sha256=uvhFOtqbBreCePhAxZfIT
42
42
  dbos/_migrations/versions/f4b9b32ba814_functionname_childid_op_outputs.py,sha256=m90Lc5YH0ZISSq1MyxND6oq3RZrZKrIqEsZtwJ1jWxA,1049
43
43
  dbos/_outcome.py,sha256=Kz3aL7517q9UEFTx3Cq9zzztjWyWVOx_08fZyHo9dvg,7035
44
44
  dbos/_queue.py,sha256=0kJTPwXy3nZ4Epzt-lHky9M9S4L31645drPGFR8fIJY,4854
45
- dbos/_recovery.py,sha256=TBNjkmSEqBU-g5YXExsLJ9XoCe4iekqtREsskXZECEg,2507
46
- dbos/_registrations.py,sha256=U-PwDZBuyuJjA2LYtud7D3VxDR440mVpMYE-S11BWDo,7369
45
+ dbos/_recovery.py,sha256=K-wlFhdf4yGRm6cUzyhcTjQUS0xp2T5rdNMLiiBErYg,2882
46
+ dbos/_registrations.py,sha256=bEOntObnWaBylnebr5ZpcX2hk7OVLDd1z4BvW4_y3zA,7380
47
47
  dbos/_roles.py,sha256=kCuhhg8XLtrHCgKgm44I0abIRTGHltf88OwjEKAUggk,2317
48
48
  dbos/_scheduler.py,sha256=CWeGVfl9h51VXfxt80y5Da_5pE8SPty_AYkfpJkkMxQ,2117
49
49
  dbos/_schemas/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
@@ -71,4 +71,4 @@ dbos/cli/migration.py,sha256=eI0sc0vYq2iUP3cBHPfTa6WHCyDBr8ld9nRxEZZzFrU,3316
71
71
  dbos/dbos-config.schema.json,sha256=CjaspeYmOkx6Ip_pcxtmfXJTn_YGdSx_0pcPBF7KZmo,6060
72
72
  dbos/py.typed,sha256=QfzXT1Ktfk3Rj84akygc7_42z0lRpCq0Ilh8OXI6Zas,44
73
73
  version/__init__.py,sha256=L4sNxecRuqdtSFdpUGX3TtBi9KL3k7YsZVIvv-fv9-A,1678
74
- dbos-1.11.0a5.dist-info/RECORD,,
74
+ dbos-1.12.0a1.dist-info/RECORD,,