dbos 1.9.0a3__tar.gz → 1.10.0__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.
Files changed (109) hide show
  1. {dbos-1.9.0a3 → dbos-1.10.0}/PKG-INFO +1 -1
  2. {dbos-1.9.0a3 → dbos-1.10.0}/dbos/_dbos.py +11 -0
  3. {dbos-1.9.0a3 → dbos-1.10.0}/dbos/_dbos_config.py +2 -0
  4. {dbos-1.9.0a3 → dbos-1.10.0}/dbos/cli/cli.py +39 -34
  5. {dbos-1.9.0a3 → dbos-1.10.0}/pyproject.toml +1 -1
  6. {dbos-1.9.0a3 → dbos-1.10.0}/tests/test_classdecorators.py +27 -0
  7. {dbos-1.9.0a3 → dbos-1.10.0}/tests/test_dbos.py +23 -1
  8. {dbos-1.9.0a3 → dbos-1.10.0}/LICENSE +0 -0
  9. {dbos-1.9.0a3 → dbos-1.10.0}/README.md +0 -0
  10. {dbos-1.9.0a3 → dbos-1.10.0}/dbos/__init__.py +0 -0
  11. {dbos-1.9.0a3 → dbos-1.10.0}/dbos/__main__.py +0 -0
  12. {dbos-1.9.0a3 → dbos-1.10.0}/dbos/_admin_server.py +0 -0
  13. {dbos-1.9.0a3 → dbos-1.10.0}/dbos/_app_db.py +0 -0
  14. {dbos-1.9.0a3 → dbos-1.10.0}/dbos/_classproperty.py +0 -0
  15. {dbos-1.9.0a3 → dbos-1.10.0}/dbos/_client.py +0 -0
  16. {dbos-1.9.0a3 → dbos-1.10.0}/dbos/_conductor/conductor.py +0 -0
  17. {dbos-1.9.0a3 → dbos-1.10.0}/dbos/_conductor/protocol.py +0 -0
  18. {dbos-1.9.0a3 → dbos-1.10.0}/dbos/_context.py +0 -0
  19. {dbos-1.9.0a3 → dbos-1.10.0}/dbos/_core.py +0 -0
  20. {dbos-1.9.0a3 → dbos-1.10.0}/dbos/_croniter.py +0 -0
  21. {dbos-1.9.0a3 → dbos-1.10.0}/dbos/_debug.py +0 -0
  22. {dbos-1.9.0a3 → dbos-1.10.0}/dbos/_docker_pg_helper.py +0 -0
  23. {dbos-1.9.0a3 → dbos-1.10.0}/dbos/_error.py +0 -0
  24. {dbos-1.9.0a3 → dbos-1.10.0}/dbos/_event_loop.py +0 -0
  25. {dbos-1.9.0a3 → dbos-1.10.0}/dbos/_fastapi.py +0 -0
  26. {dbos-1.9.0a3 → dbos-1.10.0}/dbos/_flask.py +0 -0
  27. {dbos-1.9.0a3 → dbos-1.10.0}/dbos/_kafka.py +0 -0
  28. {dbos-1.9.0a3 → dbos-1.10.0}/dbos/_kafka_message.py +0 -0
  29. {dbos-1.9.0a3 → dbos-1.10.0}/dbos/_logger.py +0 -0
  30. {dbos-1.9.0a3 → dbos-1.10.0}/dbos/_migrations/env.py +0 -0
  31. {dbos-1.9.0a3 → dbos-1.10.0}/dbos/_migrations/script.py.mako +0 -0
  32. {dbos-1.9.0a3 → dbos-1.10.0}/dbos/_migrations/versions/04ca4f231047_workflow_queues_executor_id.py +0 -0
  33. {dbos-1.9.0a3 → dbos-1.10.0}/dbos/_migrations/versions/27ac6900c6ad_add_queue_dedup.py +0 -0
  34. {dbos-1.9.0a3 → dbos-1.10.0}/dbos/_migrations/versions/50f3227f0b4b_fix_job_queue.py +0 -0
  35. {dbos-1.9.0a3 → dbos-1.10.0}/dbos/_migrations/versions/5c361fc04708_added_system_tables.py +0 -0
  36. {dbos-1.9.0a3 → dbos-1.10.0}/dbos/_migrations/versions/66478e1b95e5_consolidate_queues.py +0 -0
  37. {dbos-1.9.0a3 → dbos-1.10.0}/dbos/_migrations/versions/83f3732ae8e7_workflow_timeout.py +0 -0
  38. {dbos-1.9.0a3 → dbos-1.10.0}/dbos/_migrations/versions/933e86bdac6a_add_queue_priority.py +0 -0
  39. {dbos-1.9.0a3 → dbos-1.10.0}/dbos/_migrations/versions/a3b18ad34abe_added_triggers.py +0 -0
  40. {dbos-1.9.0a3 → dbos-1.10.0}/dbos/_migrations/versions/d76646551a6b_job_queue_limiter.py +0 -0
  41. {dbos-1.9.0a3 → dbos-1.10.0}/dbos/_migrations/versions/d76646551a6c_workflow_queue.py +0 -0
  42. {dbos-1.9.0a3 → dbos-1.10.0}/dbos/_migrations/versions/d994145b47b6_consolidate_inputs.py +0 -0
  43. {dbos-1.9.0a3 → dbos-1.10.0}/dbos/_migrations/versions/eab0cc1d9a14_job_queue.py +0 -0
  44. {dbos-1.9.0a3 → dbos-1.10.0}/dbos/_migrations/versions/f4b9b32ba814_functionname_childid_op_outputs.py +0 -0
  45. {dbos-1.9.0a3 → dbos-1.10.0}/dbos/_outcome.py +0 -0
  46. {dbos-1.9.0a3 → dbos-1.10.0}/dbos/_queue.py +0 -0
  47. {dbos-1.9.0a3 → dbos-1.10.0}/dbos/_recovery.py +0 -0
  48. {dbos-1.9.0a3 → dbos-1.10.0}/dbos/_registrations.py +0 -0
  49. {dbos-1.9.0a3 → dbos-1.10.0}/dbos/_roles.py +0 -0
  50. {dbos-1.9.0a3 → dbos-1.10.0}/dbos/_scheduler.py +0 -0
  51. {dbos-1.9.0a3 → dbos-1.10.0}/dbos/_schemas/__init__.py +0 -0
  52. {dbos-1.9.0a3 → dbos-1.10.0}/dbos/_schemas/application_database.py +0 -0
  53. {dbos-1.9.0a3 → dbos-1.10.0}/dbos/_schemas/system_database.py +0 -0
  54. {dbos-1.9.0a3 → dbos-1.10.0}/dbos/_serialization.py +0 -0
  55. {dbos-1.9.0a3 → dbos-1.10.0}/dbos/_sys_db.py +0 -0
  56. {dbos-1.9.0a3 → dbos-1.10.0}/dbos/_templates/dbos-db-starter/README.md +0 -0
  57. {dbos-1.9.0a3 → dbos-1.10.0}/dbos/_templates/dbos-db-starter/__package/__init__.py +0 -0
  58. {dbos-1.9.0a3 → dbos-1.10.0}/dbos/_templates/dbos-db-starter/__package/main.py.dbos +0 -0
  59. {dbos-1.9.0a3 → dbos-1.10.0}/dbos/_templates/dbos-db-starter/__package/schema.py +0 -0
  60. {dbos-1.9.0a3 → dbos-1.10.0}/dbos/_templates/dbos-db-starter/alembic.ini +0 -0
  61. {dbos-1.9.0a3 → dbos-1.10.0}/dbos/_templates/dbos-db-starter/dbos-config.yaml.dbos +0 -0
  62. {dbos-1.9.0a3 → dbos-1.10.0}/dbos/_templates/dbos-db-starter/migrations/env.py.dbos +0 -0
  63. {dbos-1.9.0a3 → dbos-1.10.0}/dbos/_templates/dbos-db-starter/migrations/script.py.mako +0 -0
  64. {dbos-1.9.0a3 → dbos-1.10.0}/dbos/_templates/dbos-db-starter/migrations/versions/2024_07_31_180642_init.py +0 -0
  65. {dbos-1.9.0a3 → dbos-1.10.0}/dbos/_templates/dbos-db-starter/start_postgres_docker.py +0 -0
  66. {dbos-1.9.0a3 → dbos-1.10.0}/dbos/_tracer.py +0 -0
  67. {dbos-1.9.0a3 → dbos-1.10.0}/dbos/_utils.py +0 -0
  68. {dbos-1.9.0a3 → dbos-1.10.0}/dbos/_workflow_commands.py +0 -0
  69. {dbos-1.9.0a3 → dbos-1.10.0}/dbos/cli/_github_init.py +0 -0
  70. {dbos-1.9.0a3 → dbos-1.10.0}/dbos/cli/_template_init.py +0 -0
  71. {dbos-1.9.0a3 → dbos-1.10.0}/dbos/dbos-config.schema.json +0 -0
  72. {dbos-1.9.0a3 → dbos-1.10.0}/dbos/py.typed +0 -0
  73. {dbos-1.9.0a3 → dbos-1.10.0}/tests/__init__.py +0 -0
  74. {dbos-1.9.0a3 → dbos-1.10.0}/tests/atexit_no_ctor.py +0 -0
  75. {dbos-1.9.0a3 → dbos-1.10.0}/tests/atexit_no_launch.py +0 -0
  76. {dbos-1.9.0a3 → dbos-1.10.0}/tests/classdefs.py +0 -0
  77. {dbos-1.9.0a3 → dbos-1.10.0}/tests/client_collateral.py +0 -0
  78. {dbos-1.9.0a3 → dbos-1.10.0}/tests/client_worker.py +0 -0
  79. {dbos-1.9.0a3 → dbos-1.10.0}/tests/conftest.py +0 -0
  80. {dbos-1.9.0a3 → dbos-1.10.0}/tests/dupname_classdefs1.py +0 -0
  81. {dbos-1.9.0a3 → dbos-1.10.0}/tests/dupname_classdefsa.py +0 -0
  82. {dbos-1.9.0a3 → dbos-1.10.0}/tests/more_classdefs.py +0 -0
  83. {dbos-1.9.0a3 → dbos-1.10.0}/tests/queuedworkflow.py +0 -0
  84. {dbos-1.9.0a3 → dbos-1.10.0}/tests/test_admin_server.py +0 -0
  85. {dbos-1.9.0a3 → dbos-1.10.0}/tests/test_async.py +0 -0
  86. {dbos-1.9.0a3 → dbos-1.10.0}/tests/test_async_workflow_management.py +0 -0
  87. {dbos-1.9.0a3 → dbos-1.10.0}/tests/test_cli.py +0 -0
  88. {dbos-1.9.0a3 → dbos-1.10.0}/tests/test_client.py +0 -0
  89. {dbos-1.9.0a3 → dbos-1.10.0}/tests/test_concurrency.py +0 -0
  90. {dbos-1.9.0a3 → dbos-1.10.0}/tests/test_config.py +0 -0
  91. {dbos-1.9.0a3 → dbos-1.10.0}/tests/test_croniter.py +0 -0
  92. {dbos-1.9.0a3 → dbos-1.10.0}/tests/test_debug.py +0 -0
  93. {dbos-1.9.0a3 → dbos-1.10.0}/tests/test_docker_secrets.py +0 -0
  94. {dbos-1.9.0a3 → dbos-1.10.0}/tests/test_failures.py +0 -0
  95. {dbos-1.9.0a3 → dbos-1.10.0}/tests/test_fastapi.py +0 -0
  96. {dbos-1.9.0a3 → dbos-1.10.0}/tests/test_fastapi_roles.py +0 -0
  97. {dbos-1.9.0a3 → dbos-1.10.0}/tests/test_flask.py +0 -0
  98. {dbos-1.9.0a3 → dbos-1.10.0}/tests/test_kafka.py +0 -0
  99. {dbos-1.9.0a3 → dbos-1.10.0}/tests/test_outcome.py +0 -0
  100. {dbos-1.9.0a3 → dbos-1.10.0}/tests/test_package.py +0 -0
  101. {dbos-1.9.0a3 → dbos-1.10.0}/tests/test_queue.py +0 -0
  102. {dbos-1.9.0a3 → dbos-1.10.0}/tests/test_scheduler.py +0 -0
  103. {dbos-1.9.0a3 → dbos-1.10.0}/tests/test_schema_migration.py +0 -0
  104. {dbos-1.9.0a3 → dbos-1.10.0}/tests/test_singleton.py +0 -0
  105. {dbos-1.9.0a3 → dbos-1.10.0}/tests/test_spans.py +0 -0
  106. {dbos-1.9.0a3 → dbos-1.10.0}/tests/test_sqlalchemy.py +0 -0
  107. {dbos-1.9.0a3 → dbos-1.10.0}/tests/test_workflow_introspection.py +0 -0
  108. {dbos-1.9.0a3 → dbos-1.10.0}/tests/test_workflow_management.py +0 -0
  109. {dbos-1.9.0a3 → dbos-1.10.0}/version/__init__.py +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.1
2
2
  Name: dbos
3
- Version: 1.9.0a3
3
+ Version: 1.10.0
4
4
  Summary: Ultra-lightweight durable execution in Python
5
5
  Author-Email: "DBOS, Inc." <contact@dbos.dev>
6
6
  License: MIT
@@ -324,6 +324,17 @@ class DBOS:
324
324
  self.conductor_websocket: Optional[ConductorWebsocket] = None
325
325
  self._background_event_loop: BackgroundEventLoop = BackgroundEventLoop()
326
326
 
327
+ # Globally set the application version and executor ID.
328
+ # In DBOS Cloud, instead use the values supplied through environment variables.
329
+ if not os.environ.get("DBOS__CLOUD") == "true":
330
+ if (
331
+ "application_version" in config
332
+ and config["application_version"] is not None
333
+ ):
334
+ GlobalParams.app_version = config["application_version"]
335
+ if "executor_id" in config and config["executor_id"] is not None:
336
+ GlobalParams.executor_id = config["executor_id"]
337
+
327
338
  init_logger()
328
339
 
329
340
  # Translate user provided config to an internal format
@@ -47,6 +47,8 @@ class DBOSConfig(TypedDict, total=False):
47
47
  admin_port: Optional[int]
48
48
  run_admin_server: Optional[bool]
49
49
  otlp_attributes: Optional[dict[str, str]]
50
+ application_version: Optional[str]
51
+ executor_id: Optional[str]
50
52
 
51
53
 
52
54
  class RuntimeConfig(TypedDict, total=False):
@@ -260,11 +260,9 @@ def _resolve_project_name_and_template(
260
260
  return project_name, template
261
261
 
262
262
 
263
- @app.command(
264
- help="Run your database schema migrations using the migration commands in 'dbos-config.yaml'"
265
- )
263
+ @app.command(help="Create DBOS system tables.")
266
264
  def migrate(
267
- db_url: Annotated[
265
+ app_database_url: Annotated[
268
266
  typing.Optional[str],
269
267
  typer.Option(
270
268
  "--db-url",
@@ -272,30 +270,34 @@ def migrate(
272
270
  help="Your DBOS application database URL",
273
271
  ),
274
272
  ] = None,
275
- sys_db_name: Annotated[
273
+ system_database_url: Annotated[
276
274
  typing.Optional[str],
277
275
  typer.Option(
278
- "--sys-db-name",
276
+ "--sys-db-url",
279
277
  "-s",
280
- help="Specify the name of the system database to reset",
278
+ help="Your DBOS system database URL",
281
279
  ),
282
280
  ] = None,
283
281
  ) -> None:
284
- config = load_config(run_process_config=False, silent=True)
285
- connection_string = _get_db_url(db_url)
286
- app_db_name = sa.make_url(connection_string).database
287
- assert app_db_name is not None, "Database name is required in URL"
288
- if sys_db_name is None:
289
- sys_db_name = app_db_name + SystemSchema.sysdb_suffix
282
+ app_database_url = _get_db_url(app_database_url)
283
+ system_database_url = get_system_database_url(
284
+ {
285
+ "system_database_url": system_database_url,
286
+ "database_url": app_database_url,
287
+ "database": {},
288
+ }
289
+ )
290
290
 
291
- typer.echo(f"Starting schema migration for database {app_db_name}")
291
+ typer.echo(f"Starting DBOS migrations")
292
+ typer.echo(f"Application database: {sa.make_url(app_database_url)}")
293
+ typer.echo(f"System database: {sa.make_url(system_database_url)}")
292
294
 
293
295
  # First, run DBOS migrations on the system database and the application database
294
296
  app_db = None
295
297
  sys_db = None
296
298
  try:
297
299
  sys_db = SystemDatabase(
298
- system_database_url=get_system_database_url(config),
300
+ system_database_url=system_database_url,
299
301
  engine_kwargs={
300
302
  "pool_timeout": 30,
301
303
  "max_overflow": 0,
@@ -303,7 +305,7 @@ def migrate(
303
305
  },
304
306
  )
305
307
  app_db = ApplicationDatabase(
306
- database_url=connection_string,
308
+ database_url=app_database_url,
307
309
  engine_kwargs={
308
310
  "pool_timeout": 30,
309
311
  "max_overflow": 0,
@@ -313,17 +315,19 @@ def migrate(
313
315
  sys_db.run_migrations()
314
316
  app_db.run_migrations()
315
317
  except Exception as e:
316
- typer.echo(f"DBOS system schema migration failed: {e}")
318
+ typer.echo(f"DBOS migrations failed: {e}")
319
+ raise typer.Exit(code=1)
317
320
  finally:
318
321
  if sys_db:
319
322
  sys_db.destroy()
320
323
  if app_db:
321
324
  app_db.destroy()
322
325
 
326
+ typer.echo(f"DBOS migrations successful")
327
+
323
328
  # Next, run any custom migration commands specified in the configuration
324
- typer.echo("Executing migration commands from 'dbos-config.yaml'")
325
- try:
326
- # handle the case where the user has not specified migrations commands
329
+ if os.path.exists("dbos-config.yaml"):
330
+ config = load_config(run_process_config=False, silent=True)
327
331
  if "database" not in config:
328
332
  config["database"] = {}
329
333
  migrate_commands = (
@@ -331,20 +335,21 @@ def migrate(
331
335
  if "migrate" in config["database"] and config["database"]["migrate"]
332
336
  else []
333
337
  )
334
- for command in migrate_commands:
335
- typer.echo(f"Executing migration command: {command}")
336
- result = subprocess.run(command, shell=True, text=True)
337
- if result.returncode != 0:
338
- typer.echo(f"Migration command failed: {command}")
339
- typer.echo(result.stderr)
340
- raise typer.Exit(1)
341
- if result.stdout:
342
- typer.echo(result.stdout.rstrip())
343
- except Exception as e:
344
- typer.echo(f"An error occurred during schema migration: {e}")
345
- raise typer.Exit(code=1)
346
-
347
- typer.echo(f"Completed schema migration for database {app_db_name}")
338
+ if migrate_commands:
339
+ typer.echo("Executing migration commands from 'dbos-config.yaml'")
340
+ try:
341
+ for command in migrate_commands:
342
+ typer.echo(f"Executing migration command: {command}")
343
+ result = subprocess.run(command, shell=True, text=True)
344
+ if result.returncode != 0:
345
+ typer.echo(f"Migration command failed: {command}")
346
+ typer.echo(result.stderr)
347
+ raise typer.Exit(1)
348
+ if result.stdout:
349
+ typer.echo(result.stdout.rstrip())
350
+ except Exception as e:
351
+ typer.echo(f"An error occurred during schema migration: {e}")
352
+ raise typer.Exit(code=1)
348
353
 
349
354
 
350
355
  @app.command(help="Reset the DBOS system database")
@@ -27,7 +27,7 @@ dependencies = [
27
27
  ]
28
28
  requires-python = ">=3.9"
29
29
  readme = "README.md"
30
- version = "1.9.0a3"
30
+ version = "1.10.0"
31
31
 
32
32
  [project.license]
33
33
  text = "MIT"
@@ -911,3 +911,30 @@ def test_class_step_without_dbos(dbos: DBOS, config: DBOSConfig) -> None:
911
911
  DBOS.launch()
912
912
 
913
913
  assert inst.step(input) == input + input
914
+
915
+
916
+ def test_class_with_only_steps(dbos: DBOS) -> None:
917
+
918
+ class StepClass:
919
+ def __init__(self, x: int) -> None:
920
+ self.x = x
921
+
922
+ @DBOS.step()
923
+ def step(self, x: int, expr: Callable[[int, int], int]) -> int:
924
+ return expr(self.x, x)
925
+
926
+ input = 5
927
+ inst = StepClass(5)
928
+
929
+ l = lambda x, y: x + y
930
+
931
+ @DBOS.workflow()
932
+ def test_workflow() -> int:
933
+ return inst.step(input, l) + inst.step(input, l)
934
+
935
+ handle = DBOS.start_workflow(test_workflow)
936
+ assert handle.get_result() == input * 4
937
+
938
+ steps = DBOS.list_workflow_steps(handle.workflow_id)
939
+ assert len(steps) == 2
940
+ assert steps[1]["output"] == steps[1]["output"] == input * 2
@@ -1397,7 +1397,7 @@ def test_app_version(config: DBOSConfig) -> None:
1397
1397
  assert GlobalParams.app_version != app_version
1398
1398
 
1399
1399
  # Verify that version can be overriden with an environment variable
1400
- app_version = "12345"
1400
+ app_version = str(uuid.uuid4())
1401
1401
  os.environ["DBOS__APPVERSION"] = app_version
1402
1402
 
1403
1403
  DBOS.destroy(destroy_registry=True)
@@ -1412,6 +1412,28 @@ def test_app_version(config: DBOSConfig) -> None:
1412
1412
 
1413
1413
  del os.environ["DBOS__APPVERSION"]
1414
1414
 
1415
+ # Verify that version and executor ID can be overriden with a config parameter
1416
+ app_version = str(uuid.uuid4())
1417
+ executor_id = str(uuid.uuid4())
1418
+
1419
+ DBOS.destroy(destroy_registry=True)
1420
+ config["application_version"] = app_version
1421
+ config["executor_id"] = executor_id
1422
+ DBOS(config=config)
1423
+
1424
+ @DBOS.workflow()
1425
+ def test_workflow() -> str:
1426
+ assert DBOS.workflow_id
1427
+ return DBOS.workflow_id
1428
+
1429
+ DBOS.launch()
1430
+ assert GlobalParams.app_version == app_version
1431
+ assert GlobalParams.executor_id == executor_id
1432
+ wfid = test_workflow()
1433
+ handle: WorkflowHandle[str] = DBOS.retrieve_workflow(wfid)
1434
+ assert handle.get_status().app_version == app_version
1435
+ assert handle.get_status().executor_id == executor_id
1436
+
1415
1437
 
1416
1438
  def test_recovery_appversion(config: DBOSConfig) -> None:
1417
1439
  input = 5
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes