Shared config, logging, cache and common tooling for 40F services.
Project description
f40-toolkit
Shared configuration, logging, caching, and common utilities for 40F services.
f40-toolkit is a dependency-light Python package intended to provide a stable set of building blocks that multiple services can share without duplicating glue code.
It currently focuses on four areas:
- Config (
f40_toolkit.config) — local single-file and layered config loading, env overrides, canonical key aliases, and optional remote config overlays from HTTP or S3-compatible object storage. - Logging (
f40_toolkit.logging) — opinionated logging setup with console / rotating-file handlers and channel-based level overrides. - Cache (
f40_toolkit.cache) — backend-agnostic cache manager with memory, file, and optional Redis backends. - Common (
f40_toolkit.common) — shared utilities used across the modules above.
Requirements
- Python 3.12+
Installation
Core package, with minimal dependencies:
pip install f40-toolkit
Optional extras:
# Marker extra for cache (memory/file backends; no extra dependency)
pip install f40-toolkit[cache]
# Redis backend support for cache
pip install f40-toolkit[cache-redis]
# YAML support for config loading
pip install f40-toolkit[config]
# S3-compatible remote config support
pip install f40-toolkit[config-s3]
# YAML + S3-compatible remote config support
pip install f40-toolkit[config,config-s3]
# Convenience install for all optional runtime features
pip install f40-toolkit[all]
What is included
f40_toolkit.config
The configuration subsystem is designed to let services use a homogeneous API while staying flexible about where configuration comes from.
Highlights:
- single-file mode via
<PREFIX>CONFIG_PATH - layered mode via
<PREFIX>CONFIG_DIR,<PREFIX>PROJECT, and<PREFIX>ENV - deep env var overrides with
__ - canonical key aliases for migrations
- optional remote overlay support from:
- HTTP/HTTPS
- S3-compatible object storage (for example Scaleway object storage)
- optional mirrored remote layered loading
Typical usage:
from f40_toolkit.config import get_config
cfg = get_config()
include_system = cfg.get("ops.include_system_in_health", False)
f40_toolkit.logging
Logging is explicit and does not configure itself at import time.
Highlights:
- console + file logging configuration helpers
- channel-based level overrides
- session-aware loggers
- safe defaults for service startup
f40_toolkit.cache
The cache module provides a common cache API that can be backed by different storage implementations.
Highlights:
- memory backend
- file backend
- optional Redis backend
- cache key helpers
- simple observability / health-check support
get_or_set(...)convenience flow
f40_toolkit.common
Shared helpers used by the rest of the toolkit, including:
- env parsing
- deep merge / dict helpers
- config redaction for logging
- small filesystem / path helpers
Quickstart
Configuration
Minimal usage:
from f40_toolkit.config import configure_global_config, get_config
configure_global_config()
cfg = get_config()
port = cfg.get("server.port", 8080)
Using canonical keys during a migration:
from f40_toolkit.config import configure_global_config, get_config
CANONICAL_KEYS = {
"server.port": ["server.backend_port", "server_settings.port"],
}
configure_global_config(canonical_keys=CANONICAL_KEYS)
cfg = get_config()
port = cfg.get_canonical("server.port", default=8080)
Logging
from f40_toolkit.logging import configure_logging, get_logger
configure_logging()
log = get_logger("service.startup", channel="service")
log.info("Service booted")
Cache
from f40_toolkit.cache import create_cache_from_config, InvalidCacheValue
cfg = {
"env": "prod",
"service": {"name": "billing"},
"customer": "acme",
"cache": {
"backend": "memory", # "memory" | "file" | "redis"
"default_timeout": 300,
"serializer": "json",
},
}
cache = create_cache_from_config(cfg)
cache.set("example", {"ok": True}, timeout=60)
try:
value = cache.get("example")
except InvalidCacheValue:
value = None
print(value)
Memoization helper:
def expensive(a: int, b: int) -> int:
return a + b
value = cache.get_or_set(
key="sum:1:2",
func=expensive,
f_args=[1, 2],
timeout=120,
)
Configuration conventions
By default the config loader uses the F40_ env prefix.
Important env vars:
F40_CONFIG_PATH— enables single-file modeF40_CONFIG_EXTRA— optional extra files appended after local configF40_CONFIG_DIR— root directory for layered modeF40_PROJECT— project name for layered modeF40_ENV— environment / stage for layered mode
F40_CONFIG_EXTRA uses the platform path separator:
- Linux / macOS:
: - Windows:
;
Deep env var overrides use __ as a path separator:
export F40_DB__HOST="db.internal"
export F40_SERVER__PORT="8080"
export F40_FEATURES__0__NAME="beta"
Those can be read back with the same dotted path style:
cfg.get("features.0.name")
Remote config
Remote config is bootstrapped from local config and/or environment variables.
Supported remote providers:
https3
Supported remote modes:
overlaymirrored_layers
Example HTTP overlay bootstrap:
[remote_config]
enabled = true
provider = "http"
mode = "overlay"
url = "https://example.internal/config/my-service.toml"
Example S3-compatible overlay bootstrap:
[remote_config]
enabled = true
provider = "s3"
mode = "overlay"
bucket_name = "service-config"
object_path = "my-service/prod.toml"
endpoint_url = "https://s3.fr-par.scw.cloud"
region_name = "fr-par"
access_key_env = "SCW_ACCESS_KEY"
secret_key_env = "SCW_SECRET_KEY"
Effective precedence is:
- local main file or local layered files
- local extra files from
<PREFIX>CONFIG_EXTRA - remote overlay or remote mirrored layers
- env var overrides
Env vars always win.
Development
Editable install:
pip install -e .[dev]
Run checks:
pytest
ruff check .
mypy src
Local documentation
The repository includes Markdown docs under docs/.
They can be:
- read directly in the repository
- served locally with MkDocs
To run a local docs site:
pip install -e .[docs]
mkdocs serve
License
MIT. See LICENSE.
Project details
Release history Release notifications | RSS feed
Download files
Download the file for your platform. If you're not sure which to choose, learn more about installing packages.
Source Distribution
Built Distribution
Filter files by name, interpreter, ABI, and platform.
If you're not sure about the file name format, learn more about wheel file names.
Copy a direct link to the current filters
File details
Details for the file f40_toolkit-1.1.0.tar.gz.
File metadata
- Download URL: f40_toolkit-1.1.0.tar.gz
- Upload date:
- Size: 33.8 kB
- Tags: Source
- Uploaded using Trusted Publishing? No
- Uploaded via: twine/6.2.0 CPython/3.13.5
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
eb465f65e22a38a372da94ecaa416d7f714f41d966b40da7339c0d46a7e70e18
|
|
| MD5 |
f83ac1407b0e469fe340b450bfb38d1d
|
|
| BLAKE2b-256 |
feed12e00e54c2ed0d4751859231e72937915788e2254bf73413f576b3cd7a1d
|
File details
Details for the file f40_toolkit-1.1.0-py3-none-any.whl.
File metadata
- Download URL: f40_toolkit-1.1.0-py3-none-any.whl
- Upload date:
- Size: 42.2 kB
- Tags: Python 3
- Uploaded using Trusted Publishing? No
- Uploaded via: twine/6.2.0 CPython/3.13.5
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
ad2e38624b6c5f285585a39911d202e2a58ab8a0f06ca3115747731961556b6a
|
|
| MD5 |
5e9da7114f6cef13e35410217566b995
|
|
| BLAKE2b-256 |
8076ff4a0940ca5006dd90efac3330979843dbd09ebf6dc1e6197d3640cb8489
|