processor.py 3.0KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111
  1. # -*- coding: utf-8 -*-
  2. import typing
  3. from hapic.exception import InputValidationException, OutputValidationException
  4. class RequestParameters(object):
  5. def __init__(
  6. self,
  7. path_parameters,
  8. query_parameters,
  9. body_parameters,
  10. form_parameters,
  11. header_parameters,
  12. ):
  13. self.path_parameters = path_parameters
  14. self.query_parameters = query_parameters
  15. self.body_parameters = body_parameters
  16. self.form_parameters = form_parameters
  17. self.header_parameters = header_parameters
  18. class ProcessValidationError(object):
  19. def __init__(
  20. self,
  21. message: str,
  22. details: dict,
  23. ) -> None:
  24. self.message = message
  25. self.details = details
  26. class ProcessorInterface(object):
  27. def __init__(self):
  28. self.schema = None
  29. def process(self, value):
  30. raise NotImplementedError
  31. def get_validation_error(
  32. self,
  33. request_context: RequestParameters,
  34. ) -> ProcessValidationError:
  35. raise NotImplementedError
  36. class Processor(ProcessorInterface):
  37. @classmethod
  38. def clean_data(cls, data: typing.Any) -> dict:
  39. # Fixes #22: Schemas make not validation if None is given
  40. if data is None:
  41. return {}
  42. return data
  43. class InputProcessor(Processor):
  44. pass
  45. class OutputProcessor(Processor):
  46. pass
  47. class MarshmallowOutputProcessor(OutputProcessor):
  48. def process(self, data: typing.Any):
  49. clean_data = self.clean_data(data)
  50. dump_data = self.schema.dump(clean_data).data
  51. self.validate(dump_data)
  52. return dump_data
  53. def validate(self, data: typing.Any) -> None:
  54. clean_data = self.clean_data(data)
  55. errors = self.schema.load(clean_data).errors
  56. if errors:
  57. raise OutputValidationException(
  58. 'Error when validate input: {}'.format(
  59. str(errors),
  60. )
  61. )
  62. def get_validation_error(self, data: dict) -> ProcessValidationError:
  63. clean_data = self.clean_data(data)
  64. dump_data = self.schema.dump(clean_data).data
  65. errors = self.schema.load(dump_data).errors
  66. return ProcessValidationError(
  67. message='Validation error of output data',
  68. details=errors,
  69. )
  70. class MarshmallowInputProcessor(InputProcessor):
  71. def process(self, data: dict):
  72. clean_data = self.clean_data(data)
  73. unmarshall = self.schema.load(clean_data)
  74. if unmarshall.errors:
  75. raise OutputValidationException(
  76. 'Error when validate ouput: {}'.format(
  77. str(unmarshall.errors),
  78. )
  79. )
  80. return unmarshall.data
  81. def get_validation_error(self, data: dict) -> ProcessValidationError:
  82. clean_data = self.clean_data(data)
  83. marshmallow_errors = self.schema.load(clean_data).errors
  84. return ProcessValidationError(
  85. message='Validation error of input data',
  86. details=marshmallow_errors,
  87. )