Exemple #1
0
def test_get_employees_200_response_yaml():
    with open("examples/employees.yaml") as f:
        response = f.read()
    oapi = build_openapi("GET", "/employees", "200", response=response)
    spec_dict, spec_url = read_from_filename(
        "tests/test_get_employees_200_response.yaml")
    assert oapi == spec_dict
Exemple #2
0
 def test_open_api_tag(self):
     spec = get_spec(
         'test api',
         camel_case=True,
         default_response_descriptions={
             HTTPStatus.INTERNAL_SERVER_ERROR:
             'Unexpected internal server error.',
             HTTPStatus.NO_CONTENT:
             'Operation succeeded. Nothing to return.',
             HTTPStatus.NOT_FOUND: 'Could not find data.',
             HTTPStatus.CREATED: 'Resource was created successfully.',
             HTTPStatus.BAD_REQUEST: 'Invalid input data.',
             HTTPStatus.OK: 'Success.'
         },
         default_parameter_descriptions={
             'skip':
             'The number of data records to skip before fetching a page.',
             'take':
             'Number of records to return. Use value -1 to get all data.',
             'sortColumn':
             'The database field to sort by. Use python_syntax for the field name.',
             'sortDirection': 'The direction to sort by (asc or desc).',
             'createdAt':
             'Filter on the creation date. Use an exact date, or a date range e.g. \'[2018-01-01,2019-01-01[\', \']2018-01-01,\' or \'2015-01-01\'',
             'modifiedAt':
             'Filter on the last modification date. Use an exact date, or a date range e.g. \'[2018-01-01,2019-01-01[\', \']2018-01-01,\' or \'2015-01-01\'',
             'ids': 'Ids to match.'
         })
     self.assertEqual(spec['openapi'], '3.0.0')
     os.makedirs('./temp', exist_ok=True)
     spec_file = './temp/openapi.json'
     with open(spec_file, 'w') as file:
         file.write(json.dumps(spec, indent=4))
         spec_dict, spec_url = read_from_filename(spec_file)
         validate_spec(spec_dict)
Exemple #3
0
def test_get_employees_200_info():
    oapi = build_openapi("GET",
                         "/employees",
                         "200",
                         title="Custom Title",
                         version="v1-custom")
    spec_dict, spec_url = read_from_filename(
        "tests/test_get_employees_200_info.yaml")
    assert oapi == spec_dict
Exemple #4
0
def load_spec():
    """Validate openapi spec."""
    napp_dir = Path(__file__).parent
    yml_file = napp_dir / "openapi.yml"
    spec_dict, _ = read_from_filename(yml_file)

    validate_spec(spec_dict)

    return create_spec(spec_dict)
Exemple #5
0
def test_get_employees_200_params():
    oapi = build_openapi(
        "GET",
        "/employees",
        "200",
        parameters=[("id", "path"), ("limit", "query"), ("token", "header")],
    )
    spec_dict, spec_url = read_from_filename(
        "tests/test_get_employees_200_params.yaml")
    assert oapi == spec_dict
Exemple #6
0
def test_post_employees_201_request_response():
    with open("examples/new_employee_req.json") as f:
        request = f.read()
    with open("examples/new_employee_resp.json") as f:
        response = f.read()
    oapi = build_openapi("POST",
                         "/employees",
                         "201",
                         request=request,
                         response=response)
    spec_dict, spec_url = read_from_filename(
        "tests/test_post_employees_201_request_response.yaml")
    assert oapi == spec_dict
Exemple #7
0
def test_get_employees_200_response_mediatype():
    with open("examples/employees.json") as f:
        response = f.read()
    oapi = build_openapi(
        "GET",
        "/employees",
        "200",
        response=response,
        media_type="application/yaml",
    )
    spec_dict, spec_url = read_from_filename(
        "tests/test_get_employees_200_response_mediatype.yaml")
    assert oapi == spec_dict
Exemple #8
0
 def __init__(self, path: str):
     self.path = path
     self.body, self.url = read_from_filename(path)
     self.ref_resolver = RefResolver.from_schema(self.body)
Exemple #9
0
def test_get_employees_200():
    oapi = build_openapi("GET", "/employees", "200")
    spec_dict, spec_url = read_from_filename(
        "tests/test_get_employees_200.yaml")
    assert oapi == spec_dict
Exemple #10
0
def ChillApi(app: Flask = None,
             config_file: str = _CONFIG_FILE,
             export_path: str = f"{CWD}/var"):
    """ChillApi Loader.

    :param app: param config_file:
    :param export_path:
    :param app: Flask:  (Default value = None)
    :param config_file: str:  (Default value = _CONFIG_FILE)
    :param export_path: str:  (Default value = f"{CWD}/var")

    """
    if not os.path.exists(export_path):
        os.makedirs(export_path)
    SCHEMA_CONFIG_FILE = os.path.realpath(
        f"{pathlib.Path(__file__).parent.absolute()}/api.schema.json")
    api_config = read_yaml(config_file)
    api_schema = json.load(open(SCHEMA_CONFIG_FILE))

    try:
        validate(instance=api_config, schema=api_schema)
    except ValidationError as e:
        raise ConfigError(e)

    _app_name = api_config["app"]["name"]

    if app is None:
        app = Flask(_app_name)
        ApiConfig.reset()

    module_loader = ChillApiModuleLoader()

    set_api_security(api_config, module_loader)

    extensions = ChillApiExtensions(module_loader)
    config = ApiConfig(**{**api_config, **{"extensions": extensions}})
    db = config.db
    data_repository = config.repository

    api_manager = FlaskApiManager(config)

    register_error_handlers(app)
    app.config["BASE_DIR"] = CWD
    # app.config["SQLALCHEMY_DATABASE_URI"] = os.environ.get("__CHILLAPI_DB_DSN__")
    app.config["SECRET_KEY"] = os.environ.get("__CHILLAPI_APP_SECRET_KEY__")
    app.config["WTF_CSRF_ENABLED"] = False
    app.config["SQLALCHEMY_TRACK_MODIFICATIONS"] = True
    app.config["TRAP_HTTP_EXCEPTIONS"] = True
    app.config["TRAP_BAD_REQUEST_ERRORS"] = True
    app.config["REQUEST_ID_UNIQUE_VALUE_PREFIX"] = None
    CORS(app)
    RequestID(app)
    api = Api(
        app,
        security_level=api_config["app"]["security_level"]
        if "security_level" in api_config["app"] else "STANDARD",
        version=api_config["app"]["version"],
        api_spec_url=api_config["app"]["swagger_url"],
        security=api_config["app"]["security"]
        if "security" in api_config["app"] else None,
        license=api_config["app"]["license"]
        if "license" in api_config["app"] else None,
        contact=api_config["app"]["contact"]
        if "contact" in api_config["app"] else None,
        externalDocs=api_config["app"]["externalDocs"]
        if "externalDocs" in api_config["app"] else None,
        components={
            "securitySchemes":
            api_config["app"]["securitySchemes"]
            if "securitySchemes" in api_config["app"] else None
        },
    )

    api_doc.SwaggerUI(app,
                      title=_app_name,
                      doc=api_config["app"]["swagger_ui_url"],
                      config={"app_name":
                              _app_name})  # Swagger UI config overrides

    api_spec_file = f"{export_path}/api_spec.json"

    if not os.path.exists(api_spec_file):
        import requests

        url = "https://raw.githubusercontent.com/OAI/OpenAPI-Specification/main/schemas/v3.1/schema.yaml"  # noqa E501
        r = requests.get(url, allow_redirects=True)
        open(api_spec_file, "wb").write(r.content)

    path_full = api_spec_file
    schema_v3 = read_yaml_file(path_full)
    schema_v3_url = parse.urljoin("file:", request.pathname2url(path_full))

    openapi_v3_validator_factory = JSONSpecValidatorFactory(
        schema_v3,
        schema_v3_url,
        resolver_handlers=default_handlers,
    )

    openapi_v3_spec_validator = SpecValidator(
        openapi_v3_validator_factory,
        resolver_handlers=default_handlers,
    )

    simplejson.dump(api.get_swagger_doc(),
                    open(f"{export_path}/{_app_name}_swagger.json", "w"),
                    indent=2,
                    cls=CustomEncoder,
                    for_json=True)

    spec_dict, spec_url = read_from_filename(
        f"{export_path}/{_app_name}_swagger.json")

    # If no exception is raised by validate_spec(), the spec is valid.
    # do not stop the execution but show a critical
    errors_iterator = openapi_v3_spec_validator.iter_errors(spec_dict)
    for _ie, err in enumerate(errors_iterator):
        logger.critical(err)

    simplejson.dump(config.to_dict(),
                    open(f"{export_path}/{_app_name}_api.config.json", "w"),
                    indent=2,
                    cls=CustomEncoder,
                    for_json=True)

    api_manager.create_api(api)
    # register_audit_handler(app, extensions.get_extension("audit"))

    if api_config["app"]["debug"]:
        if not os.path.exists(f"{export_path}/profile"):
            os.makedirs(f"{export_path}/profile")
        from werkzeug.middleware.profiler import ProfilerMiddleware

        app.config["PROFILE"] = True
        app.config["DEBUG"] = True

        def filename_format(env):
            """

            :param env:

            """
            return "{uuid}.prof".format(uuid=env["HTTP_X_REQUEST_ID"])

        app.wsgi_app = ProfilerMiddleware(app.wsgi_app,
                                          restrictions=[30],
                                          profile_dir=f"{export_path}/profile",
                                          filename_format=filename_format)

        register_routes_sitemap(app)

    return AttributeDict({
        "app": app,
        "api": api,
        "api_manager": api_manager,
        "api_config": api_config,
        "db": db,
        "data_repository": data_repository,
        "module_loader": module_loader,
        "table_extensions": extensions,
    })
from typing import Any
from openapi_spec_validator.readers import read_from_filename
from jinja2 import Template

spec_dict, spec_url = read_from_filename('example-api.yaml')


def openapi_type_to_python(property: Any, quote: bool = True) -> str:
    if property.get('$ref') is not None:
        res = f"{property['$ref'].rsplit('/', maxsplit=1)[1]}"
        return f"'{res}'" if quote else res

    if property['type'] == 'string':
        return 'str'
    elif property['type'] == 'boolean':
        return 'bool'
    elif property['type'] == 'integer':
        return 'int'
    elif property['type'] == 'number':
        return 'float'
    elif property['type'] == 'array':
        return f'List[{openapi_type_to_python(property["items"])}]'
    else:
        return 'object'


with open('template.py', 'r+') as f:
    template = Template(f.read())
    template.globals[
        'openapi_type_to_python'] = openapi_type_to_python  # type: ignore