Skip to content

Preserve router path parameter names#554

Merged
koxudaxi merged 3 commits intomainfrom
issue-487-router-path
Apr 27, 2026
Merged

Preserve router path parameter names#554
koxudaxi merged 3 commits intomainfrom
issue-487-router-path

Conversation

@koxudaxi
Copy link
Copy Markdown
Owner

@koxudaxi koxudaxi commented Apr 27, 2026

Fixes: #487

Summary by CodeRabbit

  • Bug Fixes

    • Fixed FastAPI route path generation to correctly preserve original path parameter names (e.g., camelCase) instead of converting them to snake_case in URL templates. Function parameters and aliases remain properly mapped.
  • Tests

    • Added test case validating camelCase path parameters in modular router generation.

@coderabbitai
Copy link
Copy Markdown

coderabbitai Bot commented Apr 27, 2026

Warning

Rate limit exceeded

@koxudaxi has exceeded the limit for the number of commits that can be reviewed per hour. Please wait 3 minutes and 18 seconds before requesting another review.

To keep reviews running without waiting, you can enable usage-based add-on for your organization. This allows additional reviews beyond the hourly cap. Account admins can enable it under billing.

⌛ How to resolve this issue?

After the wait time has elapsed, a review can be triggered using the @coderabbitai review command as a PR comment. Alternatively, push new commits to this PR.

We recommend that you space out your commits to avoid hitting the rate limit.

🚦 How do rate limits work?

CodeRabbit enforces hourly rate limits for each developer per organization.

Our paid plans have higher rate limits than the trial, open-source and free plans. In all cases, we re-allow further reviews after a brief timeout.

Please see our FAQ for further information.

ℹ️ Review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro

Run ID: a67eff24-1791-4a26-974c-7da989785f2d

📥 Commits

Reviewing files that changed from the base of the PR and between 28cbc18 and 8537ab0.

📒 Files selected for processing (1)
  • tests/main/test_main.py

Walkthrough

The router template was modified to use operation.path instead of operation.snake_case_path when generating FastAPI route decorators. This change propagates through test expectations and includes a new test to verify camelCase path parameter handling.

Changes

Cohort / File(s) Summary
Router Template Updates
fastapi_code_generator/modular_template/routers.jinja2, tests/data/modular_template/routers.jinja2
Updated route path generation to use operation.path instead of operation.snake_case_path in decorator arguments.
Test Data Updates (Expected Outputs)
tests/data/expected/openapi/.../routers/fat_cats.py, tests/data/expected/openapi/.../routers/wild_boars.py, tests/data/expected/openapi/.../routers/slim_dogs.py
Route path parameters changed from snake_case to camelCase (e.g., {cat_id}{catId}, {boar_id}{boarId}, {dog_id}{dogId}) to align with OpenAPI alias declarations.
New Test
tests/main/test_main.py
Added test to verify router generation preserves camelCase path parameters while maintaining Python parameter naming conventions and OpenAPI aliases.

Estimated code review effort

🎯 2 (Simple) | ⏱️ ~15 minutes

Poem

🐰 A template tweak, so clean and bright,
From snake_case paths to camelCase light,
The routers now speak the OpenAPI way,
With aliases true and names on display,
One test to bind them, all working just right! 🎉

🚥 Pre-merge checks | ✅ 5
✅ Passed checks (5 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title 'Preserve router path parameter names' accurately and concisely describes the main change: updating router templates to use original parameter names (e.g., camelCase like 'itemId') instead of snake_case variants in FastAPI route decorators.
Docstring Coverage ✅ Passed Docstring coverage is 83.33% which is sufficient. The required threshold is 80.00%.
Linked Issues check ✅ Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check ✅ Passed Check skipped because no linked issues were found for this pull request.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.

✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch issue-487-router-path

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands and usage tips.

@github-actions
Copy link
Copy Markdown
Contributor

github-actions Bot commented Apr 27, 2026

📚 Docs Preview: https://pr-554.fastapi-code-generator.pages.dev

@codspeed-hq
Copy link
Copy Markdown

codspeed-hq Bot commented Apr 27, 2026

Merging this PR will degrade performance by 16.25%

⚠️ Unknown Walltime execution environment detected

Using the Walltime instrument on standard Hosted Runners will lead to inconsistent data.

For the most accurate results, we recommend using CodSpeed Macro Runners: bare-metal machines fine-tuned for performance measurement consistency.

⚠️ Different runtime environments detected

Some benchmarks with significant performance changes were compared across different runtime environments,
which may affect the accuracy of the results.

Open the report in CodSpeed to investigate

❌ 1 regressed benchmark

⚠️ Please fix the performance issues or acknowledge them on CodSpeed.

Performance Changes

Benchmark BASE HEAD Efficiency
test_generate_default_template_benchmark 43.3 ms 51.6 ms -16.25%

Comparing issue-487-router-path (8537ab0) with main (67bb774)

Open in CodSpeed

Copy link
Copy Markdown

@coderabbitai coderabbitai Bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🧹 Nitpick comments (2)
tests/main/test_main.py (1)

410-449: LGTM — targeted regression test for the path-parameter-preservation fix.

The two assertions cleanly pin down both halves of the fix (preserved URL template and the alias-based binding), and validate_generated_code ensures the generated module compiles.

Optional follow-up (non-blocking): consider also asserting that the main.py wires up the new router (e.g., from .routers import items), mirroring test_generate_router_name_from_hyphenated_tag on lines 403–406. That would catch regressions in router registration alongside the path-rendering behavior in the same test.

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@tests/main/test_main.py` around lines 410 - 449, Add an assertion in
test_generate_router_preserves_path_parameter_name to also verify the generated
main app wires up the new router: after reading router_text, read
output_dir.joinpath("main.py") and assert it contains the router
import/registration (e.g., "from .routers import items" or the equivalent router
inclusion) so the test catches regressions where the router is generated but not
registered; keep the existing assertions and call validate_generated_code as
before.
tests/data/modular_template/routers.jinja2 (1)

13-13: Mirror template kept in sync — LGTM.

This is intentionally a duplicate of fastapi_code_generator/modular_template/routers.jinja2 used as a --template-dir in tests. Pre-existing duplication; updating both in lockstep is correct. As a future cleanup, the test could point --template-dir at the package's built-in template directory (BUILTIN_MODULAR_TEMPLATE_DIR) to avoid drift, but that's out of scope here.

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@tests/data/modular_template/routers.jinja2` at line 13, This duplicate
template (tests/data/modular_template/routers.jinja2) intentionally mirrors the
built-in template using symbols like operation.type, operation.path, and
operation.response; leave it unchanged to keep tests passing and keep it in
lockstep with fastapi_code_generator/modular_template/routers.jinja2, or as a
future cleanup update the test harness to point at BUILTIN_MODULAR_TEMPLATE_DIR
instead of maintaining this duplicate.
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.

Nitpick comments:
In `@tests/data/modular_template/routers.jinja2`:
- Line 13: This duplicate template (tests/data/modular_template/routers.jinja2)
intentionally mirrors the built-in template using symbols like operation.type,
operation.path, and operation.response; leave it unchanged to keep tests passing
and keep it in lockstep with
fastapi_code_generator/modular_template/routers.jinja2, or as a future cleanup
update the test harness to point at BUILTIN_MODULAR_TEMPLATE_DIR instead of
maintaining this duplicate.

In `@tests/main/test_main.py`:
- Around line 410-449: Add an assertion in
test_generate_router_preserves_path_parameter_name to also verify the generated
main app wires up the new router: after reading router_text, read
output_dir.joinpath("main.py") and assert it contains the router
import/registration (e.g., "from .routers import items" or the equivalent router
inclusion) so the test catches regressions where the router is generated but not
registered; keep the existing assertions and call validate_generated_code as
before.

ℹ️ Review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro

Run ID: d752f732-8398-4a17-b289-8422bc6cc578

📥 Commits

Reviewing files that changed from the base of the PR and between 67bb774 and 28cbc18.

📒 Files selected for processing (8)
  • fastapi_code_generator/modular_template/routers.jinja2
  • tests/data/expected/openapi/modify_specific_routers/expected/using_routers_example/routers/fat_cats.py
  • tests/data/expected/openapi/modify_specific_routers/expected/using_routers_example/routers/wild_boars.py
  • tests/data/expected/openapi/using_routers/using_routers_example/routers/fat_cats.py
  • tests/data/expected/openapi/using_routers/using_routers_example/routers/slim_dogs.py
  • tests/data/expected/openapi/using_routers/using_routers_example/routers/wild_boars.py
  • tests/data/modular_template/routers.jinja2
  • tests/main/test_main.py

@codecov
Copy link
Copy Markdown

codecov Bot commented Apr 27, 2026

Codecov Report

✅ All modified and coverable lines are covered by tests.
✅ Project coverage is 100.00%. Comparing base (67bb774) to head (8537ab0).
⚠️ Report is 6 commits behind head on main.

Additional details and impacted files
@@            Coverage Diff            @@
##              main      #554   +/-   ##
=========================================
  Coverage   100.00%   100.00%           
=========================================
  Files           16        16           
  Lines         1064      1074   +10     
  Branches       110       110           
=========================================
+ Hits          1064      1074   +10     
Flag Coverage Δ
unittests 100.00% <100.00%> (ø)

Flags with carried forward coverage won't be shown. Click here to find out more.

☔ View full report in Codecov by Sentry.
📢 Have feedback on the report? Share it here.

🚀 New features to boost your workflow:
  • ❄️ Test Analytics: Detect flaky tests, report on failures, and find test suite problems.

@koxudaxi koxudaxi marked this pull request as ready for review April 27, 2026 08:38
@koxudaxi koxudaxi merged commit 18e87fe into main Apr 27, 2026
42 of 43 checks passed
@koxudaxi koxudaxi deleted the issue-487-router-path branch April 27, 2026 08:39
@github-actions github-actions Bot added the breaking-change-analyzed PR has been checked for release draft updates label Apr 27, 2026
@github-actions
Copy link
Copy Markdown
Contributor

Breaking Change Analysis

Result: No breaking changes detected

Reasoning: The breaking-change label is absent, so this PR is treated as a non-breaking release update.


This analysis was performed by repository automation using PR labels and the ## Breaking Changes section.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

breaking-change-analyzed PR has been checked for release draft updates

Projects

None yet

Development

Successfully merging this pull request may close these issues.

In routers.jinja2 template operation path is specified as "snake_case_path" instead of just "path"

1 participant