# utils Reusable Python utilities for application configuration and logging. The package currently provides: - a Pydantic-based settings base class with environment-variable support - configurable application logging via `uvicorn`'s `DefaultFormatter` - console logging and optional daily rotating file logs - configurable log retention and log file naming The project requires Python 3.14 or newer. ## Publish package ### Prerequisites - Python 3.14 or newer - [`uv`](https://docs.astral.sh/uv/) - a Gitea repository with Package Registry support enabled - a Gitea Personal Access Token with permission to write packages The examples below use: ```text Gitea host: https://gitea.schneiderserver.site Owner: mathias Package: utils ``` Create a token in Gitea under **User settings → Applications → Access Tokens**. Keep it private and do not commit it to the repository. ### Publish Run the tests and build the source distribution and wheel: ```bash uv sync uv run pytest rm -rf dist uv build ``` The build artifacts will be written to `dist/`: ```text dist/utils-.tar.gz dist/utils--py3-none-any.whl ``` Configure the Gitea PyPI registry in `~/.pypirc`: ```ini [distutils] index-servers = gitea [gitea] repository = https://gitea.schneiderserver.site/api/packages/mathias/pypi username = mathias password = YOUR_PRIVATE_GITEA_TOKEN ``` Upload the package: ```bash python -m twine upload --repository gitea dist/* ``` Gitea does not allow the same package version to be uploaded twice. To publish an update, increment `version` in `pyproject.toml`, rebuild, and upload again: ```toml version = "0.1.1" ``` It is useful to create a matching Git tag for each published version: ```bash git tag v0.1.0 git push origin v0.1.0 ``` ## Consume package in other projects ### Public package If the package is publicly readable, install it with: ```bash pip install \ --index-url https://gitea.schneiderserver.site/api/packages/mathias/pypi/simple \ utils ``` The equivalent `uv` command is: ```bash uv pip install \ --index-url https://gitea.schneiderserver.site/api/packages/mathias/pypi/simple \ utils ``` ### Private package For a private package, use a token with package-read permission. Avoid putting the token directly into commands where possible because it can end up in shell history or process listings. ```bash pip install \ --index-url https://:@gitea.schneiderserver.site/api/packages/mathias/pypi/simple \ utils ``` For CI, provide the token through a secret rather than committing it to a configuration file. ### Add as a project dependency with `uv add` Yes. `uv add` adds the package to the consuming project's `[project].dependencies` in `pyproject.toml` and updates `uv.lock`: ```bash uv add --index gitea=https://gitea.schneiderserver.site/api/packages/mathias/pypi/simple utils ``` For a public package, this may be enough for the initial add. To keep the package source explicit and avoid accidentally resolving `utils` from another index, configure the index and source in the consuming project's `pyproject.toml`: ```toml [project] dependencies = [ "utils>=0.1.0", ] [tool.uv.sources] utils = { index = "gitea" } [[tool.uv.index]] name = "gitea" url = "https://gitea.schneiderserver.site/api/packages/mathias/pypi/simple" explicit = true ``` For a private package, keep the URL free of credentials and provide them at install or lock time through environment variables. For the index name `gitea`, `uv` expects: ```bash export UV_INDEX_GITEA_USERNAME=mathias export UV_INDEX_GITEA_PASSWORD=YOUR_PRIVATE_GITEA_TOKEN uv lock uv sync ``` The token is not written to `pyproject.toml` or `uv.lock`. In CI, set these variables from protected secrets. The `utils` entry in `pyproject.toml` can then be installed in any checkout with: ```bash uv sync ``` ## Usage ### Logging configuration `LoggingSettings` configures the root logger when instantiated. By default it writes to the console and to `logs/monitoring_backend.log`, rotating the file at midnight and retaining 30 rotated files. ```python from utils.logging_config import LoggingSettings settings = LoggingSettings( LOG_LEVEL="INFO", LOG_TO_FILE=True, LOG_FILE_PATH="logs/application.log", LOG_BACKUP_COUNT=14, ) ``` The settings can also be overridden with environment variables: ```bash export LOG_LEVEL=DEBUG export LOG_TO_FILE=true export LOG_FILE_PATH=logs/application.log export LOG_BACKUP_COUNT=14 ``` Invalid log levels fall back to `INFO`. `LOG_BACKUP_COUNT` must be zero or greater. ### Base settings `BaseSettingsConfig` is a small base class for Pydantic settings models. Extra environment variables are ignored and environment variable names are matched case-sensitively: ```python from utils.settings import BaseSettingsConfig class ApplicationSettings(BaseSettingsConfig): APP_NAME: str = "example" ``` ## Development Install the locked development environment and run the test suite with: ```bash uv sync uv run pytest ``` Build the package without publishing it: ```bash uv build ```