context.py 3.6KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144
  1. # coding: utf-8
  2. import asyncio
  3. import typing
  4. from http import HTTPStatus
  5. from json import JSONDecodeError
  6. from aiohttp.web_request import Request
  7. from multidict import MultiDict
  8. from hapic.context import BaseContext
  9. from hapic.context import RouteRepresentation
  10. from hapic.decorator import DecoratedController
  11. from hapic.exception import WorkflowException
  12. from hapic.processor import ProcessValidationError
  13. from hapic.processor import RequestParameters
  14. from aiohttp import web
  15. class AiohttpContext(BaseContext):
  16. def __init__(
  17. self,
  18. app: web.Application,
  19. ) -> None:
  20. self._app = app
  21. @property
  22. def app(self) -> web.Application:
  23. return self._app
  24. async def get_request_parameters(
  25. self,
  26. *args,
  27. **kwargs
  28. ) -> RequestParameters:
  29. try:
  30. request = args[0]
  31. except IndexError:
  32. raise WorkflowException(
  33. 'Unable to get aiohttp request object',
  34. )
  35. request = typing.cast(Request, request)
  36. path_parameters = dict(request.match_info)
  37. query_parameters = MultiDict(request.query.items())
  38. if request.can_read_body:
  39. try:
  40. # FIXME NOW: request.json() make
  41. # request.content empty, do it ONLY if json headers
  42. # body_parameters = await request.json()
  43. # body_parameters = await request.content.read()
  44. body_parameters = {}
  45. pass
  46. except JSONDecodeError:
  47. # FIXME BS 2018-07-13: Raise an 400 error if header contain
  48. # json type
  49. body_parameters = {}
  50. else:
  51. body_parameters = {}
  52. form_parameters_multi_dict_proxy = await request.post()
  53. form_parameters = MultiDict(form_parameters_multi_dict_proxy.items())
  54. header_parameters = dict(request.headers.items())
  55. # TODO BS 2018-07-13: Manage files (see
  56. # https://docs.aiohttp.org/en/stable/multipart.html)
  57. files_parameters = dict()
  58. return RequestParameters(
  59. path_parameters=path_parameters,
  60. query_parameters=query_parameters,
  61. body_parameters=body_parameters,
  62. form_parameters=form_parameters,
  63. header_parameters=header_parameters,
  64. files_parameters=files_parameters,
  65. )
  66. def get_response(
  67. self,
  68. response: str,
  69. http_code: int,
  70. mimetype: str = 'application/json',
  71. ) -> typing.Any:
  72. pass
  73. def get_validation_error_response(
  74. self,
  75. error: ProcessValidationError,
  76. http_code: HTTPStatus = HTTPStatus.BAD_REQUEST,
  77. ) -> typing.Any:
  78. pass
  79. def find_route(
  80. self,
  81. decorated_controller: DecoratedController,
  82. ) -> RouteRepresentation:
  83. pass
  84. def get_swagger_path(
  85. self,
  86. contextualised_rule: str,
  87. ) -> str:
  88. pass
  89. def by_pass_output_wrapping(
  90. self,
  91. response: typing.Any,
  92. ) -> bool:
  93. pass
  94. def add_view(
  95. self,
  96. route: str,
  97. http_method: str,
  98. view_func: typing.Callable[..., typing.Any],
  99. ) -> None:
  100. pass
  101. def serve_directory(
  102. self,
  103. route_prefix: str,
  104. directory_path: str,
  105. ) -> None:
  106. pass
  107. def is_debug(
  108. self,
  109. ) -> bool:
  110. pass
  111. def handle_exception(
  112. self,
  113. exception_class: typing.Type[Exception],
  114. http_code: int,
  115. ) -> None:
  116. pass
  117. def handle_exceptions(
  118. self,
  119. exception_classes: typing.List[typing.Type[Exception]],
  120. http_code: int,
  121. ) -> None:
  122. pass