Config from cloud object storage¶
If the data is in a bucket, the document that describes it may as well be too — the same credentials already reach it, and a deployment that reads its collections from object storage should not need a file baked into its image to know which ones they are.
PYGEOAPI_CONFIG (per-environment: DEV_PYGEOAPI_CONFIG / PROD_PYGEOAPI_CONFIG) accepts a local path or an object-storage URL — one code path for both, the same layer the providers read through, built on obstore:
| Source | Example |
|---|---|
| Local file | pygeoapi-config.yml |
| Amazon S3 | s3://my-bucket/tenants/acme/pygeoapi-config.yml |
| S3-compatible (Tigris, MinIO) | same as S3 + AWS_ENDPOINT_URL_S3 |
| Google Cloud Storage | gs://my-bucket/pygeoapi-config.yml |
| Azure Blob Storage | az://container/pygeoapi-config.yml |
Credentials come exclusively from each provider's standard environment variables (AWS_ACCESS_KEY_ID / AWS_SECRET_ACCESS_KEY / AWS_ENDPOINT_URL_S3, GOOGLE_APPLICATION_CREDENTIALS, AZURE_STORAGE_ACCOUNT_NAME / AZURE_STORAGE_ACCOUNT_KEY). fastgeoapi never defines its own credential settings.
The configuration is read as bytes and handed to pygeoapi as an in-memory dictionary: no temporary file is written, and ${VAR} placeholders inside the config are resolved with the same semantics as vanilla pygeoapi.
The OpenAPI artifact¶
PYGEOAPI_OPENAPI is an output target and accepts the same set of sources — local path or bucket URL. The runtime never reads it back (everything is built in memory); it exists for external consumers such as the control plane or CLI tooling.
- Startup writes it only when it is missing.
- An applied reload always rewrites it, so the artifact never goes stale against the config that is serving.
- A failed write is logged as a warning and never aborts startup or a reload.
- Writing to a bucket needs read-write credentials; reading the config alone works with read-only ones.
fastgeoapi openapi writes the security-enriched JSON document to the same target (with a .json suffix), through the same layer.
Hot reload¶
After updating the config object, call the reload webhook:
- Responds
202 Acceptedimmediately; the reload happens in the background. - Idempotent via the object's ETag: same ETag → outcome
unchanged, no rebuild. - A broken config never replaces the running one: the outcome is
failedand the previous config keeps serving. - The mounted OGC API surface follows the config: only the specifications the configured resources actually expose are served (a deployment without EDR resources answers 404 on the EDR paths), and the set is recomputed on every applied reload.
GET /admin/config/reloadreturns what this process serves and what its last reload did:
{
"status": "idle",
"instance": "9f2c1a7b",
"etag": "\"abc-123\"",
"last": {
"outcome": "applied",
"at": "2026-08-22T17:00:00+00:00",
"etag": "\"abc-123\""
}
}
instance is an opaque identifier of the worker process that handled the request, and etag identifies the configuration version active on that worker. last.etag is the version the worker found the last time it looked. After an applied or unchanged reload the two are equal. When the last attempt failed, last carries the error instead of an ETag, and etag still names the previous version, which is the one still being served.
The endpoint is protected by the same authentication chain configured for the API (API key, JWT via JWKS, or OPA) — no separate secret to manage.
Hot reloading when there is more than one worker¶
When using fastgeoapi run --workers N there are N processes, each with its own copy of the configuration read from the source during startup.
Requests to POST /admin/config/reload are handled by the single worker that happens to pick up the request. That worker reloads its own configuration immediately; the other processes do so only when they get a chance to re-read the source.
You can configure how long it takes for the other workers to notice by setting FASTGEOAPI_CONFIG_POLL_SECONDS (with the DEV_/PROD_ prefix of your ENV_STATE). Workers then poll the source at that interval and reload themselves whenever they detect a change; a poll that finds nothing new costs one HEAD per worker, or a stat on a local file. fastgeoapi run --workers N with N > 1 sets it to 5 unless you set it yourself. At 0, the default, there is no polling, so the hot reload reaches a single worker only.
The same setting matters with --workers 1 behind an external orchestrator. If several fastgeoapi instances read their configuration from a shared location, polling is the only way for all of them to converge after a change, because the webhook, like any other request, is served by one instance.
To check that every worker serves a revision, sample GET /admin/config/reload for longer than the poll interval and confirm that each instance you have seen reports the etag you wrote. Behind a load balancer you cannot tell how many workers exist from the instances you have seen, so this confirms convergence only for the workers that answered.
If the reload answers unchanged right after you changed the file, the store is still serving the old one. Idempotence compares the ETag the store reports with the one currently loaded, so a stale read is honestly reported as "nothing to do". Observed twice on Tigris after overwriting the same key, converging on its own — once within seconds of a second POST, once after several minutes. Trigger it again, or avoid the situation entirely: write a new key and point PYGEOAPI_CONFIG at it rather than overwriting, which also gives you a configuration history and a rollback.
The MCP tool list follows the reload as well. It is generated from the OpenAPI document, so a collection added to the configuration becomes an MCP tool — and one removed stops being offered — without restarting the instance.
What a connected client sees: the server is correct straight away, but nothing pushes the change out. This FastMCP version has no server-side notifications/tools/list_changed, and the stateless transport cannot send server-initiated messages by design, so a client keeps the list it cached until it asks for it again — normally when it reconnects.