The project implements application which adapts calls from one DIAL Core to calls to another DIAL Core.
Useful for local DIAL development against remote DIAL Core. See the example of such a setup.
This project requires Python ≥3.11 and Poetry ≥2.1.1 for dependency management.
-
Install Poetry. See the official installation guide.
-
(Optional) Specify custom Python or Poetry executables in
.env.dev. This is useful if multiple versions are installed. By default,pythonandpoetryare used.POETRY_PYTHON=path-to-python-exe POETRY=path-to-poetry-exe
-
Create and activate the virtual environment:
make init_env source .venv/bin/activate -
Install project dependencies (including linting, formatting, and test tools):
make install
The recommended IDE is VS Code. Open the project in VS Code and install the recommended extensions. VS Code is configured to use the Ruff formatter.
Alternatively you can use PyCharm that has built-in Ruff support.
Run the development server:
make serveAs of now, Windows distributions do not include the make tool. To run make commands, the tool can be installed using the following command (since Windows 10):
winget install GnuWin32.MakeFor convenience, the tool folder can be added to the PATH environment variable as C:\Program Files (x86)\GnuWin32\bin.
The command definitions inside Makefile should be cross-platform to keep the development environment setup simple.
Copy .env.example to .env and customize it for your environment:
| Variable | Default | Description |
|---|---|---|
| LOG_LEVEL | INFO | Application log level. Use DEBUG for dev purposes and INFO in prod |
| WEB_CONCURRENCY | 1 | Number of workers for the server |
| TIMEOUT_KEEP_ALIVE | 70 | How long in seconds the server keeps an idle HTTP keep-alive connection open before closing it. Must be greater than the caller's pooled-connection timeout — see Keep-alive timeout |
| DIAL_URL | URL of the local DIAL Core server used for development | |
| HEADERS_TO_PROXY | Accept |
Comma-separated list of headers to pass through to the upstream. |
| HTTP_MAX_CONNECTIONS | 1000 | Maximum number of concurrent connections the upstream HTTP client opens. Requests above the limit wait for a free connection |
| HTTP_MAX_KEEPALIVE_CONNECTIONS | 100 | Maximum number of idle connections the upstream HTTP client keeps open for reuse |
| HTTP_POOL_TIMEOUT | 10 | How long in seconds a request waits for a free upstream connection when HTTP_MAX_CONNECTIONS is reached. On timeout the adapter returns 503 |
TIMEOUT_KEEP_ALIVE is passed to uvicorn as --timeout-keep-alive. It sets how long, in seconds, the adapter keeps an idle HTTP keep-alive connection open before closing it.
The caller must give up on an idle connection before the adapter closes it. On the DIAL Core side the matching setting is client.keepAliveTimeout — the Vert.x HTTP client option that controls how long Core keeps an idle connection in its pool. It is also expressed in seconds and defaults to 60.
Keep TIMEOUT_KEEP_ALIVE at DIAL Core's client.keepAliveTimeout plus 10 seconds:
DIAL Core client.keepAliveTimeout |
TIMEOUT_KEEP_ALIVE |
|---|---|
| 60 (default) | 70 (default) |
The default of 70 already covers an unmodified DIAL Core, so change it only if you have changed client.keepAliveTimeout.
Note that uvicorn's own default of 5 seconds is not safe here. The adapter would close idle connections long before Core expires them; Core would eventually hand a request to a connection the adapter had already closed; and that request — written into a half-closed socket and never read — would fail with Connection was closed. The 10 second margin keeps Core the side that always closes first, which removes the race.
Logging is provided by the DIAL SDK. The LOG_LEVEL variable sets the severity threshold for the adapter's logs (INFO by default; use DEBUG for development).
By default logs are emitted as human-readable text.
Set DIAL_SDK_LOG_FORMAT=json for structured JSON logging.
The format is controlled by DIAL_SDK_TEXT_LOG_FORMAT / DIAL_SDK_JSON_LOG_FORMAT (both optional),
which use Python's %-style logging attributes
and default to the values shown below.
Text logging (default):
DIAL_SDK_LOG_FORMAT=text
DIAL_SDK_TEXT_LOG_FORMAT='%(levelprefix)s | %(asctime)s | %(name)s | %(process)d | %(message)s'Structured JSON logging:
DIAL_SDK_LOG_FORMAT=json
DIAL_SDK_JSON_LOG_FORMAT='{"level": "%(levelname)s", "time": "%(asctime)s", "logger": "%(name)s", "process": "%(process)d", "message": "%(message)s"}'See the full logging documentation for details.
Run the server in Docker:
make docker_serveRun the linting before committing:
make lintTo auto-fix formatting issues run:
make formatRun unit tests locally:
make testTo remove the virtual environment and build artifacts:
make cleanYou may optionally install Git hooks that will automatically run the linting step on Git push. You only need to do it once for the given repository.
make install_git_hooksImportant
This command doesn't work if you have already installed Git hooks locally or globally.