class GridPropSchema(PropertySchema): varname = SchemaNode(String()) grid = PyGridSchema(missing=drop) data_file = SchemaNode(typ=Sequence(accept_scalar=True), children=[SchemaNode(String())]) grid_file = SchemaNode(typ=Sequence(accept_scalar=True), children=[SchemaNode(String())])
class SchemaAssociations(MappingSchema): users = SchemaNode(Sequence(), SchemaAssociationUser(), missing=None) routes = SchemaNode(Sequence(), SchemaAssociationDoc(), missing=None) waypoints = SchemaNode(Sequence(), SchemaAssociationDoc(), missing=None) waypoint_children = SchemaNode(Sequence(), SchemaAssociationDoc(), missing=None) images = SchemaNode(Sequence(), SchemaAssociationDoc(), missing=None)
class FilterPreferencesSchema(MappingSchema): activities = SchemaNode(Sequence(), SchemaNode(String(), validator=OneOf(activities)), missing=required) langs = SchemaNode(Sequence(), SchemaNode(String(), validator=OneOf(default_langs)), missing=required) areas = SchemaNode(Sequence(), SchemaAssociationDoc(), missing=required) followed_only = SchemaNode(Boolean(), missing=required)
def _check_coordinates(self, node, geom_type, coordinates): serializers = { 'Point': PointNode(gps=False), 'LineString': SchemaNode(Sequence(), PointNode(gps=False)), 'Polygon': SchemaNode(Sequence(), LinearRingNode(gps=False)) } single_serializers = [kv for kv in serializers.items()] for singletype, serializer in single_serializers: multitype = 'Multi' + singletype serializers[multitype] = SchemaNode(Sequence(), serializer) # Match coordinates by type. Can raise ``colander.Invalid`` serializers[geom_type].deserialize(coordinates)
class GridVectorPropSchema(VectorPropSchema): varnames = SequenceSchema(SchemaNode(String())) grid = PyGridSchema(missing=drop) data_file = SchemaNode(typ=Sequence(accept_scalar=True), children=[SchemaNode(String())]) grid_file = SchemaNode(typ=Sequence(accept_scalar=True), children=[SchemaNode(String())]) def __init__(self, json_='webapi', *args, **kwargs): if json_ == 'save': self.add( SchemaNode(typ=Sequence(), children=[SchemaNode(EnvProp())], name='variables')) super(GridVectorPropSchema, self).__init__(*args, **kwargs)
def __init__(self, json_='webapi', *args, **kwargs): if json_ == 'save': self.add( SchemaNode(typ=Sequence(), children=[SchemaNode(EnvProp())], name='variables')) super(GridVectorPropSchema, self).__init__(*args, **kwargs)
def definition(cls, **kwargs): schema = super(EnumField, cls).definition() schema.add( SchemaNode(Sequence(), SchemaNode(String()), name='choices', validator=Length(min=1))) return schema
class PyWindMoverSchema(base_schema.ObjType): filename = SchemaNode(typ=Sequence(accept_scalar=True), children=[SchemaNode(String())], missing=drop) current_scale = SchemaNode(Float(), missing=drop) extrapolate = SchemaNode(Bool(), missing=drop) time_offset = SchemaNode(Float(), missing=drop) wind = GridVectorPropSchema(missing=drop)
def __init__(self): super(DefinitionValidator, self).__init__(Mapping()) self.add(SchemaNode(String(), name='title')) self.add(SchemaNode(String(), name='description')) self.add( SchemaNode(Sequence(), SchemaNode(TypeFieldNode()), name='fields', validator=Length(min=1)))
def __init__(self, *args, **kwargs): super(DefinitionSchema, self).__init__(Mapping(), *args, **kwargs) self.add(SchemaNode(String(), name='title')) self.add(SchemaNode(String(), name='description')) self.add( SchemaNode(Mapping(unknown="preserve"), name="extra", missing=drop)) self.add( SchemaNode(Sequence(), SchemaNode(TypeFieldNode()), name='fields', validator=Length(min=1)))
def definition(cls, **kwargs): schema = super(GroupField, cls).definition(**kwargs) # Keep the ``type`` node only schema.children = [ c for c in schema.children if c.name not in ('hint', 'name', 'required') ] schema.add(SchemaNode(String(), name='description', missing=drop)) schema.add( SchemaNode(Sequence(), SchemaNode(TypeFieldNode()), name='fields', validator=Length(min=1))) return schema
def deserialize(self, cstruct=null): # Remove potential extra child from previous deserialization self.children = self.children[:2] value = super(ModelSchema, self).deserialize(cstruct) # Add extra child ``records`` with validation based on definition definition = value['definition'] self.add( SchemaNode(Sequence(), RecordSchema(definition), name='records', missing=[])) return super(ModelSchema, self).deserialize(cstruct)
def add_sequence_node(schema, sequence_node, single_key, plural_key=None, with_filter_by=False): if not sequence_node.name: sequence_node = sequence_node.clone(name=single_key) if with_filter_by: sequence_node = set_node_with_filter_by(sequence_node) single_node = SequenceSchema(Sequence(), sequence_node, missing=drop, name=single_key) schema.__class_schema_nodes__.append(single_node) schema.__all_schema_nodes__.append(single_node) if plural_key: if not sequence_node.name: sequence_node = sequence_node.clone(name=plural_key) plural_node = SequenceSchema( Sequence(), sequence_node, missing=drop, preparer=split_values, name=plural_key) schema.__class_schema_nodes__.append(plural_node) schema.__all_schema_nodes__.append(plural_node) sequence_finisher = SequenceFinisher(single_key, plural_key) if hasattr(schema, 'finisher'): if not is_nonstr_iter(schema.finisher): previous_finisher = schema.finisher def decorator(cls, appstruct): appstruct = sequence_finisher(cls, appstruct) return previous_finisher(cls, appstruct) schema.finisher = decorator else: schema.finisher.append(sequence_finisher) else: schema.finisher = [sequence_finisher]
def definition(cls, **kwargs): schema = super(ObjectField, cls).definition(**kwargs) db = get_db() schema.add( SchemaNode(String(), name='model', missing=drop, validator=ModelExist(db))) schema.add( SchemaNode(Sequence(), SchemaNode(TypeFieldNode()), name='fields', validator=Length(min=1), missing=drop)) schema.validator = ExclusiveKeys('model', 'fields') return schema
def __init__(self, title, name, field, round=1, desc=None, widget=None): self.title = title self.name = name self.field = field self.desc = desc self.round = round self.mapinit = [field.mapinit] self.processing_form = { 'form': lambda l: [field.processing_form['form'](v) for v in l], 'db': lambda l: [field.processing_form['db'](v) for v in l] } self.sn = sn(Sequence(), field.sn, name=self.name, title=self.title, description=self.desc, widget=widget)
class TimeSchema(base_schema.ObjType): # time = SequenceSchema(SchemaNode(DateTime(default_tzinfo=None), missing=drop), missing=drop) filename = SchemaNode(typ=Sequence(accept_scalar=True), children=[SchemaNode(String())], missing=drop) varname = SchemaNode(String(), missing=drop) data = SchemaNode(typ=Sequence(), children=[SchemaNode(DateTime(None))], missing=drop)
def __init__(self, *args, **kwargs): defaults = dict(validator=Length(min=3)) defaults.update(**kwargs) super(LinearRingNode, self).__init__(Sequence(), PointNode(gps=self.gps), **defaults)
def get_schema_from_relationship(self, prop: RelationshipProperty, overrides: dict) -> SchemaNode: """Build and return a :class:`colander.SchemaNode` for a relationship. The mapping process will translate one-to-many and many-to-many relationships from SQLAlchemy into a ``Sequence`` of ``Mapping`` nodes in Colander, and translate one-to-one and many-to-one relationships into a ``Mapping`` node in Colander. The related class involved in the relationship will be recursively mapped by ColanderAlchemy as part of this process, following the same mapping process. This method uses information stored in the relationship within the ``info`` that was passed to the relationship on creation. This means that ``Colander`` options can be specified declaratively in ``SQLAlchemy`` models using the ``info`` argument that you can pass to :meth:`sqlalchemy.orm.relationship`. For all relationships, the settings will only be applied to the outer Sequence or Mapping. To customise the inner schema node, create the attribute ``__colanderalchemy_config__`` on the related model with a dict-like structure corresponding to the Colander options that should be customised. Arguments/Keywords :param prop: RelationshipProperty :param overrides: Dictionary with attributes to be overriden. :return: SchemaNode instance. """ # The name of the SchemaNode is the ColumnProperty key. name = self._change_name(prop) kwargs = {'name': name} decl_overrides = prop.info.get(self.sqla_info_key, {}).copy() self.declarative_overrides[name] = decl_overrides.copy() class_ = prop.mapper.class_ if decl_overrides.pop('exclude', False): logger.debug( f'Relationship {name} skipped due to declarative overrides') return None for key in ['name', 'typ']: self.check_overrides(name, key, {}, decl_overrides, overrides) children = self._relationship_config(name, 'children', overrides, decl_overrides) includes = self._relationship_config(name, 'includes', overrides, decl_overrides) excludes = self._relationship_config(name, 'excludes', overrides, decl_overrides) rel_overrides = self._relationship_config(name, 'overrides', overrides, decl_overrides) # Add default values for missing parameters. missing = [] if prop.innerjoin: # Inner joined relationships imply it is mandatory missing = required kwargs['missing'] = missing kwargs.update(decl_overrides) kwargs.update(overrides) if children is not None: node_type = Mapping() if prop.uselist: # xToMany relationships. node_type = Sequence() return SchemaNode(node_type, *children, **kwargs) node = BriefySchemaNode(class_, name=name, includes=includes, excludes=excludes, overrides=rel_overrides, missing=missing, parents_=self.parents_ + [self.class_]) if prop.uselist: node = SchemaNode(Sequence(), node, **kwargs) node.name = name return node
def get_schema_from_relationship(self, prop, overrides): """ Build and return a :class:`colander.SchemaNode` for a relationship. The mapping process will translate one-to-many and many-to-many relationships from SQLAlchemy into a ``Sequence`` of ``Mapping`` nodes in Colander, and translate one-to-one and many-to-one relationships into a ``Mapping`` node in Colander. The related class involved in the relationship will be recursively mapped by ColanderAlchemy as part of this process, following the same mapping process. This method uses information stored in the relationship within the ``info`` that was passed to the relationship on creation. This means that ``Colander`` options can be specified declaratively in ``SQLAlchemy`` models using the ``info`` argument that you can pass to :meth:`sqlalchemy.orm.relationship`. For all relationships, the settings will only be applied to the outer Sequence or Mapping. To customise the inner schema node, create the attribute ``__colanderalchemy_config__`` on the related model with a dict-like structure corresponding to the Colander options that should be customised. Arguments/Keywords prop A given :class:`sqlalchemy.orm.properties.RelationshipProperty` instance that represents the relationship being mapped. overrides A dict-like structure that consists of schema attributes to override imperatively. Values provides as part of :attr:`overrides` will take precendence over all others. Example keys include ``children``, ``includes``, ``excludes``, ``overrides``. """ # The name of the SchemaNode is the ColumnProperty key. name = prop.key kwargs = dict(name=name) declarative_overrides = prop.info.get(self.sqla_info_key, {}).copy() self.declarative_overrides[name] = declarative_overrides.copy() class_ = prop.mapper.class_ key = 'exclude' if declarative_overrides.pop(key, False): log.debug('Relationship %s skipped due to declarative overrides', name) return None if overrides.pop(key, False): log.debug('Relationship %s skipped due to imperative overrides', name) return None for key in ['name', 'typ']: self.check_overrides(name, key, {}, declarative_overrides, overrides) key = 'children' imperative_children = overrides.pop(key, None) declarative_children = declarative_overrides.pop(key, None) if imperative_children is not None: children = imperative_children msg = 'Relationship %s: %s overridden imperatively.' log.debug(msg, name, key) elif declarative_children is not None: children = declarative_children msg = 'Relationship %s: %s overridden via declarative.' log.debug(msg, name, key) else: children = None key = 'includes' imperative_includes = overrides.pop(key, None) declarative_includes = declarative_overrides.pop(key, None) if imperative_includes is not None: includes = imperative_includes msg = 'Relationship %s: %s overridden imperatively.' log.debug(msg, name, key) elif declarative_includes is not None: includes = declarative_includes msg = 'Relationship %s: %s overridden via declarative.' log.debug(msg, name, key) else: includes = None key = 'excludes' imperative_excludes = overrides.pop(key, None) declarative_excludes = declarative_overrides.pop(key, None) if imperative_excludes is not None: excludes = imperative_excludes msg = 'Relationship %s: %s overridden imperatively.' log.debug(msg, name, key) elif declarative_excludes is not None: excludes = declarative_excludes msg = 'Relationship %s: %s overridden via declarative.' log.debug(msg, name, key) else: excludes = None key = 'overrides' imperative_rel_overrides = overrides.pop(key, None) declarative_rel_overrides = declarative_overrides.pop(key, None) if imperative_rel_overrides is not None: rel_overrides = imperative_rel_overrides msg = 'Relationship %s: %s overridden imperatively.' log.debug(msg, name, key) elif declarative_rel_overrides is not None: rel_overrides = declarative_rel_overrides msg = 'Relationship %s: %s overridden via declarative.' log.debug(msg, name, key) else: rel_overrides = None # Add default values for missing parameters. if prop.innerjoin: # Inner joined relationships imply it is mandatory missing = required else: # Any other join is thus optional missing = [] kwargs['missing'] = missing kwargs.update(declarative_overrides) kwargs.update(overrides) if children is not None: if prop.uselist: # xToMany relationships. return SchemaNode(Sequence(), *children, **kwargs) else: # xToOne relationships. return SchemaNode(Mapping(), *children, **kwargs) if prop.uselist: node = SQLAlchemySchemaNode(class_, name=name, includes=includes, excludes=excludes, overrides=rel_overrides, missing=missing, parents_=self.parents_ + [self.class_]) node = SchemaNode(Sequence(), node, **kwargs) else: kwargs['name'] = name kwargs['includes'] = includes kwargs['excludes'] = excludes kwargs['overrides'] = rel_overrides kwargs['parents_'] = self.parents_ + [self.class_] node = SQLAlchemySchemaNode(class_, **kwargs) node.name = name return node
class PropertySchema(base_schema.ObjType): name = SchemaNode(String(), missing='default') units = SchemaNode(typ=Sequence(accept_scalar=True), children=[SchemaNode(String(), missing=drop), SchemaNode(String(), missing=drop)]) time = SequenceSchema(SchemaNode(DateTime(default_tzinfo=None), missing=drop), missing=drop)
def get_schema_from_relationship(self, prop, overrides): """Extended for property support.""" # The name of the SchemaNode is the ColumnProperty key. name = prop.key kwargs = dict(name=name) declarative_overrides = prop.info.get(self.sqla_info_key, {}).copy() self.declarative_overrides[name] = declarative_overrides.copy() class_ = prop.mapper if declarative_overrides.pop('exclude', False): log.debug('Relationship %s skipped due to declarative overrides', name) return None for key in ['name', 'typ']: self.check_overrides(name, key, {}, declarative_overrides, overrides) key = 'children' imperative_children = overrides.pop(key, None) declarative_children = declarative_overrides.pop(key, None) if imperative_children is not None: children = imperative_children msg = 'Relationship %s: %s overridden imperatively.' log.debug(msg, name, key) elif declarative_children is not None: children = declarative_children msg = 'Relationship %s: %s overridden via declarative.' log.debug(msg, name, key) else: children = None key = 'includes' imperative_includes = overrides.pop(key, None) declarative_includes = declarative_overrides.pop(key, None) if imperative_includes is not None: includes = imperative_includes msg = 'Relationship %s: %s overridden imperatively.' log.debug(msg, name, key) elif declarative_includes is not None: includes = declarative_includes msg = 'Relationship %s: %s overridden via declarative.' log.debug(msg, name, key) else: includes = None # TODO: Utmost piece of garbage here.. remove this if not self.automatic_relationships: if name not in (self.includes or ()): log.debug("Does not construct relationship for %s unless explicitly included", name) return None if self.relationship_overrides: result = self.relationship_overrides(self, name, prop, class_) if result == TypeOverridesHandling.drop: return None elif result == TypeOverridesHandling.unknown: pass else: assert isinstance(result, colander.SchemaNode) return result key = 'excludes' imperative_excludes = overrides.pop(key, None) declarative_excludes = declarative_overrides.pop(key, None) if imperative_excludes is not None: excludes = imperative_excludes msg = 'Relationship %s: %s overridden imperatively.' log.debug(msg, name, key) elif declarative_excludes is not None: excludes = declarative_excludes msg = 'Relationship %s: %s overridden via declarative.' log.debug(msg, name, key) else: excludes = None # see issue #25 in ColanderAlchemy for possible patch if includes is None and excludes is None: includes = [p.key for p in inspect(class_).column_attrs] key = 'overrides' imperative_rel_overrides = overrides.pop(key, None) declarative_rel_overrides = declarative_overrides.pop(key, None) if imperative_rel_overrides is not None: rel_overrides = imperative_rel_overrides msg = 'Relationship %s: %s overridden imperatively.' log.debug(msg, name, key) elif declarative_rel_overrides is not None: rel_overrides = declarative_rel_overrides msg = 'Relationship %s: %s overridden via declarative.' log.debug(msg, name, key) else: rel_overrides = None # Add default values for missing parameters. if prop.innerjoin: # Inner joined relationships imply it is mandatory missing = required else: # Any other join is thus optional missing = [] kwargs['missing'] = missing kwargs.update(declarative_overrides) kwargs.update(overrides) if children is not None: if prop.uselist: # xToMany relationships. return SchemaNode(Sequence(), *children, **kwargs) else: # xToOne relationships. return SchemaNode(Mapping(), *children, **kwargs) node = PropertyAwareSQLAlchemySchemaNode(class_, name=name, includes=includes, excludes=excludes, overrides=rel_overrides, missing=missing, type_overrides=self.type_overrides, relationship_overrides=self.relationship_overrides) if prop.uselist: node = SchemaNode(Sequence(), node, **kwargs) node.name = name return node
class PyGridSchema(base_schema.ObjType): # filename = SequenceSchema(SchemaNode(String()), accept_scalar=True) filename = SchemaNode(typ=Sequence(accept_scalar=True), children=[SchemaNode(String())])
class TestNoneSchema(MappingSchema): foo = SchemaNode(String()) bar = SchemaNode(Sequence(), SchemaNode(String()), missing=None)
def get_node_perms(identifier): identifier_validator(self, identifier) perm_node = SchemaNode(String(), validator=PermissionValidator()) return SchemaNode(Sequence(), perm_node, name=identifier)
def __init__(self, *args, **kwargs): kwargs['typ'] = Sequence(accept_scalar=True) super(FilenameSchema, self).__init__(SchemaNode(String()), *args, **kwargs)
def sequence(name, *children, **kw): return _node(Sequence(), name, *children, **kw)
class PaginationInput(MappingSchema): page = PAGE.clone(missing=1) limit_per_page = LIMIT_PER_PAGE.clone(missing=20) order_by = SequenceSchema(Sequence(), ORDER_BY, missing=drop, preparer=split_values) finisher = [OrderFinisher]
class SchemaImageList(MappingSchema): images = SchemaNode( Sequence(), schema_create_image, missing=None)
def __init__(self, *args, **kwargs): defaults = dict(validator=Length(min=2)) defaults.update(**kwargs) super(PointNode, self).__init__(Sequence(), SchemaNode(Float()), **defaults)