Skip to content

feat(fastapi): add APP_URL support to FastAPIConfig#111

Closed
bedus-creation wants to merge 5 commits into
mainfrom
fix/fastapi-config-app-url
Closed

feat(fastapi): add APP_URL support to FastAPIConfig#111
bedus-creation wants to merge 5 commits into
mainfrom
fix/fastapi-config-app-url

Conversation

@bedus-creation

Copy link
Copy Markdown
Contributor

Summary

  • Adds APP_URL env var support to FastAPIConfig so host and port can be derived from a full URL (e.g. http://myapp.com:8080 or https://production.example.com)
  • Introduces _parse_app_url(), _default_host(), and _default_port() helper functions with clear priority rules
  • Resolution order: APP_HOST/APP_PORT wins → APP_URL hostname/port → hard-coded defaults (127.0.0.1 / 8000)
  • URLs without a scheme (e.g. myapp.com:9000) are handled by prepending http:// before parsing

Changes

  • fastapi_startkit/src/fastapi_startkit/fastapi/config/fastapi.py — rewired host/port fields to use new helper functions; added urllib.parse and os imports
  • fastapi_startkit/tests/fastapi/test_fastapi_config.py — 15 new tests across 4 test classes covering all resolution scenarios

Test plan

  • No env vars → host="127.0.0.1", port=8000
  • APP_HOST + APP_PORT set → those values used
  • APP_URL=http://myapp.com:9000host="myapp.com", port=9000
  • APP_URL=https://production.example.comhost="production.example.com", port=8000 (no port in URL)
  • APP_URL=http://myapp.com:9000 + APP_HOST=override.comAPP_HOST wins: "override.com"
  • APP_URL=myapp.com:9000 (no scheme) → host="myapp.com", port=9000
  • All 15 tests pass: uv run pytest tests/fastapi/test_fastapi_config.py -v

🤖 Generated with Claude Code

@bedus-creation

Copy link
Copy Markdown
Contributor Author

❌ Code Review: CHANGES REQUESTED — 6 tests fail

Critical: Tests test the wrong layer

The PR moves host/port/URL resolution logic from FastAPIConfig into _resolve_host_port() in serve_command.py, which is a sound architectural decision. However, the test file test_fastapi_config.py was not updated to match — it still tests FastAPIConfig() for behaviours (defaults, URL parsing, priority) that now live in _resolve_host_port. Running the suite confirms 6 failures:

FAILED tests/fastapi/test_fastapi_config.py::TestDefaults::test_default_host
FAILED tests/fastapi/test_fastapi_config.py::TestDefaults::test_default_port
FAILED tests/fastapi/test_fastapi_config.py::TestAppUrlParsing::test_host_and_port_from_url
FAILED tests/fastapi/test_fastapi_config.py::TestAppUrlParsing::test_https_url_no_port
FAILED tests/fastapi/test_fastapi_config.py::TestAppUrlParsing::test_url_without_scheme
FAILED tests/fastapi/test_fastapi_config.py::TestPriority::test_app_host_overrides_only_host_url_port_still_used

(The PR description says "All 15 tests pass" — this is incorrect.)


Issue 1 — test_fastapi_config.py lines 9–17: Default assertions fail

FastAPIConfig().host is now env("APP_HOST") which returns "" (empty string) when not set — not "127.0.0.1". Same for port: returns "", not 8000.

Fix: Update TestDefaults.test_default_host and test_default_port to assert == "" (matching the raw-DTO contract). Move the "127.0.0.1" / 8000 default assertions into new tests for _resolve_host_port(None, None, None).

Issue 2 — test_fastapi_config.py lines 50–72 (TestAppUrlParsing): Wrong layer

FastAPIConfig no longer parses APP_URL — it just stores the raw string. These three tests assert cfg.host == "myapp.com" etc. on a FastAPIConfig instance, which will always fail.

Fix: Move these tests to tests/fastapi/test_serve_command.py and call _resolve_host_port() directly.

Issue 3 — test_fastapi_config.py line 88–92: Mixed-priority test fails

test_app_host_overrides_only_host_url_port_still_used checks that cfg.port == 9000 when only APP_URL provides the port — but FastAPIConfig no longer does that resolution.

Fix: Same as Issue 2 — belongs in tests for _resolve_host_port("override.com", None, "http://myapp.com:9000").

Issue 4 — serve_command.py line 94: Missing reload string→bool coercion (PR #110 fix absent)

The new serve_command.py still has:

reload = cfg_reload if self.option("reload") is None else self.option("reload")

--reload False (string) is still forwarded to uvicorn as "False" — the same bug PR #110 fixes. This PR must either include or rebase on top of PR #110.

Issue 5 — No tests for _resolve_host_port() itself

The entire resolution logic now lives in this function, but there are zero direct unit tests for it. The six tests that were supposed to cover this behaviour are all testing the wrong layer.

Fix: Add tests that call _resolve_host_port() directly: defaults, APP_URL parsing, priority rules, schemaless URL handling.


What's correct ✓

  • Architectural decision (raw DTO in config, resolution logic in command) is sound
  • The _resolve_host_port() implementation logic is correct
  • TestExplicitEnvVars and most TestPriority tests pass correctly
  • FastAPIConfig.app_url field and urlparse usage are well-structured

Please fix items 1–5 (focus on 1–3 and 5 for the test failures), then re-request review.

bedus-creation and others added 4 commits June 13, 2026 09:53
…ivation

Parse APP_URL (e.g. http://myapp.com:8080 or https://production.example.com)
to derive default host and port. Priority order: APP_HOST/APP_PORT env vars
win, then APP_URL hostname/port, then hard-coded defaults (127.0.0.1/8000).
Adds 15 tests covering all resolution scenarios.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Replace three-function APP_URL parsing helpers with a single
_parse_app_url(component) helper and inline or-chain lambdas in the
dataclass fields. Remove all importlib.reload() calls from the test
suite — monkeypatch works directly since default_factory lambdas
call env() at instantiation time.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
…o ServeCommand

FastAPIConfig now stores only raw env values (APP_HOST, APP_PORT, APP_URL)
with no parsing logic or hardcoded defaults.  _resolve_host_port() in
ServeCommand owns the full APP_HOST/APP_PORT → APP_URL → 127.0.0.1/8000
resolution chain, making the priority order explicit and testable in
isolation.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
…priority

Replace urllib.parse.urlparse with Uri.of() from fastapi_startkit.support.
Extend _resolve_host_port() to accept CLI args as top-priority parameters,
enforcing strict: CLI flag → APP_HOST/APP_PORT → APP_URL → hardcoded default.
Rewrite tests to target _resolve_host_port() directly and cover the full
priority chain including CLI overrides; update FastAPIConfig tests to reflect
that the config dataclass stores raw env values only (no defaults or parsing).

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
@bedus-creation bedus-creation force-pushed the fix/fastapi-config-app-url branch from ecccaaa to d2223e5 Compare June 13, 2026 16:56
… _resolve_host_port

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
@bedus-creation bedus-creation deleted the fix/fastapi-config-app-url branch June 13, 2026 17:31
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant