Skip to content

Commit 8ec7550

Browse files
authored
validate db url in client ctor and in CLI (#355)
![Screenshot 2025-05-16 at 16 37 30](https://github.com/user-attachments/assets/fc67f67e-1dcb-4370-afd7-72cba6ba8201)
1 parent 5b647bc commit 8ec7550

File tree

3 files changed

+24
-13
lines changed

3 files changed

+24
-13
lines changed

dbos/_client.py

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -3,8 +3,6 @@
33
import uuid
44
from typing import Any, Generic, List, Optional, TypedDict, TypeVar
55

6-
from sqlalchemy import URL
7-
86
from dbos._app_db import ApplicationDatabase
97
from dbos._context import MaxPriority, MinPriority
108

@@ -15,6 +13,7 @@
1513

1614
from dbos import _serialization
1715
from dbos._dbos import WorkflowHandle, WorkflowHandleAsync
16+
from dbos._dbos_config import is_valid_database_url
1817
from dbos._error import DBOSException, DBOSNonExistentWorkflowError
1918
from dbos._registrations import DEFAULT_MAX_RECOVERY_ATTEMPTS
2019
from dbos._serialization import WorkflowInputs
@@ -99,6 +98,7 @@ async def get_status(self) -> WorkflowStatus:
9998

10099
class DBOSClient:
101100
def __init__(self, database_url: str, *, system_database: Optional[str] = None):
101+
assert is_valid_database_url(database_url)
102102
# We only create database connections but do not run migrations
103103
self._sys_db = SystemDatabase(
104104
database_url=database_url,

dbos/_dbos_config.py

Lines changed: 20 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -329,17 +329,9 @@ def process_config(
329329
if data.get("database_url") is not None and data["database_url"] != "":
330330
# Parse the db string and check required fields
331331
assert data["database_url"] is not None
332+
assert is_valid_database_url(data["database_url"])
333+
332334
url = make_url(data["database_url"])
333-
required_fields = [
334-
("username", "Username must be specified in the connection URL"),
335-
("password", "Password must be specified in the connection URL"),
336-
("host", "Host must be specified in the connection URL"),
337-
("database", "Database name must be specified in the connection URL"),
338-
]
339-
for field_name, error_message in required_fields:
340-
field_value = getattr(url, field_name, None)
341-
if not field_value:
342-
raise DBOSInitializationError(error_message)
343335

344336
if not data["database"].get("sys_db_name"):
345337
assert url.database is not None
@@ -385,6 +377,9 @@ def process_config(
385377
if not silent and logs["logLevel"] == "INFO" or logs["logLevel"] == "DEBUG":
386378
log_url = make_url(data["database_url"]).render_as_string(hide_password=True)
387379
print(f"[bold blue]Using database connection string: {log_url}[/bold blue]")
380+
print(
381+
f"[bold blue]Database engine parameters: {data['database']['db_engine_kwargs']}[/bold blue]"
382+
)
388383

389384
# Return data as ConfigFile type
390385
return data
@@ -432,6 +427,21 @@ def configure_db_engine_parameters(
432427
data["sys_db_engine_kwargs"] = system_engine_kwargs
433428

434429

430+
def is_valid_database_url(database_url: str) -> bool:
431+
url = make_url(database_url)
432+
required_fields = [
433+
("username", "Username must be specified in the connection URL"),
434+
("password", "Password must be specified in the connection URL"),
435+
("host", "Host must be specified in the connection URL"),
436+
("database", "Database name must be specified in the connection URL"),
437+
]
438+
for field_name, error_message in required_fields:
439+
field_value = getattr(url, field_name, None)
440+
if not field_value:
441+
raise DBOSInitializationError(error_message)
442+
return True
443+
444+
435445
def _is_valid_app_name(name: str) -> bool:
436446
name_len = len(name)
437447
if name_len < 3 or name_len > 30:

dbos/cli/cli.py

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -18,7 +18,7 @@
1818

1919
from .._app_db import ApplicationDatabase
2020
from .._client import DBOSClient
21-
from .._dbos_config import _is_valid_app_name, load_config
21+
from .._dbos_config import _is_valid_app_name, is_valid_database_url, load_config
2222
from .._docker_pg_helper import start_docker_pg, stop_docker_pg
2323
from .._schemas.system_database import SystemSchema
2424
from .._sys_db import SystemDatabase, reset_system_database
@@ -35,6 +35,7 @@ def _get_db_url(db_url: Optional[str]) -> str:
3535
raise ValueError(
3636
"Missing database URL: please set it using the --db-url flag or the DBOS_DATABASE_URL environment variable."
3737
)
38+
assert is_valid_database_url(database_url)
3839
return database_url
3940

4041

0 commit comments

Comments
 (0)