Skip to content

Commit

Permalink
Enabled to pass log_config as ConfigParser instance or a file object
Browse files Browse the repository at this point in the history
  • Loading branch information
antonymayi committed May 13, 2023
1 parent d43afed commit 0af21ed
Show file tree
Hide file tree
Showing 3 changed files with 24 additions and 7 deletions.
14 changes: 11 additions & 3 deletions tests/test_config.py
Original file line number Diff line number Diff line change
@@ -1,3 +1,5 @@
import configparser
import io
import json
import logging
import os
Expand Down Expand Up @@ -414,15 +416,21 @@ def test_log_config_yaml(
mocked_logging_config_module.dictConfig.assert_called_once_with(logging_config)


def test_log_config_file(mocked_logging_config_module: MagicMock) -> None:
@pytest.mark.parametrize(
"config_file", ["log_config.ini", configparser.ConfigParser(), io.StringIO()]
)
def test_log_config_file(
mocked_logging_config_module: MagicMock,
config_file: typing.Union[str, configparser.RawConfigParser, typing.IO],
) -> None:
"""
Test that one can load a configparser config from disk.
"""
config = Config(app=asgi_app, log_config="log_config")
config = Config(app=asgi_app, log_config=config_file)
config.load()

mocked_logging_config_module.fileConfig.assert_called_once_with(
"log_config", disable_existing_loggers=False
config_file, disable_existing_loggers=False
)


Expand Down
12 changes: 9 additions & 3 deletions uvicorn/config.py
Original file line number Diff line number Diff line change
Expand Up @@ -7,8 +7,10 @@
import socket
import ssl
import sys
from configparser import RawConfigParser
from pathlib import Path
from typing import (
IO,
TYPE_CHECKING,
Any,
Awaitable,
Expand Down Expand Up @@ -209,7 +211,9 @@ def __init__(
ws_per_message_deflate: bool = True,
lifespan: LifespanType = "auto",
env_file: Optional[Union[str, os.PathLike]] = None,
log_config: Optional[Union[Dict[str, Any], str]] = LOGGING_CONFIG,
log_config: Optional[
Union[Dict[str, Any], str, RawConfigParser, IO]
] = LOGGING_CONFIG,
log_level: Optional[Union[str, int]] = None,
access_log: bool = True,
use_colors: Optional[bool] = None,
Expand Down Expand Up @@ -397,11 +401,13 @@ def configure_logging(self) -> None:
"use_colors"
] = self.use_colors
logging.config.dictConfig(self.log_config)
elif self.log_config.endswith(".json"):
elif isinstance(self.log_config, str) and self.log_config.endswith(".json"):
with open(self.log_config) as file:
loaded_config = json.load(file)
logging.config.dictConfig(loaded_config)
elif self.log_config.endswith((".yaml", ".yml")):
elif isinstance(self.log_config, str) and self.log_config.endswith(
(".yaml", ".yml")
):
# Install the PyYAML package or the uvicorn[standard] optional
# dependencies to enable this functionality.
import yaml
Expand Down
5 changes: 4 additions & 1 deletion uvicorn/main.py
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
import asyncio
import configparser
import logging
import os
import platform
Expand Down Expand Up @@ -481,7 +482,9 @@ def run(
workers: typing.Optional[int] = None,
env_file: typing.Optional[typing.Union[str, os.PathLike]] = None,
log_config: typing.Optional[
typing.Union[typing.Dict[str, typing.Any], str]
typing.Union[
typing.Dict[str, typing.Any], str, configparser.RawConfigParser, typing.IO
]
] = LOGGING_CONFIG,
log_level: typing.Optional[typing.Union[str, int]] = None,
access_log: bool = True,
Expand Down

0 comments on commit 0af21ed

Please sign in to comment.