Skip to content

Folders and files

NameName
Last commit message
Last commit date

Latest commit

History

184 Commits

Repository files navigation

🏭 Foundry Python Core

LicenseCIQuality GateSecurityMaintainabilityTechnical DebtCode SmellsDependabotRenovate enabledCoverageRuffPyrightCopier

Foundational infrastructure for Foundry components.

Prerequisites

Install mise (task runner and dev tool manager):

brew install mise

Or follow the installation guide for other methods. Then activate mise in your shell profile.

Usage

Quickstart

FoundryContext is the single source of truth for all project-specific values. One call at application startup makes everything available library-wide — logging, Sentry, database settings, and more all derive from it automatically.

Initialise and boot

# main.pyfromaignostics_foundry_core.foundryimportFoundryContext, set_contextfromaignostics_foundry_core.bootimportbootset_context(FoundryContext.from_package("myproject"))
boot()

FoundryContext.from_package("myproject") reads package metadata and environment variables to populate every field:

  • name, version, version_full — from importlib.metadata
  • environment — resolved from env vars in priority order (see Configuration reference below)
  • env_prefix ("MYPROJECT_") — used by every settings class; all env vars for this project share this prefix
  • is_container, is_cli, is_test, is_library — detected automatically

boot() initialises logging (loguru), amends the SSL trust chain (truststore + certifi), and optionally starts Sentry — all in one call.

Env file search order

Settings are loaded from the environment and from env files. Highest priority first:

  1. .env.{environment}
  2. .env
  3. {MYPROJECT_ENV_FILE} (optional extra file; when the variable is set)
  4. ~/.myproject/.env.{environment}
  5. ~/.myproject/.env

Access the context from any module

fromaignostics_foundry_core.foundryimportget_contextctx=get_context()
print(f"Running {ctx.name} v{ctx.version_full} in {ctx.environment}")
# → Running myproject v1.2.3+main-abc1234---run.12345---build.42 in staging

get_context() raises RuntimeError with a clear message if set_context() was never called.

Testing pattern

Never call set_context() in tests. Pass a FoundryContext directly to functions via their optional context parameter:

fromaignostics_foundry_core.foundryimportFoundryContextfromaignostics_foundry_core.logimportlogging_initializectx=FoundryContext(name="myproject", version="0.0.0", version_full="0.0.0", environment="test")
logging_initialize(context=ctx)

All public library functions (logging_initialize, sentry_initialize, boot, load_modules, etc.) accept an optional context keyword argument and fall back to get_context() when it is None.


Configuration reference

All settings classes read from environment variables prefixed with {PREFIX} where {PREFIX} = MYPROJECT_ for a package named myproject.

Context & deployment environment

Read directly by FoundryContext.from_package() — no settings class.

VariableDefaultDescription
{PREFIX}ENVIRONMENT"local"Deployment environment name. Highest priority.
ENVFallback environment (lower priority than {PREFIX}ENVIRONMENT).
VERCEL_ENVVercel deployment environment (lower priority).
RAILWAY_ENVIRONMENTRailway deployment environment (lower priority).
{PREFIX}RUNNING_IN_CONTAINERunsetSet to any non-empty value to mark is_container = True.
{PREFIX}ENV_FILEunsetPath to an additional env file, inserted between the home-dir files and the local .env.

Build metadata

Read by FoundryContext.from_package() to build version_full and version_with_vcs_ref. All optional; most useful in CI.

VariableDefaultDescription
VCS_REFread from .git/HEADBranch name or commit SHA. Falls back to reading .git/HEAD when project path is found.
COMMIT_SHA"unknown"Full commit SHA; first 7 chars used.
BUILD_DATE"unknown"Build date string.
CI_RUN_ID"unknown"CI system run ID.
CI_RUN_NUMBER"unknown"CI system build number.
BUILDER"uv"Build tool name.

When any of these variables is set, version_full gains a +… suffix, e.g. 1.2.3+main-abc1234---run.12345---build.42.

Logging ({PREFIX}LOG_)

Settings class: LogSettings

VariableDefaultDescription
{PREFIX}LOG_LEVELINFOLog level: CRITICAL, ERROR, WARNING, SUCCESS, INFO, DEBUG, or TRACE.
{PREFIX}LOG_STDERR_ENABLEDtrueEnable logging to stderr.
{PREFIX}LOG_FILE_ENABLEDfalseEnable logging to a file.
{PREFIX}LOG_FILE_NAMEplatform log dirPath to the log file (validated on startup when FILE_ENABLED is true).
{PREFIX}LOG_REDIRECT_LOGGINGtrueRedirect stdlib logging to loguru via InterceptHandler.

Sentry ({PREFIX}SENTRY_)

Settings class: SentrySettings. Sentry is only initialised when ENABLED=trueandDSN is set.

VariableDefaultDescription
{PREFIX}SENTRY_ENABLEDfalseEnable Sentry error and performance monitoring.
{PREFIX}SENTRY_DSNunsetSentry DSN (must be an HTTPS URL with a valid ingest.*.sentry.io domain).
{PREFIX}SENTRY_DEBUGfalseEnable Sentry SDK debug mode.
{PREFIX}SENTRY_SEND_DEFAULT_PIIfalseInclude personally-identifiable information in events.
{PREFIX}SENTRY_MAX_BREADCRUMBS50Maximum breadcrumbs stored per event.
{PREFIX}SENTRY_SAMPLE_RATE1.0Error event sample rate (0.0–1.0).
{PREFIX}SENTRY_TRACES_SAMPLE_RATE0.1Transaction/trace sample rate.
{PREFIX}SENTRY_PROFILES_SAMPLE_RATE0.1Profiler sample rate.
{PREFIX}SENTRY_PROFILE_SESSION_SAMPLE_RATE0.1Profile session sample rate.
{PREFIX}SENTRY_PROFILE_LIFECYCLE"trace"Profile lifecycle mode: "trace" or "manual".
{PREFIX}SENTRY_ENABLE_LOGStrueForward log records to Sentry.

OpenTelemetry ({PREFIX}OTEL_)

Settings class: OTelSettings. OpenTelemetry is only initialised when ENABLED=trueand the standard OTEL_EXPORTER_OTLP_ENDPOINT is set. Each signal is then independently toggleable — traces and metrics default on, logs off (their volume/cost profile differs). Telemetry is exported via OTLP/gRPC, e.g. to the internal OTel gateway backing the Grafana stack (Tempo/Loki/Prometheus).

VariableDefaultDescription
{PREFIX}OTEL_ENABLEDfalseMaster switch for OpenTelemetry export via OTLP.
{PREFIX}OTEL_TRACES_ENABLEDtrueExport traces (once ENABLED).
{PREFIX}OTEL_METRICS_ENABLEDtrueExport metrics (once ENABLED).
{PREFIX}OTEL_LOGS_ENABLEDfalseBridge loguru records into OTLP log export (once ENABLED).

Endpoint, service name, and all other exporter behaviour come from the standard, unprefixedOpenTelemetry environment variables the SDK reads itself — not project-prefixed settings:

VariableDefaultDescription
OTEL_EXPORTER_OTLP_ENDPOINTunsetOTLP/gRPC collector endpoint. Required — export is skipped if unset.
OTEL_SERVICE_NAMEproject nameService name attached to all telemetry. Defaults to the FoundryContext name.
OTEL_EXPORTER_OTLP_CERTIFICATEOS CA bundle, else certifi'sCA file for the exporter's TLS. The Foundry Cloud Run Dockerfile installs the fleet's internal CA into the OS trust store, so this defaults to that bundle (falls back to certifi's public-roots-only bundle if it isn't present, e.g. running locally); set explicitly to override.
OTEL_RESOURCE_ATTRIBUTESunsetExtra resource attributes, comma-separated key=value pairs.
OTEL_SEMCONV_STABILITY_OPT_INhttpOpts HTTP instrumentation into the stable semantic conventions (low-cardinality route-template span names) instead of the old, experimental ones.

Process-level tracing/metrics/logs are set up by boot(). boot() also applies default auto-instrumentors (HTTPX, SQLAlchemy) when traces are enabled — override via boot(otel_instrumentors=[...]), or pass [] to opt out. Request-level FastAPI spans are instrumented automatically too: init_api() applies instrument_fastapi() to the app it builds (and to every versioned sub-app) — no explicit call needed. A project that constructs its FastAPI instance some other way can call instrument_fastapi(app) directly, once, after construction.

Database ({PREFIX}DB_)

Settings class: DatabaseSettings. Database configuration is only activated when {PREFIX}DB_URL is present (in the environment or in an env file).

VariableRequiredDefaultDescription
{PREFIX}DB_URLto activateFull async database connection URL (e.g. postgresql+asyncpg://user:pass@host/db). Always access via DatabaseSettings.get_url().
{PREFIX}DB_POOL_SIZEno10SQLAlchemy connection pool size.
{PREFIX}DB_POOL_MAX_OVERFLOWno10Max connections above pool size.
{PREFIX}DB_POOL_TIMEOUTno30.0Seconds to wait for a pool connection.
{PREFIX}DB_NAMEnounsetOverride the database name in the URL path at runtime.

Once a context is configured via set_context(), all database functions work with no arguments — the URL and pool settings are read from the context:

fromaignostics_foundry_core.databaseimportinit_engine, cli_run_with_db, with_engine# Zero-arg engine init — reads MYPROJECT_DB_URL, _DB_POOL_SIZE, etc. from envinit_engine()
# CLI helper — initialises engine, runs coroutine, disposes enginecli_run_with_db(my_async_func)
# Background job decorator — engine initialised before each invocation@with_engineasyncdefmy_job(): ...
# Override for a secondary database@with_engine(db_url="postgresql+asyncpg://user:pass@host/secondary")asyncdefmy_other_job(): ...

In tests, construct DatabaseSettings directly instead of setting env vars:

fromaignostics_foundry_core.databaseimportDatabaseSettingsfromtests.conftestimportmake_contextctx=make_context(database=DatabaseSettings(_env_prefix="TEST_DB_", url="sqlite+aiosqlite:///test.db"))

Authentication ({PREFIX}AUTH_)

Settings class: AuthSettings. All fields are optional with defaults unless enabled=True, which activates several cross-field requirements. Only needed when using aignostics_foundry_core.api.auth dependencies.

VariableRequiredDefaultDescription
{PREFIX}AUTH_ENABLEDnofalseEnable Auth0 authentication. When true, several other fields become required.
{PREFIX}AUTH_SESSION_SECRETwhen enabled""Secret to sign session cookies. Required when AUTH_ENABLED=true.
{PREFIX}AUTH_SESSION_EXPIRATIONno86400Session cookie expiration in seconds (range: 61–31536000).
{PREFIX}AUTH_DOMAINwhen enabled""Auth0 domain (e.g. myapp.eu.auth0.com). Required when AUTH_ENABLED=true.
{PREFIX}AUTH_CLIENT_IDwhen enabled""Auth0 client ID (max 32 chars). Required when AUTH_ENABLED=true.
{PREFIX}AUTH_CLIENT_SECRETwhen enabled""Auth0 client secret (64 chars). Required when AUTH_ENABLED=true.
{PREFIX}AUTH_INTERNAL_ORG_IDwhen enabled""Auth0 organization ID identifying the internal org (used by require_internal). Required when AUTH_ENABLED=true.
{PREFIX}AUTH_ROLE_CLAIMwhen enabled""JWT claim name containing the user's role (e.g. https://myapp.example.com/roles). Required when AUTH_ENABLED=true.

Console

Read directly from the environment — no settings class.

VariableDefaultDescription
{PREFIX}CONSOLE_WIDTHauto-detectOverride Rich console width (integer, characters). Defaults to terminal width or 80 in non-TTY environments.

Further Reading

About

🏭 Foundational infrastructure for Foundry components.

Resources

Security policy

Stars

2 stars

Watchers

0 watching

Forks

Releases

Packages

Used by

Contributors

Languages