dbos 0.9.0a1__py3-none-any.whl → 0.10.0__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.

@@ -59,6 +59,10 @@
59
59
  "type": "string",
60
60
  "description": "If using SSL/TLS to securely connect to a database, path to an SSL root certificate file"
61
61
  },
62
+ "local_suffix": {
63
+ "type": "boolean",
64
+ "description": "Whether to suffix app_db_name with '_local'. Set to true when doing local development using a DBOS Cloud database."
65
+ },
62
66
  "app_db_client": {
63
67
  "type": "string",
64
68
  "description": "Specify the database client to use to connect to the application database",
@@ -140,6 +144,10 @@
140
144
  "start": {
141
145
  "type": "array",
142
146
  "description": "Specify commands to run to start your application (Python only)"
147
+ },
148
+ "admin_port": {
149
+ "type": "number",
150
+ "description": "The port number of the admin server (Default: 3001)"
143
151
  }
144
152
  }
145
153
  },
dbos/dbos.py CHANGED
@@ -277,6 +277,7 @@ class DBOS:
277
277
  self.fastapi: Optional["FastAPI"] = fastapi
278
278
  self.flask: Optional["Flask"] = flask
279
279
  self._executor_field: Optional[ThreadPoolExecutor] = None
280
+ self._background_threads: List[threading.Thread] = []
280
281
 
281
282
  # If using FastAPI, set up middleware and lifecycle events
282
283
  if self.fastapi is not None:
@@ -348,27 +349,48 @@ class DBOS:
348
349
  self._executor_field = ThreadPoolExecutor(max_workers=64)
349
350
  self._sys_db_field = SystemDatabase(self.config)
350
351
  self._app_db_field = ApplicationDatabase(self.config)
351
- self._admin_server_field = AdminServer(dbos=self)
352
+ admin_port = self.config["runtimeConfig"].get("admin_port")
353
+ if admin_port is None:
354
+ admin_port = 3001
355
+ self._admin_server_field = AdminServer(dbos=self, port=admin_port)
352
356
 
353
357
  if not os.environ.get("DBOS__VMID"):
354
358
  workflow_ids = self._sys_db.get_pending_workflows("local")
355
359
  self._executor.submit(_startup_recovery_thread, self, workflow_ids)
356
360
 
357
361
  # Listen to notifications
358
- self._executor.submit(self._sys_db._notification_listener)
362
+ notification_listener_thread = threading.Thread(
363
+ target=self._sys_db._notification_listener,
364
+ daemon=True,
365
+ )
366
+ notification_listener_thread.start()
367
+ self._background_threads.append(notification_listener_thread)
359
368
 
360
369
  # Start flush workflow buffers thread
361
- self._executor.submit(self._sys_db.flush_workflow_buffers)
370
+ flush_workflow_buffers_thread = threading.Thread(
371
+ target=self._sys_db.flush_workflow_buffers,
372
+ daemon=True,
373
+ )
374
+ flush_workflow_buffers_thread.start()
375
+ self._background_threads.append(flush_workflow_buffers_thread)
362
376
 
363
377
  # Start the queue thread
364
378
  evt = threading.Event()
365
379
  self.stop_events.append(evt)
366
- self._executor.submit(queue_thread, evt, self)
380
+ bg_queue_thread = threading.Thread(
381
+ target=queue_thread, args=(evt, self), daemon=True
382
+ )
383
+ bg_queue_thread.start()
384
+ self._background_threads.append(bg_queue_thread)
367
385
 
368
386
  # Grab any pollers that were deferred and start them
369
387
  for evt, func, args, kwargs in self._registry.pollers:
370
388
  self.stop_events.append(evt)
371
- self._executor.submit(func, *args, **kwargs)
389
+ poller_thread = threading.Thread(
390
+ target=func, args=args, kwargs=kwargs, daemon=True
391
+ )
392
+ poller_thread.start()
393
+ self._background_threads.append(poller_thread)
372
394
  self._registry.pollers = []
373
395
 
374
396
  dbos_logger.info("DBOS launched")
@@ -400,6 +422,8 @@ class DBOS:
400
422
  if self._executor_field is not None:
401
423
  self._executor_field.shutdown(cancel_futures=True)
402
424
  self._executor_field = None
425
+ for bg_thread in self._background_threads:
426
+ bg_thread.join()
403
427
 
404
428
  @classmethod
405
429
  def register_instance(cls, inst: object) -> None:
@@ -829,7 +853,7 @@ class DBOSConfiguredInstance:
829
853
 
830
854
  # Apps that import DBOS probably don't exit. If they do, let's see if
831
855
  # it looks like startup was abandoned or a call was forgotten...
832
- def log_exit_info() -> None:
856
+ def dbos_exit_hook() -> None:
833
857
  if _dbos_global_registry is None:
834
858
  # Probably used as or for a support module
835
859
  return
@@ -843,7 +867,9 @@ def log_exit_info() -> None:
843
867
  print("DBOS exiting; DBOS exists but launch() was not called")
844
868
  dbos_logger.warning("DBOS exiting; DBOS exists but launch() was not called")
845
869
  return
870
+ # If we get here, we're exiting normally
871
+ _dbos_global_instance.destroy()
846
872
 
847
873
 
848
874
  # Register the exit hook
849
- atexit.register(log_exit_info)
875
+ atexit.register(dbos_exit_hook)
dbos/dbos_config.py CHANGED
@@ -2,7 +2,7 @@ import json
2
2
  import os
3
3
  import re
4
4
  from importlib import resources
5
- from typing import Any, Dict, List, Optional, TypedDict
5
+ from typing import Any, Dict, List, Optional, TypedDict, cast
6
6
 
7
7
  import yaml
8
8
  from jsonschema import ValidationError, validate
@@ -14,6 +14,7 @@ from dbos.logger import dbos_logger
14
14
 
15
15
  class RuntimeConfig(TypedDict, total=False):
16
16
  start: List[str]
17
+ admin_port: Optional[int]
17
18
 
18
19
 
19
20
  class DatabaseConfig(TypedDict, total=False):
@@ -26,6 +27,7 @@ class DatabaseConfig(TypedDict, total=False):
26
27
  sys_db_name: Optional[str]
27
28
  ssl: Optional[bool]
28
29
  ssl_ca: Optional[str]
30
+ local_suffix: Optional[bool]
29
31
  app_db_client: Optional[str]
30
32
  migrate: Optional[List[str]]
31
33
  rollback: Optional[List[str]]
@@ -163,6 +165,11 @@ def load_config(config_file_path: str = "dbos-config.yaml") -> ConfigFile:
163
165
  if "runtimeConfig" not in data or "start" not in data["runtimeConfig"]:
164
166
  raise DBOSInitializationError(f"dbos-config.yaml must specify a start command")
165
167
 
168
+ data = cast(ConfigFile, data)
169
+
170
+ if "local_suffix" in data["database"] and data["database"]["local_suffix"]:
171
+ data["database"]["app_db_name"] = f"{data['database']['app_db_name']}_local"
172
+
166
173
  # Return data as ConfigFile type
167
174
  return data # type: ignore
168
175
 
@@ -1,24 +1,24 @@
1
1
  Metadata-Version: 2.1
2
2
  Name: dbos
3
- Version: 0.9.0a1
3
+ Version: 0.10.0
4
4
  Summary: Ultra-lightweight durable execution in Python
5
5
  Author-Email: "DBOS, Inc." <contact@dbos.dev>
6
6
  License: MIT
7
7
  Requires-Python: >=3.9
8
8
  Requires-Dist: pyyaml>=6.0.2
9
9
  Requires-Dist: jsonschema>=4.23.0
10
- Requires-Dist: alembic>=1.13.2
10
+ Requires-Dist: alembic>=1.13.3
11
11
  Requires-Dist: typing-extensions>=4.12.2; python_version < "3.10"
12
- Requires-Dist: typer>=0.12.3
13
- Requires-Dist: jsonpickle>=3.2.2
14
- Requires-Dist: opentelemetry-api>=1.26.0
15
- Requires-Dist: opentelemetry-sdk>=1.26.0
16
- Requires-Dist: opentelemetry-exporter-otlp-proto-http>=1.26.0
12
+ Requires-Dist: typer>=0.12.5
13
+ Requires-Dist: jsonpickle>=3.3.0
14
+ Requires-Dist: opentelemetry-api>=1.27.0
15
+ Requires-Dist: opentelemetry-sdk>=1.27.0
16
+ Requires-Dist: opentelemetry-exporter-otlp-proto-http>=1.27.0
17
17
  Requires-Dist: python-dateutil>=2.9.0.post0
18
- Requires-Dist: fastapi[standard]>=0.112.1
18
+ Requires-Dist: fastapi[standard]>=0.115.2
19
19
  Requires-Dist: psutil>=6.0.0
20
20
  Requires-Dist: tomlkit>=0.13.2
21
- Requires-Dist: psycopg>=3.2.1
21
+ Requires-Dist: psycopg>=3.2.3
22
22
  Description-Content-Type: text/markdown
23
23
 
24
24
 
@@ -1,16 +1,16 @@
1
- dbos-0.9.0a1.dist-info/METADATA,sha256=cTVI8Ycq1xzitja99TcUvA2hqjjl6T7nmZs9GUpeVF8,5010
2
- dbos-0.9.0a1.dist-info/WHEEL,sha256=Vza3XR51HW1KmFP0iIMUVYIvz0uQuKJpIXKYOBGQyFQ,90
3
- dbos-0.9.0a1.dist-info/entry_points.txt,sha256=z6GcVANQV7Uw_82H9Ob2axJX6V3imftyZsljdh-M1HU,54
4
- dbos-0.9.0a1.dist-info/licenses/LICENSE,sha256=VGZit_a5-kdw9WT6fY5jxAWVwGQzgLFyPWrcVVUhVNU,1067
1
+ dbos-0.10.0.dist-info/METADATA,sha256=NhI4MeQSyGupnlrGBEkpP3vvUnaZZPW-UAoe33zufp0,5009
2
+ dbos-0.10.0.dist-info/WHEEL,sha256=pM0IBB6ZwH3nkEPhtcp50KvKNX-07jYtnb1g1m6Z4Co,90
3
+ dbos-0.10.0.dist-info/entry_points.txt,sha256=z6GcVANQV7Uw_82H9Ob2axJX6V3imftyZsljdh-M1HU,54
4
+ dbos-0.10.0.dist-info/licenses/LICENSE,sha256=VGZit_a5-kdw9WT6fY5jxAWVwGQzgLFyPWrcVVUhVNU,1067
5
5
  dbos/__init__.py,sha256=-h1QgWNL11CiLlHEKa2ycAJVJw5SXYZ4BGNNWBAiE9k,726
6
6
  dbos/admin_sever.py,sha256=Qg5T3YRrbPW05PR_99yAaxgo1ugQrAp_uTeTqSfjm_k,3397
7
7
  dbos/application_database.py,sha256=knFK8We8y6WrIpnFCKvFq5hvSuFQqUuJqOqDpSVMCPI,5521
8
8
  dbos/cli.py,sha256=z5dXbbnGWzSC3E1rfS8Lp1_OIImzcDKM7jP-iu_Q4aI,8602
9
9
  dbos/context.py,sha256=4MsxZdoh1WIsgoUsaxo0B6caGN6xq2WC60MzbBppzGk,17738
10
10
  dbos/core.py,sha256=ggsRC2XicvNI1qqruEFoqxoTU5oSSnhMZvDih3AG_3A,30879
11
- dbos/dbos-config.schema.json,sha256=azpfmoDZg7WfSy3kvIsk9iEiKB_-VZt03VEOoXJAkqE,5331
12
- dbos/dbos.py,sha256=qQOHcgaT4rru1gZJy1nFrIvz8YzEhDfMJmN9eCskPZ4,29857
13
- dbos/dbos_config.py,sha256=NJVze2GkKgYUmcPP31Unb-QpsA0TzImEeQGJgVq6W6k,5352
11
+ dbos/dbos-config.schema.json,sha256=GQAxrtERczP-ANpzJJJbhCp_CUtQ8pUcH87AqlyC02A,5697
12
+ dbos/dbos.py,sha256=4_jOtcjoJdIF27wjs_jpsrl-LsyhZ22rod8J1UgKo1E,31021
13
+ dbos/dbos_config.py,sha256=N48Ll-57lKVuh4SF3sLD4W4VnuELAGYA71j3oZPc6Sw,5622
14
14
  dbos/decorators.py,sha256=lbPefsLK6Cya4cb7TrOcLglOpGT3pc6qjZdsQKlfZLg,629
15
15
  dbos/error.py,sha256=UETk8CoZL-TO2Utn1-E7OSWelhShWmKM-fOlODMR9PE,3893
16
16
  dbos/fastapi.py,sha256=gx9hlpxYOiwbuhSlbY9bn5C-F_FsCbrJvkX9ZAvDG6U,3418
@@ -51,4 +51,4 @@ dbos/templates/hello/start_postgres_docker.py,sha256=lQVLlYO5YkhGPEgPqwGc7Y8uDKs
51
51
  dbos/tracer.py,sha256=GaXDhdKKF_IQp5SAMipGXiDVwteRKjNbrXyYCH1mor0,2520
52
52
  dbos/utils.py,sha256=lwRymY-y7GprAS8pKmbICQvOJd5eGxKGTxCMFn0OwaQ,1739
53
53
  version/__init__.py,sha256=L4sNxecRuqdtSFdpUGX3TtBi9KL3k7YsZVIvv-fv9-A,1678
54
- dbos-0.9.0a1.dist-info/RECORD,,
54
+ dbos-0.10.0.dist-info/RECORD,,
@@ -1,4 +1,4 @@
1
1
  Wheel-Version: 1.0
2
- Generator: pdm-backend (2.4.1)
2
+ Generator: pdm-backend (2.4.2)
3
3
  Root-Is-Purelib: true
4
4
  Tag: py3-none-any