Created
January 23, 2016 09:32
-
-
Save Hardtack/8baeba02bd509e489f38 to your computer and use it in GitHub Desktop.
Marshmallow JSON Schema for Formencode schema
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
import datetime | |
import decimal | |
import uuid | |
from marshmallow import Schema, fields | |
from formencode import validators as v | |
from formencode.api import Validator as FormencodeValidator, NoDefault | |
from formencode.schema import Schema as FormencodeSchema | |
# From https://github.com/fuhrysteve/marshmallow-jsonschema/blob/master/marshmallow_jsonschema/base.py | |
TYPE_MAP = { | |
dict: { | |
'type': 'object', | |
}, | |
list: { | |
'type': 'array', | |
}, | |
datetime.time: { | |
'type': 'string', | |
'format': 'time', | |
}, | |
datetime.timedelta: { | |
# TODO explore using 'range'? | |
'type': 'string', | |
}, | |
datetime.datetime: { | |
'type': 'string', | |
'format': 'date-time', | |
}, | |
datetime.date: { | |
'type': 'string', | |
'format': 'date', | |
}, | |
uuid.UUID: { | |
'type': 'string', | |
'format': 'uuid', | |
}, | |
str: { | |
'type': 'string', | |
}, | |
bytes: { | |
'type': 'string', | |
}, | |
decimal.Decimal: { | |
'type': 'number', | |
'format': 'decimal', | |
}, | |
set: { | |
'type': 'array', | |
}, | |
tuple: { | |
'type': 'array', | |
}, | |
float: { | |
'type': 'number', | |
'format': 'float', | |
}, | |
int: { | |
'type': 'number', | |
'format': 'integer', | |
}, | |
bool: { | |
'type': 'boolean', | |
}, | |
} | |
class JSONSchema(Schema): | |
type = fields.Constant('object') | |
properties = fields.Method('get_properties') | |
required = fields.Method('get_required') | |
_type_mapping = { | |
v.ByteString: bytes, | |
v.StringBool: str, | |
v.Bool: bool, | |
v.Int: int, | |
v.Number: float, | |
v.UnicodeString: str, | |
v.Regex: str, | |
} | |
def get_properties(self, schema: FormencodeSchema): | |
fields = schema.fields | |
properties = {} | |
for name, validator in fields.items(): | |
properties[name] = self._convert_validator(validator) | |
return properties | |
def _convert_type(self, python_type): | |
return TYPE_MAP[python_type] | |
def _convert_validator(self, validator: FormencodeValidator): | |
for validator_class, python_type in self._type_mapping.items(): | |
if isinstance(validator, validator_class): | |
return self._convert_type(python_type) | |
def get_required(self, schema: FormencodeSchema): | |
fields = schema.fields | |
required = [] | |
for name, validator in fields.items(): | |
if self._is_required(validator): | |
required.append(name) | |
return required | |
def _is_required(self, validator: FormencodeValidator): | |
if validator.not_empty: | |
return True | |
if validator.if_missing is NoDefault: | |
return True | |
return False |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment