def __init__(self, bind, name=None, label=None, description=None, html_attributes=None, modifiers=None, **kwargs): # increment the instance counter self.instance_counter = Widget.instance_counter Widget.instance_counter += 1 self.html_attributes = HTMLAttrs() self.schema = Schema() self.modifiers = [] # default properties self.bind = bind # is an HTML attribute (see properties) self.name = name # is an HTML attribute (see properties) self.label = label self.description = description if self.atomic_schema is not None: self.schema[bind] = copy.deepcopy(self.atomic_schema) self._apply_customize(**kwargs) # final user's stuff override everything else if modifiers is not None: self.modifiers += modifiers if html_attributes is not None: self.html_attributes.update(html_attributes) self.apply_modifiers()
def _init_schema(self, schema, fqn): """ Combine the information from the `schema` attribute of the class and from `bind` property of the `Widget` instance to compute a validating JSON schema. """ schema.update(Schema({'type': 'object', 'properties': {}})) # convert a nested object to nested schemas. parent = schema for child in self.bind.split('.')[:-1]: new = Schema({'type': 'object', 'properties': {}}) parent['properties'][child] = new parent = new last = self.bind.split('.')[-1] parent['properties'][last] = Schema(self.__class__.schema) return True
def _schema(self): """ On the fly schema computation """ schema = Schema() schema.apply_func(self._init_schema) # Apply modifiers for modifier in self.modifiers: if hasattr(modifier, 'alter_schema'): schema.apply_func(modifier.alter_schema) return schema.compile()
def schema_merger(*schemas): """ Merge multiple schemas in a new-one. """ res = Schema(description='Generated with Flask-Triangle') for schema in schemas: for k, v in schema: if k is not None and k not in res and isinstance(v, Object): res[k] = Object() elif not isinstance(v, Object): res[k] = copy.deepcopy(v) if hasattr(v, 'required') and k is not None: res[k].required += [prop for prop in v.required if prop not in res[k].required] elif hasattr(v, 'required'): res.required += [prop for prop in v.required if prop not in res.required] return res
def alter_schema(self, schema, fqn): if schema[u'type'] != u'object': # some properties must be moved from the array object to the item # object : items = Schema(schema) # clean some uneeded value in items for k in items.keys(): if k in ['asPatternProperty', 'required']: del items[k] # delete migrated values for k in schema.keys(): if k in items: del schema[k] schema[u'type'] = u'array' schema[u'items'] = items if self.min_items is not None: schema[u'minItems'] = self.min_items if self.max_items is not None: schema[u'maxItems'] = self.max_items