Skip to content

feat: refactor subrouter file path#1314

Open
sansyrox wants to merge 1 commit intomainfrom
refactor/subrouter-remove-file-path
Open

feat: refactor subrouter file path#1314
sansyrox wants to merge 1 commit intomainfrom
refactor/subrouter-remove-file-path

Conversation

@sansyrox
Copy link
Member

@sansyrox sansyrox commented Feb 15, 2026

Description

This PR fixes #1189

Summary

This PR does a much needed refactor in subrouter

PR Checklist

Please ensure that:

  • The PR contains a descriptive title
  • The PR contains a descriptive summary of the changes
  • You build and test your changes before submitting a PR.
  • You have added relevant documentation
  • You have added relevant tests. We prefer integration tests wherever possible

Pre-Commit Instructions:

Summary by CodeRabbit

Release Notes

  • Refactor

    • Simplified SubRouter API: constructor now requires only the prefix parameter for route grouping, removing mandatory file path and module name arguments.
  • Documentation

    • Updated documentation examples, code samples, and integration tests across multiple languages to reflect the new SubRouter constructor signature.

@vercel
Copy link

vercel bot commented Feb 15, 2026

The latest updates on your projects. Learn more about Vercel for GitHub.

Project Deployment Actions Updated (UTC)
robyn Error Error Feb 15, 2026 9:14pm

@coderabbitai
Copy link

coderabbitai bot commented Feb 15, 2026

📝 Walkthrough

Walkthrough

SubRouter's constructor is refactored to remove the file/name parameter, now accepting only prefix and dependencies. Correspondingly, BaseRobyn initialization is simplified while Robyn assumes responsibility for OpenAPI setup and dev-mode handling. All documentation and integration tests are updated to reflect the new API.

Changes

Cohort / File(s) Summary
Documentation - SubRouter API Updates
docs_src/public/llms.txt, docs_src/src/pages/documentation/en/api_reference/advanced_routing.mdx, docs_src/src/pages/documentation/en/api_reference/openapi.mdx, docs_src/src/pages/documentation/en/example_app/openapi.mdx, docs_src/src/pages/documentation/en/example_app/subrouters.mdx, docs_src/src/pages/documentation/en/example_app/zh/subrouters.mdx, docs_src/src/pages/documentation/zh/api_reference/openapi.mdx, docs_src/src/pages/documentation/zh/example_app/openapi.mdx, docs_src/src/pages/documentation/zh/example_app/subrouters_and_views.mdx, llms.txt
Multiple documentation files updated to reflect SubRouter constructor changes from passing __file__ or __name__ as first argument to using only prefix parameter.
Integration Tests - SubRouter API Updates
integration_tests/subroutes/__init__.py, integration_tests/subroutes/di_subrouter.py, integration_tests/subroutes/file_api.py
Integration test files updated to use the new SubRouter API without file/name positional arguments; file_api.py also adds POST method support to /build route alongside GET.
Core Implementation
robyn/__init__.py
Refactors initialization responsibility: BaseRobyn simplified to remove file_object, config, openapi_file_path, and openapi parameters; Robyn assumes OpenAPI setup, dev-mode handling, and OpenAPI route registration; SubRouter constructor reduced to accept only prefix and dependencies with __add_prefix logic for route resolution.

Estimated code review effort

🎯 3 (Moderate) | ⏱️ ~25 minutes

Possibly related PRs

Suggested reviewers

  • VishnuSanal

Poem

🐰 SubRouter hops lighter now, no files to carry along,
Robyn takes the OpenAPI tune, a refactored song,
Prefix-only whispers make the API clean and bright,
Initialization delegated, init flows feel just right!

🚥 Pre-merge checks | ✅ 1 | ❌ 5
❌ Failed checks (5 warnings)
Check name Status Explanation Resolution
Description check ⚠️ Warning The PR description lacks substantive detail about what the refactor accomplishes. It only states 'does a much needed refactor in subrouter' without explaining the specific changes, rationale, or impact. Expand the summary to explain what was removed/changed (e.g., SubRouter no longer requires file path parameter), why this change was needed, and what benefits it provides.
Linked Issues check ⚠️ Warning The PR claims to fix issue #1189, which is about updating dependencies to support Python 3.9-3.13. However, the code changes only refactor SubRouter's constructor signature and do not address any dependency updates. Either update dependencies as required by #1189, or clarify if this PR addresses a different issue unrelated to the listed objective.
Out of Scope Changes check ⚠️ Warning The PR's SubRouter refactoring changes are unrelated to the stated objective of updating project dependencies to support Python 3.9-3.13. The changes focus on removing file path parameters from SubRouter, which is out of scope for the linked issue. Align the PR scope with issue #1189 by adding dependency updates, or update the linked issue reference to match the actual refactoring work being performed.
Docstring Coverage ⚠️ Warning Docstring coverage is 18.18% which is insufficient. The required threshold is 80.00%. Write docstrings for the functions missing them to satisfy the coverage threshold.
Merge Conflict Detection ⚠️ Warning ❌ Merge conflicts detected (22 files):

⚔️ docs_src/package-lock.json (content)
⚔️ docs_src/package.json (content)
⚔️ docs_src/public/llms.txt (content)
⚔️ docs_src/src/pages/documentation/en/api_reference/advanced_routing.mdx (content)
⚔️ docs_src/src/pages/documentation/en/api_reference/openapi.mdx (content)
⚔️ docs_src/src/pages/documentation/en/example_app/openapi.mdx (content)
⚔️ docs_src/src/pages/documentation/en/example_app/subrouters.mdx (content)
⚔️ docs_src/src/pages/documentation/en/example_app/zh/subrouters.mdx (content)
⚔️ docs_src/src/pages/documentation/zh/api_reference/openapi.mdx (content)
⚔️ docs_src/src/pages/documentation/zh/example_app/openapi.mdx (content)
⚔️ docs_src/src/pages/documentation/zh/example_app/subrouters_and_views.mdx (content)
⚔️ integration_tests/base_routes.py (content)
⚔️ integration_tests/helpers/http_methods_helpers.py (content)
⚔️ integration_tests/subroutes/__init__.py (content)
⚔️ integration_tests/subroutes/di_subrouter.py (content)
⚔️ integration_tests/subroutes/file_api.py (content)
⚔️ integration_tests/test_json_types.py (content)
⚔️ llms.txt (content)
⚔️ pyproject.toml (content)
⚔️ robyn/__init__.py (content)
⚔️ robyn/robyn.pyi (content)
⚔️ src/types/request.rs (content)

These conflicts must be resolved before merging into main.
Resolve conflicts locally and push changes to this branch.
✅ Passed checks (1 passed)
Check name Status Explanation
Title check ✅ Passed The title 'feat: refactor subrouter file path' clearly and concisely summarizes the main change: refactoring how SubRouter handles file path arguments.

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

✨ Finishing touches
  • 📝 Generate docstrings
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Post copyable unit tests in a comment
  • Commit unit tests in branch refactor/subrouter-remove-file-path
⚔️ Resolve merge conflicts (beta)
  • Auto-commit resolved conflicts to branch refactor/subrouter-remove-file-path
  • Create stacked PR with resolved conflicts
  • Post resolved changes as copyable diffs in a comment

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.

Copy link

@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.

Caution

Some comments are outside the diff and can’t be posted inline due to platform limitations.

⚠️ Outside diff range comments (2)
robyn/__init__.py (2)

79-95: ⚠️ Potential issue | 🟠 Major

Fix mutable default argument shared across instances: DependencyMap()

dependencies: DependencyMap = DependencyMap() creates a shared default instance across all callers who don't pass an explicit value. This pattern appears in BaseRobyn.__init__ (line 79), Robyn.__init__ (line 557), and SubRouter.__init__ (line 691).

Since DependencyMap has mutating methods (add_router_dependency, add_global_dependency, merge_dependencies) that are actively called in the codebase, multiple instances will inadvertently share and mutate the same DependencyMap if created without explicitly passing a value. This causes state to leak across independent instances.

Use None as default and instantiate inside the method:

def __init__(self, dependencies: DependencyMap = None) -> None:
    self.dependencies = dependencies if dependencies is not None else DependencyMap()

496-497: ⚠️ Potential issue | 🔴 Critical

include_router on BaseRobyn references attributes only defined on Robyn—will crash on SubRouter.

self.config and self.openapi are only initialized in Robyn.__init__, not in BaseRobyn.__init__. Since include_router is defined on BaseRobyn (line 480), calling it on a SubRouter instance will raise AttributeError when accessing self.config at line 496.

Additionally, line 497 has a separate bug: self.openapi.add_subrouter_paths(self.openapi) passes self's OpenAPI object to its own method instead of the router being included. The parameter should be the incoming router's OpenAPI data (or relevant paths). Since SubRouter has no openapi attribute at all, this logic should not live on BaseRobyn—it belongs only in Robyn.include_router.

Proposed fix

Move OpenAPI handling to Robyn.include_router by overriding the method, or guard attribute access with hasattr:

-        if not self.config.disable_openapi and self.openapi is not None:
-            self.openapi.add_subrouter_paths(self.openapi)
+        if hasattr(self, "config") and not self.config.disable_openapi and hasattr(self, "openapi") and self.openapi is not None:
+            self.openapi.add_subrouter_paths(router.router)

Or better: override include_router in Robyn to handle OpenAPI integration separately, keeping BaseRobyn.include_router focused on route merging.

🧹 Nitpick comments (1)
robyn/__init__.py (1)

583-607: Minor inconsistency in ROBYN_CLI env var handling.

Line 569 uses bool(os.environ.get("ROBYN_CLI", False)) while line 600 uses os.getenv("ROBYN_CLI", False) directly. Both treat any truthy string as enabled, but the inconsistent patterns make the intent less clear. Consider unifying to a single helper or consistent idiom.

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.

Update dependencies in robyn

1 participant