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
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)
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), }
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)
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)
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." )
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), }
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), }
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)
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, })