draft07.py 4.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116
  1. from .draft06 import CodeGeneratorDraft06
  2. class CodeGeneratorDraft07(CodeGeneratorDraft06):
  3. FORMAT_REGEXS = dict(CodeGeneratorDraft06.FORMAT_REGEXS, **{
  4. 'date': r'^(?P<year>\d{4})-(?P<month>(0[1-9]|1[0-2]))-(?P<day>(0[1-9]|[12]\d|3[01]))\Z',
  5. 'iri': r'^\w+:(\/?\/?)[^\s]+\Z',
  6. 'iri-reference': r'^(\w+:(\/?\/?))?[^#\\\s]*(#[^\\\s]*)?\Z',
  7. 'idn-email': r'^[^@]+@[^@]+\.[^@]+\Z',
  8. 'idn-hostname': r'^(?!-)(xn--)?[a-zA-Z0-9][a-zA-Z0-9-_]{0,61}[a-zA-Z0-9]{0,1}\.(?!-)(xn--)?([a-zA-Z0-9\-]{1,50}|[a-zA-Z0-9-]{1,30}\.[a-zA-Z]{2,})$',
  9. 'relative-json-pointer': r'^(?:0|[1-9][0-9]*)(?:#|(?:\/(?:[^~/]|~0|~1)*)*)\Z',
  10. #'regex': r'',
  11. 'time': (
  12. r'^(?P<hour>\d{1,2}):(?P<minute>\d{1,2})'
  13. r'(?::(?P<second>\d{1,2})(?:\.(?P<microsecond>\d{1,6}))?'
  14. r'([zZ]|[+-]\d\d:\d\d)?)?\Z'
  15. ),
  16. })
  17. def __init__(self, definition, resolver=None, formats={}, use_default=True, use_formats=True, detailed_exceptions=True):
  18. super().__init__(definition, resolver, formats, use_default, use_formats, detailed_exceptions)
  19. # pylint: disable=duplicate-code
  20. self._json_keywords_to_function.update((
  21. ('if', self.generate_if_then_else),
  22. ('contentEncoding', self.generate_content_encoding),
  23. ('contentMediaType', self.generate_content_media_type),
  24. ))
  25. def generate_if_then_else(self):
  26. """
  27. Implementation of if-then-else.
  28. .. code-block:: python
  29. {
  30. 'if': {
  31. 'exclusiveMaximum': 0,
  32. },
  33. 'then': {
  34. 'minimum': -10,
  35. },
  36. 'else': {
  37. 'multipleOf': 2,
  38. },
  39. }
  40. Valid values are any between -10 and 0 or any multiplication of two.
  41. """
  42. with self.l('try:', optimize=False):
  43. self.generate_func_code_block(
  44. self._definition['if'],
  45. self._variable,
  46. self._variable_name,
  47. clear_variables=True
  48. )
  49. with self.l('except JsonSchemaValueException:'):
  50. if 'else' in self._definition:
  51. self.generate_func_code_block(
  52. self._definition['else'],
  53. self._variable,
  54. self._variable_name,
  55. clear_variables=True
  56. )
  57. else:
  58. self.l('pass')
  59. if 'then' in self._definition:
  60. with self.l('else:'):
  61. self.generate_func_code_block(
  62. self._definition['then'],
  63. self._variable,
  64. self._variable_name,
  65. clear_variables=True
  66. )
  67. def generate_content_encoding(self):
  68. """
  69. Means decoding value when it's encoded by base64.
  70. .. code-block:: python
  71. {
  72. 'contentEncoding': 'base64',
  73. }
  74. """
  75. if self._definition['contentEncoding'] == 'base64':
  76. with self.l('if isinstance({variable}, str):'):
  77. with self.l('try:'):
  78. self.l('import base64')
  79. self.l('{variable} = base64.b64decode({variable})')
  80. with self.l('except Exception:'):
  81. self.exc('{name} must be encoded by base64')
  82. with self.l('if {variable} == "":'):
  83. self.exc('contentEncoding must be base64')
  84. def generate_content_media_type(self):
  85. """
  86. Means loading value when it's specified as JSON.
  87. .. code-block:: python
  88. {
  89. 'contentMediaType': 'application/json',
  90. }
  91. """
  92. if self._definition['contentMediaType'] == 'application/json':
  93. with self.l('if isinstance({variable}, bytes):'):
  94. with self.l('try:'):
  95. self.l('{variable} = {variable}.decode("utf-8")')
  96. with self.l('except Exception:'):
  97. self.exc('{name} must encoded by utf8')
  98. with self.l('if isinstance({variable}, str):'):
  99. with self.l('try:'):
  100. self.l('import json')
  101. self.l('{variable} = json.loads({variable})')
  102. with self.l('except Exception:'):
  103. self.exc('{name} must be valid JSON')