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

1import re 

2from importlib import import_module 

3from pathlib import Path 

4from types import ModuleType 

5from typing import List 

6 

7from rest_framework.routers import DefaultRouter 

8from rest_framework.viewsets import GenericViewSet 

9 

10 

11class ConflictingUrlNames(Exception): 

12 pass 

13 

14 

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. 

17 

18 Returns: 

19 DefaultRouter: The main router object with registered URL patterns. 

20 """ 

21 main_router = DefaultRouter() 

22 url_name_list: List[str] = [] 

23 

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", "") 

38 

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) 

44 

45 return main_router 

46 

47 

48main_api_router = build_main_router() 

49# for url in main_api_router.urls: 

50# print(url)