def test_response_primitive():
    expected_openapi_dict = {
        '200': {
            'description': 'Test Response',
            'content': {
                'application/json': {
                    'schema': {
                        'type': 'string'
                    }
                }
            }
        }
    }
    openapi_response = OpenApiResponse('Test Response', data_type=str)
    assert expected_openapi_dict == openapi_response.as_dict()
def test_path_with_request_body():
    expected_openapi_dict = {
        '/test_path': {
            'post': {
                'description': 'Test Description',
                'summary': 'Test Summary',
                'operationId': '[post]_/test_path',
                'requestBody': {
                    'content': {
                        'application/json': {
                            'schema': {
                                '$ref': '#/components/schemas/Marshmallow'
                            }
                        }
                    }
                },
                'responses': {
                    '200': {
                        'description': 'Test Response'
                    }
                },
                'parameters': [
                ]
            }
        }
    }
    openapi_path = OpenApiPath('/test_path',
                               'post',
                               [OpenApiResponse('Test Response')],
                               descr='Test Description',
                               summary='Test Summary',
                               request_body=MarshmallowSchema
                               )
    assert expected_openapi_dict == openapi_path.as_dict()
def test_response_object():
    expected_openapi_dict = {
        '200': {
            'description': 'Test Response',
            'content': {
                'application/json': {
                    'schema': {
                        '$ref': '#/components/schemas/DataclassObject'
                    }
                }
            }
        }
    }
    openapi_response = OpenApiResponse('Test Response',
                                       data_type=DataclassObject)
    assert expected_openapi_dict == openapi_response.as_dict()
def test_path_with_params():
    expected_openapi_dict = {
        '/test_path': {
            'get': {
                'description': 'Test Description',
                'summary': 'Test Summary',
                'operationId': '[get]_/test_path',
                'responses': {
                    '200': {
                        'description': 'Test Response'
                    }
                },
                'parameters': [
                    {
                        'required': True,
                        'schema': {
                            'title': 'Test_Param',
                            'type': 'string'
                        },
                        'name': 'test_param',
                        'in': 'query'
                    }
                ]
            }
        }
    }
    openapi_path = OpenApiPath('/test_path',
                               'get',
                               [OpenApiResponse('Test Response')],
                               [OpenApiParam('test_param', 'query', str)],
                               'Test Description',
                               'Test Summary'
                               )
    assert expected_openapi_dict == openapi_path.as_dict()
    def add_openapi_path(self, rule: str, methods: List[str],
                         view_func: Callable):
        '''Add a new OpenApi Path for each method. Inspects view_func's type hints to be able to determine
        the appropriate paramater types.

            Args:
                rule (str): HTTP Path that the view_func will be registered in Flask
                methods (List[str]): List of HTTP Methods this path can receive
                view_func (Callable): Function that is called when this HTTP path is invoked
        '''
        func_sig = get_func_sig(view_func)
        openapi_params = []
        body = None

        for param_name, param in func_sig['params'].items():
            if hasattr(param.annotation, '__marshmallow__'):
                body = param.annotation.__marshmallow__
            elif is_dataclass(param.annotation):
                body = param.annotation
            elif f'<{param_name}>' in re.findall('<.*?>', rule):
                openapi_params.append(
                    OpenApiParam(param_name,
                                 'path',
                                 data_type=param.annotation if param.annotation
                                 is not param.empty else str,
                                 default=param.default
                                 if param.default is not param.empty else None,
                                 required=param.default is param.empty))
            else:
                openapi_params.append(
                    OpenApiParam(param_name,
                                 'query',
                                 data_type=param.annotation if param.annotation
                                 is not param.empty else str,
                                 default=param.default
                                 if param.default is not param.empty else None,
                                 required=param.default is param.empty))

        response_type = func_sig['return'] if func_sig[
            'return'] is not func_sig['empty'] else str

        if hasattr(response_type, '__marshmallow__'):
            response_type = response_type.__marshmallow__

        openapi_response = OpenApiResponse('', data_type=response_type)

        for method in methods:
            self.openapi_paths.append(
                OpenApiPath(rule.replace('<', '{').replace('>', '}'),
                            method.lower(), [openapi_response],
                            openapi_params,
                            descr=func_sig['doc'],
                            request_body=body))
def test_path_no_params():
    expected_openapi_dict = {
        '/test_path': {
            'get': {
                'description': 'Test Description',
                'summary': 'Test Summary',
                'operationId': '[get]_/test_path',
                'responses': {
                    '200': {
                        'description': 'Test Response'
                    }
                },
                'parameters': [
                ]
            }
        }
    }
    openapi_path = OpenApiPath('/test_path',
                               'get',
                               [OpenApiResponse('Test Response')],
                               descr='Test Description',
                               summary='Test Summary'
                               )
    assert expected_openapi_dict == openapi_path.as_dict()
def test_response_empty():
    expected_openapi_dict = {'201': {'description': 'Test Empty Response'}}
    openapi_response = OpenApiResponse('Test Empty Response', '201')
    assert expected_openapi_dict == openapi_response.as_dict()
def test_openapi_with_dataclass():
    expected_openapi_dict = {
        'openapi': '3.0.2',
        'info': {
            'title': 'test_api',
            'version': '3.0.2'
        },
        'paths': {
            '/test_path': {
                'get': {
                    'description':
                    '',
                    'summary':
                    '',
                    'operationId':
                    '[get]_/test_path',
                    'responses': {
                        '200': {
                            'description': 'test_response',
                            'content': {
                                'application/json': {
                                    'schema': {
                                        '$ref':
                                        '#/components/schemas/DataclassNestedObject'
                                    }
                                }
                            }
                        }
                    },
                    'parameters': [{
                        'required': True,
                        'name': 'test_param',
                        'in': 'query',
                        'schema': {
                            'title': 'Test_Param',
                            'type': 'string'
                        }
                    }]
                }
            }
        },
        'components': {
            'schemas': {
                'DataclassObject': {
                    'title':
                    'DataclassObject',
                    'required': [
                        'str_field', 'int_field', 'float_field',
                        'boolean_field', 'list_field', 'date_field',
                        'datetime_field'
                    ],
                    'type':
                    'object',
                    'properties': {
                        'str_field': {
                            'type': 'string'
                        },
                        'int_field': {
                            'type': 'integer'
                        },
                        'float_field': {
                            'type': 'number'
                        },
                        'boolean_field': {
                            'type': 'boolean'
                        },
                        'list_field': {
                            'type': 'array',
                            'items': {}
                        },
                        'date_field': {
                            'type': 'string',
                            'format': 'date'
                        },
                        'datetime_field': {
                            'type': 'string',
                            'format': 'date-time'
                        },
                    }
                },
                'DataclassNestedObject': {
                    'title': 'DataclassNestedObject',
                    'required': ['str_field', 'nested_object'],
                    'type': 'object',
                    'properties': {
                        'str_field': {
                            'type': 'string'
                        },
                        'nested_object': {
                            '$ref': '#/components/schemas/DataclassObject'
                        }
                    }
                }
            }
        }
    }

    test_resp = OpenApiResponse('test_response',
                                data_type=DataclassNestedObject)
    test_param = OpenApiParam('test_param', 'query', data_type=str)
    test_path = OpenApiPath('/test_path', 'get', [test_resp], [test_param])
    test_api = OpenApi('test_api', [test_path])
    assert expected_openapi_dict == test_api.as_dict()
Beispiel #9
0
def test_openapi_with_marshmallow():
    expected_openapi_dict = {
        'openapi': '3.0.2',
        'info': {
            'title': 'test_api',
            'version': '3.0.2'
        },
        'security': [{
            'ApiKeyAuth': []
        }, {
            'BearerAuth': []
        }],
        'paths': {
            '/test_path': {
                'get': {
                    'description':
                    '',
                    'summary':
                    '',
                    'operationId':
                    '[get]_/test_path',
                    'responses': {
                        '200': {
                            'description': 'test_response',
                            'content': {
                                'application/json': {
                                    'schema': {
                                        '$ref':
                                        '#/components/schemas/Marshmallow'
                                    }
                                }
                            }
                        }
                    },
                    'parameters': [{
                        'required': True,
                        'name': 'test_param',
                        'in': 'query',
                        'schema': {
                            'title': 'Test_Param',
                            'type': 'string'
                        }
                    }]
                }
            }
        },
        'components': {
            'schemas': {
                'Marshmallow': {
                    'title': 'Marshmallow',
                    'required': ['str_field'],
                    'type': 'object',
                    'properties': {
                        'str_field': {
                            'type': 'string'
                        },
                        'int_field': {
                            'type': 'integer'
                        },
                        'float_field': {
                            'type': 'number'
                        },
                        'boolean_field': {
                            'type': 'boolean'
                        },
                        'list_field': {
                            'type': 'array',
                            'items': {
                                'type': 'string'
                            }
                        },
                        'date_field': {
                            'type': 'string',
                            'format': 'date'
                        },
                        'datetime_field': {
                            'type': 'string',
                            'format': 'date-time'
                        },
                    }
                }
            },
            'securitySchemes': {
                'ApiKeyAuth': {
                    'in': 'header',
                    'name': 'X-API-Key',
                    'type': 'apiKey'
                },
                'BearerAuth': {
                    'scheme': 'bearer',
                    'type': 'http'
                }
            }
        }
    }

    test_resp = OpenApiResponse('test_response', data_type=MarshmallowSchema)
    test_param = OpenApiParam('test_param', 'query', data_type=str)
    test_path = OpenApiPath('/test_path', 'get', [test_resp], [test_param])
    test_security = OpenApiSecurity(bearer_auth=BearerAuth(),
                                    api_key_auth=ApiKeyAuth())
    test_api = OpenApi('test_api', [test_path], security=test_security)
    print(test_api.as_dict())
    assert expected_openapi_dict == test_api.as_dict()