dbos 0.24.0a4__tar.gz → 0.24.0a6__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-0.24.0a4 → dbos-0.24.0a6}/PKG-INFO +1 -1
  2. {dbos-0.24.0a4 → dbos-0.24.0a6}/dbos/__init__.py +2 -1
  3. {dbos-0.24.0a4 → dbos-0.24.0a6}/dbos/_core.py +3 -1
  4. {dbos-0.24.0a4 → dbos-0.24.0a6}/dbos/_db_wizard.py +18 -14
  5. {dbos-0.24.0a4 → dbos-0.24.0a6}/dbos/_dbos.py +49 -12
  6. dbos-0.24.0a6/dbos/_dbos_config.py +513 -0
  7. {dbos-0.24.0a4 → dbos-0.24.0a6}/dbos/_error.py +9 -3
  8. {dbos-0.24.0a4 → dbos-0.24.0a6}/dbos/_templates/dbos-db-starter/dbos-config.yaml.dbos +2 -4
  9. {dbos-0.24.0a4 → dbos-0.24.0a6}/dbos/dbos-config.schema.json +4 -1
  10. {dbos-0.24.0a4 → dbos-0.24.0a6}/pyproject.toml +1 -1
  11. {dbos-0.24.0a4 → dbos-0.24.0a6}/tests/atexit_no_launch.py +0 -1
  12. {dbos-0.24.0a4 → dbos-0.24.0a6}/tests/conftest.py +0 -6
  13. {dbos-0.24.0a4 → dbos-0.24.0a6}/tests/queuedworkflow.py +0 -1
  14. dbos-0.24.0a6/tests/test_config.py +1187 -0
  15. dbos-0.24.0a6/tests/test_dbwizard.py +84 -0
  16. {dbos-0.24.0a4 → dbos-0.24.0a6}/tests/test_failures.py +69 -3
  17. {dbos-0.24.0a4 → dbos-0.24.0a6}/tests/test_package.py +2 -1
  18. {dbos-0.24.0a4 → dbos-0.24.0a6}/tests/test_queue.py +0 -2
  19. {dbos-0.24.0a4 → dbos-0.24.0a6}/tests/test_singleton.py +5 -8
  20. dbos-0.24.0a4/dbos/_dbos_config.py +0 -293
  21. dbos-0.24.0a4/tests/test_config.py +0 -462
  22. {dbos-0.24.0a4 → dbos-0.24.0a6}/LICENSE +0 -0
  23. {dbos-0.24.0a4 → dbos-0.24.0a6}/README.md +0 -0
  24. {dbos-0.24.0a4 → dbos-0.24.0a6}/dbos/__main__.py +0 -0
  25. {dbos-0.24.0a4 → dbos-0.24.0a6}/dbos/_admin_server.py +0 -0
  26. {dbos-0.24.0a4 → dbos-0.24.0a6}/dbos/_app_db.py +0 -0
  27. {dbos-0.24.0a4 → dbos-0.24.0a6}/dbos/_classproperty.py +0 -0
  28. {dbos-0.24.0a4 → dbos-0.24.0a6}/dbos/_cloudutils/authentication.py +0 -0
  29. {dbos-0.24.0a4 → dbos-0.24.0a6}/dbos/_cloudutils/cloudutils.py +0 -0
  30. {dbos-0.24.0a4 → dbos-0.24.0a6}/dbos/_cloudutils/databases.py +0 -0
  31. {dbos-0.24.0a4 → dbos-0.24.0a6}/dbos/_conductor/conductor.py +0 -0
  32. {dbos-0.24.0a4 → dbos-0.24.0a6}/dbos/_conductor/protocol.py +0 -0
  33. {dbos-0.24.0a4 → dbos-0.24.0a6}/dbos/_context.py +0 -0
  34. {dbos-0.24.0a4 → dbos-0.24.0a6}/dbos/_croniter.py +0 -0
  35. {dbos-0.24.0a4 → dbos-0.24.0a6}/dbos/_debug.py +0 -0
  36. {dbos-0.24.0a4 → dbos-0.24.0a6}/dbos/_fastapi.py +0 -0
  37. {dbos-0.24.0a4 → dbos-0.24.0a6}/dbos/_flask.py +0 -0
  38. {dbos-0.24.0a4 → dbos-0.24.0a6}/dbos/_kafka.py +0 -0
  39. {dbos-0.24.0a4 → dbos-0.24.0a6}/dbos/_kafka_message.py +0 -0
  40. {dbos-0.24.0a4 → dbos-0.24.0a6}/dbos/_logger.py +0 -0
  41. {dbos-0.24.0a4 → dbos-0.24.0a6}/dbos/_migrations/env.py +0 -0
  42. {dbos-0.24.0a4 → dbos-0.24.0a6}/dbos/_migrations/script.py.mako +0 -0
  43. {dbos-0.24.0a4 → dbos-0.24.0a6}/dbos/_migrations/versions/04ca4f231047_workflow_queues_executor_id.py +0 -0
  44. {dbos-0.24.0a4 → dbos-0.24.0a6}/dbos/_migrations/versions/50f3227f0b4b_fix_job_queue.py +0 -0
  45. {dbos-0.24.0a4 → dbos-0.24.0a6}/dbos/_migrations/versions/5c361fc04708_added_system_tables.py +0 -0
  46. {dbos-0.24.0a4 → dbos-0.24.0a6}/dbos/_migrations/versions/a3b18ad34abe_added_triggers.py +0 -0
  47. {dbos-0.24.0a4 → dbos-0.24.0a6}/dbos/_migrations/versions/d76646551a6b_job_queue_limiter.py +0 -0
  48. {dbos-0.24.0a4 → dbos-0.24.0a6}/dbos/_migrations/versions/d76646551a6c_workflow_queue.py +0 -0
  49. {dbos-0.24.0a4 → dbos-0.24.0a6}/dbos/_migrations/versions/eab0cc1d9a14_job_queue.py +0 -0
  50. {dbos-0.24.0a4 → dbos-0.24.0a6}/dbos/_outcome.py +0 -0
  51. {dbos-0.24.0a4 → dbos-0.24.0a6}/dbos/_queue.py +0 -0
  52. {dbos-0.24.0a4 → dbos-0.24.0a6}/dbos/_recovery.py +0 -0
  53. {dbos-0.24.0a4 → dbos-0.24.0a6}/dbos/_registrations.py +0 -0
  54. {dbos-0.24.0a4 → dbos-0.24.0a6}/dbos/_request.py +0 -0
  55. {dbos-0.24.0a4 → dbos-0.24.0a6}/dbos/_roles.py +0 -0
  56. {dbos-0.24.0a4 → dbos-0.24.0a6}/dbos/_scheduler.py +0 -0
  57. {dbos-0.24.0a4 → dbos-0.24.0a6}/dbos/_schemas/__init__.py +0 -0
  58. {dbos-0.24.0a4 → dbos-0.24.0a6}/dbos/_schemas/application_database.py +0 -0
  59. {dbos-0.24.0a4 → dbos-0.24.0a6}/dbos/_schemas/system_database.py +0 -0
  60. {dbos-0.24.0a4 → dbos-0.24.0a6}/dbos/_serialization.py +0 -0
  61. {dbos-0.24.0a4 → dbos-0.24.0a6}/dbos/_sys_db.py +0 -0
  62. {dbos-0.24.0a4 → dbos-0.24.0a6}/dbos/_templates/dbos-db-starter/README.md +0 -0
  63. {dbos-0.24.0a4 → dbos-0.24.0a6}/dbos/_templates/dbos-db-starter/__package/__init__.py +0 -0
  64. {dbos-0.24.0a4 → dbos-0.24.0a6}/dbos/_templates/dbos-db-starter/__package/main.py +0 -0
  65. {dbos-0.24.0a4 → dbos-0.24.0a6}/dbos/_templates/dbos-db-starter/__package/schema.py +0 -0
  66. {dbos-0.24.0a4 → dbos-0.24.0a6}/dbos/_templates/dbos-db-starter/alembic.ini +0 -0
  67. {dbos-0.24.0a4 → dbos-0.24.0a6}/dbos/_templates/dbos-db-starter/migrations/env.py.dbos +0 -0
  68. {dbos-0.24.0a4 → dbos-0.24.0a6}/dbos/_templates/dbos-db-starter/migrations/script.py.mako +0 -0
  69. {dbos-0.24.0a4 → dbos-0.24.0a6}/dbos/_templates/dbos-db-starter/migrations/versions/2024_07_31_180642_init.py +0 -0
  70. {dbos-0.24.0a4 → dbos-0.24.0a6}/dbos/_templates/dbos-db-starter/start_postgres_docker.py +0 -0
  71. {dbos-0.24.0a4 → dbos-0.24.0a6}/dbos/_tracer.py +0 -0
  72. {dbos-0.24.0a4 → dbos-0.24.0a6}/dbos/_utils.py +0 -0
  73. {dbos-0.24.0a4 → dbos-0.24.0a6}/dbos/_workflow_commands.py +0 -0
  74. {dbos-0.24.0a4 → dbos-0.24.0a6}/dbos/cli/_github_init.py +0 -0
  75. {dbos-0.24.0a4 → dbos-0.24.0a6}/dbos/cli/_template_init.py +0 -0
  76. {dbos-0.24.0a4 → dbos-0.24.0a6}/dbos/cli/cli.py +0 -0
  77. {dbos-0.24.0a4 → dbos-0.24.0a6}/dbos/py.typed +0 -0
  78. {dbos-0.24.0a4 → dbos-0.24.0a6}/tests/__init__.py +0 -0
  79. {dbos-0.24.0a4 → dbos-0.24.0a6}/tests/atexit_no_ctor.py +0 -0
  80. {dbos-0.24.0a4 → dbos-0.24.0a6}/tests/classdefs.py +0 -0
  81. {dbos-0.24.0a4 → dbos-0.24.0a6}/tests/more_classdefs.py +0 -0
  82. {dbos-0.24.0a4 → dbos-0.24.0a6}/tests/test_admin_server.py +0 -0
  83. {dbos-0.24.0a4 → dbos-0.24.0a6}/tests/test_async.py +0 -0
  84. {dbos-0.24.0a4 → dbos-0.24.0a6}/tests/test_classdecorators.py +0 -0
  85. {dbos-0.24.0a4 → dbos-0.24.0a6}/tests/test_concurrency.py +0 -0
  86. {dbos-0.24.0a4 → dbos-0.24.0a6}/tests/test_croniter.py +0 -0
  87. {dbos-0.24.0a4 → dbos-0.24.0a6}/tests/test_dbos.py +0 -0
  88. {dbos-0.24.0a4 → dbos-0.24.0a6}/tests/test_debug.py +0 -0
  89. {dbos-0.24.0a4 → dbos-0.24.0a6}/tests/test_fastapi.py +0 -0
  90. {dbos-0.24.0a4 → dbos-0.24.0a6}/tests/test_fastapi_roles.py +0 -0
  91. {dbos-0.24.0a4 → dbos-0.24.0a6}/tests/test_flask.py +0 -0
  92. {dbos-0.24.0a4 → dbos-0.24.0a6}/tests/test_kafka.py +0 -0
  93. {dbos-0.24.0a4 → dbos-0.24.0a6}/tests/test_outcome.py +0 -0
  94. {dbos-0.24.0a4 → dbos-0.24.0a6}/tests/test_scheduler.py +0 -0
  95. {dbos-0.24.0a4 → dbos-0.24.0a6}/tests/test_schema_migration.py +0 -0
  96. {dbos-0.24.0a4 → dbos-0.24.0a6}/tests/test_spans.py +0 -0
  97. {dbos-0.24.0a4 → dbos-0.24.0a6}/tests/test_sqlalchemy.py +0 -0
  98. {dbos-0.24.0a4 → dbos-0.24.0a6}/tests/test_workflow_cancel.py +0 -0
  99. {dbos-0.24.0a4 → dbos-0.24.0a6}/tests/test_workflow_cmds.py +0 -0
  100. {dbos-0.24.0a4 → dbos-0.24.0a6}/version/__init__.py +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.1
2
2
  Name: dbos
3
- Version: 0.24.0a4
3
+ Version: 0.24.0a6
4
4
  Summary: Ultra-lightweight durable execution in Python
5
5
  Author-Email: "DBOS, Inc." <contact@dbos.dev>
6
6
  License: MIT
@@ -1,13 +1,14 @@
1
1
  from . import _error as error
2
2
  from ._context import DBOSContextEnsure, DBOSContextSetAuth, SetWorkflowID
3
3
  from ._dbos import DBOS, DBOSConfiguredInstance, WorkflowHandle, WorkflowStatus
4
- from ._dbos_config import ConfigFile, get_dbos_database_url, load_config
4
+ from ._dbos_config import ConfigFile, DBOSConfig, get_dbos_database_url, load_config
5
5
  from ._kafka_message import KafkaMessage
6
6
  from ._queue import Queue
7
7
  from ._sys_db import GetWorkflowsInput, WorkflowStatusString
8
8
 
9
9
  __all__ = [
10
10
  "ConfigFile",
11
+ "DBOSConfig",
11
12
  "DBOS",
12
13
  "DBOSConfiguredInstance",
13
14
  "DBOSContextEnsure",
@@ -824,7 +824,9 @@ def decorate_step(
824
824
  stepOutcome = Outcome[R].make(functools.partial(func, *args, **kwargs))
825
825
  if retries_allowed:
826
826
  stepOutcome = stepOutcome.retry(
827
- max_attempts, on_exception, lambda i: DBOSMaxStepRetriesExceeded()
827
+ max_attempts,
828
+ on_exception,
829
+ lambda i: DBOSMaxStepRetriesExceeded(func.__name__, i),
828
830
  )
829
831
 
830
832
  outcome = (
@@ -28,7 +28,20 @@ class DatabaseConnection(TypedDict):
28
28
  local_suffix: Optional[bool]
29
29
 
30
30
 
31
- def db_wizard(config: "ConfigFile", config_file_path: str) -> "ConfigFile":
31
+ def db_wizard(config: "ConfigFile") -> "ConfigFile":
32
+ """Checks database connectivity and helps the user start a database if needed
33
+
34
+ First, check connectivity to the database configured in the provided `config` object.
35
+ If it fails:
36
+ - Return an error if the connection failed due to incorrect credentials.
37
+ - Return an error if it detects a non-default configuration.
38
+ - Otherwise assume the configured database is not running and guide the user through setting it up.
39
+
40
+ The wizard will first attempt to start a local Postgres instance using Docker.
41
+ If Docker is not available, it will prompt the user to connect to a DBOS Cloud database.
42
+
43
+ Finally, if a database was configured, its connection details will be saved in the local `.dbos/db_connection` file.
44
+ """
32
45
  # 1. Check the connectivity to the database. Return if successful. If cannot connect, continue to the following steps.
33
46
  db_connection_error = _check_db_connectivity(config)
34
47
  if db_connection_error is None:
@@ -44,27 +57,18 @@ def db_wizard(config: "ConfigFile", config_file_path: str) -> "ConfigFile":
44
57
  raise DBOSInitializationError(
45
58
  f"Could not connect to Postgres: password authentication failed: {db_connection_error}"
46
59
  )
47
- db_config = config["database"]
48
-
49
- # Read the config file and check if the database hostname/port/username are set. If so, skip the wizard.
50
- with open(config_file_path, "r") as file:
51
- content = file.read()
52
- local_config = yaml.safe_load(content)
53
- if "database" not in local_config:
54
- local_config["database"] = {}
55
- local_config = cast("ConfigFile", local_config)
56
60
 
61
+ # If the database config is not the default one, surface the error and exit.
62
+ db_config = config["database"] # FIXME: what if database is not in config?
57
63
  if (
58
- local_config["database"].get("hostname")
59
- or local_config["database"].get("port")
60
- or local_config["database"].get("username")
61
- or db_config["hostname"] != "localhost"
64
+ db_config["hostname"] != "localhost"
62
65
  or db_config["port"] != 5432
63
66
  or db_config["username"] != "postgres"
64
67
  ):
65
68
  raise DBOSInitializationError(
66
69
  f"Could not connect to the database. Exception: {db_connection_error}"
67
70
  )
71
+
68
72
  print("[yellow]Postgres not detected locally[/yellow]")
69
73
 
70
74
  # 3. If the database config is the default one, check if the user has Docker properly installed.
@@ -88,13 +88,23 @@ from ._context import (
88
88
  assert_current_dbos_context,
89
89
  get_local_dbos_context,
90
90
  )
91
- from ._dbos_config import ConfigFile, load_config, set_env_vars
91
+ from ._dbos_config import (
92
+ ConfigFile,
93
+ DBOSConfig,
94
+ check_config_consistency,
95
+ is_dbos_configfile,
96
+ load_config,
97
+ overwrite_config,
98
+ process_config,
99
+ set_env_vars,
100
+ translate_dbos_config_to_config_file,
101
+ )
92
102
  from ._error import (
93
103
  DBOSConflictingRegistrationError,
94
104
  DBOSException,
95
105
  DBOSNonExistentWorkflowError,
96
106
  )
97
- from ._logger import add_otlp_to_all_loggers, dbos_logger
107
+ from ._logger import add_otlp_to_all_loggers, config_logger, dbos_logger, init_logger
98
108
  from ._sys_db import SystemDatabase
99
109
 
100
110
  # Most DBOS functions are just any callable F, so decorators / wrappers work on F
@@ -257,7 +267,7 @@ class DBOS:
257
267
  def __new__(
258
268
  cls: Type[DBOS],
259
269
  *,
260
- config: Optional[ConfigFile] = None,
270
+ config: Optional[Union[ConfigFile, DBOSConfig]] = None,
261
271
  fastapi: Optional["FastAPI"] = None,
262
272
  flask: Optional["Flask"] = None,
263
273
  conductor_url: Optional[str] = None,
@@ -302,7 +312,7 @@ class DBOS:
302
312
  def __init__(
303
313
  self,
304
314
  *,
305
- config: Optional[ConfigFile] = None,
315
+ config: Optional[Union[ConfigFile, DBOSConfig]] = None,
306
316
  fastapi: Optional["FastAPI"] = None,
307
317
  flask: Optional["Flask"] = None,
308
318
  conductor_url: Optional[str] = None,
@@ -312,12 +322,7 @@ class DBOS:
312
322
  return
313
323
 
314
324
  self._initialized: bool = True
315
- if config is None:
316
- config = load_config()
317
- set_env_vars(config)
318
- dbos_tracer.config(config)
319
- dbos_logger.info("Initializing DBOS")
320
- self.config: ConfigFile = config
325
+
321
326
  self._launched: bool = False
322
327
  self._debug_mode: bool = False
323
328
  self._sys_db_field: Optional[SystemDatabase] = None
@@ -334,6 +339,36 @@ class DBOS:
334
339
  self.conductor_key: Optional[str] = conductor_key
335
340
  self.conductor_websocket: Optional[ConductorWebsocket] = None
336
341
 
342
+ init_logger()
343
+
344
+ unvalidated_config: Optional[ConfigFile] = None
345
+
346
+ if config is None:
347
+ # If no config is provided, load it from dbos-config.yaml
348
+ unvalidated_config = load_config(run_process_config=False)
349
+ elif is_dbos_configfile(config):
350
+ unvalidated_config = cast(ConfigFile, config)
351
+ if os.environ.get("DBOS__CLOUD") == "true":
352
+ unvalidated_config = overwrite_config(unvalidated_config)
353
+ check_config_consistency(name=unvalidated_config["name"])
354
+ else:
355
+ unvalidated_config = translate_dbos_config_to_config_file(
356
+ cast(DBOSConfig, config)
357
+ )
358
+ if os.environ.get("DBOS__CLOUD") == "true":
359
+ unvalidated_config = overwrite_config(unvalidated_config)
360
+ check_config_consistency(name=unvalidated_config["name"])
361
+
362
+ if unvalidated_config is not None:
363
+ self.config: ConfigFile = process_config(data=unvalidated_config)
364
+ else:
365
+ raise ValueError("No valid configuration was loaded.")
366
+
367
+ set_env_vars(self.config)
368
+ config_logger(self.config)
369
+ dbos_tracer.config(self.config)
370
+ dbos_logger.info("Initializing DBOS")
371
+
337
372
  # If using FastAPI, set up middleware and lifecycle events
338
373
  if self.fastapi is not None:
339
374
  from ._fastapi import setup_fastapi_middleware
@@ -419,7 +454,7 @@ class DBOS:
419
454
  if debug_mode:
420
455
  return
421
456
 
422
- admin_port = self.config["runtimeConfig"].get("admin_port")
457
+ admin_port = self.config.get("runtimeConfig", {}).get("admin_port")
423
458
  if admin_port is None:
424
459
  admin_port = 3001
425
460
  self._admin_server_field = AdminServer(dbos=self, port=admin_port)
@@ -923,7 +958,9 @@ class DBOS:
923
958
  reg = _get_or_create_dbos_registry()
924
959
  if reg.config is not None:
925
960
  return reg.config
926
- config = load_config()
961
+ config = (
962
+ load_config()
963
+ ) # This will return the processed & validated config (with defaults)
927
964
  reg.config = config
928
965
  return config
929
966