Coverage for django_napse/api/api_urls.py: 93%
29 statements
« prev ^ index » next coverage.py v7.4.3, created at 2024-03-12 13:49 +0000
« prev ^ index » next coverage.py v7.4.3, created at 2024-03-12 13:49 +0000
1import re
2from importlib import import_module
3from pathlib import Path
4from types import ModuleType
5from typing import List
7from rest_framework.routers import DefaultRouter
8from rest_framework.viewsets import GenericViewSet
11class ConflictingUrlNames(Exception):
12 pass
15def build_main_router() -> DefaultRouter:
16 """Create a main router object and register the appropriate viewsets to it based on the modules and classes found in the `api` directory.
18 Returns:
19 DefaultRouter: The main router object with registered URL patterns.
20 """
21 main_router = DefaultRouter()
22 url_name_list: List[str] = []
24 api_dir = Path(__file__).parent
25 api_modules_folders_names = [folder.name for folder in api_dir.iterdir() if folder.is_dir() and not folder.name.startswith("_")]
26 for module_name in api_modules_folders_names:
27 # print(f"module name: {module_name}")
28 try:
29 module: ModuleType = import_module(f"django_napse.api.{module_name}.views")
30 except (ImportError, ModuleNotFoundError) as error: # noqa: F841
31 # print(f"Could not import module {module_name} ({type(error)})")
32 # print(error)
33 continue
34 for obj in vars(module).values():
35 if isinstance(obj, type) and issubclass(obj, GenericViewSet):
36 # from CamelCase to snake_case & remove "_view" (ex: MyWalletView -> my_wallet)
37 url_name = re.sub(r"(?<!^)(?=[A-Z])", "_", obj.__name__).lower().replace("_view", "")
39 if url_name in url_name_list:
40 error_msg: str = f"Url name {url_name} already exists"
41 raise ConflictingUrlNames(error_msg)
42 main_router.register(url_name, obj, basename=url_name)
43 url_name_list.append(url_name)
45 return main_router
48main_api_router = build_main_router()
49# for url in main_api_router.urls:
50# print(url)