dbos 0.20.0a7__py3-none-any.whl → 0.20.0a9__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/_dbos.py CHANGED
@@ -56,7 +56,7 @@ from ._registrations import (
56
56
  )
57
57
  from ._roles import default_required_roles, required_roles
58
58
  from ._scheduler import ScheduledWorkflow, scheduled
59
- from ._sys_db import WorkflowStatusString
59
+ from ._sys_db import WorkflowStatusString, reset_system_database
60
60
  from ._tracer import dbos_tracer
61
61
 
62
62
  if TYPE_CHECKING:
@@ -409,6 +409,22 @@ class DBOS:
409
409
  dbos_logger.error(f"DBOS failed to launch: {traceback.format_exc()}")
410
410
  raise
411
411
 
412
+ @classmethod
413
+ def reset_system_database(cls) -> None:
414
+ """
415
+ Destroy the DBOS system database. Useful for resetting the state of DBOS between tests.
416
+ This is a destructive operation and should only be used in a test environment.
417
+ More information on testing DBOS apps: https://docs.dbos.dev/python/tutorials/testing
418
+ """
419
+ if _dbos_global_instance is not None:
420
+ _dbos_global_instance._reset_system_database()
421
+
422
+ def _reset_system_database(self) -> None:
423
+ assert (
424
+ not self._launched
425
+ ), "The system database cannot be reset after DBOS is launched. Resetting the system database is a destructive operation that should only be used in a test environment."
426
+ reset_system_database(self.config)
427
+
412
428
  def _destroy(self) -> None:
413
429
  self._initialized = False
414
430
  for event in self.stop_events:
dbos/_sys_db.py CHANGED
@@ -1265,3 +1265,46 @@ class SystemDatabase:
1265
1265
  .where(SystemSchema.workflow_queue.c.workflow_uuid == workflow_id)
1266
1266
  .values(completed_at_epoch_ms=int(time.time() * 1000))
1267
1267
  )
1268
+
1269
+
1270
+ def reset_system_database(config: ConfigFile) -> None:
1271
+ sysdb_name = (
1272
+ config["database"]["sys_db_name"]
1273
+ if "sys_db_name" in config["database"] and config["database"]["sys_db_name"]
1274
+ else config["database"]["app_db_name"] + SystemSchema.sysdb_suffix
1275
+ )
1276
+ postgres_db_url = sa.URL.create(
1277
+ "postgresql+psycopg",
1278
+ username=config["database"]["username"],
1279
+ password=config["database"]["password"],
1280
+ host=config["database"]["hostname"],
1281
+ port=config["database"]["port"],
1282
+ database="postgres",
1283
+ )
1284
+ try:
1285
+ # Connect to postgres default database
1286
+ engine = sa.create_engine(postgres_db_url)
1287
+
1288
+ with engine.connect() as conn:
1289
+ # Set autocommit required for database dropping
1290
+ conn.execution_options(isolation_level="AUTOCOMMIT")
1291
+
1292
+ # Terminate existing connections
1293
+ conn.execute(
1294
+ sa.text(
1295
+ """
1296
+ SELECT pg_terminate_backend(pg_stat_activity.pid)
1297
+ FROM pg_stat_activity
1298
+ WHERE pg_stat_activity.datname = :db_name
1299
+ AND pid <> pg_backend_pid()
1300
+ """
1301
+ ),
1302
+ {"db_name": sysdb_name},
1303
+ )
1304
+
1305
+ # Drop the database
1306
+ conn.execute(sa.text(f"DROP DATABASE IF EXISTS {sysdb_name}"))
1307
+
1308
+ except sa.exc.SQLAlchemyError as e:
1309
+ dbos_logger.error(f"Error resetting system database: {str(e)}")
1310
+ raise e
dbos/cli/cli.py CHANGED
@@ -18,8 +18,7 @@ from typing_extensions import Annotated
18
18
  from .. import load_config
19
19
  from .._app_db import ApplicationDatabase
20
20
  from .._dbos_config import _is_valid_app_name
21
- from .._schemas.system_database import SystemSchema
22
- from .._sys_db import SystemDatabase
21
+ from .._sys_db import SystemDatabase, reset_system_database
23
22
  from .._workflow_commands import _cancel_workflow, _get_workflow, _list_workflows
24
23
  from ..cli._github_init import create_template_from_github
25
24
  from ._template_init import copy_template, get_project_name, get_templates_directory
@@ -101,7 +100,7 @@ def init(
101
100
  ) -> None:
102
101
  try:
103
102
 
104
- git_templates = ["dbos-app-starter", "dbos-cron-starter"]
103
+ git_templates = ["dbos-toolbox", "dbos-app-starter", "dbos-cron-starter"]
105
104
  templates_dir = get_templates_directory()
106
105
  templates = git_templates + [
107
106
  x.name for x in os.scandir(templates_dir) if x.is_dir()
@@ -224,56 +223,12 @@ def reset(
224
223
  typer.echo("Operation cancelled.")
225
224
  raise typer.Exit()
226
225
  config = load_config()
227
- sysdb_name = (
228
- config["database"]["sys_db_name"]
229
- if "sys_db_name" in config["database"] and config["database"]["sys_db_name"]
230
- else config["database"]["app_db_name"] + SystemSchema.sysdb_suffix
231
- )
232
- postgres_db_url = sa.URL.create(
233
- "postgresql+psycopg",
234
- username=config["database"]["username"],
235
- password=config["database"]["password"],
236
- host=config["database"]["hostname"],
237
- port=config["database"]["port"],
238
- database="postgres",
239
- )
240
226
  try:
241
- # Connect to postgres default database
242
- engine = sa.create_engine(postgres_db_url)
243
-
244
- with engine.connect() as conn:
245
- # Set autocommit required for database dropping
246
- conn.execution_options(isolation_level="AUTOCOMMIT")
247
-
248
- # Terminate existing connections
249
- conn.execute(
250
- sa.text(
251
- """
252
- SELECT pg_terminate_backend(pg_stat_activity.pid)
253
- FROM pg_stat_activity
254
- WHERE pg_stat_activity.datname = :db_name
255
- AND pid <> pg_backend_pid()
256
- """
257
- ),
258
- {"db_name": sysdb_name},
259
- )
260
-
261
- # Drop the database
262
- conn.execute(sa.text(f"DROP DATABASE IF EXISTS {sysdb_name}"))
263
-
227
+ reset_system_database(config)
264
228
  except sa.exc.SQLAlchemyError as e:
265
- typer.echo(f"Error dropping database: {str(e)}")
229
+ typer.echo(f"Error resetting system database: {str(e)}")
266
230
  return
267
231
 
268
- sys_db = None
269
- try:
270
- sys_db = SystemDatabase(config)
271
- except Exception as e:
272
- typer.echo(f"DBOS system schema migration failed: {e}")
273
- finally:
274
- if sys_db:
275
- sys_db.destroy()
276
-
277
232
 
278
233
  @workflow.command(help="List workflows for your application")
279
234
  def list(
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.1
2
2
  Name: dbos
3
- Version: 0.20.0a7
3
+ Version: 0.20.0a9
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-0.20.0a7.dist-info/METADATA,sha256=j0WaCOp5iSA99CTnKeAW1PID3e9_xRF5-USnyGaQsyQ,5309
2
- dbos-0.20.0a7.dist-info/WHEEL,sha256=thaaA2w1JzcGC48WYufAs8nrYZjJm8LqNfnXFOFyCC4,90
3
- dbos-0.20.0a7.dist-info/entry_points.txt,sha256=_QOQ3tVfEjtjBlr1jS4sHqHya9lI2aIEIWkz8dqYp14,58
4
- dbos-0.20.0a7.dist-info/licenses/LICENSE,sha256=VGZit_a5-kdw9WT6fY5jxAWVwGQzgLFyPWrcVVUhVNU,1067
1
+ dbos-0.20.0a9.dist-info/METADATA,sha256=NX9gLPLU9KG0-Rt5dpCc6Em3XznKk6yJ3kN1nO7pG9I,5309
2
+ dbos-0.20.0a9.dist-info/WHEEL,sha256=thaaA2w1JzcGC48WYufAs8nrYZjJm8LqNfnXFOFyCC4,90
3
+ dbos-0.20.0a9.dist-info/entry_points.txt,sha256=_QOQ3tVfEjtjBlr1jS4sHqHya9lI2aIEIWkz8dqYp14,58
4
+ dbos-0.20.0a9.dist-info/licenses/LICENSE,sha256=VGZit_a5-kdw9WT6fY5jxAWVwGQzgLFyPWrcVVUhVNU,1067
5
5
  dbos/__init__.py,sha256=CxRHBHEthPL4PZoLbZhp3rdm44-KkRTT2-7DkK9d4QQ,724
6
6
  dbos/_admin_server.py,sha256=PJgneZG9-64TapZrPeJtt73puAswRImCE5uce2k2PKU,4750
7
7
  dbos/_app_db.py,sha256=_tv2vmPjjiaikwgxH3mqxgJ4nUUcG2-0uMXKWCqVu1c,5509
@@ -13,7 +13,7 @@ dbos/_context.py,sha256=RH08s_nee95vgxdz6AsYuVWF1LuJSVtOyIifblsa4pw,18760
13
13
  dbos/_core.py,sha256=-2oh2-NicMJBwTwrd2EQBQm4Vu0caozFeoS9Kj47DzM,36588
14
14
  dbos/_croniter.py,sha256=hbhgfsHBqclUS8VeLnJ9PSE9Z54z6mi4nnrr1aUXn0k,47561
15
15
  dbos/_db_wizard.py,sha256=xgKLna0_6Xi50F3o8msRosXba8NScHlpJR5ICVCkHDQ,7534
16
- dbos/_dbos.py,sha256=VeSw9768_qa1kn4QRlmO1iymcHIhGXtcXsiwL9h8Zzc,35386
16
+ dbos/_dbos.py,sha256=1PG142hzPBFguAbuBXaKS-YwzRdaIUW8087JCi78RmU,36193
17
17
  dbos/_dbos_config.py,sha256=h_q1gzudhsAMVkGMD0qQ6kLic6YhdJgzm50YFSIx9Bo,8196
18
18
  dbos/_error.py,sha256=vtaSsG0QW6cRlwfZ4zzZWy_IHCZlomwSlrDyGWuyn8c,4337
19
19
  dbos/_fastapi.py,sha256=ke03vqsSYDnO6XeOtOVFXj0-f-v1MGsOxa9McaROvNc,3616
@@ -41,7 +41,7 @@ dbos/_schemas/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
41
41
  dbos/_schemas/application_database.py,sha256=KeyoPrF7hy_ODXV7QNike_VFSD74QBRfQ76D7QyE9HI,966
42
42
  dbos/_schemas/system_database.py,sha256=rwp4EvCSaXcUoMaRczZCvETCxGp72k3-hvLyGUDkih0,5163
43
43
  dbos/_serialization.py,sha256=YCYv0qKAwAZ1djZisBC7khvKqG-5OcIv9t9EC5PFIog,1743
44
- dbos/_sys_db.py,sha256=wru-RJL2ANn05PzU3tclaoz5V1cpMGC9G54A87I9830,52290
44
+ dbos/_sys_db.py,sha256=eXFXzmw_bq5Qp3s2_OzjkQKQj9HxMbP4AyJ2VQnJ08g,53786
45
45
  dbos/_templates/dbos-db-starter/README.md,sha256=GhxhBj42wjTt1fWEtwNriHbJuKb66Vzu89G4pxNHw2g,930
46
46
  dbos/_templates/dbos-db-starter/__package/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
47
47
  dbos/_templates/dbos-db-starter/__package/main.py,sha256=eI0SS9Nwj-fldtiuSzIlIG6dC91GXXwdRsoHxv6S_WI,2719
@@ -56,8 +56,8 @@ dbos/_tracer.py,sha256=rvBY1RQU6DO7rL7EnaJJxGcmd4tP_PpGqUEE6imZnhY,2518
56
56
  dbos/_workflow_commands.py,sha256=tj-gJARjDJ5aYo0ii2udTAU4l36vbeXwmOYh8Q4y_ac,4625
57
57
  dbos/cli/_github_init.py,sha256=Y_bDF9gfO2jB1id4FV5h1oIxEJRWyqVjhb7bNEa5nQ0,3224
58
58
  dbos/cli/_template_init.py,sha256=AfuMaO8bmr9WsPNHr6j2cp7kjVVZDUpH7KpbTg0hhFs,2722
59
- dbos/cli/cli.py,sha256=puqB6hYvHHM1lBkj69G1Ei6Ri7xbgNKzeJTd0u96qR8,13899
59
+ dbos/cli/cli.py,sha256=07TXdfDhImEOjB2-yhWJc1CK07_CSF-xF7TYCtB1kRY,12410
60
60
  dbos/dbos-config.schema.json,sha256=X5TpXNcARGceX0zQs0fVgtZW_Xj9uBbY5afPt9Rz9yk,5741
61
61
  dbos/py.typed,sha256=QfzXT1Ktfk3Rj84akygc7_42z0lRpCq0Ilh8OXI6Zas,44
62
62
  version/__init__.py,sha256=L4sNxecRuqdtSFdpUGX3TtBi9KL3k7YsZVIvv-fv9-A,1678
63
- dbos-0.20.0a7.dist-info/RECORD,,
63
+ dbos-0.20.0a9.dist-info/RECORD,,