dbos 1.15.0a3__tar.gz → 1.15.0a5__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 dbos might be problematic. Click here for more details.

Files changed (100) hide show
  1. {dbos-1.15.0a3 → dbos-1.15.0a5}/PKG-INFO +1 -1
  2. {dbos-1.15.0a3 → dbos-1.15.0a5}/dbos/_admin_server.py +1 -1
  3. {dbos-1.15.0a3 → dbos-1.15.0a5}/dbos/_client.py +0 -2
  4. {dbos-1.15.0a3 → dbos-1.15.0a5}/dbos/_dbos.py +4 -24
  5. {dbos-1.15.0a3 → dbos-1.15.0a5}/dbos/_dbos_config.py +4 -18
  6. {dbos-1.15.0a3 → dbos-1.15.0a5}/dbos/_debouncer.py +7 -5
  7. {dbos-1.15.0a3 → dbos-1.15.0a5}/dbos/_queue.py +2 -2
  8. {dbos-1.15.0a3 → dbos-1.15.0a5}/dbos/cli/cli.py +0 -42
  9. dbos-1.15.0a5/dbos/dbos-config.schema.json +61 -0
  10. {dbos-1.15.0a3 → dbos-1.15.0a5}/pyproject.toml +1 -1
  11. {dbos-1.15.0a3 → dbos-1.15.0a5}/tests/test_admin_server.py +4 -4
  12. {dbos-1.15.0a3 → dbos-1.15.0a5}/tests/test_async_workflow_management.py +0 -19
  13. {dbos-1.15.0a3 → dbos-1.15.0a5}/tests/test_client.py +6 -8
  14. {dbos-1.15.0a3 → dbos-1.15.0a5}/tests/test_config.py +2 -52
  15. {dbos-1.15.0a3 → dbos-1.15.0a5}/tests/test_dbos.py +6 -6
  16. {dbos-1.15.0a3 → dbos-1.15.0a5}/tests/test_debouncer.py +1 -1
  17. {dbos-1.15.0a3 → dbos-1.15.0a5}/tests/test_package.py +0 -11
  18. {dbos-1.15.0a3 → dbos-1.15.0a5}/tests/test_queue.py +4 -1
  19. {dbos-1.15.0a3 → dbos-1.15.0a5}/tests/test_schema_migration.py +0 -25
  20. {dbos-1.15.0a3 → dbos-1.15.0a5}/tests/test_spans.py +7 -7
  21. {dbos-1.15.0a3 → dbos-1.15.0a5}/tests/test_workflow_introspection.py +5 -5
  22. {dbos-1.15.0a3 → dbos-1.15.0a5}/tests/test_workflow_management.py +2 -61
  23. dbos-1.15.0a3/dbos/dbos-config.schema.json +0 -182
  24. {dbos-1.15.0a3 → dbos-1.15.0a5}/LICENSE +0 -0
  25. {dbos-1.15.0a3 → dbos-1.15.0a5}/README.md +0 -0
  26. {dbos-1.15.0a3 → dbos-1.15.0a5}/dbos/__init__.py +0 -0
  27. {dbos-1.15.0a3 → dbos-1.15.0a5}/dbos/__main__.py +0 -0
  28. {dbos-1.15.0a3 → dbos-1.15.0a5}/dbos/_app_db.py +0 -0
  29. {dbos-1.15.0a3 → dbos-1.15.0a5}/dbos/_classproperty.py +0 -0
  30. {dbos-1.15.0a3 → dbos-1.15.0a5}/dbos/_conductor/conductor.py +0 -0
  31. {dbos-1.15.0a3 → dbos-1.15.0a5}/dbos/_conductor/protocol.py +0 -0
  32. {dbos-1.15.0a3 → dbos-1.15.0a5}/dbos/_context.py +0 -0
  33. {dbos-1.15.0a3 → dbos-1.15.0a5}/dbos/_core.py +0 -0
  34. {dbos-1.15.0a3 → dbos-1.15.0a5}/dbos/_croniter.py +0 -0
  35. {dbos-1.15.0a3 → dbos-1.15.0a5}/dbos/_debug.py +0 -0
  36. {dbos-1.15.0a3 → dbos-1.15.0a5}/dbos/_docker_pg_helper.py +0 -0
  37. {dbos-1.15.0a3 → dbos-1.15.0a5}/dbos/_error.py +0 -0
  38. {dbos-1.15.0a3 → dbos-1.15.0a5}/dbos/_event_loop.py +0 -0
  39. {dbos-1.15.0a3 → dbos-1.15.0a5}/dbos/_fastapi.py +0 -0
  40. {dbos-1.15.0a3 → dbos-1.15.0a5}/dbos/_flask.py +0 -0
  41. {dbos-1.15.0a3 → dbos-1.15.0a5}/dbos/_kafka.py +0 -0
  42. {dbos-1.15.0a3 → dbos-1.15.0a5}/dbos/_kafka_message.py +0 -0
  43. {dbos-1.15.0a3 → dbos-1.15.0a5}/dbos/_logger.py +0 -0
  44. {dbos-1.15.0a3 → dbos-1.15.0a5}/dbos/_migration.py +0 -0
  45. {dbos-1.15.0a3 → dbos-1.15.0a5}/dbos/_outcome.py +0 -0
  46. {dbos-1.15.0a3 → dbos-1.15.0a5}/dbos/_recovery.py +0 -0
  47. {dbos-1.15.0a3 → dbos-1.15.0a5}/dbos/_registrations.py +0 -0
  48. {dbos-1.15.0a3 → dbos-1.15.0a5}/dbos/_roles.py +0 -0
  49. {dbos-1.15.0a3 → dbos-1.15.0a5}/dbos/_scheduler.py +0 -0
  50. {dbos-1.15.0a3 → dbos-1.15.0a5}/dbos/_schemas/__init__.py +0 -0
  51. {dbos-1.15.0a3 → dbos-1.15.0a5}/dbos/_schemas/application_database.py +0 -0
  52. {dbos-1.15.0a3 → dbos-1.15.0a5}/dbos/_schemas/system_database.py +0 -0
  53. {dbos-1.15.0a3 → dbos-1.15.0a5}/dbos/_serialization.py +0 -0
  54. {dbos-1.15.0a3 → dbos-1.15.0a5}/dbos/_sys_db.py +0 -0
  55. {dbos-1.15.0a3 → dbos-1.15.0a5}/dbos/_sys_db_postgres.py +0 -0
  56. {dbos-1.15.0a3 → dbos-1.15.0a5}/dbos/_sys_db_sqlite.py +0 -0
  57. {dbos-1.15.0a3 → dbos-1.15.0a5}/dbos/_templates/dbos-db-starter/README.md +0 -0
  58. {dbos-1.15.0a3 → dbos-1.15.0a5}/dbos/_templates/dbos-db-starter/__package/__init__.py +0 -0
  59. {dbos-1.15.0a3 → dbos-1.15.0a5}/dbos/_templates/dbos-db-starter/__package/main.py.dbos +0 -0
  60. {dbos-1.15.0a3 → dbos-1.15.0a5}/dbos/_templates/dbos-db-starter/__package/schema.py +0 -0
  61. {dbos-1.15.0a3 → dbos-1.15.0a5}/dbos/_templates/dbos-db-starter/dbos-config.yaml.dbos +0 -0
  62. {dbos-1.15.0a3 → dbos-1.15.0a5}/dbos/_templates/dbos-db-starter/migrations/create_table.py.dbos +0 -0
  63. {dbos-1.15.0a3 → dbos-1.15.0a5}/dbos/_templates/dbos-db-starter/start_postgres_docker.py +0 -0
  64. {dbos-1.15.0a3 → dbos-1.15.0a5}/dbos/_tracer.py +0 -0
  65. {dbos-1.15.0a3 → dbos-1.15.0a5}/dbos/_utils.py +0 -0
  66. {dbos-1.15.0a3 → dbos-1.15.0a5}/dbos/_workflow_commands.py +0 -0
  67. {dbos-1.15.0a3 → dbos-1.15.0a5}/dbos/cli/_github_init.py +0 -0
  68. {dbos-1.15.0a3 → dbos-1.15.0a5}/dbos/cli/_template_init.py +0 -0
  69. {dbos-1.15.0a3 → dbos-1.15.0a5}/dbos/cli/migration.py +0 -0
  70. {dbos-1.15.0a3 → dbos-1.15.0a5}/dbos/py.typed +0 -0
  71. {dbos-1.15.0a3 → dbos-1.15.0a5}/tests/__init__.py +0 -0
  72. {dbos-1.15.0a3 → dbos-1.15.0a5}/tests/atexit_no_ctor.py +0 -0
  73. {dbos-1.15.0a3 → dbos-1.15.0a5}/tests/atexit_no_launch.py +0 -0
  74. {dbos-1.15.0a3 → dbos-1.15.0a5}/tests/classdefs.py +0 -0
  75. {dbos-1.15.0a3 → dbos-1.15.0a5}/tests/client_collateral.py +0 -0
  76. {dbos-1.15.0a3 → dbos-1.15.0a5}/tests/client_worker.py +0 -0
  77. {dbos-1.15.0a3 → dbos-1.15.0a5}/tests/conftest.py +0 -0
  78. {dbos-1.15.0a3 → dbos-1.15.0a5}/tests/dupname_classdefs1.py +0 -0
  79. {dbos-1.15.0a3 → dbos-1.15.0a5}/tests/dupname_classdefsa.py +0 -0
  80. {dbos-1.15.0a3 → dbos-1.15.0a5}/tests/more_classdefs.py +0 -0
  81. {dbos-1.15.0a3 → dbos-1.15.0a5}/tests/queuedworkflow.py +0 -0
  82. {dbos-1.15.0a3 → dbos-1.15.0a5}/tests/script_without_fastapi.py +0 -0
  83. {dbos-1.15.0a3 → dbos-1.15.0a5}/tests/test_async.py +0 -0
  84. {dbos-1.15.0a3 → dbos-1.15.0a5}/tests/test_classdecorators.py +0 -0
  85. {dbos-1.15.0a3 → dbos-1.15.0a5}/tests/test_cli.py +0 -0
  86. {dbos-1.15.0a3 → dbos-1.15.0a5}/tests/test_concurrency.py +0 -0
  87. {dbos-1.15.0a3 → dbos-1.15.0a5}/tests/test_croniter.py +0 -0
  88. {dbos-1.15.0a3 → dbos-1.15.0a5}/tests/test_debug.py +0 -0
  89. {dbos-1.15.0a3 → dbos-1.15.0a5}/tests/test_docker_secrets.py +0 -0
  90. {dbos-1.15.0a3 → dbos-1.15.0a5}/tests/test_failures.py +0 -0
  91. {dbos-1.15.0a3 → dbos-1.15.0a5}/tests/test_fastapi.py +0 -0
  92. {dbos-1.15.0a3 → dbos-1.15.0a5}/tests/test_fastapi_roles.py +0 -0
  93. {dbos-1.15.0a3 → dbos-1.15.0a5}/tests/test_flask.py +0 -0
  94. {dbos-1.15.0a3 → dbos-1.15.0a5}/tests/test_kafka.py +0 -0
  95. {dbos-1.15.0a3 → dbos-1.15.0a5}/tests/test_outcome.py +0 -0
  96. {dbos-1.15.0a3 → dbos-1.15.0a5}/tests/test_scheduler.py +0 -0
  97. {dbos-1.15.0a3 → dbos-1.15.0a5}/tests/test_singleton.py +0 -0
  98. {dbos-1.15.0a3 → dbos-1.15.0a5}/tests/test_sqlalchemy.py +0 -0
  99. {dbos-1.15.0a3 → dbos-1.15.0a5}/tests/test_streaming.py +0 -0
  100. {dbos-1.15.0a3 → dbos-1.15.0a5}/version/__init__.py +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.1
2
2
  Name: dbos
3
- Version: 1.15.0a3
3
+ Version: 1.15.0a5
4
4
  Summary: Ultra-lightweight durable execution in Python
5
5
  Author-Email: "DBOS, Inc." <contact@dbos.dev>
6
6
  License: MIT
@@ -244,7 +244,7 @@ class AdminRequestHandler(BaseHTTPRequestHandler):
244
244
  def _handle_restart(self, workflow_id: str) -> None:
245
245
  try:
246
246
  print(f"Restarting workflow {workflow_id}")
247
- handle = self.dbos.restart_workflow(workflow_id)
247
+ handle = self.dbos.fork_workflow(workflow_id, 1)
248
248
  response_body = json.dumps(
249
249
  {
250
250
  "workflow_id": handle.workflow_id,
@@ -124,7 +124,6 @@ class DBOSClient:
124
124
  system_database_url: Optional[str] = None,
125
125
  application_database_url: Optional[str] = None,
126
126
  dbos_system_schema: Optional[str] = "dbos",
127
- system_database: Optional[str] = None, # DEPRECATED
128
127
  ):
129
128
  application_database_url = (
130
129
  database_url if database_url else application_database_url
@@ -133,7 +132,6 @@ class DBOSClient:
133
132
  {
134
133
  "system_database_url": system_database_url,
135
134
  "database_url": application_database_url,
136
- "database": {"sys_db_name": system_database},
137
135
  }
138
136
  )
139
137
  assert is_valid_database_url(system_database_url)
@@ -1029,16 +1029,6 @@ class DBOS:
1029
1029
  await asyncio.to_thread(cls.resume_workflow, workflow_id)
1030
1030
  return await cls.retrieve_workflow_async(workflow_id)
1031
1031
 
1032
- @classmethod
1033
- def restart_workflow(cls, workflow_id: str) -> WorkflowHandle[Any]:
1034
- """Restart a workflow with a new workflow ID"""
1035
- return cls.fork_workflow(workflow_id, 1)
1036
-
1037
- @classmethod
1038
- async def restart_workflow_async(cls, workflow_id: str) -> WorkflowHandleAsync[Any]:
1039
- """Restart a workflow with a new workflow ID"""
1040
- return await cls.fork_workflow_async(workflow_id, 1)
1041
-
1042
1032
  @classmethod
1043
1033
  def fork_workflow(
1044
1034
  cls,
@@ -1232,6 +1222,10 @@ class DBOS:
1232
1222
  async def list_workflow_steps_async(cls, workflow_id: str) -> List[StepInfo]:
1233
1223
  await cls._configure_asyncio_thread_pool()
1234
1224
  return await asyncio.to_thread(cls.list_workflow_steps, workflow_id)
1225
+
1226
+ @classproperty
1227
+ def application_version(cls) -> str:
1228
+ return GlobalParams.app_version
1235
1229
 
1236
1230
  @classproperty
1237
1231
  def logger(cls) -> Logger:
@@ -1274,20 +1268,6 @@ class DBOS:
1274
1268
  else:
1275
1269
  return None
1276
1270
 
1277
- @classproperty
1278
- def parent_workflow_id(cls) -> str:
1279
- """
1280
- This method is deprecated and should not be used.
1281
- """
1282
- dbos_logger.warning(
1283
- "DBOS.parent_workflow_id is deprecated and should not be used"
1284
- )
1285
- ctx = assert_current_dbos_context()
1286
- assert (
1287
- ctx.is_within_workflow()
1288
- ), "parent_workflow_id is only available within a workflow."
1289
- return ctx.parent_workflow_id
1290
-
1291
1271
  @classproperty
1292
1272
  def span(cls) -> "Span":
1293
1273
  """Return the tracing `Span` associated with the current context."""
@@ -22,7 +22,6 @@ class DBOSConfig(TypedDict, total=False):
22
22
  system_database_url (str): Connection string for the DBOS system database. Defaults to sqlite:///{name} if not provided.
23
23
  application_database_url (str): Connection string for the DBOS application database, in which DBOS @Transaction functions run. Optional. Should be the same type of database (SQLite or Postgres) as the system database.
24
24
  database_url (str): (DEPRECATED) Database connection string
25
- sys_db_name (str): (DEPRECATED) System database name
26
25
  sys_db_pool_size (int): System database pool size
27
26
  db_engine_kwargs (Dict[str, Any]): SQLAlchemy engine kwargs (See https://docs.sqlalchemy.org/en/20/core/engines.html#sqlalchemy.create_engine)
28
27
  log_level (str): Log level
@@ -41,7 +40,6 @@ class DBOSConfig(TypedDict, total=False):
41
40
  system_database_url: Optional[str]
42
41
  application_database_url: Optional[str]
43
42
  database_url: Optional[str]
44
- sys_db_name: Optional[str]
45
43
  sys_db_pool_size: Optional[int]
46
44
  db_engine_kwargs: Optional[Dict[str, Any]]
47
45
  log_level: Optional[str]
@@ -74,14 +72,10 @@ class DatabaseConfig(TypedDict, total=False):
74
72
  dbos_system_schema (str): Schema name for DBOS system tables. Defaults to "dbos".
75
73
  """
76
74
 
77
- sys_db_name: Optional[str]
78
- sys_db_pool_size: Optional[
79
- int
80
- ] # For internal use, will be removed in a future version
75
+ sys_db_pool_size: Optional[int]
81
76
  db_engine_kwargs: Optional[Dict[str, Any]]
82
77
  sys_db_engine_kwargs: Optional[Dict[str, Any]]
83
78
  migrate: Optional[List[str]]
84
- rollback: Optional[List[str]] # Will be removed in a future version
85
79
 
86
80
 
87
81
  class OTLPExporterConfig(TypedDict, total=False):
@@ -139,8 +133,6 @@ def translate_dbos_config_to_config_file(config: DBOSConfig) -> ConfigFile:
139
133
 
140
134
  # Database config
141
135
  db_config: DatabaseConfig = {}
142
- if "sys_db_name" in config:
143
- db_config["sys_db_name"] = config.get("sys_db_name")
144
136
  if "sys_db_pool_size" in config:
145
137
  db_config["sys_db_pool_size"] = config.get("sys_db_pool_size")
146
138
  if "db_engine_kwargs" in config:
@@ -409,10 +401,7 @@ def process_config(
409
401
  else:
410
402
  url = make_url(data["database_url"])
411
403
  assert url.database
412
- if data["database"].get("sys_db_name"):
413
- url = url.set(database=data["database"]["sys_db_name"])
414
- else:
415
- url = url.set(database=f"{url.database}{SystemSchema.sysdb_suffix}")
404
+ url = url.set(database=f"{url.database}{SystemSchema.sysdb_suffix}")
416
405
  data["system_database_url"] = url.render_as_string(hide_password=False)
417
406
 
418
407
  # If a system database URL is provided but not an application database URL,
@@ -617,11 +606,8 @@ def get_system_database_url(config: ConfigFile) -> str:
617
606
  if config["database_url"].startswith("sqlite"):
618
607
  return config["database_url"]
619
608
  app_db_url = make_url(config["database_url"])
620
- if config.get("database") and config["database"].get("sys_db_name") is not None:
621
- sys_db_name = config["database"]["sys_db_name"]
622
- else:
623
- assert app_db_url.database is not None
624
- sys_db_name = app_db_url.database + SystemSchema.sysdb_suffix
609
+ assert app_db_url.database is not None
610
+ sys_db_name = app_db_url.database + SystemSchema.sysdb_suffix
625
611
  return app_db_url.set(database=sys_db_name).render_as_string(
626
612
  hide_password=False
627
613
  )
@@ -89,11 +89,13 @@ def debouncer_workflow(
89
89
  # Every time the debounced workflow is called, a message is sent to this workflow.
90
90
  # It waits until debounce_period_sec have passed since the last message or until
91
91
  # debounce_timeout_sec has elapsed.
92
- debounce_deadline_epoch_sec = (
93
- time.time() + options["debounce_timeout_sec"]
94
- if options["debounce_timeout_sec"]
95
- else math.inf
96
- )
92
+ def get_debounce_deadline_epoch_sec() -> float:
93
+ return (
94
+ time.time() + options["debounce_timeout_sec"]
95
+ if options["debounce_timeout_sec"]
96
+ else math.inf
97
+ )
98
+ debounce_deadline_epoch_sec = dbos._sys_db.call_function_as_step(get_debounce_deadline_epoch_sec, "get_debounce_deadline_epoch_sec")
97
99
  debounce_period_sec = initial_debounce_period_sec
98
100
  while time.time() < debounce_deadline_epoch_sec:
99
101
  time_until_deadline = max(debounce_deadline_epoch_sec - time.time(), 0)
@@ -61,7 +61,7 @@ class Queue:
61
61
 
62
62
  registry = _get_or_create_dbos_registry()
63
63
  if self.name in registry.queue_info_map and self.name != INTERNAL_QUEUE_NAME:
64
- dbos_logger.warning(f"Queue {name} has already been declared")
64
+ raise Exception(f"Queue {name} has already been declared")
65
65
  registry.queue_info_map[self.name] = self
66
66
 
67
67
  def enqueue(
@@ -75,7 +75,7 @@ class Queue:
75
75
  and context.priority is not None
76
76
  and not self.priority_enabled
77
77
  ):
78
- dbos_logger.warning(
78
+ raise Exception(
79
79
  f"Priority is not enabled for queue {self.name}. Setting priority will not have any effect."
80
80
  )
81
81
 
@@ -681,48 +681,6 @@ def resume(
681
681
  client.resume_workflow(workflow_id=workflow_id)
682
682
 
683
683
 
684
- @workflow.command(
685
- help="[DEPRECATED - Use fork instead] Restart a workflow from the beginning with a new id"
686
- )
687
- def restart(
688
- workflow_id: Annotated[str, typer.Argument()],
689
- application_database_url: Annotated[
690
- typing.Optional[str],
691
- typer.Option(
692
- "--db-url",
693
- "-D",
694
- help="Your DBOS application database URL",
695
- ),
696
- ] = None,
697
- system_database_url: Annotated[
698
- typing.Optional[str],
699
- typer.Option(
700
- "--sys-db-url",
701
- "-s",
702
- help="Your DBOS system database URL",
703
- ),
704
- ] = None,
705
- schema: Annotated[
706
- typing.Optional[str],
707
- typer.Option(
708
- "--schema",
709
- help='Schema name for DBOS system tables. Defaults to "dbos".',
710
- ),
711
- ] = "dbos",
712
- ) -> None:
713
- system_database_url, application_database_url = _get_db_url(
714
- system_database_url=system_database_url,
715
- application_database_url=application_database_url,
716
- )
717
- client = DBOSClient(
718
- application_database_url=application_database_url,
719
- system_database_url=system_database_url,
720
- dbos_system_schema=schema,
721
- )
722
- status = client.fork_workflow(workflow_id=workflow_id, start_step=1).get_status()
723
- print(json.dumps(status.__dict__, cls=DefaultEncoder))
724
-
725
-
726
684
  @workflow.command(
727
685
  help="fork a workflow from the beginning with a new id and from a step"
728
686
  )
@@ -0,0 +1,61 @@
1
+ {
2
+ "$schema": "http://json-schema.org/draft-07/schema#",
3
+ "title": "DBOS Config",
4
+ "type": "object",
5
+ "additionalProperties": false,
6
+ "properties": {
7
+ "name": {
8
+ "type": "string",
9
+ "description": "The name of your application"
10
+ },
11
+ "language": {
12
+ "type": "string",
13
+ "description": "The language used in your application",
14
+ "enum": [
15
+ "python"
16
+ ]
17
+ },
18
+ "database_url": {
19
+ "type": ["string", "null"],
20
+ "description": "The URL of the application database"
21
+ },
22
+ "system_database_url": {
23
+ "type": ["string", "null"],
24
+ "description": "The URL of the system database"
25
+ },
26
+ "database": {
27
+ "type": "object",
28
+ "additionalProperties": false,
29
+ "properties": {
30
+ "app_db_name": {
31
+ "type": ["string", "null"],
32
+ "description": "The name of the application database in DBOS Cloud",
33
+ "deprecated": true
34
+ },
35
+ "migrate": {
36
+ "type": "array",
37
+ "description": "Specify a list of user database migration commands to run in DBOS Cloud"
38
+ }
39
+ }
40
+ },
41
+ "runtimeConfig": {
42
+ "type": "object",
43
+ "additionalProperties": false,
44
+ "properties": {
45
+ "start": {
46
+ "type": "array",
47
+ "description": "Specify commands to run to start your application in DBOS Cloud"
48
+ },
49
+ "setup": {
50
+ "type": "array",
51
+ "items": {
52
+ "type": "string"
53
+ },
54
+ "description": "Commands to setup the application execution environment in DBOS Cloud"
55
+ }
56
+ }
57
+ },
58
+ "env": {}
59
+ }
60
+ }
61
+
@@ -15,7 +15,7 @@ dependencies = [
15
15
  ]
16
16
  requires-python = ">=3.10"
17
17
  readme = "README.md"
18
- version = "1.15.0a3"
18
+ version = "1.15.0a5"
19
19
 
20
20
  [project.license]
21
21
  text = "MIT"
@@ -520,7 +520,7 @@ def test_list_workflows(dbos: DBOS, skip_with_sqlite_imprecise_time: None) -> No
520
520
  assert workflows[0]["CreatedAt"] is not None and len(workflows[0]["CreatedAt"]) > 0
521
521
  assert workflows[0]["UpdatedAt"] is not None and len(workflows[0]["UpdatedAt"]) > 0
522
522
  assert workflows[0]["QueueName"] is None
523
- assert workflows[0]["ApplicationVersion"] == GlobalParams.app_version
523
+ assert workflows[0]["ApplicationVersion"] == DBOS.application_version
524
524
  assert workflows[0]["ExecutorID"] == GlobalParams.executor_id
525
525
 
526
526
  # Only load input and output as requested
@@ -620,7 +620,7 @@ def test_list_workflows(dbos: DBOS, skip_with_sqlite_imprecise_time: None) -> No
620
620
  assert len(workflows) == 2
621
621
 
622
622
  filters = {
623
- "application_version": GlobalParams.app_version,
623
+ "application_version": DBOS.application_version,
624
624
  }
625
625
  response = requests.post("http://localhost:3001/workflows", json=filters, timeout=5)
626
626
  assert response.status_code == 200
@@ -699,7 +699,7 @@ def test_get_workflow_by_id(dbos: DBOS) -> None:
699
699
  workflow_data["UpdatedAt"] is not None and len(workflow_data["UpdatedAt"]) > 0
700
700
  )
701
701
  assert workflow_data["QueueName"] is None
702
- assert workflow_data["ApplicationVersion"] == GlobalParams.app_version
702
+ assert workflow_data["ApplicationVersion"] == DBOS.application_version
703
703
  assert workflow_data["ExecutorID"] == GlobalParams.executor_id
704
704
 
705
705
  # Test GET /workflows/:workflow_id for a non-existing workflow
@@ -812,7 +812,7 @@ def test_queued_workflows_endpoint(
812
812
  and len(queued_workflows[0]["UpdatedAt"]) > 0
813
813
  )
814
814
  assert queued_workflows[0]["QueueName"] == test_queue1.name
815
- assert queued_workflows[0]["ApplicationVersion"] == GlobalParams.app_version
815
+ assert queued_workflows[0]["ApplicationVersion"] == DBOS.application_version
816
816
  assert queued_workflows[0]["ExecutorID"] == GlobalParams.executor_id
817
817
 
818
818
  # Verify sort_desc inverts the order
@@ -95,25 +95,6 @@ async def test_resume_workflow_async(dbos: DBOS) -> None:
95
95
  assert steps_completed == 2
96
96
 
97
97
 
98
- @pytest.mark.asyncio
99
- async def test_restart_workflow_async(dbos: DBOS) -> None:
100
- """Test async restart_workflow method."""
101
- input_val = 2
102
- multiplier = 5
103
-
104
- @DBOS.workflow()
105
- def simple_workflow(x: int) -> int:
106
- return x * multiplier
107
-
108
- # Start the workflow, let it finish, restart it async
109
- handle = DBOS.start_workflow(simple_workflow, input_val)
110
- assert handle.get_result() == input_val * multiplier
111
-
112
- forked_handle = await DBOS.restart_workflow_async(handle.workflow_id)
113
- assert forked_handle.workflow_id != handle.workflow_id
114
- assert (await forked_handle.get_result()) == input_val * multiplier
115
-
116
-
117
98
  @pytest.mark.asyncio
118
99
  async def test_fork_workflow_async(dbos: DBOS) -> None:
119
100
  """Test async fork_workflow method."""
@@ -14,8 +14,6 @@ from sqlalchemy.exc import DBAPIError
14
14
 
15
15
  from dbos import DBOS, DBOSClient, DBOSConfig, EnqueueOptions, SetWorkflowID
16
16
  from dbos._dbos import WorkflowHandle, WorkflowHandleAsync
17
- from dbos._sys_db import SystemDatabase
18
- from dbos._utils import GlobalParams
19
17
  from tests import client_collateral
20
18
  from tests.client_collateral import event_test, retrieve_test, send_test
21
19
 
@@ -125,7 +123,7 @@ def test_client_enqueue_appver_not_set(dbos: DBOS, client: DBOSClient) -> None:
125
123
  assert wf_status is not None
126
124
  assert wf_status.status == "SUCCESS"
127
125
  assert wf_status.name == "enqueue_test"
128
- assert wf_status.app_version == GlobalParams.app_version
126
+ assert wf_status.app_version == DBOS.application_version
129
127
 
130
128
 
131
129
  def test_client_enqueue_appver_set(dbos: DBOS, client: DBOSClient) -> None:
@@ -138,7 +136,7 @@ def test_client_enqueue_appver_set(dbos: DBOS, client: DBOSClient) -> None:
138
136
  "queue_name": "test_queue",
139
137
  "workflow_name": "enqueue_test",
140
138
  "workflow_id": wfid,
141
- "app_version": GlobalParams.app_version,
139
+ "app_version": DBOS.application_version,
142
140
  }
143
141
 
144
142
  client.enqueue(options, 42, "test", johnDoe)
@@ -151,7 +149,7 @@ def test_client_enqueue_appver_set(dbos: DBOS, client: DBOSClient) -> None:
151
149
  assert wf_status is not None
152
150
  assert wf_status.status == "SUCCESS"
153
151
  assert wf_status.name == "enqueue_test"
154
- assert wf_status.app_version == GlobalParams.app_version
152
+ assert wf_status.app_version == DBOS.application_version
155
153
 
156
154
 
157
155
  def test_client_enqueue_wrong_appver(dbos: DBOS, client: DBOSClient) -> None:
@@ -205,7 +203,7 @@ def test_client_enqueue_idempotent(config: DBOSConfig, client: DBOSClient) -> No
205
203
  assert wf_status is not None
206
204
  assert wf_status.status == "SUCCESS"
207
205
  assert wf_status.name == "enqueue_test"
208
- assert wf_status.app_version == GlobalParams.app_version
206
+ assert wf_status.app_version == DBOS.application_version
209
207
 
210
208
  DBOS.destroy(destroy_registry=True)
211
209
 
@@ -272,7 +270,7 @@ def test_client_send_idempotent(
272
270
  idempotency_key = f"test-idempotency-{now}"
273
271
  sendWFID = f"{wfid}-{idempotency_key}"
274
272
 
275
- run_send_worker(wfid, topic, GlobalParams.app_version)
273
+ run_send_worker(wfid, topic, DBOS.application_version)
276
274
 
277
275
  client.send(wfid, message, topic, idempotency_key)
278
276
  client.send(wfid, message, topic, idempotency_key)
@@ -315,7 +313,7 @@ def test_client_send_failure(
315
313
  idempotency_key = f"test-idempotency-{now}"
316
314
  sendWFID = f"{wfid}-{idempotency_key}"
317
315
 
318
- run_send_worker(wfid, topic, GlobalParams.app_version)
316
+ run_send_worker(wfid, topic, DBOS.application_version)
319
317
 
320
318
  client.send(wfid, message, topic, idempotency_key)
321
319
 
@@ -168,7 +168,6 @@ def test_process_config_full():
168
168
  "name": "some-app",
169
169
  "database_url": "postgres://user:password@localhost:7777/dbn?connect_timeout=1&sslmode=require&sslrootcert=ca.pem",
170
170
  "database": {
171
- "sys_db_name": "sys_db",
172
171
  "sys_db_pool_size": 27,
173
172
  "db_engine_kwargs": {"key": "value"},
174
173
  "migrate": ["alembic upgrade head"],
@@ -199,10 +198,9 @@ def test_process_config_full():
199
198
  configFile["database_url"]
200
199
  == "postgres://user:password@localhost:7777/dbn?connect_timeout=1&sslmode=require&sslrootcert=ca.pem"
201
200
  )
202
- assert configFile["database"]["sys_db_name"] == "sys_db"
203
201
  assert (
204
202
  configFile["system_database_url"]
205
- == f"postgres://user:password@localhost:7777/{config['database']['sys_db_name']}?connect_timeout=1&sslmode=require&sslrootcert=ca.pem"
203
+ == f"postgres://user:password@localhost:7777/dbn_dbos_sys?connect_timeout=1&sslmode=require&sslrootcert=ca.pem"
206
204
  )
207
205
  assert configFile["database"]["migrate"] == ["alembic upgrade head"]
208
206
  assert configFile["database"]["db_engine_kwargs"] == {
@@ -241,7 +239,6 @@ def test_process_config_system_database():
241
239
  "database_url": "postgres://user:password@localhost:7777/dbn?connect_timeout=1&sslmode=require&sslrootcert=ca.pem",
242
240
  "system_database_url": "postgres://user:password@localhost:7778/dbn_sys?connect_timeout=1&sslmode=require&sslrootcert=ca.pem",
243
241
  "database": {
244
- "sys_db_name": "sys_db",
245
242
  "sys_db_pool_size": 27,
246
243
  "db_engine_kwargs": {"key": "value"},
247
244
  "migrate": ["alembic upgrade head"],
@@ -386,24 +383,6 @@ def test_config_bad_name():
386
383
  assert "Invalid app name" in str(exc_info.value)
387
384
 
388
385
 
389
- def test_config_mixed_params():
390
- config = {
391
- "name": "some-app",
392
- "database": {
393
- "sys_db_name": "yoohoo",
394
- },
395
- }
396
-
397
- configFile = process_config(data=config)
398
- assert configFile["name"] == "some-app"
399
- assert configFile["database_url"] is None
400
- assert configFile["system_database_url"] == f"sqlite:///some_app.sqlite"
401
- assert configFile["database"]["db_engine_kwargs"] is not None
402
- assert configFile["database"]["sys_db_engine_kwargs"] is not None
403
- assert configFile["telemetry"]["logs"]["logLevel"] == "INFO"
404
- assert configFile["runtimeConfig"]["run_admin_server"] == True
405
-
406
-
407
386
  ####################
408
387
  # PROCESS DB ENGINE KWARGS
409
388
  ####################
@@ -682,7 +661,6 @@ def test_translate_dbosconfig_full_input():
682
661
  config: DBOSConfig = {
683
662
  "name": "test-app",
684
663
  "database_url": "postgres://user:password@localhost:5432/dbname?connect_timeout=11&sslmode=require&sslrootcert=ca.pem",
685
- "sys_db_name": "sysdb",
686
664
  "sys_db_pool_size": 27,
687
665
  "db_engine_kwargs": {"key": "value"},
688
666
  "log_level": "DEBUG",
@@ -696,7 +674,6 @@ def test_translate_dbosconfig_full_input():
696
674
 
697
675
  assert translated_config["name"] == "test-app"
698
676
  assert translated_config["database_url"] == config["database_url"]
699
- assert translated_config["database"]["sys_db_name"] == "sysdb"
700
677
  assert translated_config["database"]["sys_db_pool_size"] == 27
701
678
  assert translated_config["database"]["db_engine_kwargs"] == {"key": "value"}
702
679
  assert translated_config["telemetry"]["logs"]["logLevel"] == "DEBUG"
@@ -728,19 +705,6 @@ def test_translate_dbosconfig_minimal_input():
728
705
  assert "env" not in translated_config
729
706
 
730
707
 
731
- def test_translate_dbosconfig_just_sys_db_name():
732
- config: DBOSConfig = {
733
- "name": "test-app",
734
- "sys_db_name": "sysdb",
735
- }
736
- translated_config = translate_dbos_config_to_config_file(config)
737
-
738
- assert translated_config["database"]["sys_db_name"] == "sysdb"
739
- assert "sys_db_pool_size" not in translated_config["database"]
740
- assert "env" not in translated_config
741
- assert "admin_port" not in translated_config["runtimeConfig"]
742
-
743
-
744
708
  def test_translate_dbosconfig_just_sys_db_pool_size():
745
709
  config: DBOSConfig = {
746
710
  "name": "test-app",
@@ -749,7 +713,6 @@ def test_translate_dbosconfig_just_sys_db_pool_size():
749
713
  translated_config = translate_dbos_config_to_config_file(config)
750
714
 
751
715
  assert translated_config["database"]["sys_db_pool_size"] == 27
752
- assert "sys_db_name" not in translated_config["database"]
753
716
  assert "env" not in translated_config
754
717
 
755
718
 
@@ -762,7 +725,6 @@ def test_translate_dbosconfig_just_db_engine_kwargs():
762
725
 
763
726
  assert translated_config["database"]["db_engine_kwargs"] == {"key": "value"}
764
727
  assert "sys_db_pool_size" not in translated_config["database"]
765
- assert "sys_db_name" not in translated_config["database"]
766
728
  assert "env" not in translated_config
767
729
  assert "admin_port" not in translated_config["runtimeConfig"]
768
730
 
@@ -851,7 +813,6 @@ def test_overwrite_config(mocker):
851
813
  name: "stock-prices"
852
814
  language: "python"
853
815
  database:
854
- sys_db_name: sysdbname
855
816
  migrate:
856
817
  - alembic upgrade head
857
818
  telemetry:
@@ -870,9 +831,7 @@ def test_overwrite_config(mocker):
870
831
 
871
832
  provided_config: ConfigFile = {
872
833
  "name": "test-app",
873
- "database": {
874
- "sys_db_name": "sysdb",
875
- },
834
+ "database": {},
876
835
  "telemetry": {
877
836
  "OTLPExporter": {
878
837
  "tracesEndpoint": ["a"],
@@ -924,7 +883,6 @@ def test_overwrite_config_minimal(mocker):
924
883
  name: "stock-prices"
925
884
  language: "python"
926
885
  database:
927
- sys_db_name: sysdbname
928
886
  migrate:
929
887
  - alembic upgrade head
930
888
  telemetry:
@@ -973,7 +931,6 @@ def test_overwrite_config_has_telemetry(mocker):
973
931
  name: "stock-prices"
974
932
  language: "python"
975
933
  database:
976
- sys_db_name: sysdbname
977
934
  migrate:
978
935
  - alembic upgrade head
979
936
  telemetry:
@@ -1022,8 +979,6 @@ def test_overwrite_config_no_telemetry_in_file(mocker):
1022
979
  mock_config = """
1023
980
  name: "stock-prices"
1024
981
  language: "python"
1025
- database:
1026
- sys_db_name: sysdbname
1027
982
  """
1028
983
  mocker.patch(
1029
984
  "builtins.open", side_effect=generate_mock_open("dbos-config.yaml", mock_config)
@@ -1058,8 +1013,6 @@ def test_overwrite_config_no_otlp_in_file(mocker):
1058
1013
  mock_config = """
1059
1014
  name: "stock-prices"
1060
1015
  language: "python"
1061
- database:
1062
- sys_db_name: sysdbname
1063
1016
  telemetry:
1064
1017
  logs:
1065
1018
  logLevel: INFO
@@ -1100,7 +1053,6 @@ def test_overwrite_config_with_provided_database_url(mocker):
1100
1053
  name: "stock-prices"
1101
1054
  language: "python"
1102
1055
  database:
1103
- sys_db_name: sysdbname
1104
1056
  migrate:
1105
1057
  - alembic upgrade head
1106
1058
  telemetry:
@@ -1146,8 +1098,6 @@ def test_overwrite_config_with_provided_database_url(mocker):
1146
1098
  def test_overwrite_config_missing_dbos_database_url(mocker):
1147
1099
  mock_config = """
1148
1100
  name: "stock-prices"
1149
- database:
1150
- sys_db_name: "sysdbname"
1151
1101
  """
1152
1102
 
1153
1103
  mocker.patch(
@@ -1371,12 +1371,12 @@ def test_app_version(config: DBOSConfig) -> None:
1371
1371
  DBOS.launch()
1372
1372
 
1373
1373
  # Verify that app version is correctly set to a hex string
1374
- app_version = GlobalParams.app_version
1374
+ app_version = DBOS.application_version
1375
1375
  assert len(app_version) > 0
1376
1376
  assert is_hex(app_version)
1377
1377
 
1378
1378
  DBOS.destroy(destroy_registry=True)
1379
- assert GlobalParams.app_version == ""
1379
+ assert DBOS.application_version == ""
1380
1380
  dbos = DBOS(config=config)
1381
1381
 
1382
1382
  @DBOS.workflow()
@@ -1390,7 +1390,7 @@ def test_app_version(config: DBOSConfig) -> None:
1390
1390
  DBOS.launch()
1391
1391
 
1392
1392
  # Verify stability--the same workflow source produces the same app version.
1393
- assert GlobalParams.app_version == app_version
1393
+ assert DBOS.application_version == app_version
1394
1394
 
1395
1395
  DBOS.destroy(destroy_registry=True)
1396
1396
  dbos = DBOS(config=config)
@@ -1401,7 +1401,7 @@ def test_app_version(config: DBOSConfig) -> None:
1401
1401
 
1402
1402
  # Verify that changing the workflow source changes the workflow version
1403
1403
  DBOS.launch()
1404
- assert GlobalParams.app_version != app_version
1404
+ assert DBOS.application_version != app_version
1405
1405
 
1406
1406
  # Verify that version can be overriden with an environment variable
1407
1407
  app_version = str(uuid.uuid4())
@@ -1415,7 +1415,7 @@ def test_app_version(config: DBOSConfig) -> None:
1415
1415
  return x
1416
1416
 
1417
1417
  DBOS.launch()
1418
- assert GlobalParams.app_version == app_version
1418
+ assert DBOS.application_version == app_version
1419
1419
 
1420
1420
  del os.environ["DBOS__APPVERSION"]
1421
1421
 
@@ -1434,7 +1434,7 @@ def test_app_version(config: DBOSConfig) -> None:
1434
1434
  return DBOS.workflow_id
1435
1435
 
1436
1436
  DBOS.launch()
1437
- assert GlobalParams.app_version == app_version
1437
+ assert DBOS.application_version == app_version
1438
1438
  assert GlobalParams.executor_id == executor_id
1439
1439
  wfid = test_workflow()
1440
1440
  handle: WorkflowHandle[str] = DBOS.retrieve_workflow(wfid)
@@ -147,7 +147,7 @@ def test_debouncer_queue(dbos: DBOS) -> None:
147
147
  return x
148
148
 
149
149
  first_value, second_value, third_value, fourth_value = 0, 1, 2, 3
150
- queue = Queue("test-queue")
150
+ queue = Queue("test-queue", priority_enabled=True)
151
151
 
152
152
  debouncer = Debouncer.create(workflow, queue=queue)
153
153
  debounce_period_sec = 2