feat(dev): support running locally without full auth/S3 config#10
Merged
Conversation
Make the app boot gracefully when optional integrations are absent, and document the full local setup: - OIDC: skip Keycloak client registration when OIDC_ISSUER_URL is unset and log a warning, so `flask db ...` and other CLI commands work without auth configured (auth routes fail only on actual login). - storage: public_url() returns "" when S3_PUBLIC_BASE_URL is unset, so pages render with broken <img> tags instead of 500ing. - compose: comment out the local Keycloak service/volume (local dev points at the remote realm); keep Postgres + MinIO. - .env.example: add OIDC and S3/MinIO dev defaults. - README: document the OIDC/S3 env vars, MinIO bootstrap, and switch the schema step from `flask db init/migrate` to `flask db upgrade` against the committed migrations. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
There was a problem hiding this comment.
Pull request overview
This PR improves the local-development experience by making optional external integrations (OIDC/Keycloak and S3/MinIO) non-fatal at app startup, and updates developer documentation to match the intended “boots with minimal config” workflow.
Changes:
- Make OIDC initialization optional by skipping Keycloak client registration when
OIDC_ISSUER_URLis unset. - Make S3 image URL resolution optional by not crashing when
S3_PUBLIC_BASE_URLis unset. - Update local-dev docs and compose configuration (MinIO bootstrap + guidance; Keycloak service commented out).
Reviewed changes
Copilot reviewed 5 out of 5 changed files in this pull request and generated 4 comments.
Show a summary per file
| File | Description |
|---|---|
README.md |
Documents local-dev env vars, backing services, and using flask db upgrade against committed migrations. |
docker-compose.yml |
Keeps Postgres + MinIO + bucket bootstrap; comments out local Keycloak service/volume. |
app/storage.py |
Avoids raising on missing public S3 base URL when rendering image URLs. |
app/__init__.py |
Avoids failing app creation when OIDC issuer is not configured. |
.env.example |
Adds example OIDC and S3/MinIO environment variables for local development. |
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
Comment on lines
+95
to
+100
| base = current_app.config["S3_PUBLIC_BASE_URL"] | ||
| if not base: | ||
| # No public bucket configured — e.g. local dev without the S3/MinIO | ||
| # env vars set. Return "" so templates render a broken <img> rather | ||
| # than 500ing the whole page on a missing optional config. | ||
| return "" |
Comment on lines
+6
to
+10
| # auth | ||
| OIDC_ISSUER_URL=https://login.keyholding.com/realms/keyholding | ||
| OIDC_CLIENT_ID=tkc-library | ||
| OIDC_CLIENT_SECRET=dev-secret | ||
|
|
| | `AWS_ACCESS_KEY_ID` | `minioadmin` | MinIO/S3 access key (needed for uploads) | | ||
| | `AWS_SECRET_ACCESS_KEY` | `minioadmin` | MinIO/S3 secret key (needed for uploads) | | ||
|
|
||
| > If `OIDC_ISSUER_URL` or `S3_PUBLIC_BASE_URL` are unset, the app still boots (handy for running `flask db …` commands): auth routes are disabled and book images render broken, rather than crashing the page. |
Comment on lines
+51
to
+75
| issuer_url = app.config["OIDC_ISSUER_URL"] | ||
| if issuer_url: | ||
| oauth.register( | ||
| name="keycloak", | ||
| server_metadata_url=f"{issuer_url.rstrip('/')}/.well-known/openid-configuration", | ||
| client_id=app.config["OIDC_CLIENT_ID"], | ||
| client_secret=app.config["OIDC_CLIENT_SECRET"], | ||
| # PKCE is required by the Keycloak client config (S256). Authlib | ||
| # doesn't auto-enable it from server metadata; opting in here makes | ||
| # the SDK generate the code_verifier and send code_challenge / | ||
| # code_challenge_method on the authorize redirect. | ||
| client_kwargs={ | ||
| "scope": "openid email profile", | ||
| "code_challenge_method": "S256", | ||
| }, | ||
| ) | ||
| else: | ||
| # No OIDC config — e.g. running `flask db ...` or other CLI commands | ||
| # locally without auth set up. Skip client registration so the app | ||
| # factory doesn't crash; the /auth/* routes resolve `oauth.keycloak` | ||
| # lazily and will fail only if someone actually tries to log in. | ||
| app.logger.warning( | ||
| "OIDC_ISSUER_URL is unset — Keycloak auth disabled; /auth/* routes " | ||
| "will be unavailable until it is configured." | ||
| ) |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
Makes the app boot gracefully when optional integrations aren't configured, and documents the full local-dev setup.
app/__init__.py): skip Keycloak client registration whenOIDC_ISSUER_URLis unset and log a warning, soflask db …/ other CLI commands run without auth configured. Auth routes fail only if someone actually tries to log in.app/storage.py):public_url()returns""whenS3_PUBLIC_BASE_URLis unset, so pages render with a broken<img>rather than 500ing the whole page.docker-compose.yml): comment out the local Keycloak service + volume (local dev points at the remote realm); keep Postgres + MinIO..env.example: add OIDC and S3/MinIO dev defaults.flask db init/migratetoflask db upgradeagainst the committed migrations.Notes
These changes pre-existed in the working tree at the start of the session (not part of the branding PR #9) and are grouped here as one cohesive local-dev concern.
🤖 Generated with Claude Code