class SignRequestSchema(OpenAPISchema): """Request schema for signing a jsonld doc.""" verkey = fields.Str(required=True, description="Verkey to use for signing") doc = fields.Nested( Schema.from_dict({ "credential": fields.Dict( required=True, description="Credential to sign", ), "options": fields.Nested( Schema.from_dict({ "creator": fields.Str(required=False), "verificationMethod": fields.Str(required=False), "proofPurpose": fields.Str(required=False), }), required=True, ), }), required=True, )
def _add_missing_time(field, data, time_): ds = Schema.from_dict({field: fields.Date()})() dts = Schema.from_dict({field: NaiveDateTime()})() try: # let's see if we can load this as a DateTime dts.load({field: data[field]}) except ValidationError: # if not, we assume it's a valid date and append the time date = ds.load({field: data[field]})[field] data[field] = dts.dump({field: datetime.combine(date, time_)})[field]
def set_parameters(self, Accounts={}, Regions={}, Variables={}, with_trusts=True): accounts_fields_map = { k: fields.Nested( AccountIdSerializer( context={'RequireAccessRole': v.RequireAccessRole, "Name": k} ), required=False if v.Id else True, missing=v if v.Id else missing, ) for k, v in self.Accounts.items() } regions_fields_map = { k: fields.Nested( RegionIdSerializer, required=False if v.Id else True, missing=v if v.Id else missing, ) for k, v in self.Regions.items() } variables_fields_map = { k: fields.Nested( VariableValueSerializer.get_value_serializer_class(self.Variables[k]), required=True ) for k in self.Variables.keys() } accounts_schema = Schema.from_dict(accounts_fields_map) regions_schema = Schema.from_dict(regions_fields_map) variables_schema = Schema.from_dict(variables_fields_map) validator = Schema.from_dict({ 'Accounts': fields.Nested(accounts_schema), 'Regions': fields.Nested(regions_schema), 'Variables': fields.Nested(variables_schema) }) patch_dict(Accounts, self.Accounts) patch_dict(Regions, self.Regions) patch_dict(Variables, self.Variables) result = validator().load(data={ 'Accounts': Accounts, 'Regions': Regions, 'Variables': Variables }) self.Accounts = result['Accounts'] self.Regions = result['Regions'] self.Variables = result['Variables'] self.parse() return self.generate_cloudformation_templates(with_trusts=with_trusts)
def validate_json(schema: dict, json_data: dict): validator = Schema.from_dict(schema) try: result = validator().load(json_data) return result except ValidationError as err: abort(Responses.invalid_entity(str(err)))
class CloudStorageServerOption(Schema): """Used to indicate in the server options which types of cloud storage is enabled.""" s3 = fields.Nested( Schema.from_dict({"enabled": fields.Bool(required=True)})(), required=True, )
def to_schema(self): """Dynamically creates and returns the extensions Schema.""" schema_dict = { field_key: field_cfg['marshmallow'] for field_key, field_cfg in self.extensions.items() } return Schema.from_dict(schema_dict)
class IndyProofReqPredSpecSchema(OpenAPISchema): """Schema for predicate specification in indy proof request.""" name = fields.Str(example="index", description="Attribute name", required=True) p_type = fields.Str( description="Predicate type ('<', '<=', '>=', or '>')", required=True, **INDY_PREDICATE, ) p_value = fields.Int(description="Threshold value", required=True, strict=True) restrictions = fields.List( fields.Nested(IndyProofReqPredSpecRestrictionsSchema()), description="If present, credential must satisfy one of given restrictions", required=False, ) non_revoked = fields.Nested( Schema.from_dict( { "from": fields.Int( required=False, description="Earliest time of interest in non-revocation interval", strict=True, **INT_EPOCH, ), "to": fields.Int( required=False, description="Latest time of interest in non-revocation interval", strict=True, **INT_EPOCH, ), } ), allow_none=True, # accommodate libvcx required=False, )
def delete(self, id): hacknight = Hacknight.query.get_or_404(id) participants = { participant.id for participant in hacknight.participants } json_data = request.get_json(force=True) ids_schema = Schema.from_dict( {"participants_ids": fields.List(fields.Int())}) try: data = ids_schema().load(json_data) except ValidationError as err: return err.messages, HTTPStatus.UNPROCESSABLE_ENTITY to_remove = participants.intersection(set(data["participants_ids"])) if not to_remove: return { "message": "No participant to delete" }, HTTPStatus.BAD_REQUEST hacknight.participants = [ participant for participant in hacknight.participants if participant.id not in to_remove ] db.session.commit() hacknight_schema = HacknightSchema() return hacknight_schema.dump(hacknight), HTTPStatus.OK
def post(self, id): hacknight = Hacknight.query.get_or_404(id) participants = [ participant.id for participant in hacknight.participants ] json_data = request.get_json(force=True) ids_schema = Schema.from_dict( {"participants_ids": fields.List(fields.Int())}) try: data = ids_schema().load(json_data) except ValidationError as err: return err.messages, HTTPStatus.UNPROCESSABLE_ENTITY new_participants = [ _id for _id in data["participants_ids"] if _id not in participants ] if not new_participants: return ( { "message": "No new participant has been provided" }, HTTPStatus.BAD_REQUEST, ) for new_participant in new_participants: hacknight.participants.append( Participant.query.get_or_404(new_participant)) db.session.add(hacknight) db.session.commit() hacknight_schema = HacknightSchema() return hacknight_schema.dump(hacknight), HTTPStatus.OK
def post(self, id): team = Team.query.get_or_404(id) members = [member.id for member in team.members] json_data = request.get_json(force=True) ids_schema = Schema.from_dict({"members_ids": fields.List(fields.Int())}) try: data = ids_schema().load(json_data) except ValidationError as err: return err.messages, HTTPStatus.UNPROCESSABLE_ENTITY new_members = [_id for _id in data["members_ids"] if _id not in members] if not new_members: return ( {"message": "No new member has been provided"}, HTTPStatus.BAD_REQUEST, ) for new_member in new_members: team.members.append(Participant.query.get_or_404(new_member)) db.session.add(team) db.session.commit() team_schema = TeamSchema() return team_schema.dump(team), HTTPStatus.OK
class ServerInfoApi(Resource): @doc(description="Return FreeDiscovery server information " " (versions, etc).") @marshal_with( Schema.from_dict({ 'version': wfields.Nested({'number': wfields.Str()}), 'env': wfields.Nested({'python_version': wfields.Str()}), 'config': wfields.Nested({ 'cache_dir': wfields.Str(), 'debug': wfields.Boolean(), 'hostname': wfields.Str(), 'log_file': wfields.Str(), 'n_workers': wfields.Int(), 'port': wfields.Int(), 'server': wfields.Str() }) })) def get(self): out = {'version': {}, 'env': {}} out['version']['number'] = __version__ out['env']['python_version'] = sys.version out['config'] = self._fd_config return out
class RunConfig(BaseConfig): schema = Schema.from_dict({ "port": fields.Int(missing=ServerDefaults.HOST_PORT, help="Bind port"), "hostname": fields.Str(missing=ServerDefaults.HOST_ADDRESS, help="Bind Address"), "conf_file": fields.Str( missing=ServerDefaults.PROJECT_CONF, help="Name of config file in this directory", ), }) def __init__(self, port: int, hostname: str, conf_file: str, run_dev_server=False, *args, **kwargs): """Wrapper around run-server Args: ...RunConfig.Schema run_dev_server (bool) : If True will run back-end with CORS on Flask (No Gunicorn) """ self.port = port self.hostname = hostname self.conf_file = conf_file self.run_dev_server = run_dev_server self.project_conf = ProjectConfig.from_conf_file(self.conf_file)
def test_delimited_tuple_passed_invalid_type(web_request, parser): web_request.json = {"ids": 1} schema_cls = Schema.from_dict({"ids": fields.DelimitedTuple((fields.Int,))}) schema = schema_cls() with pytest.raises(ValidationError) as excinfo: parser.parse(schema, web_request) assert excinfo.value.messages == {"json": {"ids": ["Not a valid delimited tuple."]}}
class PlantInfoSchema(Schema): plant = fields.Nested(Schema.from_dict({ "name": fields.Str(required=True, validate=lambda x: len(x) >= 3), "sprout-time": fields.Str(required=True, validate=lambda x: len(x) >= 5), "full-growth": fields.Str(required=True, validate=lambda x: len(x) >= 5), "edible": fields.Boolean() })) num = fields.Int(required=True, validate=lambda x: x >= 1)
def test_delimited_tuple_incorrect_arity(web_request, parser): web_request.json = {"ids": "1,2"} schema_cls = Schema.from_dict( {"ids": fields.DelimitedTuple((fields.Int, fields.Int, fields.Int))}) schema = schema_cls() with pytest.raises(ValidationError): parser.parse(schema, web_request)
def make_schema(schema=None, **kwargs): """ Create a schema from a dictionary. **Deprecated**: Use `Schema.from_dict` instead. """ return Schema.from_dict(schema or kwargs)
class IndyProofRequestSchema(BaseModelSchema): """Schema for indy proof request.""" class Meta: """Indy proof request schema metadata.""" model_class = IndyProofRequest unknown = EXCLUDE nonce = fields.Str( description="Nonce", required=False, **NUM_STR_NATURAL, ) name = fields.Str( description="Proof request name", required=False, example="Proof request", default="Proof request", ) version = fields.Str( description="Proof request version", required=False, default="1.0", **INDY_VERSION, ) requested_attributes = fields.Dict( description="Requested attribute specifications of proof request", keys=fields.Str(decription="Attribute referent", example="0_legalname_uuid"), values=fields.Nested(IndyProofReqAttrSpecSchema()), ) requested_predicates = fields.Dict( description="Requested predicate specifications of proof request", keys=fields.Str(description="Predicate referent", example="0_age_GE_uuid"), values=fields.Nested(IndyProofReqPredSpecSchema()), ) non_revoked = fields.Nested( Schema.from_dict( { "from": fields.Int( required=False, description="Earliest time of interest in non-revocation interval", strict=True, **INT_EPOCH, ), "to": fields.Int( required=False, description="Latest time of interest in non-revocation interval", strict=True, **INT_EPOCH, ), }, name="IndyProofRequestNonRevokedSchema", ), allow_none=True, # accommodate libvcx required=False, )
def test_nested_field_from_dict(): # webargs.fields.Nested implements dict handling argmap = {"nest": fields.Nested({"foo": fields.Field()})} schema_cls = Schema.from_dict(argmap) assert issubclass(schema_cls, Schema) schema = schema_cls() assert "nest" in schema.fields assert type(schema.fields["nest"]) is fields.Nested assert "foo" in schema.fields["nest"].schema.fields
def test_params(self, app, path, openapi): params = path['get']['parameters'] rule = app.url_map._rules_by_endpoint['get_band'][0] expected = ( openapi.schema2parameters( Schema.from_dict({'name': fields.Str()}), location='query') + rule_to_params(rule) ) assert params == expected
def use_args( self, argmap: ArgMap, req: Optional[Request] = None, *, location: Optional[str] = None, unknown: Optional[str] = _UNKNOWN_DEFAULT_PARAM, # pylint: disable=unused-argument as_kwargs: bool = False, validate: ValidateArg = None, error_status_code: Optional[int] = None, error_headers: Optional[Mapping[str, str]] = None, ) -> Callable: """Decorator that injects parsed arguments into a view function or method. Edited from core parser to include the resource object """ location = location or self.location request_obj = req # Optimization: If argmap is passed as a dictionary, we only need # to generate a Schema once if isinstance(argmap, Mapping): argmap = Schema.from_dict(argmap)() def decorator(func: Callable) -> Callable: req_ = request_obj @functools.wraps(func) def wrapper(*args: Any, **kwargs: Any) -> Callable: req_obj = req_ if not req_obj: req_obj = self.get_request_from_view_args( func, args, kwargs) # pylint: disable=assignment-from-none # noqa: E501 # NOTE: At this point, argmap may be a Schema, or a callable parsed_args = self.parse( args[0], # This should be the self of the resource object argmap, req=req_obj, location=location, validate=validate, error_status_code=error_status_code, error_headers=error_headers, ) args, kwargs = self._update_args_kwargs( # type: ignore args, kwargs, parsed_args, as_kwargs, # type: ignore ) return func(*args, **kwargs) wrapper.__wrapped__ = func # type: ignore return wrapper return decorator
def test_delimited_list_empty_string(web_request, parser): web_request.json = {"dates": ""} schema_cls = Schema.from_dict({"dates": fields.DelimitedList(fields.Str())}) schema = schema_cls() parsed = parser.parse(schema, web_request) assert parsed["dates"] == [] data = schema.dump(parsed) assert data["dates"] == ""
def test_delimited_list_default_delimiter(web_request, parser): web_request.json = {"ids": "1,2,3"} schema_cls = Schema.from_dict({"ids": fields.DelimitedList(fields.Int())}) schema = schema_cls() parsed = parser.parse(schema, web_request) assert parsed["ids"] == [1, 2, 3] data = schema.dump(parsed) assert data["ids"] == "1,2,3"
class IndyProofReqPredSpecSchema(OpenAPISchema): """Schema for predicate specification in indy proof request.""" name = fields.Str(example="index", description="Attribute name", required=True) p_type = fields.Str( description="Predicate type ('<', '<=', '>=', or '>')", required=True, **INDY_PREDICATE, ) p_value = fields.Int(description="Threshold value", required=True, strict=True) restrictions = fields.List( fields.Dict( keys=fields.Str( validate=validate.Regexp( "^schema_id|" "schema_issuer_did|" "schema_name|" "schema_version|" "issuer_did|" "cred_def_id|" "attr::.+::value$" # indy does not support attr::...::marker here ), example="cred_def_id", ), values=fields.Str(example=INDY_CRED_DEF_ID["example"]), ), description=( "If present, credential must satisfy one of given restrictions: specify " "schema_id, schema_issuer_did, schema_name, schema_version, " "issuer_did, cred_def_id, and/or attr::<attribute-name>::value " "where <attribute-name> represents a credential attribute name" ), required=False, ) non_revoked = fields.Nested( Schema.from_dict( { "from": fields.Int( required=False, description="Earliest time of interest in non-revocation interval", strict=True, **INT_EPOCH, ), "to": fields.Int( required=False, description="Latest time of interest in non-revocation interval", strict=True, **INT_EPOCH, ), }, name="IndyProofReqPredSpecNonRevokedSchema", ), allow_none=True, # accommodate libvcx required=False, )
def get_output_schema(func: Callable[..., Any]) -> tuple[dict, Schema]: dschema = getattr(func, "output_schema", None) dschema = dschema or inspect_output(func) return ( dschema, Schema.from_dict({ field: build_field(meta["dtype"]) for field, meta in dschema.items() })(), )
def test_delimited_list_load_list_errors(web_request, parser): web_request.json = {"ids": [1, 2, 3]} schema_cls = Schema.from_dict({"ids": fields.DelimitedList(fields.Int())}) schema = schema_cls() with pytest.raises(ValidationError) as excinfo: parser.parse(schema, web_request) exc = excinfo.value assert isinstance(exc, ValidationError) errors = exc.args[0] assert errors["ids"] == ["Not a valid delimited list."]
def test_delimited_tuple_custom_delimiter(web_request, parser): web_request.json = {"ids": "1|2"} schema_cls = Schema.from_dict( {"ids": fields.DelimitedTuple((fields.Int, fields.Int), delimiter="|")} ) schema = schema_cls() parsed = parser.parse(schema, web_request) assert parsed["ids"] == (1, 2) data = schema.dump(parsed) assert data["ids"] == "1|2"
class ProjectConfig(BaseConfig): schema = Schema.from_dict( { # CLI Arguments "name": fields.Str( missing=ProjectDefaults.PROJECT_NAME, help="Name of the root project folder", ), "wml_dir": fields.Str( missing=ProjectDefaults.WML_FOLDER, help="Folder to store windmill WML files", ), "dags_dir": fields.Str( missing=ProjectDefaults.DAGS_FOLDER, help="Folder to store generated YML DAG files", ), "operators_dir": fields.Str( missing=ProjectDefaults.OPERATORS_FOLDER, help="Folder to store custom operator files", ), } ) def __init__( self, name: str, wml_dir: str, dags_dir: str, operators_dir: str, conf_file: str = ProjectDefaults.PROJECT_CONF, *args, **kwargs, ): """Handler for project file Args: ...Project.schema conf_file (str, optional): Default project config filename. Defaults to ProjectDefaults.PROJECT_CONF. """ self.name = name self.wml_dir = wml_dir self.dags_dir = dags_dir self.operators_dir = operators_dir self.conf_file = conf_file @staticmethod def from_conf_file(filename): try: with open(filename, "r+") as f: return ProjectConfig(**yaml.load(f)) except Exception as e: raise InitError("This directory is not a valid windmill project") from e
class DocSchema(OpenAPISchema): """Verifiable doc schema.""" class Meta: """Keep unknown values.""" unknown = INCLUDE proof = fields.Nested( Schema.from_dict({ "creator": fields.Str(required=False), "verificationMethod": fields.Str(required=False), "proofPurpose": fields.Str(required=False), }))
def test_whitespace_stripping_parser_example(web_request): def _strip_whitespace(value): if isinstance(value, str): value = value.strip() elif isinstance(value, typing.Mapping): return {k: _strip_whitespace(value[k]) for k in value} elif isinstance(value, (list, tuple)): return type(value)(map(_strip_whitespace, value)) return value class WhitspaceStrippingParser(MockRequestParser): def pre_load(self, location_data, *, schema, req, location): if location in ("query", "form"): ret = _strip_whitespace(location_data) return ret return location_data parser = WhitspaceStrippingParser() # mock data for query, form, and json web_request.form = web_request.query = web_request.json = {"value": " hello "} argmap = {"value": fields.Str()} # data gets through for 'json' just fine ret = parser.parse(argmap, web_request) assert ret == {"value": " hello "} # but for 'query' and 'form', the pre_load hook changes things for loc in ("query", "form"): ret = parser.parse(argmap, web_request, location=loc) assert ret == {"value": "hello"} # check that it applies in the case where the field is a list type # applied to an argument (logic for `tuple` is effectively the same) web_request.form = web_request.query = web_request.json = { "ids": [" 1", "3", " 4"], "values": [" foo ", " bar"], } schema = Schema.from_dict( {"ids": fields.List(fields.Int), "values": fields.List(fields.Str)} ) for loc in ("query", "form"): ret = parser.parse(schema, web_request, location=loc) assert ret == {"ids": [1, 3, 4], "values": ["foo", "bar"]} # json loading should also work even though the pre_load hook above # doesn't strip whitespace from JSON data # - values=[" foo ", ...] will have whitespace preserved # - ids=[" 1", ...] will still parse okay because " 1" is valid for fields.Int ret = parser.parse(schema, web_request, location="json") assert ret == {"ids": [1, 3, 4], "values": [" foo ", " bar"]}
def to_representation(self, instance): ret = {} try: for field in self.readable_fields: attr = getattr(instance, field) if isinstance(attr, peewee.Model): attr = attr.id ret[field] = attr except ValueError as e: self._errors.append(e) schema = Schema.from_dict(self.readable_fields)() return schema.dump(ret)