Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Enhance code quality #6

Merged
merged 21 commits into from
May 31, 2024
Merged
Show file tree
Hide file tree
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 2 additions & 3 deletions trolldb/cli.py
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@
from posttroll.subscriber import create_subscriber_from_dict_config
from pydantic import FilePath

from trolldb.config.config import AppConfig, parse_config_yaml_file
from trolldb.config.config import AppConfig, parse_config
from trolldb.database.mongodb import MongoDB, mongodb_context


Expand Down Expand Up @@ -62,8 +62,7 @@ async def record_messages(config: AppConfig) -> None:

async def record_messages_from_config(config_file: FilePath) -> None:
"""Record messages into the database, getting the configuration from a file."""
config = parse_config_yaml_file(config_file)
await record_messages(config)
await record_messages(parse_config(config_file))


async def record_messages_from_command_line(args=None) -> None:
Expand Down
50 changes: 26 additions & 24 deletions trolldb/config/config.py
Original file line number Diff line number Diff line change
Expand Up @@ -10,17 +10,18 @@

import errno
import sys
from os import PathLike
from typing import Any, NamedTuple

from bson import ObjectId
from bson.errors import InvalidId
from loguru import logger
from pydantic import AnyUrl, BaseModel, Field, FilePath, MongoDsn, ValidationError, validate_call
from pydantic import AnyUrl, BaseModel, MongoDsn, PositiveFloat, ValidationError, validate_call
from pydantic.functional_validators import AfterValidator
from typing_extensions import Annotated
from yaml import safe_load
from yaml import parser, safe_load

Timeout = Annotated[float, Field(ge=0)]
Timeout = PositiveFloat
"""A type hint for the timeout in seconds (non-negative float)."""


Expand Down Expand Up @@ -108,37 +109,38 @@ class AppConfig(BaseModel):
subscriber: SubscriberConfig


@validate_call
def parse_config_yaml_file(filename: FilePath) -> AppConfig:
"""Parses and validates the configurations from a YAML file.
@logger.catch(onerror=lambda _: sys.exit(1))
def parse_config(file: int | str | bytes | PathLike[str] | PathLike[bytes]) -> AppConfig:
pkhalaj marked this conversation as resolved.
Show resolved Hide resolved
"""Parses and validates the configurations from a YAML file (descriptor).

Args:
filename:
The filename of a valid YAML file which holds the configurations.
file:
A path-like object (``str`` or ``bytes``) or an integer file descriptor. This will be directly passed to the
pkhalaj marked this conversation as resolved.
Show resolved Hide resolved
``open()`` function. For example, it can be the filename (absolute or relative) of a valid YAML file which
holds the configurations.

Returns:
An instance of :class:`AppConfig`.

Raises:
ParserError:
If the file cannot be properly parsed.

ValidationError:
If the ``filename`` is not of type ``FilePath``.

ValidationError:
If the successfully parsed file fails the validation, i.e. its schema or the content does not conform to
:class:`AppConfig`.
"""
logger.info("Attempt to parse the YAML file ...")
with open(filename, "r") as file:
config = safe_load(file)
try:
logger.info("Attempt to parse the YAML file ...")
with open(file, "r") as f:
config = safe_load(f)
except parser.ParserError as e:
logger.error(f"The file could not be parsed: {e}")
sys.exit(errno.EIO)
except (OSError, FileNotFoundError) as e:
logger.error(f"The file (descriptor) could not be found or opened: {e}")
sys.exit(errno.EIO)
pkhalaj marked this conversation as resolved.
Show resolved Hide resolved

logger.info("Parsing YAML file is successful.")

try:
logger.info("Attempt to validate the parsed YAML file ...")
config = AppConfig(**config)
logger.info("Validation of the parsed YAML file is successful.")
return config
except ValidationError as e:
logger.error(e)
sys.exit(errno.EIO)

logger.info("Validation of the parsed YAML file is successful.")
return config
Loading