Skip to content

Instantly share code, notes, and snippets.

@dstanek

dstanek/jsd.py Secret

Last active August 29, 2015 14:03
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save dstanek/a4f8fed405df911ada81 to your computer and use it in GitHub Desktop.
Save dstanek/a4f8fed405df911ada81 to your computer and use it in GitHub Desktop.
class _ObjectMeta(type):
def __new__(meta, name, bases, dct):
new_dct = {'properties': {}, 'required_properties': [], 'required': False}
for name, obj in dct.items():
if not isinstance(obj, _Type):
new_dct[name] = obj
else:
new_dct['properties'][name] = obj
if obj.required:
new_dct['required_properties'].append(name)
return super(_ObjectMeta, meta).__new__(meta, name, bases, new_dct)
class _Type(object):
def __init__(self, required=False, **kwargs):
self.required = required
def json(self):
if self.required:
return {'type': self.__class__.__name__.lower()}
else:
return {'type': [self.__class__.__name__.lower(), 'null']}
class Object(_Type):
__metaclass__ = _ObjectMeta
additional_properties = False
def create(self):
d = {
'type': 'object',
'required': self.required_properties,
'properties': dict((name, obj.json()) for name, obj in self.properties.items()),
}
if self.additional_properties:
d['additionalProperties'] = True
return d
def update(self):
d = {
'type': 'object',
'minProperties': 1,
'properties': dict((name, obj.json()) for name, obj in self.properties.items()),
}
if self.additional_properties:
d['additionalProperties'] = True
return d
class String(_Type):
pass
class Array(_Type):
def __init__(self, item_type=None, required=False, min_items=0):
self.item_type = item_type
self.required = required
self.min_items = min_items
def json(self):
data = super(Array, self).json()
data['minItems'] = self.min_items
if self.item_type:
data['items'] = create_if_needed(self.item_type).json()
return data
class Boolean(_Type):
pass
class OneOf(object):
def __init__(self, *types):
self.types = [create_if_needed(t) for t in types]
def json(self):
return {'oneOf': [t.json() for t in self.types]}
# FIXME: does type: object also need to be returned?
def create_if_needed(cls_or_obj):
return cls_or_obj() if isinstance(cls_or_obj, type) else cls_or_obj
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment