Coverage for nexios\views.py: 73%

1 from typing import Any, Dict, List, Optional, Type, Callable, Coroutine

2 from nexios.http import Request, Response

3 from nexios.routing import Routes as Route

4 import logging

5 from nexios.types import MiddlewareType

6

7 logger = logging.getLogger(__name__)

8

9

10 class APIView:

11 """

12 Enhanced class-based view that can be directly registered with the app or router.

13 """

14

15 middlewares: List[MiddlewareType] = []

16

17 error_handlers: Dict[

18 Type[Exception],

19 Callable[[Request, Response, Exception], Coroutine[Any, Any, Response]],

20 ] = {}

21

22 @classmethod

23 def as_route(

24 cls, path: str, methods: Optional[List[str]] = None, **kwargs

25 ) -> Route:

26 """

27 Convert the APIView class into a Route that can be registered with the app or router.

28 """

29 if methods is None:

30 methods = [

31 name.lower()

32 for name in {"get", "post", "put", "delete", "patch"}

33 if name in cls.__dict__

34 ]

35

36 async def handler(req: Request, res: Response, **kwargs) -> Response:

37 instance = cls()

38 return await instance.dispatch(req, res, **kwargs)

39

40 return Route(

41 path, handler, methods=methods, middlewares=cls.middlewares, **kwargs

42 )

43

44 async def dispatch(self, req: Request, res: Response, **kwargs) -> Response:

45 """

46 Dispatch the request to the appropriate handler method.

47 """

48

49 self.request = req

50 self.res = res

51 try:

52

53 method = req.method.lower()

54 handler = getattr(self, method, self.method_not_allowed)

55 return await handler(req, res, **kwargs)

56 except Exception as e:

57 for exc_type, handler in self.error_handlers.items():

58 if isinstance(e, exc_type):

59 return await handler(req, res, e)

60 raise e

61

62 async def method_not_allowed(

63 self, req: Request, res: Response, **kwargs

64 ) -> Response:

65 """

66 Handle requests with unsupported HTTP methods.

67 """

68 return res.status(405).json({"error": "Method Not Allowed"})

69

70 async def get(self, req: Request, res: Response) -> Response:

71 """

72 Handle GET requests.

73 """

74 return res.status(404).json({"error": "Not Found"})

75

76 async def post(self, req: Request, res: Response) -> Response:

77 """

78 Handle POST requests.

79 """

80 return res.status(404).json({"error": "Not Found"})

81

82 async def put(self, req: Request, res: Response) -> Response:

83 """

84 Handle PUT requests.

85 """

86 return res.status(404).json({"error": "Not Found"})

87

88 async def delete(self, req: Request, res: Response) -> Response:

89 """

90 Handle DELETE requests.

91 """

92 return res.status(404).json({"error": "Not Found"})

93

94 async def patch(self, req: Request, res: Response) -> Response:

95 """

96 Handle PATCH requests.

97 """

98 return res.status(404).json({"error": "Not Found"})