Types
- Start here: Credentials in a config object
- Common recipes: annotate a settings field that holds a connection URL with
SecretUrl[RedisDsn]so the password never reaches a log line, and read it back withget_secret_value().
grelmicro.types
Shared types used across grelmicro modules and in user configuration.
LogLevel
LogLevel = Literal[
"DEBUG", "INFO", "WARNING", "ERROR", "CRITICAL"
]
Standard logging level names, matching logging.getLevelName output.
Environment
Environment = Literal[
"development", "test", "staging", "production"
]
Deployment tier the application runs in.
The well-known values of the OpenTelemetry deployment.environment.name
attribute. Grelmicro(environment=...) and GREL_ENVIRONMENT take one, and
staging and production turn the backend scope check into an error. A tier
your organisation calls something else maps onto the closest of the four.
BackendScope
BackendScope = Literal['process', 'host', 'cluster']
How far a backend shares the state it holds.
Ordered: process is one process (Memory), host is the processes on one
host (SQLite), cluster is every process that connects to the backend
(Redis, Valkey, Postgres, Kubernetes). An Adapter declares its own as a
scope class attribute, and a Component requires at least one of them.
SecretUrl
Bases: Secret[UrlType], Generic[UrlType]
A URL whose embedded credentials never reach any output.
A URL carries its credentials inside itself: the password sits in the
userinfo section (redis://user:password@host) and tokens often ride
in the query string (?api_key=...). A plain URL field puts those in
repr(), model_dump(), model_dump_json(), and any log line that
prints the settings object.
SecretUrl shows the URL with its credentials replaced by ***
everywhere the value is displayed or dumped, so an operator still
reads the scheme, host, port, and path. The real URL comes back from
get_secret_value():
from pydantic import BaseModel, RedisDsn
from grelmicro.types import SecretUrl
class Settings(BaseModel):
url: SecretUrl[RedisDsn]
settings = Settings(url="redis://app:hunter2@cache:6379/0")
print(repr(settings))
#> Settings(url=SecretUrl('redis://app:***@cache:6379/0'))
print(settings.url.get_secret_value())
#> redis://app:hunter2@cache:6379/0
Parametrize it with any pydantic URL type to keep that type's
validation: SecretUrl[RedisDsn] accepts only Redis schemes, and
SecretUrl[PostgresDsn] accepts the multi-host Postgres form.
Unparametrized, SecretUrl accepts any URL. Use SecretUrl[str] for
an endpoint that is not always a full URL, such as the host:port
form the OTLP gRPC exporter takes.
Parametrized with anything that is not a URL or a string, the whole value is masked instead, since nothing can be redacted from it safely.
TimeZoneName
Bases: str
An IANA timezone name, such as UTC or Europe/Zurich.
Validation accepts any casing and stores the name in the casing the
timezone database uses, so europe/zurich and Europe/Zurich behave
the same on every filesystem.
A name is accepted only when zoneinfo can load it. An abbreviation
that names no zone, such as PST, is rejected where it is written
rather than at the first use of the value.