Skip to content

Index

template_python

Core initialization module for the template-python package.

This module serves as the primary entry point for the library, exposing the public API components such as logging settings, application configuration, and version metadata for convenient access by downstream consumers.

LoggingSettings

Bases: BaseSettings

Settings model for configuring the loguru logging infrastructure.

This Pydantic model loads configuration from environment variables prefixed with TEMPLATE_PYTHON__LOGGING__ and provides typed fields for controlling log output, formatting, and OpenTelemetry integration.

Example: .. code-block:: python

    from template_python.logging import LoggingSettings, configure_logger

    settings = LoggingSettings(enabled=True, level="DEBUG")
    configure_logger(settings)
Source code in src/template_python/logging.py
class LoggingSettings(BaseSettings):
    """
    Settings model for configuring the loguru logging infrastructure.

    This Pydantic model loads configuration from environment variables prefixed
    with ``TEMPLATE_PYTHON__LOGGING__`` and provides typed fields for controlling
    log output, formatting, and OpenTelemetry integration.

    Example:
        .. code-block:: python

            from template_python.logging import LoggingSettings, configure_logger

            settings = LoggingSettings(enabled=True, level="DEBUG")
            configure_logger(settings)
    """

    enabled: bool = Field(
        default=False,
        description=(
            "Whether to enable template_python loguru logging across the application."
        ),
    )
    clear_loggers: bool = Field(
        default=False,
        description=(
            "If true, removes all existing loguru handlers before configuring new ones."
        ),
    )
    sink: str | Any = Field(
        default=sys.stdout,
        description=(
            "The output sink for log messages. Can be an object or string "
            "alias ('stdout')."
        ),
    )
    level: str = Field(
        default="INFO",
        description="The minimum severity level for emitted log messages.",
    )
    otel_formatting: Literal["auto", "enable", "disable"] = Field(
        default="auto",
        description=(
            "Controls OpenTelemetry JSON formatting. 'auto' enables it if "
            "otel is installed."
        ),
    )
    format: str | Callable[..., Any] | None = Field(
        default="<green>{time:HH:mm:ss}</green> | <level>{level: <8}</level> | "
        "<cyan>{name}</cyan>:<cyan>{function}</cyan> - <level>{message}</level>\n",
        description=(
            "The log format string or function to use when otel formatting is disabled."
        ),
    )
    filter: Any = Field(
        default=True,
        description=(
            "Filters log records. Defaults to True to filter by the "
            "'template_python' prefix."
        ),
    )
    enqueue: bool = Field(
        default=True,
        description="Whether to enable thread-safe asynchronous logging.",
    )
    kwargs: dict[str, Any] = Field(
        default_factory=dict,
        description=(
            "Additional keyword arguments to pass directly to loguru's add() method."
        ),
    )

    model_config: ClassVar[SettingsConfigDict] = SettingsConfigDict(
        env_prefix="TEMPLATE_PYTHON__LOGGING__",
        env_nested_delimiter="__",
    )
    """Pydantic configuration dict dictating environment variable prefixes."""

    @field_validator("sink", mode="before")
    @classmethod
    def _parse_sink(cls, value: Any) -> Any:
        # Convert string aliases for stdout/stderr to actual objects.
        if isinstance(value, str):
            mapping = {
                "stdout": sys.stdout,
                "sys.stdout": sys.stdout,
                "stderr": sys.stderr,
                "sys.stderr": sys.stderr,
            }
            return mapping.get(value.lower(), value)
        return value

model_config = SettingsConfigDict(env_prefix='TEMPLATE_PYTHON__LOGGING__', env_nested_delimiter='__') class-attribute

Pydantic configuration dict dictating environment variable prefixes.

Settings

Bases: BaseSettings

Configuration state for the application.

This class aggregates and prioritizes configuration from multiple sources, providing a unified state for the application. It is built on top of pydantic-settings to allow validation, default values, and type coercion.

Example: .. code-block:: python

    from template_python.settings import Settings

    settings = Settings(environment="production")
    print(settings.project_root)
Source code in src/template_python/settings.py
class Settings(BaseSettings):
    """
    Configuration state for the application.

    This class aggregates and prioritizes configuration from multiple sources,
    providing a unified state for the application. It is built on top of
    pydantic-settings to allow validation, default values, and type coercion.

    Example:
        .. code-block:: python

            from template_python.settings import Settings

            settings = Settings(environment="production")
            print(settings.project_root)
    """

    model_config: ClassVar[SettingsConfigDict] = SettingsConfigDict(
        arbitrary_types_allowed=True,
        extra="ignore",
        populate_by_name=True,
        validate_assignment=True,
        env_prefix="TEMPLATE_PYTHON__",
    )
    """Pydantic config dict dictating environment prefixes and validation."""

    # Core Application Properties
    project_root: Path = Field(
        default_factory=Path.cwd,
        description=(
            "The root directory of the project. Used for resolving relative paths."
        ),
    )
    environment: Literal["development", "staging", "production"] = Field(
        default="development",
        description="The current deployment environment of the application.",
    )

    def __str__(self) -> str:
        """
        Return a concise string representation of the settings.

        :return: A concise, human-readable string summary of the settings.
        :rtype: str
        """
        return (
            f"Settings(environment={self.environment!r}, "
            f"project_root={self.project_root!r})"
        )

    def __repr__(self) -> str:
        """
        Return a detailed string representation of the settings.

        :return: A detailed string representation suitable for debugging.
        :rtype: str
        """
        return (
            f"Settings("
            f"environment={self.environment!r}, "
            f"project_root={self.project_root!r}"
            f")"
        )

model_config = SettingsConfigDict(arbitrary_types_allowed=True, extra='ignore', populate_by_name=True, validate_assignment=True, env_prefix='TEMPLATE_PYTHON__') class-attribute

Pydantic config dict dictating environment prefixes and validation.

__repr__()

Return a detailed string representation of the settings.

Returns:

Type Description
str

A detailed string representation suitable for debugging.

Source code in src/template_python/settings.py
def __repr__(self) -> str:
    """
    Return a detailed string representation of the settings.

    :return: A detailed string representation suitable for debugging.
    :rtype: str
    """
    return (
        f"Settings("
        f"environment={self.environment!r}, "
        f"project_root={self.project_root!r}"
        f")"
    )

__str__()

Return a concise string representation of the settings.

Returns:

Type Description
str

A concise, human-readable string summary of the settings.

Source code in src/template_python/settings.py
def __str__(self) -> str:
    """
    Return a concise string representation of the settings.

    :return: A concise, human-readable string summary of the settings.
    :rtype: str
    """
    return (
        f"Settings(environment={self.environment!r}, "
        f"project_root={self.project_root!r})"
    )

configure_logger(settings=None)

Initializes the loguru logger with the provided settings or from the environment.

This function configures the global loguru logger instance based on the provided LoggingSettings. It handles enabling/disabling the logger, managing sinks, and injecting the appropriate formatter (including OpenTelemetry).

Example: .. code-block:: python

    from template_python.logging import configure_logger, LoggingSettings

    configure_logger(LoggingSettings(level="DEBUG"))

Parameters:

Name Type Description Default
settings LoggingSettings | None

An optional instance of LoggingSettings. If not provided, settings are automatically loaded from the environment.

None

Returns:

Type Description
None

None

Raises:

Type Description
ImportError

If OpenTelemetry formatting is explicitly enabled but the package is not installed.

Source code in src/template_python/logging.py
def configure_logger(settings: LoggingSettings | None = None) -> None:
    """
    Initializes the loguru logger with the provided settings or from the environment.

    This function configures the global loguru logger instance based on the provided
    ``LoggingSettings``. It handles enabling/disabling the logger, managing sinks,
    and injecting the appropriate formatter (including OpenTelemetry).

    Example:
        .. code-block:: python

            from template_python.logging import configure_logger, LoggingSettings

            configure_logger(LoggingSettings(level="DEBUG"))

    :param settings: An optional instance of ``LoggingSettings``. If not provided,
                     settings are automatically loaded from the environment.
    :return: None
    :raises ImportError: If OpenTelemetry formatting is explicitly enabled but the
                         package is not installed.
    """
    global _HANDLER_ID  # noqa: PLW0603

    settings = settings or LoggingSettings()

    if not settings.enabled:
        logger.disable("template_python")
        return

    logger.enable("template_python")

    if settings.clear_loggers:
        logger.remove()
        _HANDLER_ID = None
    elif isinstance(_HANDLER_ID, int):
        with contextlib.suppress(ValueError):
            logger.remove(_HANDLER_ID)
        _HANDLER_ID = None

    use_otel = settings.otel_formatting == "enable" or (
        settings.otel_formatting == "auto" and opentelemetry_trace is not None
    )
    if settings.otel_formatting == "enable" and opentelemetry_trace is None:
        raise ImportError(
            "OpenTelemetry is not installed but 'otel_formatting' was set to 'enable'."
        )

    log_format = _otel_formatter if use_otel else settings.format
    filter_val = "template_python" if settings.filter is True else settings.filter

    if isinstance(filter_val, (list, tuple)):
        prefixes = tuple(filter_val)

        def final_filter(record: dict[str, Any]) -> bool:
            return bool(record["name"] and record["name"].startswith(prefixes))

    elif isinstance(filter_val, str):

        def final_filter(record: dict[str, Any]) -> bool:
            return bool(record["name"] and record["name"].startswith(filter_val))

    else:
        final_filter = None if filter_val is False else filter_val  # type: ignore[assignment]

    _HANDLER_ID = logger.add(
        settings.sink,  # type: ignore[arg-type]
        level=settings.level,
        filter=final_filter,  # type: ignore[arg-type]
        format=log_format,  # type: ignore[arg-type]
        enqueue=settings.enqueue,
        **settings.kwargs,
    )