Пример #1
0
    def __init__(
        self,
        api_spec_path: Optional[str] = None,
        server: Optional[str] = None,
        logger: logging.Logger = _default_logger,
    ):
        """
        Initialize the API spec.

        :param api_spec_path: Directory API path and filename of the API spec YAML source file.
        """
        self._validator = None  # type: Optional[RequestValidator]
        self.logger = logger
        if api_spec_path is not None:
            try:
                api_spec_dict = read_yaml_file(api_spec_path)
                if server is not None:
                    api_spec_dict["servers"] = [{"url": server}]
                api_spec = create_spec(api_spec_dict)
                self._validator = RequestValidator(api_spec)
            except OpenAPIValidationError as e:  # pragma: nocover
                self.logger.error(
                    f"API specification YAML source file not correctly formatted: {str(e)}"
                )
            except Exception:
                self.logger.exception(
                    "API specification YAML source file not correctly formatted."
                )
                raise
Пример #2
0
    def register() -> None:
        settings = config.registry.settings.get(apiname)
        if settings and settings.get("spec") is not None:
            raise ConfigurationError(
                "Spec has already been configured. You may only call "
                "pyramid_openapi3_spec or pyramid_openapi3_spec_directory once"
            )

        if hupper.is_active():  # pragma: no cover
            hupper.get_reloader().watch_files([filepath])
        spec_dict = read_yaml_file(filepath)

        validate_spec(spec_dict)
        spec = create_spec(spec_dict)

        def spec_view(request: Request) -> FileResponse:
            return FileResponse(filepath, request=request, content_type="text/yaml")

        config.add_route(route_name, route)
        config.add_view(route_name=route_name, permission=permission, view=spec_view)

        custom_formatters = config.registry.settings.get("pyramid_openapi3_formatters")

        config.registry.settings[apiname] = {
            "filepath": filepath,
            "spec_route_name": route_name,
            "spec": spec,
            "request_validator": RequestValidator(
                spec, custom_formatters=custom_formatters
            ),
            "response_validator": ResponseValidator(
                spec, custom_formatters=custom_formatters
            ),
        }
        APIS.append(apiname)
Пример #3
0
    def register() -> None:
        if hupper.is_active():  # pragma: no cover
            hupper.get_reloader().watch_files([filepath])
        spec_dict = read_yaml_file(filepath)

        validate_spec(spec_dict)
        spec = create_spec(spec_dict)

        def spec_view(request: Request) -> FileResponse:
            return FileResponse(filepath,
                                request=request,
                                content_type="text/yaml")

        config.add_route(route_name, route)
        config.add_view(route_name=route_name, view=spec_view)

        custom_formatters = config.registry.settings.get(
            "pyramid_openapi3_formatters")

        config.registry.settings["pyramid_openapi3"] = {
            "filepath": filepath,
            "spec_route_name": route_name,
            "spec": spec,
            "request_validator": RequestValidator(spec, custom_formatters),
            "response_validator": ResponseValidator(spec, custom_formatters),
        }
Пример #4
0
    def register() -> None:
        settings = config.registry.settings.get(apiname)
        if settings and settings.get("spec") is not None:
            raise ConfigurationError(
                "Spec has already been configured. You may only call "
                "pyramid_openapi3_spec or pyramid_openapi3_spec_directory once"
            )
        if route.endswith((".yaml", ".yml", ".json")):
            raise ConfigurationError(
                "Having route be a filename is not allowed when using a spec directory"
            )

        path = Path(filepath).resolve()
        if hupper.is_active():  # pragma: no cover
            hupper.get_reloader().watch_files(list(path.parent.iterdir()))

        spec_dict = read_yaml_file(path)
        spec_url = path.as_uri()
        validate_spec(spec_dict, spec_url=spec_url)
        spec = create_spec(spec_dict, spec_url=spec_url)

        config.add_static_view(route, str(path.parent), permission=permission)
        config.add_route(route_name, f"{route}/{path.name}")

        custom_formatters = config.registry.settings.get(
            "pyramid_openapi3_formatters")
        custom_deserializers = config.registry.settings.get(
            "pyramid_openapi3_deserializers")

        config.registry.settings[apiname] = {
            "filepath":
            filepath,
            "spec_route_name":
            route_name,
            "spec":
            spec,
            "request_validator":
            RequestValidator(
                spec,
                custom_formatters=custom_formatters,
                custom_media_type_deserializers=custom_deserializers,
            ),
            "response_validator":
            ResponseValidator(
                spec,
                custom_formatters=custom_formatters,
                custom_media_type_deserializers=custom_deserializers,
            ),
        }
        config.registry.settings.setdefault("pyramid_openapi3_apinames",
                                            []).append(apiname)
Пример #5
0
def main():
    global app
    specfile = "./apis/api.yaml"
    specurl = "file://" + abspath(specfile)
    specdict = read_yaml_file(specfile)
    openapi_spec = create_spec(specdict, spec_url=specurl)

    openapi_middleware = FalconOpenAPIMiddleware.from_spec(openapi_spec)

    app = API(middleware=[openapi_middleware])

    auth_server = Auth()
    user_server = User()

    app.add_route('/user', user_server)
    app.add_route('/token', auth_server)
Пример #6
0
    def __init__(
        self, api_spec_path: Optional[str] = None, server: Optional[str] = None
    ):
        """
        Initialize the API spec.

        :param api_spec_path: Directory API path and filename of the API spec YAML source file.
        """
        self._validator = None  # type: Optional[RequestValidator]
        if api_spec_path is not None:
            try:
                api_spec_dict = read_yaml_file(api_spec_path)
                if server is not None:
                    api_spec_dict["servers"] = [{"url": server}]
                api_spec = create_spec(api_spec_dict)
                self._validator = RequestValidator(api_spec)
            except Exception:
                logger.error(
                    "API specification YAML source file not correctly formatted."
                )
Пример #7
0
    def register() -> None:
        spec_dict = read_yaml_file(filepath)

        validate_spec(spec_dict)
        spec = create_spec(spec_dict)

        def spec_view(request: Request) -> FileResponse:
            return FileResponse(filepath, request=request, content_type="text/yaml")

        config.add_route(route_name, route)
        config.add_view(route_name=route_name, view=spec_view)

        custom_formatters = config.registry.settings.get("pyramid_openapi3_formatters")

        config.registry.settings["pyramid_openapi3"] = {
            "filepath": filepath,
            "spec_route_name": route_name,
            "spec": spec,
            "request_validator": RequestValidator(spec, custom_formatters),
            "response_validator": ResponseValidator(spec, custom_formatters),
        }
Пример #8
0
    def register():
        spec_dict = read_yaml_file(filepath)

        validate_spec(spec_dict)
        spec = create_spec(spec_dict)

        def spec_view(request):
            return FileResponse(
                filepath,
                request=request,
                content_type='text/yaml'
            )
        config.add_view(route_name=route_name, view=spec_view)
        config.add_route(route_name, route)

        custom_formatters = config.registry.settings.get('pyramid_openapi3_formatters')

        config.registry.settings['pyramid_openapi3'] = {
           "filepath": filepath,
           "spec_route_name": route_name,
           "spec": spec,
           "request_validator": RequestValidator(spec, custom_formatters),
           "response_validator": ResponseValidator(spec, custom_formatters),
        }
Пример #9
0
def spec_from_file(spec_file):
    directory = path.abspath(path.dirname(__file__))
    path_full = path.join(directory, spec_file)
    return read_yaml_file(path_full)
Пример #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,
    })