The traversal works by using the os.walk
function to recursively walk through the "addons" directory and its subdirectories, identifying all Python files:
-
Directory Structure:
addons/ ├── test1/ │ ├── models/ │ │ └── model.py │ └── routes/ │ └── test1_service.py ├── test2/ │ ├── models/ │ │ └── model.py │ └── routes/ │ └── test2_service.py
-
Traversal Process:
- The
os.walk
function is called with the "addons" directory. - It recursively visits each subdirectory and collects all files.
- The
-
Example of
os.walk
Output:- For the given structure,
os.walk
will generate:root = 'addons' dirs = ['test1', 'test2'] files = [] root = 'addons/test1' dirs = ['models', 'routes'] files = [] root = 'addons/test1/models' dirs = [] files = ['model.py'] root = 'addons/test1/routes' dirs = [] files = ['test1_service.py'] root = 'addons/test2' dirs = ['models', 'routes'] files = [] root = 'addons/test2/models' dirs = [] files = ['model.py'] root = 'addons/test2/routes' dirs = [] files = ['test2_service.py']
- For the given structure,
-
Processing Each File:
- For each file found, the relative path from "addons" is determined.
- The file path is converted to a module path by replacing directory separators with dots (
.
) and removing the.py
extension.
-
Example of Module Path Conversion:
addons/test1/routes/test1_service.py
becomesaddons.test1.routes.test1_service
addons/test2/routes/test2_service.py
becomesaddons.test2.routes.test2_service
-
Including the Router:
- Each constructed module path is passed to the
include_router_from_module
function to import the module and include its router in the FastAPI application if it exists.
- Each constructed module path is passed to the
The include_router_from_module
function is responsible for dynamically importing a module and checking if it contains a router
attribute, which is then included in the FastAPI application. Here's a detailed explanation of how this function works:
-
Function Definition:
def include_router_from_module(module_name: str):
-
Importing the Module:
- The function attempts to import the module using
importlib.import_module(module_name)
.
module = importlib.import_module(module_name)
- The function attempts to import the module using
-
Checking for
router
Attribute:- It checks if the imported module has an attribute named
router
usinghasattr(module, 'router')
.
if hasattr(module, 'router'):
- It checks if the imported module has an attribute named
-
Including the Router:
- If the
router
attribute exists, the function includes it in the FastAPI application usingapp.include_router
.
app.include_router(router=module.router)
- If the
-
Logging the Success:
- A message is printed to the console indicating that the router from the module was successfully registered.
print(f"Registered router from module: {module_name}")
-
Exception Handling:
- The function includes exception handling to manage cases where the module cannot be found or does not have a
router
attribute. - If a
ModuleNotFoundError
occurs, it prints an error message indicating that the module was not found.
except ModuleNotFoundError as e: print(f"Module not found: {module_name}, error: {e}")
- If an
AttributeError
occurs because the module does not have arouter
attribute, it prints an error message.
except AttributeError as e: print(f"Module '{module_name}' does not have 'router' attribute, error: {e}")
- The function includes exception handling to manage cases where the module cannot be found or does not have a