In version 0.3.0+, we've renamed the fast_router convenience function to create_router to prevent module shadowing and ensure compatibility with Python introspection tools, documentation generators, and type checkers.
Step 1: Update your imports
# Old (v0.2.x and earlier)
from fast_router import fast_router
# New (v0.3.0+)
from fast_router import create_routerStep 2: Update function calls
# Old (v0.2.x and earlier)
router = fast_router("routes")
# New (v0.3.0+)
router = create_router("routes")That's it! The function signature and behavior are identical.
The old name fast_router shadowed the fast_router.fast_router submodule, breaking Python's standard module introspection. This caused issues with:
- Documentation generators (Sphinx, pdoc)
- Type checkers (mypy, pyright)
- IDE introspection (PyCharm, VS Code)
- Any tool relying on
getattr()or module inspection
The new name create_router is more descriptive and follows Python best practices.
# Before
from fast_router import fast_router
router = fast_router("routes")
app = router.get_app()
# After
from fast_router import create_router
router = create_router("routes")
app = router.get_app()# Before
from fast_router import FastRouter
router = FastRouter("routes")
router.set_tag_metadata("users", description="User operations")
router.scan_routes()
app = router.get_app()
# After (no change needed for class-based usage)
from fast_router import FastRouter
router = FastRouter("routes")
router.set_tag_metadata("users", description="User operations")
router.scan_routes()
app = router.get_app()# Before
from fast_router import fast_router
router = fast_router("routes")
if __name__ == "__main__":
import uvicorn
uvicorn.run(router.get_app(), host="0.0.0.0", port=8000)
# After
from fast_router import create_router
router = create_router("routes")
if __name__ == "__main__":
import uvicorn
uvicorn.run(router.get_app(), host="0.0.0.0", port=8000)If you absolutely need to keep the old function name in your code (not recommended), you can import it from the submodule:
from fast_router.fast_router import fast_router
# Works exactly as before
router = fast_router("routes")Or create an alias:
from fast_router import create_router as fast_router
# Use your preferred name
router = fast_router("routes")The following APIs remain completely unchanged:
✅ FastRouter class
✅ FastRouter.scan_routes() method
✅ FastRouter.get_app() method
✅ FastRouter.get_routes() method
✅ FastRouter.set_tag_metadata() method
✅ Route file structure and conventions
✅ Dynamic route patterns ([id], [id:int], [slug:], [...path])
✅ HTTP method handlers (get, post, put, delete, etc.)
✅ All existing functionality and behavior
Here's a Python script to automatically update your codebase:
#!/usr/bin/env python3
"""
Migrate from fast_router to create_router
"""
import re
from pathlib import Path
def migrate_file(file_path):
"""Update a single Python file."""
content = file_path.read_text()
# Pattern 1: from fast_router import fast_router
pattern1 = r'from fast_router import fast_router\b'
replacement1 = 'from fast_router import create_router'
content = re.sub(pattern1, replacement1, content)
# Pattern 2: fast_router( function calls
pattern2 = r'\bfast_router\('
replacement2 = 'create_router('
content = re.sub(pattern2, replacement2, content)
file_path.write_text(content)
print(f"✓ Updated {file_path}")
def main():
"""Migrate all Python files in current directory."""
for py_file in Path('.').rglob('*.py'):
if 'venv' in str(py_file) or '.venv' in str(py_file):
continue
try:
migrate_file(py_file)
except Exception as e:
print(f"✗ Error updating {py_file}: {e}")
if __name__ == "__main__":
print("🔄 Migrating from fast_router to create_router...")
main()
print("✅ Migration complete!")Save as migrate.py and run:
python migrate.py-
Run your test suite:
pytest # or python -m pytest -
Verify your application starts:
python main.py # or uvicorn main:app --reload -
Check for any remaining references:
grep -r "fast_router(" --include="*.py" .
A: Yes, but it's a simple rename. The migration is straightforward and the benefits (proper module introspection, tool compatibility) are significant.
A: Yes, you can temporarily import both:
from fast_router import create_router
from fast_router.fast_router import fast_router
# Use whichever you need during transitionA: No. The old name creates fundamental issues with Python's module system. However, you can always import it from the submodule if needed.
A: No! Route files are unchanged. Only update the code where you create the router.
A: No changes needed! The class-based API is unchanged:
from fast_router import FastRouter # Still works exactly the sameA: No. This is purely a naming change with zero performance impact.
A: Type hints work the same way:
from fast_router import FastRouter, create_router
def setup_router() -> FastRouter:
return create_router("routes")| Version | fast_router Function |
create_router Function |
Recommendation |
|---|---|---|---|
| < 0.3.0 | ✅ Available | ❌ Not Available | Use fast_router |
| ≥ 0.3.0 | ✅ Available | Use create_router |
If you encounter issues during migration:
- Check the examples: See
example/main.pyfor updated usage - Run the test suite:
pytest tests/to see working examples - File an issue: GitHub Issues
- Read the docs: Full documentation at [docs link]
- Update imports:
from fast_router import create_router - Update function calls:
create_router("routes") - Run tests to verify everything works
- Update documentation/comments
- Search for any remaining references
- Commit changes
- README.md - Updated usage examples
- tests/test_introspection.py - Working examples
Need help? Open an issue or check the examples directory for updated code samples.