Exemplo n.º 1
0
    def get_parameter_type(self, parameter: Dict[str, Union[str, Dict[str,
                                                                      Any]]],
                           snake_case: bool) -> Argument:
        ref: Optional[str] = parameter.get('$ref')  # type: ignore
        if ref:
            parameter = get_ref_body(ref, self.openapi_model_parser,
                                     self.components)
        name: str = parameter["name"]  # type: ignore
        orig_name = name
        if snake_case:
            name = stringcase.snakecase(name)
        content = parameter.get('content')
        schema: Optional[JsonSchemaObject] = None
        if content and isinstance(content, dict):
            content_schema = [
                c.get("schema") for c in content.values()
                if isinstance(c.get("schema"), dict)
            ]
            if content_schema:
                schema = JsonSchemaObject.parse_obj(content_schema[0])
        if not schema:
            schema = JsonSchemaObject.parse_obj(parameter["schema"])

        field = DataModelField(
            name=name,
            data_type=self.get_data_type(schema, 'parameter'),
            required=parameter.get("required")
            or parameter.get("in") == "path",
        )
        self.imports.extend(field.imports)
        if orig_name != name:
            has_in = parameter.get('in')
            if has_in and isinstance(has_in, str):
                param_is = has_in.lower().capitalize()
                self.imports.append(Import(from_='fastapi', import_=param_is))
                default: Optional[
                    str] = f"{param_is}({'...' if field.required else repr(schema.default)}, alias='{orig_name}')"
            else:
                # https://github.com/OAI/OpenAPI-Specification/blob/main/versions/3.0.3.md#parameterObject
                # the spec says 'in' is a str type
                raise TypeError(
                    f'Issue processing parameter for "in", expected a str, but got something else: {str(parameter)}'
                )
        else:
            default = repr(schema.default) if schema.has_default else None
        return Argument(
            name=field.name,
            type_hint=field.type_hint,
            default=default,  # type: ignore
            default_value=schema.default,
            required=field.required,
        )
def test_json_schema_object_ref_url_json(mocker):
    parser = JsonSchemaParser('')
    obj = JsonSchemaObject.parse_obj(
        {'$ref': 'https://example.com/person.schema.json#/definitions/User'})
    mock_get = mocker.patch('httpx.get')
    mock_get.return_value.text = json.dumps(
        {
            "$id": "https://example.com/person.schema.json",
            "$schema": "http://json-schema.org/draft-07/schema#",
            "definitions": {
                "User": {
                    "type": "object",
                    "properties": {
                        "name": {
                            "type": "string",
                        }
                    },
                }
            },
        }, )

    parser.parse_ref(obj, ['Model'])
    assert (dump_templates(list(parser.results)) == '''class User(BaseModel):
    name: Optional[str] = None''')
    parser.parse_ref(obj, ['Model'])
    mock_get.assert_has_calls([
        call('https://example.com/person.schema.json'),
    ])
Exemplo n.º 3
0
    def get_parameter_type(
        self, parameter: Dict[str, Union[str, Dict[str, str]]], snake_case: bool
    ) -> Argument:
        schema: JsonSchemaObject = JsonSchemaObject.parse_obj(parameter["schema"])
        format_ = schema.format or "default"
        type_ = json_schema_data_formats[schema.type][format_]
        name: str = parameter["name"]  # type: ignore
        orig_name = name
        if snake_case:
            name = stringcase.snakecase(name)

        field = DataModelField(
            name=name,
            data_type=type_map[type_],
            required=parameter.get("required") or parameter.get("in") == "path",
        )
        self.imports.extend(field.imports)
        if orig_name != name:
            default: Optional[
                str
            ] = f"Query({'...' if field.required else repr(schema.default)}, alias='{orig_name}')"
            self.imports.append(Import(from_='fastapi', import_='Query'))
        else:
            default = repr(schema.default) if 'default' in parameter["schema"] else None
        return Argument(
            name=field.name,
            type_hint=field.type_hint,
            default=default,  # type: ignore
            default_value=schema.default,
            required=field.required,
        )
Exemplo n.º 4
0
    def response_objects(self) -> List[Response]:
        responses: List[Response] = []
        for status_code, detail in self.responses.items():
            ref: Optional[str] = detail.get('$ref')
            if ref and ref.startswith('#/components/'):
                content: Dict[str, Any] = get_model_by_path(
                    self.components, ref[13:].split('/')
                ).get("content", {})
            else:
                content = detail.get("content", {})
            contents = {}
            for content_type, obj in content.items():
                contents[content_type] = (
                    JsonSchemaObject.parse_obj(obj["schema"])
                    if "schema" in obj
                    else None
                )

            responses.append(
                Response(
                    status_code=status_code,
                    description=detail.get("description"),
                    contents=contents,
                )
            )
        return responses
Exemplo n.º 5
0
def test_parse_any_root_object(source_obj, generated_classes):
    parser = JsonSchemaParser(BaseModel,
                              CustomRootType,
                              data_model_field_type=DataModelField)
    parser.parse_root_type('AnyObject', JsonSchemaObject.parse_obj(source_obj),
                           [])
    assert dump_templates(list(parser.results)) == generated_classes
Exemplo n.º 6
0
    def response_objects(self) -> List[Response]:
        responses: List[Response] = []
        for status_code, detail in self.responses.items():
            ref: Optional[str] = detail.get('$ref')
            if ref:
                ref_body = get_ref_body(ref, self.openapi_model_parser, self.components)
                content = ref_body.get("content", {})
                description = ref_body.get("description")
            else:
                content = detail.get("content", {})
                description = detail.get("description")
            contents = {}
            for content_type, obj in content.items():
                contents[content_type] = (
                    JsonSchemaObject.parse_obj(obj["schema"])
                    if "schema" in obj
                    else None
                )

            responses.append(
                Response(
                    status_code=status_code, description=description, contents=contents,
                )
            )
        return responses
Exemplo n.º 7
0
    def get_parameter_type(
        self, parameter: Dict[str, Union[str, Dict[str, str]]], snake_case: bool
    ) -> Argument:
        ref: Optional[str] = parameter.get('$ref')  # type: ignore
        if ref:
            parameter = get_ref_body(ref, self.openapi_model_parser, self.components)
        name: str = parameter["name"]  # type: ignore
        orig_name = name
        if snake_case:
            name = stringcase.snakecase(name)
        schema: JsonSchemaObject = JsonSchemaObject.parse_obj(parameter["schema"])

        field = DataModelField(
            name=name,
            data_type=self.get_data_type(schema),
            required=parameter.get("required") or parameter.get("in") == "path",
        )
        self.imports.extend(field.imports)
        if orig_name != name:
            default: Optional[
                str
            ] = f"Query({'...' if field.required else repr(schema.default)}, alias='{orig_name}')"
            self.imports.append(Import(from_='fastapi', import_='Query'))
        else:
            default = repr(schema.default) if 'default' in parameter["schema"] else None
        return Argument(
            name=field.name,
            type_hint=field.type_hint,
            default=default,  # type: ignore
            default_value=schema.default,
            required=field.required,
        )
def test_json_schema_object_ref_url():
    parser = JsonSchemaParser(BaseModel,
                              CustomRootType,
                              data_model_field_type=DataModelField)
    obj = JsonSchemaObject.parse_obj({'$ref': 'https://example.org'})
    with pytest.raises(NotImplementedError):
        parser.parse_ref(obj)
def test_json_schema_object_cached_ref_url_yaml(mocker):
    parser = JsonSchemaParser('')

    obj = JsonSchemaObject.parse_obj({
        'type': 'object',
        'properties': {
            'pet': {
                '$ref': 'https://example.org/schema.yaml#/definitions/Pet'
            },
            'user': {
                '$ref': 'https://example.org/schema.yaml#/definitions/User'
            },
        },
    })
    mock_get = mocker.patch('httpx.get')
    mock_get.return_value.text = yaml.safe_dump(
        json.load((DATA_PATH / 'user.json').open()))

    parser.parse_ref(obj, [])
    assert (dump_templates(list(parser.results)) == '''class Pet(BaseModel):
    name: Optional[str] = Field(None, examples=['dog', 'cat'])


class User(BaseModel):
    name: Optional[str] = Field(None, example='ken')''')
    mock_get.assert_called_once_with('https://example.org/schema.yaml', )
def test_parse_object(source_obj, generated_classes):
    parser = JsonSchemaParser(
        data_model_field_type=DataModelFieldBase,
        source='',
    )
    parser.parse_object('Person', JsonSchemaObject.parse_obj(source_obj), [])
    assert dump_templates(list(parser.results)) == generated_classes
Exemplo n.º 11
0
    def get_parameter_type(
        self, parameter: Dict[str, Union[str, Dict[str, Any]]], snake_case: bool
    ) -> Argument:
        ref: Optional[str] = parameter.get('$ref')  # type: ignore
        if ref:
            parameter = get_ref_body(ref, self.openapi_model_parser, self.components)
        name: str = parameter["name"]  # type: ignore
        orig_name = name
        if snake_case:
            name = stringcase.snakecase(name)
        content = parameter.get('content')
        schema: Optional[JsonSchemaObject] = None
        if content and isinstance(content, dict):
            content_schema = [
                c.get("schema")
                for c in content.values()
                if isinstance(c.get("schema"), dict)
            ]
            if content_schema:
                schema = JsonSchemaObject.parse_obj(content_schema[0])
        if not schema:
            schema = JsonSchemaObject.parse_obj(parameter["schema"])

        field = DataModelField(
            name=name,
            data_type=self.get_data_type(schema, 'parameter'),
            required=parameter.get("required") or parameter.get("in") == "path",
        )
        self.imports.extend(field.imports)
        if orig_name != name:
            default: Optional[
                str
            ] = f"Query({'...' if field.required else repr(schema.default)}, alias='{orig_name}')"
            self.imports.append(Import(from_='fastapi', import_='Query'))
        else:
            default = repr(schema.default) if schema.has_default else None
        return Argument(
            name=field.name,
            type_hint=field.type_hint,
            default=default,  # type: ignore
            default_value=schema.default,
            required=field.required,
        )
Exemplo n.º 12
0
    def get_parameter_type(
        self,
        parameters: ParameterObject,
        snake_case: bool,
        path: List[str],
    ) -> Optional[Argument]:
        orig_name = parameters.name
        if snake_case:
            name = stringcase.snakecase(parameters.name)
        else:
            name = parameters.name

        schema: Optional[JsonSchemaObject] = None
        data_type: Optional[DataType] = None
        for content in parameters.content.values():
            if isinstance(content.schema_, ReferenceObject):
                data_type = self.get_ref_data_type(content.schema_.ref)
                ref_model = self.get_ref_model(content.schema_.ref)
                schema = JsonSchemaObject.parse_obj(ref_model)
            else:
                schema = content.schema_
            break
        if not data_type:
            if not schema:
                schema = parameters.schema_
            data_type = self.parse_schema(name, schema, [*path, name])
        if not schema:
            return None

        field = DataModelField(
            name=name,
            data_type=data_type,
            required=parameters.required
            or parameters.in_ == ParameterLocation.path,
        )

        if orig_name != name:
            if parameters.in_:
                param_is = parameters.in_.value.lower().capitalize()
                self.imports_for_fastapi.append(
                    Import(from_='fastapi', import_=param_is))
                default: Optional[
                    str] = f"{param_is}({'...' if field.required else repr(schema.default)}, alias='{orig_name}')"
        else:
            default = repr(schema.default) if schema.has_default else None
        self.imports_for_fastapi.append(field.imports)
        self.data_types.append(field.data_type)
        return Argument(
            name=field.name,
            type_hint=field.type_hint,
            default=default,  # type: ignore
            default_value=schema.default,
            required=field.required,
        )
Exemplo n.º 13
0
 def request_objects(self) -> List[Request]:
     requests: List[Request] = []
     contents: Dict[str, JsonSchemaObject] = {}
     for content_type, obj in self.requestBody.get('content', {}).items():
         contents[content_type] = (JsonSchemaObject.parse_obj(obj['schema'])
                                   if 'schema' in obj else None)
         requests.append(
             Request(
                 description=self.requestBody.get("description"),
                 contents=contents,
                 required=self.requestBody.get("required") is True,
             ))
     return requests
Exemplo n.º 14
0
    def response_objects(self) -> List[Response]:
        responses: List[Response] = []
        for status_code, detail in self.responses.items():
            contents = {}
            for content_type, obj in detail.get("content", {}).items():
                contents[content_type] = (JsonSchemaObject.parse_obj(
                    obj["schema"]) if "schema" in obj else None)

            responses.append(
                Response(
                    status_code=status_code,
                    description=detail.get("description"),
                    contents=contents,
                ))
        return responses
Exemplo n.º 15
0
def test_json_schema_object_ref_url_yaml(mocker):
    parser = JsonSchemaParser(BaseModel,
                              CustomRootType,
                              data_model_field_type=DataModelField)
    obj = JsonSchemaObject.parse_obj(
        {'$ref': 'https://example.org/schema.yaml#/definitions/User'})
    mock_get = mocker.patch('httpx.get')
    mock_get.return_value.text = yaml.safe_dump(
        json.load((DATA_PATH / 'user.json').open()))

    parser.parse_ref(obj, ['User'])
    assert (dump_templates(list(parser.results)) == '''class User(BaseModel):
    name: Optional[str] = None''')
    parser.parse_ref(obj, [])
    mock_get.assert_called_once_with('https://example.org/schema.yaml', )
Exemplo n.º 16
0
 def request_objects(self) -> List[Request]:
     requests: List[Request] = []
     contents: Dict[str, JsonSchemaObject] = {}
     ref: Optional[str] = self.requestBody.get('$ref')
     if ref:
         request_body = get_ref_body(ref, self.openapi_model_parser,
                                     self.components)
     else:
         request_body = self.requestBody
     for content_type, obj in request_body.get('content', {}).items():
         contents[content_type] = (JsonSchemaObject.parse_obj(obj['schema'])
                                   if 'schema' in obj else None)
         requests.append(
             Request(
                 description=request_body.get("description"),
                 contents=contents,
                 required=request_body.get("required") is True,
             ))
     return requests
def test_parse_root_type(source_obj, generated_classes):
    parser = OpenAPIParser('')
    parser.parse_root_type('Name', JsonSchemaObject.parse_obj(source_obj), [])
    assert dump_templates(list(parser.results)) == generated_classes
def test_parse_array(source_obj, generated_classes):
    parser = OpenAPIParser('')
    parser.parse_array('Pets', JsonSchemaObject.parse_obj(source_obj), [])
    assert dump_templates(list(parser.results)) == generated_classes
Exemplo n.º 19
0
def test_parse_object(source_obj, generated_classes):
    parser = OpenAPIParser(BaseModel, CustomRootType)
    parser.parse_object('Pets', JsonSchemaObject.parse_obj(source_obj), [])
    assert dump_templates(list(parser.results)) == generated_classes
Exemplo n.º 20
0
def test_parse_root_type(source_obj, generated_classes):
    parser = OpenAPIParser(BaseModel, CustomRootType)
    parsed_templates = parser.parse_root_type(
        'Name', JsonSchemaObject.parse_obj(source_obj))
    assert dump_templates(list(parsed_templates)) == generated_classes
def test_parse_any_root_object(source_obj, generated_classes):
    parser = JsonSchemaParser('')
    parser.parse_root_type('AnyObject', JsonSchemaObject.parse_obj(source_obj),
                           [])
    assert dump_templates(list(parser.results)) == generated_classes