@@ -28,10 +28,13 @@ Or follow the [installation guide](https://mise.jdx.dev/getting-started.html) fo
2828
2929## Usage
3030
31- ### Initialise the context at application startup
31+ ### Quickstart
3232
33- Call ` set_context() ` once, before any library code runs, then call ` boot() ` to
34- initialise logging, the SSL trust chain, and optional Sentry integration:
33+ ` FoundryContext ` is the single source of truth for all project-specific values. One call at
34+ application startup makes everything available library-wide — logging, Sentry, database settings,
35+ and more all derive from it automatically.
36+
37+ #### Initialise and boot
3538
3639``` python
3740# main.py
@@ -42,32 +45,44 @@ set_context(FoundryContext.from_package("myproject"))
4245boot()
4346```
4447
45- ` FoundryContext.from_package() ` derives everything from package metadata and
46- environment variables :
48+ ` FoundryContext.from_package("myproject" ) ` reads package metadata and environment variables to
49+ populate every field :
4750
4851- ` name ` , ` version ` , ` version_full ` — from ` importlib.metadata `
49- - ` environment ` — from ` MYPROJECT_ENVIRONMENT ` → ` ENV ` → ` VERCEL_ENV ` →
50- ` RAILWAY_ENVIRONMENT ` → ` "local" `
52+ - ` environment ` — resolved from env vars in priority order (see [ Configuration reference ] ( #configuration-reference ) below)
53+ - ` env_prefix ` ( ` "MYPROJECT_" ` ) — used by every settings class; all env vars for this project share this prefix
5154- ` is_container ` , ` is_cli ` , ` is_test ` , ` is_library ` — detected automatically
52- - ` env_prefix ` (` "MYPROJECT_" ` ) — used by every settings class in the library
5355
54- ### Access the context from any module
56+ ` boot() ` initialises logging (loguru), amends the SSL trust chain (truststore + certifi), and
57+ optionally starts Sentry — all in one call.
58+
59+ #### Env file search order
60+
61+ Settings are loaded from the environment ** and** from env files, searched in this order
62+ (earlier files take higher priority):
63+
64+ 1 . ` ~/.myproject/.env `
65+ 2 . ` ~/.myproject/.env.{environment} `
66+ 3 . ` {MYPROJECT_ENV_FILE} ` (optional extra file; inserted here when the variable is set)
67+ 4 . ` .env `
68+ 5 . ` .env.{environment} `
69+
70+ #### Access the context from any module
5571
5672``` python
5773from aignostics_foundry_core.foundry import get_context
5874
5975ctx = get_context()
6076print (f " Running { ctx.name} v { ctx.version_full} in { ctx.environment} " )
61- # → Running myproject v1.2.3+main--- run.12345 in staging
77+ # → Running myproject v1.2.3+main-abc1234--- run.12345---build.42 in staging
6278```
6379
64- ` get_context() ` raises ` RuntimeError ` with a clear message if ` set_context() `
65- was never called.
80+ ` get_context() ` raises ` RuntimeError ` with a clear message if ` set_context() ` was never called.
6681
67- ### Pass context explicitly in tests
82+ #### Testing pattern
6883
69- Never call ` set_context() ` in tests. Pass a ` FoundryContext ` directly to each
70- function via its optional ` context ` parameter instead :
84+ Never call ` set_context() ` in tests. Pass a ` FoundryContext ` directly to functions via their
85+ optional ` context ` parameter:
7186
7287``` python
7388from aignostics_foundry_core.foundry import FoundryContext
@@ -77,14 +92,93 @@ ctx = FoundryContext(name="myproject", version="0.0.0", version_full="0.0.0", en
7792logging_initialize(context = ctx)
7893```
7994
80- All public library functions (` logging_initialize ` , ` sentry_initialize ` , ` boot ` ,
81- ` load_modules ` , etc.) accept an optional ` context ` keyword argument and fall
82- back to ` get_context() ` when it is ` None ` .
95+ All public library functions (` logging_initialize ` , ` sentry_initialize ` , ` boot ` , ` load_modules ` ,
96+ etc.) accept an optional ` context ` keyword argument and fall back to ` get_context() ` when it is
97+ ` None ` .
98+
99+ ---
100+
101+ ### Configuration reference
102+
103+ All settings classes read from environment variables prefixed with ` {PREFIX} ` where
104+ ` {PREFIX} ` = ` MYPROJECT_ ` for a package named ` myproject ` .
105+
106+ #### Context & deployment environment
83107
84- ### Database
108+ Read directly by ` FoundryContext.from_package() ` — no settings class.
85109
86- Once a context is configured via ` set_context() ` , all database functions work
87- with no arguments — the URL and pool settings are read from the context:
110+ | Variable | Default | Description |
111+ | ---| ---| ---|
112+ | ` {PREFIX}ENVIRONMENT ` | ` "local" ` | Deployment environment name. Highest priority. |
113+ | ` ENV ` | — | Fallback environment (lower priority than ` {PREFIX}ENVIRONMENT ` ). |
114+ | ` VERCEL_ENV ` | — | Vercel deployment environment (lower priority). |
115+ | ` RAILWAY_ENVIRONMENT ` | — | Railway deployment environment (lower priority). |
116+ | ` {PREFIX}RUNNING_IN_CONTAINER ` | unset | Set to any non-empty value to mark ` is_container = True ` . |
117+ | ` {PREFIX}ENV_FILE ` | unset | Path to an additional env file, inserted between the home-dir files and the local ` .env ` . |
118+
119+ #### Build metadata
120+
121+ Read by ` FoundryContext.from_package() ` to build ` version_full ` and ` version_with_vcs_ref ` . All
122+ optional; most useful in CI.
123+
124+ | Variable | Default | Description |
125+ | ---| ---| ---|
126+ | ` VCS_REF ` | read from ` .git/HEAD ` | Branch name or commit SHA. Falls back to reading ` .git/HEAD ` when project path is found. |
127+ | ` COMMIT_SHA ` | ` "unknown" ` | Full commit SHA; first 7 chars used. |
128+ | ` BUILD_DATE ` | ` "unknown" ` | Build date string. |
129+ | ` CI_RUN_ID ` | ` "unknown" ` | CI system run ID. |
130+ | ` CI_RUN_NUMBER ` | ` "unknown" ` | CI system build number. |
131+ | ` BUILDER ` | ` "uv" ` | Build tool name. |
132+
133+ When any of these variables is set, ` version_full ` gains a ` +… ` suffix, e.g.
134+ ` 1.2.3+main-abc1234---run.12345---build.42 ` .
135+
136+ #### Logging (` {PREFIX}LOG_ ` )
137+
138+ Settings class: ` LogSettings `
139+
140+ | Variable | Default | Description |
141+ | ---| ---| ---|
142+ | ` {PREFIX}LOG_LEVEL ` | ` INFO ` | Log level: ` CRITICAL ` , ` ERROR ` , ` WARNING ` , ` SUCCESS ` , ` INFO ` , ` DEBUG ` , or ` TRACE ` . |
143+ | ` {PREFIX}LOG_STDERR_ENABLED ` | ` true ` | Enable logging to stderr. |
144+ | ` {PREFIX}LOG_FILE_ENABLED ` | ` false ` | Enable logging to a file. |
145+ | ` {PREFIX}LOG_FILE_NAME ` | platform log dir | Path to the log file (validated on startup when ` FILE_ENABLED ` is true). |
146+ | ` {PREFIX}LOG_REDIRECT_LOGGING ` | ` true ` | Redirect stdlib ` logging ` to loguru via ` InterceptHandler ` . |
147+
148+ #### Sentry (` {PREFIX}SENTRY_ ` )
149+
150+ Settings class: ` SentrySettings ` . Sentry is only initialised when ` ENABLED=true ` ** and** ` DSN ` is
151+ set.
152+
153+ | Variable | Default | Description |
154+ | ---| ---| ---|
155+ | ` {PREFIX}SENTRY_ENABLED ` | ` false ` | Enable Sentry error and performance monitoring. |
156+ | ` {PREFIX}SENTRY_DSN ` | unset | Sentry DSN (must be an HTTPS URL with a valid ` ingest.*.sentry.io ` domain). |
157+ | ` {PREFIX}SENTRY_DEBUG ` | ` false ` | Enable Sentry SDK debug mode. |
158+ | ` {PREFIX}SENTRY_SEND_DEFAULT_PII ` | ` false ` | Include personally-identifiable information in events. |
159+ | ` {PREFIX}SENTRY_MAX_BREADCRUMBS ` | ` 50 ` | Maximum breadcrumbs stored per event. |
160+ | ` {PREFIX}SENTRY_SAMPLE_RATE ` | ` 1.0 ` | Error event sample rate (0.0–1.0). |
161+ | ` {PREFIX}SENTRY_TRACES_SAMPLE_RATE ` | ` 0.1 ` | Transaction/trace sample rate. |
162+ | ` {PREFIX}SENTRY_PROFILES_SAMPLE_RATE ` | ` 0.1 ` | Profiler sample rate. |
163+ | ` {PREFIX}SENTRY_PROFILE_SESSION_SAMPLE_RATE ` | ` 0.1 ` | Profile session sample rate. |
164+ | ` {PREFIX}SENTRY_PROFILE_LIFECYCLE ` | ` "trace" ` | Profile lifecycle mode: ` "trace" ` or ` "manual" ` . |
165+ | ` {PREFIX}SENTRY_ENABLE_LOGS ` | ` true ` | Forward log records to Sentry. |
166+
167+ #### Database (` {PREFIX}DB_ ` )
168+
169+ Settings class: ` DatabaseSettings ` . Database configuration is only activated when ` {PREFIX}DB_URL `
170+ is present (in the environment or in an env file).
171+
172+ | Variable | Required | Default | Description |
173+ | ---| ---| ---| ---|
174+ | ` {PREFIX}DB_URL ` | to activate | — | Full async database connection URL (e.g. ` postgresql+asyncpg://user:pass@host/db ` ). Always access via ` DatabaseSettings.get_url() ` . |
175+ | ` {PREFIX}DB_POOL_SIZE ` | no | ` 10 ` | SQLAlchemy connection pool size. |
176+ | ` {PREFIX}DB_POOL_MAX_OVERFLOW ` | no | ` 10 ` | Max connections above pool size. |
177+ | ` {PREFIX}DB_POOL_TIMEOUT ` | no | ` 30.0 ` | Seconds to wait for a pool connection. |
178+ | ` {PREFIX}DB_NAME ` | no | unset | Override the database name in the URL path at runtime. |
179+
180+ Once a context is configured via ` set_context() ` , all database functions work with no arguments —
181+ the URL and pool settings are read from the context:
88182
89183``` python
90184from aignostics_foundry_core.database import init_engine, cli_run_with_db, with_engine
@@ -106,17 +200,6 @@ async def my_job(): ...
106200async def my_other_job (): ...
107201```
108202
109- ` FoundryContext.from_package() ` activates database configuration automatically
110- when the following environment variables are present:
111-
112- | Variable | Required | Description |
113- | ---| ---| ---|
114- | ` {PREFIX}DB_URL ` | yes (to activate) | Full database connection URL |
115- | ` {PREFIX}DB_POOL_SIZE ` | no | Connection pool size (default ` 10 ` ) |
116- | ` {PREFIX}DB_MAX_OVERFLOW ` | no | Max pool overflow (default ` 10 ` ) |
117- | ` {PREFIX}DB_POOL_TIMEOUT ` | no | Pool wait timeout in seconds (default ` 30.0 ` ) |
118- | ` {PREFIX}DB_NAME ` | no | Override database name in the URL path |
119-
120203In tests, construct ` DatabaseSettings ` directly instead of setting env vars:
121204
122205``` python
@@ -126,13 +209,23 @@ from tests.conftest import make_context
126209ctx = make_context(database = DatabaseSettings(_env_prefix = " TEST_DB_" , url = " sqlite+aiosqlite:///test.db" ))
127210```
128211
129- ### Health API
212+ #### Authentication ( ` {PREFIX}AUTH_ ` )
130213
131- ``` python
132- from aignostics_foundry_core.health import Health, HealthStatus
214+ Settings class: ` AuthSettings ` . Both fields are required — no defaults. Only needed when using
215+ ` aignostics_foundry_core.api.auth ` dependencies.
133216
134- health = Health(status = HealthStatus.UP )
135- ```
217+ | Variable | Required | Description |
218+ | ---| ---| ---|
219+ | ` {PREFIX}AUTH_INTERNAL_ORG_ID ` | yes | Auth0 organization ID identifying the internal org (used by ` require_internal ` ). |
220+ | ` {PREFIX}AUTH_AUTH0_ROLE_CLAIM ` | yes | JWT claim name containing the user's role (e.g. ` https://myapp.example.com/roles ` ). |
221+
222+ #### Console
223+
224+ Read directly from the environment — no settings class.
225+
226+ | Variable | Default | Description |
227+ | ---| ---| ---|
228+ | ` {PREFIX}CONSOLE_WIDTH ` | auto-detect | Override Rich console width (integer, characters). Defaults to terminal width or 80 in non-TTY environments. |
136229
137230## Further Reading
138231
0 commit comments