Files
utils/README.md
T

227 lines
5.0 KiB
Markdown

# 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-<version>.tar.gz
dist/utils-<version>-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://<username>:<read-token>@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
```