Skip to main content

Fail-fast validation of environment-based config for Python apps.

Project description

🦉 owl · check

CI Python Pydantic pydantic-settings License PyPI

Fail-fast validation of environment-based configuration for Python applications.

owlcheck is a small ergonomics layer on top of pydantic-settings. It loads your environment-driven settings on startup, prints a readable report of what was supplied vs. defaulted, warns when your .env file contains unknown variables, and aborts the process with a clear error when something required is missing.

The owl watches silently; it only speaks up when something is wrong.

Status

Early development — API is not yet stable. Pinned to pydantic>=2, pydantic-settings>=2, Python 3.10+.

Installation

pip install owlcheck

Usage

Plain script / CLI

from owlcheck import Settings
from pydantic import Field


class AppSettings(Settings):
    database_url: str = Field(..., alias="DATABASE_URL", description="Postgres DSN")
    debug: bool = Field(False, alias="DEBUG", description="Enable verbose logging")


settings = AppSettings.load_or_exit()

print(settings.database_url)

If DATABASE_URL is missing, the process exits with code 1 and a readable log of what was wrong.

FastAPI

from fastapi import FastAPI, Depends
from typing import Annotated

settings = AppSettings.load_or_exit()  # at module import time, fails fast on bad env


def get_settings() -> AppSettings:
    return AppSettings.load()  # cached after first call


app = FastAPI()


@app.get("/health")
def health(s: Annotated[AppSettings, Depends(get_settings)]):
    return {"db": s.database_url, "debug": s.debug}

Tests

def test_something():
    s = AppSettings.load(database_url="sqlite:///:memory:", debug=True)
    # Overrides bypass the cache entirely, so other tests are unaffected.

For full isolation between tests, clear the cache:

import owlcheck

@pytest.fixture(autouse=True)
def _reset_owlcheck():
    owlcheck.clear_cache()
    yield
    owlcheck.clear_cache()

What you get

  • Fail-fast on startup. load_or_exit() calls sys.exit(1) with a readable summary if required env vars are missing or invalid.
  • Per-field status log. On a successful load, each declared field is logged as provided (from env or overrides) or default, alongside its description.
  • Typo warnings. Unknown variables in your .env file are surfaced as a warning, then cleared from the model so downstream code cannot accidentally rely on them.
  • Aliased error messages. Validation errors are reported against the env var name (the field's alias), not the Python attribute name.
  • Per-class cache. Multiple Settings subclasses can coexist without sharing state.
  • Pluggable logger. Diagnostics go to logging.getLogger("owlcheck") by default; pass logger=... to redirect.

Public API

from owlcheck import Settings, load, load_or_exit, clear_cache
Symbol Purpose
Settings Base class. Subclass it and declare fields with Field(alias=...).
Settings.load(**kw) Class-bound shortcut for load(cls, **kw).
Settings.load_or_exit(**kw) Class-bound shortcut for load_or_exit(cls, **kw).
load(cls, *, reload=False, log_fields=True, logger=None, **overrides) Construct any BaseSettings subclass with diagnostics and caching.
load_or_exit(cls, *, exit_code=1, **kwargs) Like load, but calls sys.exit on ValidationError.
clear_cache() Drop all cached load results. Mostly useful in tests.

Design choices

  • Honest typing only. If a field can be None at runtime, declare it as T | None. owlcheck does not provide "soft optional" markers that lie to the type checker. This keeps mypy/pyright reliable and avoids surprise AttributeErrors in production.
  • Library, not framework. owlcheck does not configure logging for you. Configure your application's logging once, then owlcheck writes to logging.getLogger("owlcheck") like any well-behaved library.
  • No magic globals. The cache lives at module level inside owlcheck, keyed by the concrete subclass. You can opt out with reload=True or clear_cache().

License

MIT

Project details


Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distribution

owlcheck-0.1.0.tar.gz (7.6 kB view details)

Uploaded Source

Built Distribution

If you're not sure about the file name format, learn more about wheel file names.

owlcheck-0.1.0-py3-none-any.whl (8.3 kB view details)

Uploaded Python 3

File details

Details for the file owlcheck-0.1.0.tar.gz.

File metadata

  • Download URL: owlcheck-0.1.0.tar.gz
  • Upload date:
  • Size: 7.6 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? Yes
  • Uploaded via: twine/6.1.0 CPython/3.13.12

File hashes

Hashes for owlcheck-0.1.0.tar.gz
Algorithm Hash digest
SHA256 afea986660edf35564b562a987c44e88083d147d458e6a1f03c9090894b6d8c0
MD5 f45423209e0a0f04eb0e1f75f37bff8b
BLAKE2b-256 dbc59b03d1e901276f7a4acf9b25ae95d8799160a8e0c439539b3ff39d5a3b2c

See more details on using hashes here.

Provenance

The following attestation bundles were made for owlcheck-0.1.0.tar.gz:

Publisher: publish.yml on OwlsDontTalk/owlcheck

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

File details

Details for the file owlcheck-0.1.0-py3-none-any.whl.

File metadata

  • Download URL: owlcheck-0.1.0-py3-none-any.whl
  • Upload date:
  • Size: 8.3 kB
  • Tags: Python 3
  • Uploaded using Trusted Publishing? Yes
  • Uploaded via: twine/6.1.0 CPython/3.13.12

File hashes

Hashes for owlcheck-0.1.0-py3-none-any.whl
Algorithm Hash digest
SHA256 397b86bf348c1088ca7c0050eac153e83d35416c45a5df08fd7b7ef710a30dfb
MD5 d7b3ee3dd23ad9e886abe9ccec2e0ea8
BLAKE2b-256 920d12c33763fff3798c8e7bd15d5209589b16ea79fc5fca863b85273adbeac7

See more details on using hashes here.

Provenance

The following attestation bundles were made for owlcheck-0.1.0-py3-none-any.whl:

Publisher: publish.yml on OwlsDontTalk/owlcheck

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

Supported by

AWS Cloud computing and Security Sponsor Datadog Monitoring Depot Continuous Integration Fastly CDN Google Download Analytics Pingdom Monitoring Sentry Error logging StatusPage Status page