dbos 0.24.0a3__tar.gz → 0.24.0a5__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.
- {dbos-0.24.0a3 → dbos-0.24.0a5}/PKG-INFO +1 -1
- {dbos-0.24.0a3 → dbos-0.24.0a5}/dbos/__init__.py +2 -1
- {dbos-0.24.0a3 → dbos-0.24.0a5}/dbos/_conductor/conductor.py +16 -0
- {dbos-0.24.0a3 → dbos-0.24.0a5}/dbos/_conductor/protocol.py +12 -0
- {dbos-0.24.0a3 → dbos-0.24.0a5}/dbos/_db_wizard.py +18 -14
- {dbos-0.24.0a3 → dbos-0.24.0a5}/dbos/_dbos.py +49 -12
- dbos-0.24.0a5/dbos/_dbos_config.py +513 -0
- {dbos-0.24.0a3 → dbos-0.24.0a5}/dbos/_templates/dbos-db-starter/dbos-config.yaml.dbos +2 -4
- {dbos-0.24.0a3 → dbos-0.24.0a5}/dbos/dbos-config.schema.json +4 -1
- {dbos-0.24.0a3 → dbos-0.24.0a5}/pyproject.toml +1 -1
- {dbos-0.24.0a3 → dbos-0.24.0a5}/tests/atexit_no_launch.py +0 -1
- {dbos-0.24.0a3 → dbos-0.24.0a5}/tests/conftest.py +0 -6
- {dbos-0.24.0a3 → dbos-0.24.0a5}/tests/queuedworkflow.py +0 -1
- dbos-0.24.0a5/tests/test_config.py +1187 -0
- dbos-0.24.0a5/tests/test_dbwizard.py +84 -0
- {dbos-0.24.0a3 → dbos-0.24.0a5}/tests/test_package.py +2 -1
- {dbos-0.24.0a3 → dbos-0.24.0a5}/tests/test_queue.py +0 -2
- {dbos-0.24.0a3 → dbos-0.24.0a5}/tests/test_singleton.py +5 -8
- dbos-0.24.0a3/dbos/_dbos_config.py +0 -293
- dbos-0.24.0a3/tests/test_config.py +0 -462
- {dbos-0.24.0a3 → dbos-0.24.0a5}/LICENSE +0 -0
- {dbos-0.24.0a3 → dbos-0.24.0a5}/README.md +0 -0
- {dbos-0.24.0a3 → dbos-0.24.0a5}/dbos/__main__.py +0 -0
- {dbos-0.24.0a3 → dbos-0.24.0a5}/dbos/_admin_server.py +0 -0
- {dbos-0.24.0a3 → dbos-0.24.0a5}/dbos/_app_db.py +0 -0
- {dbos-0.24.0a3 → dbos-0.24.0a5}/dbos/_classproperty.py +0 -0
- {dbos-0.24.0a3 → dbos-0.24.0a5}/dbos/_cloudutils/authentication.py +0 -0
- {dbos-0.24.0a3 → dbos-0.24.0a5}/dbos/_cloudutils/cloudutils.py +0 -0
- {dbos-0.24.0a3 → dbos-0.24.0a5}/dbos/_cloudutils/databases.py +0 -0
- {dbos-0.24.0a3 → dbos-0.24.0a5}/dbos/_context.py +0 -0
- {dbos-0.24.0a3 → dbos-0.24.0a5}/dbos/_core.py +0 -0
- {dbos-0.24.0a3 → dbos-0.24.0a5}/dbos/_croniter.py +0 -0
- {dbos-0.24.0a3 → dbos-0.24.0a5}/dbos/_debug.py +0 -0
- {dbos-0.24.0a3 → dbos-0.24.0a5}/dbos/_error.py +0 -0
- {dbos-0.24.0a3 → dbos-0.24.0a5}/dbos/_fastapi.py +0 -0
- {dbos-0.24.0a3 → dbos-0.24.0a5}/dbos/_flask.py +0 -0
- {dbos-0.24.0a3 → dbos-0.24.0a5}/dbos/_kafka.py +0 -0
- {dbos-0.24.0a3 → dbos-0.24.0a5}/dbos/_kafka_message.py +0 -0
- {dbos-0.24.0a3 → dbos-0.24.0a5}/dbos/_logger.py +0 -0
- {dbos-0.24.0a3 → dbos-0.24.0a5}/dbos/_migrations/env.py +0 -0
- {dbos-0.24.0a3 → dbos-0.24.0a5}/dbos/_migrations/script.py.mako +0 -0
- {dbos-0.24.0a3 → dbos-0.24.0a5}/dbos/_migrations/versions/04ca4f231047_workflow_queues_executor_id.py +0 -0
- {dbos-0.24.0a3 → dbos-0.24.0a5}/dbos/_migrations/versions/50f3227f0b4b_fix_job_queue.py +0 -0
- {dbos-0.24.0a3 → dbos-0.24.0a5}/dbos/_migrations/versions/5c361fc04708_added_system_tables.py +0 -0
- {dbos-0.24.0a3 → dbos-0.24.0a5}/dbos/_migrations/versions/a3b18ad34abe_added_triggers.py +0 -0
- {dbos-0.24.0a3 → dbos-0.24.0a5}/dbos/_migrations/versions/d76646551a6b_job_queue_limiter.py +0 -0
- {dbos-0.24.0a3 → dbos-0.24.0a5}/dbos/_migrations/versions/d76646551a6c_workflow_queue.py +0 -0
- {dbos-0.24.0a3 → dbos-0.24.0a5}/dbos/_migrations/versions/eab0cc1d9a14_job_queue.py +0 -0
- {dbos-0.24.0a3 → dbos-0.24.0a5}/dbos/_outcome.py +0 -0
- {dbos-0.24.0a3 → dbos-0.24.0a5}/dbos/_queue.py +0 -0
- {dbos-0.24.0a3 → dbos-0.24.0a5}/dbos/_recovery.py +0 -0
- {dbos-0.24.0a3 → dbos-0.24.0a5}/dbos/_registrations.py +0 -0
- {dbos-0.24.0a3 → dbos-0.24.0a5}/dbos/_request.py +0 -0
- {dbos-0.24.0a3 → dbos-0.24.0a5}/dbos/_roles.py +0 -0
- {dbos-0.24.0a3 → dbos-0.24.0a5}/dbos/_scheduler.py +0 -0
- {dbos-0.24.0a3 → dbos-0.24.0a5}/dbos/_schemas/__init__.py +0 -0
- {dbos-0.24.0a3 → dbos-0.24.0a5}/dbos/_schemas/application_database.py +0 -0
- {dbos-0.24.0a3 → dbos-0.24.0a5}/dbos/_schemas/system_database.py +0 -0
- {dbos-0.24.0a3 → dbos-0.24.0a5}/dbos/_serialization.py +0 -0
- {dbos-0.24.0a3 → dbos-0.24.0a5}/dbos/_sys_db.py +0 -0
- {dbos-0.24.0a3 → dbos-0.24.0a5}/dbos/_templates/dbos-db-starter/README.md +0 -0
- {dbos-0.24.0a3 → dbos-0.24.0a5}/dbos/_templates/dbos-db-starter/__package/__init__.py +0 -0
- {dbos-0.24.0a3 → dbos-0.24.0a5}/dbos/_templates/dbos-db-starter/__package/main.py +0 -0
- {dbos-0.24.0a3 → dbos-0.24.0a5}/dbos/_templates/dbos-db-starter/__package/schema.py +0 -0
- {dbos-0.24.0a3 → dbos-0.24.0a5}/dbos/_templates/dbos-db-starter/alembic.ini +0 -0
- {dbos-0.24.0a3 → dbos-0.24.0a5}/dbos/_templates/dbos-db-starter/migrations/env.py.dbos +0 -0
- {dbos-0.24.0a3 → dbos-0.24.0a5}/dbos/_templates/dbos-db-starter/migrations/script.py.mako +0 -0
- {dbos-0.24.0a3 → dbos-0.24.0a5}/dbos/_templates/dbos-db-starter/migrations/versions/2024_07_31_180642_init.py +0 -0
- {dbos-0.24.0a3 → dbos-0.24.0a5}/dbos/_templates/dbos-db-starter/start_postgres_docker.py +0 -0
- {dbos-0.24.0a3 → dbos-0.24.0a5}/dbos/_tracer.py +0 -0
- {dbos-0.24.0a3 → dbos-0.24.0a5}/dbos/_utils.py +0 -0
- {dbos-0.24.0a3 → dbos-0.24.0a5}/dbos/_workflow_commands.py +0 -0
- {dbos-0.24.0a3 → dbos-0.24.0a5}/dbos/cli/_github_init.py +0 -0
- {dbos-0.24.0a3 → dbos-0.24.0a5}/dbos/cli/_template_init.py +0 -0
- {dbos-0.24.0a3 → dbos-0.24.0a5}/dbos/cli/cli.py +0 -0
- {dbos-0.24.0a3 → dbos-0.24.0a5}/dbos/py.typed +0 -0
- {dbos-0.24.0a3 → dbos-0.24.0a5}/tests/__init__.py +0 -0
- {dbos-0.24.0a3 → dbos-0.24.0a5}/tests/atexit_no_ctor.py +0 -0
- {dbos-0.24.0a3 → dbos-0.24.0a5}/tests/classdefs.py +0 -0
- {dbos-0.24.0a3 → dbos-0.24.0a5}/tests/more_classdefs.py +0 -0
- {dbos-0.24.0a3 → dbos-0.24.0a5}/tests/test_admin_server.py +0 -0
- {dbos-0.24.0a3 → dbos-0.24.0a5}/tests/test_async.py +0 -0
- {dbos-0.24.0a3 → dbos-0.24.0a5}/tests/test_classdecorators.py +0 -0
- {dbos-0.24.0a3 → dbos-0.24.0a5}/tests/test_concurrency.py +0 -0
- {dbos-0.24.0a3 → dbos-0.24.0a5}/tests/test_croniter.py +0 -0
- {dbos-0.24.0a3 → dbos-0.24.0a5}/tests/test_dbos.py +0 -0
- {dbos-0.24.0a3 → dbos-0.24.0a5}/tests/test_debug.py +0 -0
- {dbos-0.24.0a3 → dbos-0.24.0a5}/tests/test_failures.py +0 -0
- {dbos-0.24.0a3 → dbos-0.24.0a5}/tests/test_fastapi.py +0 -0
- {dbos-0.24.0a3 → dbos-0.24.0a5}/tests/test_fastapi_roles.py +0 -0
- {dbos-0.24.0a3 → dbos-0.24.0a5}/tests/test_flask.py +0 -0
- {dbos-0.24.0a3 → dbos-0.24.0a5}/tests/test_kafka.py +0 -0
- {dbos-0.24.0a3 → dbos-0.24.0a5}/tests/test_outcome.py +0 -0
- {dbos-0.24.0a3 → dbos-0.24.0a5}/tests/test_scheduler.py +0 -0
- {dbos-0.24.0a3 → dbos-0.24.0a5}/tests/test_schema_migration.py +0 -0
- {dbos-0.24.0a3 → dbos-0.24.0a5}/tests/test_spans.py +0 -0
- {dbos-0.24.0a3 → dbos-0.24.0a5}/tests/test_sqlalchemy.py +0 -0
- {dbos-0.24.0a3 → dbos-0.24.0a5}/tests/test_workflow_cancel.py +0 -0
- {dbos-0.24.0a3 → dbos-0.24.0a5}/tests/test_workflow_cmds.py +0 -0
- {dbos-0.24.0a3 → dbos-0.24.0a5}/version/__init__.py +0 -0
|
@@ -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",
|
|
@@ -194,6 +194,22 @@ class ConductorWebsocket(threading.Thread):
|
|
|
194
194
|
),
|
|
195
195
|
)
|
|
196
196
|
websocket.send(get_workflow_response.to_json())
|
|
197
|
+
elif msg_type == p.MessageType.EXIST_PENDING_WORKFLOWS:
|
|
198
|
+
exist_pending_workflows_message = (
|
|
199
|
+
p.ExistPendingWorkflowsRequest.from_json(message)
|
|
200
|
+
)
|
|
201
|
+
pending_wfs = self.dbos._sys_db.get_pending_workflows(
|
|
202
|
+
exist_pending_workflows_message.executor_id,
|
|
203
|
+
exist_pending_workflows_message.application_version,
|
|
204
|
+
)
|
|
205
|
+
exist_pending_workflows_response = (
|
|
206
|
+
p.ExistPendingWorkflowsResponse(
|
|
207
|
+
type=p.MessageType.EXIST_PENDING_WORKFLOWS,
|
|
208
|
+
request_id=base_message.request_id,
|
|
209
|
+
exist=len(pending_wfs) > 0,
|
|
210
|
+
)
|
|
211
|
+
)
|
|
212
|
+
websocket.send(exist_pending_workflows_response.to_json())
|
|
197
213
|
else:
|
|
198
214
|
self.dbos.logger.warning(
|
|
199
215
|
f"Unexpected message type: {msg_type}"
|
|
@@ -15,6 +15,7 @@ class MessageType(str, Enum):
|
|
|
15
15
|
RESUME = "resume"
|
|
16
16
|
RESTART = "restart"
|
|
17
17
|
GET_WORKFLOW = "get_workflow"
|
|
18
|
+
EXIST_PENDING_WORKFLOWS = "exist_pending_workflows"
|
|
18
19
|
|
|
19
20
|
|
|
20
21
|
T = TypeVar("T", bound="BaseMessage")
|
|
@@ -195,3 +196,14 @@ class GetWorkflowRequest(BaseMessage):
|
|
|
195
196
|
@dataclass
|
|
196
197
|
class GetWorkflowResponse(BaseMessage):
|
|
197
198
|
output: Optional[WorkflowsOutput]
|
|
199
|
+
|
|
200
|
+
|
|
201
|
+
@dataclass
|
|
202
|
+
class ExistPendingWorkflowsRequest(BaseMessage):
|
|
203
|
+
executor_id: str
|
|
204
|
+
application_version: str
|
|
205
|
+
|
|
206
|
+
|
|
207
|
+
@dataclass
|
|
208
|
+
class ExistPendingWorkflowsResponse(BaseMessage):
|
|
209
|
+
exist: bool
|
|
@@ -28,7 +28,20 @@ class DatabaseConnection(TypedDict):
|
|
|
28
28
|
local_suffix: Optional[bool]
|
|
29
29
|
|
|
30
30
|
|
|
31
|
-
def db_wizard(config: "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
|
-
|
|
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
|
|
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
|
-
|
|
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
|
|
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 =
|
|
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
|
|