def iter_schemas(marshmallow_schema): """ Build zero or more JSON schemas for a marshmallow schema. Generates: name, schema pairs. """ if not marshmallow_schema: return base_schema = build_schema(marshmallow_schema) base_schema_name = type_name(name_for(marshmallow_schema)) yield base_schema_name, base_schema for name, field in iter_fields(marshmallow_schema): if isinstance(field, fields.Nested): nested_schema = build_schema(field.schema) nested_schema_name = type_name(name_for(field.schema)) yield nested_schema_name, nested_schema for subname, subfield in iter_schemas(field.schema): yield subname, subfield if isinstance(field, fields.List) and isinstance( field.container, fields.Nested): nested_schema = build_schema(field.container.schema) nested_schema_name = type_name(name_for(field.container.schema)) yield nested_schema_name, nested_schema for subname, subfield in iter_schemas(field.container.schema): yield subname, subfield
def build_parameter(field): """ Build a parameter from a marshmallow field. See: https://github.com/marshmallow-code/apispec/blob/dev/apispec/ext/marshmallow/swagger.py#L81 """ if hasattr(field, SWAGGER_TYPE): parameter = resolve_tagged_field(field) elif getattr(field, "enum", None): parameter = resolve_enum_field(field) elif getattr(field, 'as_string', None): parameter = resolve_numeric_string_field(field) elif isinstance(field, TimestampField): parameter = resolve_timestamp_field(field) else: parameter = resolve_default_for_field(field) if field.metadata.get("description"): parameter["description"] = field.metadata["description"] if field.default: parameter["default"] = field.default # nested if isinstance(field, fields.Nested): parameter["$ref"] = "#/definitions/{}".format( type_name(name_for(field.schema))) # arrays if isinstance(field, fields.List): parameter["items"] = build_parameter(field.container) return parameter
def add_responses(swagger_operation, operation, ns, func): """ Add responses to an operation. """ # default error swagger_operation.responses["default"] = build_response( description="An error occcurred", resource=type_name(name_for(ErrorSchema())), ) if getattr(func, "__doc__", None): description = func.__doc__.strip().splitlines()[0] else: description = "{} {}".format(operation.value.name, ns.subject_name) # resource request request_resource = get_request_schema(func) if isinstance(request_resource, string_types): if not hasattr(swagger_operation, "consumes"): swagger_operation.consumes = [] swagger_operation.consumes.append(request_resource) # resources response response_resource = get_response_schema(func) if isinstance(response_resource, string_types): if not hasattr(swagger_operation, "produces"): swagger_operation.produces = [] swagger_operation.produces.append(response_resource) else: swagger_operation.responses[str(operation.value.default_code)] = build_response( description=description, resource=response_resource, )
def parse_ref(self, field: Field) -> str: """ Parse the reference type for nested fields, if any. """ ref_name = type_name(name_for(field.schema)) return f"#/definitions/{ref_name}"
def body_param(schema): return swagger.BodyParameter(**{ "name": "body", "in": "body", "schema": swagger.JsonReference({ "$ref": "#/definitions/{}".format(type_name(name_for(schema))), }), })
def body_param(schema): return swagger.BodyParameter(**{ "name": "body", "in": "body", "schema": swagger.JsonReference({ "$ref": "#/definitions/{}".format(type_name(name_for(schema))), }), })
def build_parameter(field): """ Build a parameter from a marshmallow field. See: https://github.com/marshmallow-code/apispec/blob/dev/apispec/ext/marshmallow/swagger.py#L81 """ try: field_type, field_format = FIELD_MAPPINGS[type(field)] except KeyError: if hasattr(field, SWAGGER_TYPE): field_type = getattr(field, SWAGGER_TYPE) field_format = getattr(field, SWAGGER_FORMAT, None) else: logger.exception( "No mapped swagger type for marshmallow field: {}".format( field, )) raise parameter = {} if field_type: parameter["type"] = field_type if field.metadata.get("description"): parameter["description"] = field.metadata["description"] if field_format: parameter["format"] = field_format if field.default: parameter["default"] = field.default # enums enum = getattr(field, "enum", None) if enum: enum_values = [ choice.value if field.by_value else choice.name for choice in enum ] if all((isinstance(enum_value, string_types) for enum_value in enum_values)): enum_type = "string" elif all((is_int(enum_value) for enum_value in enum_values)): enum_type = "integer" else: raise Exception("Cannot infer enum type for field: {}".format( field.name)) parameter["type"] = enum_type parameter["enum"] = enum_values # nested if isinstance(field, fields.Nested): parameter["$ref"] = "#/definitions/{}".format( type_name(name_for(field.schema))) # arrays if isinstance(field, fields.List): parameter["items"] = build_parameter(field.container) return parameter
def build_response(description, resource=None): """ Build a response definition. """ response = swagger.Response(description=description, ) if resource is not None: response.schema = swagger.JsonReference({ "$ref": "#/definitions/{}".format(type_name(name_for(resource))), }) return response
def build_response(description, resource=None): """ Build a response definition. """ response = swagger.Response( description=description, ) if resource is not None: response.schema = swagger.JsonReference({ "$ref": "#/definitions/{}".format(type_name(name_for(resource))), }) return response
def add_responses(swagger_operation, operation, ns, func): """ Add responses to an operation. """ # default error swagger_operation.responses["default"] = build_response( description="An error occurred", resource=type_name(name_for(ErrorSchema())), ) if getattr(func, "__doc__", None): description = func.__doc__.strip().splitlines()[0] else: description = "{} {}".format(operation.value.name, ns.subject_name) if operation in (Operation.Upload, Operation.UploadFor): swagger_operation.consumes = [ "multipart/form-data" ] # resource request request_resource = get_request_schema(func) if isinstance(request_resource, str): if not hasattr(swagger_operation, "consumes"): swagger_operation.consumes = [] swagger_operation.consumes.append(request_resource) # resources response response_resource = get_response_schema(func) if isinstance(response_resource, str): if not hasattr(swagger_operation, "produces"): swagger_operation.produces = [] swagger_operation.produces.append(response_resource) elif not response_resource: response_code = ( 204 if operation.value.default_code == 200 else operation.value.default_code ) swagger_operation.responses[str(response_code)] = build_response( description=description, ) else: swagger_operation.responses[str(operation.value.default_code)] = build_response( description=description, resource=response_resource, )
def to_tuple(self, schema: Schema) -> Tuple[str, Any]: return type_name(name_for(schema)), self.build(schema)
def to_tuple(self, schema: Schema) -> Tuple[str, Any]: return type_name(name_for(schema)), self.build(schema)
def test_type_name_for_schema(): name = type_name("foo_bar_schema") assert_that(name, is_(equal_to("FooBar")))
def test_type_name_is_camel_case(): name = type_name("foo_bar") assert_that(name, is_(equal_to("FooBar")))
def definition_name_for_schema(schema_cls): return type_name(name_for(schema_cls))