diff --git a/src/spaceone/core/command.py b/src/spaceone/core/command.py index c358e88..f5fa57c 100644 --- a/src/spaceone/core/command.py +++ b/src/spaceone/core/command.py @@ -13,7 +13,7 @@ from spaceone.core.opentelemetry import set_tracer, set_metric from spaceone.core.plugin.plugin_conf import PLUGIN_SOURCES -_GLOBAL_CONFIG_PATH = '{package}.conf.global_conf:global_conf' +_GLOBAL_CONFIG_PATH = "{package}.conf.global_conf:global_conf" @click.group() @@ -22,11 +22,16 @@ def cli(): @cli.command() -@click.argument('project_name') -@click.option('-d', '--directory', type=click.Path(), help='Project directory') -@click.option('-s', '--source', type=str, help=f'skeleton code of the plugin: [' - f'{"|".join(PLUGIN_SOURCES.keys())}] or ' - f'module path(e.g. spaceone.core.skeleton)]') +@click.argument("project_name") +@click.option("-d", "--directory", type=click.Path(), help="Project directory") +@click.option( + "-s", + "--source", + type=str, + help=f"skeleton code of the plugin: [" + f'{"|".join(PLUGIN_SOURCES.keys())}] or ' + f"module path(e.g. spaceone.core.skeleton)]", +) def create_project(project_name, directory=None, source=None): """Create a new project""" @@ -40,23 +45,72 @@ def run(): @run.command() -@click.argument('package') -@click.option('-a', '--app-path', type=str, - help='Python path of gRPC application [default: {package}.interface.grpc:app]') -@click.option('-s', '--source-root', type=click.Path(exists=True), default='.', - help='Path of source root', show_default=True) -@click.option('-p', '--port', type=int, default=os.environ.get('SPACEONE_PORT', 50051), - help='Port of gRPC server', show_default=True) -@click.option('-c', '--config-file', type=click.Path(exists=True), - default=os.environ.get('SPACEONE_CONFIG_FILE'), help='Path of config file') -@click.option('-m', '--module-path', type=click.Path(exists=True), multiple=True, - help='Additional python path') -def grpc_server(package, app_path=None, source_root=None, port=None, config_file=None, module_path=None): +@click.argument("package") +@click.option( + "-a", + "--app-path", + type=str, + help="Python path of gRPC application [default: {package}.interface.grpc:app]", +) +@click.option( + "-s", + "--source-root", + type=click.Path(exists=True), + default=".", + help="Path of source root", + show_default=True, +) +@click.option( + "-p", + "--port", + type=int, + default=os.environ.get("SPACEONE_PORT", 50051), + help="Port of gRPC server", + show_default=True, +) +@click.option( + "-w", + "--worker", + type=int, + default=os.environ.get("SPACEONE_WORKER", 100), + help="Worker of gRPC server", + show_default=True, +) +@click.option( + "-c", + "--config-file", + type=click.Path(exists=True), + default=os.environ.get("SPACEONE_CONFIG_FILE"), + help="Path of config file", +) +@click.option( + "-m", + "--module-path", + type=click.Path(exists=True), + multiple=True, + help="Additional python path", +) +def grpc_server( + package, + app_path=None, + source_root=None, + port=None, + worker=None, + config_file=None, + module_path=None, +): """Run a gRPC server""" # Initialize config - _set_server_config(package, source_root, port, config_file=config_file, grpc_app_path=app_path, - module_path=module_path) + _set_server_config( + package, + source_root, + port, + config_file=config_file, + grpc_app_path=app_path, + module_path=module_path, + worker=worker, + ) # Initialize common modules _init_common_modules() @@ -66,25 +120,72 @@ def grpc_server(package, app_path=None, source_root=None, port=None, config_file @run.command() -@click.argument('package') -@click.option('-a', '--app-path', type=str, - help='Python path of REST application [default: {package}.interface.rest:app]') -@click.option('-s', '--source-root', type=click.Path(exists=True), default='.', - help='Path of source root', show_default=True) -@click.option('-p', '--port', type=int, default=os.environ.get('SPACEONE_PORT', 8000), - help='Port of REST server', show_default=True) -@click.option('-h', '--host', type=str, default=os.environ.get('SPACEONE_HOST', '127.0.0.1'), - help='Host of REST server', show_default=True) -@click.option('-c', '--config-file', type=click.Path(exists=True), - default=os.environ.get('SPACEONE_CONFIG_FILE'), help='Path of config file') -@click.option('-m', '--module-path', type=click.Path(exists=True), multiple=True, - help='Additional python path') -def rest_server(package, app_path=None, source_root=None, port=None, host=None, config_file=None, module_path=None): +@click.argument("package") +@click.option( + "-a", + "--app-path", + type=str, + help="Python path of REST application [default: {package}.interface.rest:app]", +) +@click.option( + "-s", + "--source-root", + type=click.Path(exists=True), + default=".", + help="Path of source root", + show_default=True, +) +@click.option( + "-p", + "--port", + type=int, + default=os.environ.get("SPACEONE_PORT", 8000), + help="Port of REST server", + show_default=True, +) +@click.option( + "-h", + "--host", + type=str, + default=os.environ.get("SPACEONE_HOST", "127.0.0.1"), + help="Host of REST server", + show_default=True, +) +@click.option( + "-c", + "--config-file", + type=click.Path(exists=True), + default=os.environ.get("SPACEONE_CONFIG_FILE"), + help="Path of config file", +) +@click.option( + "-m", + "--module-path", + type=click.Path(exists=True), + multiple=True, + help="Additional python path", +) +def rest_server( + package, + app_path=None, + source_root=None, + port=None, + host=None, + config_file=None, + module_path=None, +): """Run a FastAPI REST server""" # Initialize config - _set_server_config(package, source_root, port, host=host, config_file=config_file, rest_app_path=app_path, - module_path=module_path) + _set_server_config( + package, + source_root, + port, + host=host, + config_file=config_file, + rest_app_path=app_path, + module_path=module_path, + ) # Initialize common modules _init_common_modules() @@ -94,18 +195,36 @@ def rest_server(package, app_path=None, source_root=None, port=None, host=None, @run.command() -@click.argument('package') -@click.option('-s', '--source-root', type=click.Path(exists=True), default='.', - help='Path of source root', show_default=True) -@click.option('-c', '--config-file', type=click.Path(exists=True), - default=os.environ.get('SPACEONE_CONFIG_FILE'), help='Path of config file') -@click.option('-m', '--module-path', type=click.Path(exists=True), multiple=True, - help='Additional python path') +@click.argument("package") +@click.option( + "-s", + "--source-root", + type=click.Path(exists=True), + default=".", + help="Path of source root", + show_default=True, +) +@click.option( + "-c", + "--config-file", + type=click.Path(exists=True), + default=os.environ.get("SPACEONE_CONFIG_FILE"), + help="Path of config file", +) +@click.option( + "-m", + "--module-path", + type=click.Path(exists=True), + multiple=True, + help="Additional python path", +) def scheduler(package, source_root=None, config_file=None, module_path=None): """Run a scheduler server""" # Initialize config - _set_server_config(package, source_root, config_file=config_file, module_path=module_path) + _set_server_config( + package, source_root, config_file=config_file, module_path=module_path + ) # Initialize common modules _init_common_modules() @@ -115,34 +234,89 @@ def scheduler(package, source_root=None, config_file=None, module_path=None): @run.command() -@click.argument('package') -@click.option('-a', '--app-path', type=str, - help='Path of Plugin application [default: {package}.main:app]') -@click.option('-s', '--source-root', type=click.Path(exists=True), default='.', - help='Path of source root', show_default=True) -@click.option('-p', '--port', type=int, default=os.environ.get('SPACEONE_PORT', 50051), - help='Port of plugin server', show_default=True) -@click.option('-m', '--module-path', type=click.Path(exists=True), multiple=True, - help='Additional python path') -def plugin_server(package, app_path=None, source_root=None, port=None, module_path=None): +@click.argument("package") +@click.option( + "-a", + "--app-path", + type=str, + help="Path of Plugin application [default: {package}.main:app]", +) +@click.option( + "-s", + "--source-root", + type=click.Path(exists=True), + default=".", + help="Path of source root", + show_default=True, +) +@click.option( + "-p", + "--port", + type=int, + default=os.environ.get("SPACEONE_PORT", 50051), + help="Port of plugin server", + show_default=True, +) +@click.option( + "-w", + "--worker", + type=int, + default=os.environ.get("SPACEONE_WORKER", 100), + help="Worker of gRPC server", + show_default=True, +) +@click.option( + "-m", + "--module-path", + type=click.Path(exists=True), + multiple=True, + help="Additional python path", +) +def plugin_server( + package, app_path=None, source_root=None, port=None, worker=None, module_path=None +): """Run a plugin server""" # Initialize config - _set_server_config(package, source_root, port, plugin_app_path=app_path, module_path=module_path, - set_custom_config=False) + _set_server_config( + package, + source_root, + port, + plugin_app_path=app_path, + module_path=module_path, + set_custom_config=False, + worker=worker, + ) # Run Plugin Server plugin_srv.serve() @cli.command() -@click.argument('package') -@click.option('-c', '--config-file', type=click.Path(exists=True), - default=lambda: os.environ.get('SPACEONE_CONFIG_FILE'), help='Path of config file') -@click.option('-s', '--source-root', type=click.Path(exists=True), default='.', - help='Path of source root', show_default=True) -@click.option('-o', '--output', default='yaml', help='Output format', - type=click.Choice(['json', 'yaml']), show_default=True) +@click.argument("package") +@click.option( + "-c", + "--config-file", + type=click.Path(exists=True), + default=lambda: os.environ.get("SPACEONE_CONFIG_FILE"), + help="Path of config file", +) +@click.option( + "-s", + "--source-root", + type=click.Path(exists=True), + default=".", + help="Path of source root", + show_default=True, +) +@click.option( + "-o", + "--output", + default="yaml", + help="Output format", + type=click.Choice(["json", "yaml"]), + show_default=True, +) def show_config(package, source_root=None, config_file=None, output=None): """Show global configurations""" # Initialize config @@ -153,26 +327,43 @@ def show_config(package, source_root=None, config_file=None, output=None): @cli.command() -@click.option('-c', '--config-file', type=str, help='Path of config file') -@click.option('-d', '--dir', type=str, help='Directory containing test files', - default=lambda: os.environ.get('SPACEONE_WORKING_DIR', os.getcwd())) -@click.option('-f', '--failfast', help='Fast failure flag', is_flag=True) -@click.option('-s', '--scenario', type=str, help='Path of scenario file') -@click.option('-p', '--parameters', type=str, help='Custom parameters to override a scenario file. ' - '(e.g. -p domain.domain.name=new_name -p options.update_mode=false)', - multiple=True) -@click.option('-v', '--verbose', count=True, help='Verbosity level', default=1) -def test(config_file=None, dir=None, failfast=False, scenario: str = None, parameters: List[str] = None, verbose=1): +@click.option("-c", "--config-file", type=str, help="Path of config file") +@click.option( + "-d", + "--dir", + type=str, + help="Directory containing test files", + default=lambda: os.environ.get("SPACEONE_WORKING_DIR", os.getcwd()), +) +@click.option("-f", "--failfast", help="Fast failure flag", is_flag=True) +@click.option("-s", "--scenario", type=str, help="Path of scenario file") +@click.option( + "-p", + "--parameters", + type=str, + help="Custom parameters to override a scenario file. " + "(e.g. -p domain.domain.name=new_name -p options.update_mode=false)", + multiple=True, +) +@click.option("-v", "--verbose", count=True, help="Verbosity level", default=1) +def test( + config_file=None, + dir=None, + failfast=False, + scenario: str = None, + parameters: List[str] = None, + verbose=1, +): """Unit tests for source code""" # set config if config: - os.environ['TEST_CONFIG'] = config_file + os.environ["TEST_CONFIG"] = config_file if scenario: - os.environ['TEST_SCENARIO'] = scenario + os.environ["TEST_SCENARIO"] = scenario if parameters: - os.environ['TEST_SCENARIO_PARAMS'] = ','.join(parameters) + os.environ["TEST_SCENARIO_PARAMS"] = ",".join(parameters) # run test loader = unittest.TestLoader() @@ -183,7 +374,9 @@ def test(config_file=None, dir=None, failfast=False, scenario: str = None, param RichTestRunner(verbosity=verbose, failfast=failfast).run(full_suite) -def _set_python_path(package: str, source_root: str = None, module_path: List[str] = None): +def _set_python_path( + package: str, source_root: str = None, module_path: List[str] = None +): source_root = source_root or os.getcwd() if source_root not in sys.path: @@ -197,12 +390,24 @@ def _set_python_path(package: str, source_root: str = None, module_path: List[st try: __import__(package) except Exception: - raise Exception(f'The package({package}) can not imported. ' - 'Please check the module path.') - - -def _set_server_config(package, source_root=None, port=None, host=None, config_file=None, grpc_app_path=None, - rest_app_path=None, plugin_app_path=None, module_path=None, set_custom_config=True): + raise Exception( + f"The package({package}) can not imported. " "Please check the module path." + ) + + +def _set_server_config( + package, + source_root=None, + port=None, + host=None, + config_file=None, + grpc_app_path=None, + rest_app_path=None, + plugin_app_path=None, + module_path=None, + set_custom_config=True, + worker=None, +): # 1. Set a python path _set_python_path(package, source_root, module_path) @@ -210,10 +415,11 @@ def _set_server_config(package, source_root=None, port=None, host=None, config_f config.init_conf( package=package, port=port, + worker=worker, host=host, grpc_app_path=grpc_app_path, rest_app_path=rest_app_path, - plugin_app_path=plugin_app_path + plugin_app_path=plugin_app_path, ) if set_custom_config: @@ -235,25 +441,25 @@ def _create_project(project_name, directory=None, source=None): if source: skeleton = PLUGIN_SOURCES.get(source, source) else: - skeleton = 'spaceone.core.skeleton' + skeleton = "spaceone.core.skeleton" # Check skeleton module name - module_name = skeleton.split('.')[-1] - if module_name != 'skeleton': + module_name = skeleton.split(".")[-1] + if module_name != "skeleton": raise Exception('Skeleton module path must be ended with "skeleton".') # Copy skeleton source code - skeleton_module = __import__(skeleton, fromlist=['*']) + skeleton_module = __import__(skeleton, fromlist=["*"]) skeleton_path = os.path.dirname(skeleton_module.__file__) - shutil.copytree(skeleton_path, project_path, ignore=shutil.ignore_patterns('__pycache__')) + shutil.copytree( + skeleton_path, project_path, ignore=shutil.ignore_patterns("__pycache__") + ) def _print_config(output): - data = { - 'GLOBAL': config.get_global() - } + data = {"GLOBAL": config.get_global()} - if output == 'json': + if output == "json": print(utils.dump_json(data, indent=4)) else: print(utils.dump_yaml(data)) @@ -270,5 +476,5 @@ def _init_common_modules() -> None: model.init_all() -if __name__ == '__main__': +if __name__ == "__main__": cli() diff --git a/src/spaceone/core/config/__init__.py b/src/spaceone/core/config/__init__.py index e41c58b..0be7cc7 100644 --- a/src/spaceone/core/config/__init__.py +++ b/src/spaceone/core/config/__init__.py @@ -10,45 +10,55 @@ _LOGGER = logging.getLogger(__name__) -def init_conf(package: str, port: int = None, host: str = None, grpc_app_path: str = None, - rest_app_path: str = None, plugin_app_path: str = None): +def init_conf( + package: str, + port: int = None, + worker: int = None, + host: str = None, + grpc_app_path: str = None, + rest_app_path: str = None, + plugin_app_path: str = None, +): set_default_conf() - _GLOBAL['PACKAGE'] = package - _GLOBAL['SERVICE'] = package.rsplit('.', 1)[-1:][0] + _GLOBAL["PACKAGE"] = package + _GLOBAL["SERVICE"] = package.rsplit(".", 1)[-1:][0] if host: - _GLOBAL['HOST'] = host + _GLOBAL["HOST"] = host if port: - _GLOBAL['PORT'] = port + _GLOBAL["PORT"] = port + + if worker: + _GLOBAL["MAX_WORKERS"] = worker if grpc_app_path: - _GLOBAL['GRPC_APP_PATH'] = grpc_app_path + _GLOBAL["GRPC_APP_PATH"] = grpc_app_path if rest_app_path: - _GLOBAL['REST_APP_PATH'] = rest_app_path + _GLOBAL["REST_APP_PATH"] = rest_app_path if plugin_app_path: - _GLOBAL['PLUGIN_APP_PATH'] = plugin_app_path + _GLOBAL["PLUGIN_APP_PATH"] = plugin_app_path def set_default_conf(): for key, value in vars(default_conf).items(): - if not key.startswith('__'): + if not key.startswith("__"): _GLOBAL[key] = value def get_package(): - return _GLOBAL['PACKAGE'] + return _GLOBAL["PACKAGE"] def get_service(): - return _GLOBAL['SERVICE'] + return _GLOBAL["SERVICE"] def get_connector(name): - return _GLOBAL.get('CONNECTORS', {}).get(name, {}) + return _GLOBAL.get("CONNECTORS", {}).get(name, {}) def set_service_config(global_conf_path: str = None): @@ -56,18 +66,18 @@ def set_service_config(global_conf_path: str = None): Get config from service """ - package = _GLOBAL['PACKAGE'] + package = _GLOBAL["PACKAGE"] if package is None: - raise ValueError(f'Package is undefined.') + raise ValueError(f"Package is undefined.") - global_conf_path = global_conf_path or _GLOBAL['GLOBAL_CONF_PATH'] + global_conf_path = global_conf_path or _GLOBAL["GLOBAL_CONF_PATH"] global_conf_path = global_conf_path.format(package=package) - module_path, fromlist = global_conf_path.split(':') + module_path, fromlist = global_conf_path.split(":") global_module = __import__(module_path, fromlist=[fromlist]) for key, value in vars(global_module).items(): - if not key.startswith('__'): + if not key.startswith("__"): if key in _GLOBAL: if isinstance(value, dict): _GLOBAL[key] = utils.deep_merge(value, _GLOBAL[key]) @@ -89,9 +99,14 @@ def set_global(**config): for key, value in config.items(): if key in global_conf: - if not isinstance(value, type(global_conf[key])) and global_conf[key] is not None: + if ( + not isinstance(value, type(global_conf[key])) + and global_conf[key] is not None + ): value_type_name = type(global_conf[key]).__name__ - raise ValueError(f'Value type is invalid. (GLOBAL.{key} = {value_type_name})') + raise ValueError( + f"Value type is invalid. (GLOBAL.{key} = {value_type_name})" + ) if isinstance(value, dict): global_conf[key] = utils.deep_merge(value, global_conf[key]) @@ -108,16 +123,16 @@ def set_global_force(**config): def set_file_conf(config_yml: str): file_conf: dict = utils.load_yaml_from_file(config_yml) - global_conf: dict = file_conf.get('GLOBAL', {}) + global_conf: dict = file_conf.get("GLOBAL", {}) set_global(**global_conf) - import_conf: list = file_conf.get('IMPORT', []) + import_conf: list = file_conf.get("IMPORT", []) if isinstance(import_conf, list): for uri in import_conf: import_remote_conf(uri) # DEPRECATED: REMOTE_URL setting changed to IMPORT - import_conf: list = file_conf.get('REMOTE_URL', []) + import_conf: list = file_conf.get("REMOTE_URL", []) if isinstance(import_conf, list): for uri in import_conf: import_remote_conf(uri) @@ -125,17 +140,17 @@ def set_file_conf(config_yml: str): def import_remote_conf(uri): endpoint = utils.parse_endpoint(uri) - scheme = endpoint.get('scheme') + scheme = endpoint.get("scheme") remote_conf = None - if scheme == 'file': - remote_conf = utils.load_yaml_from_file(endpoint['path']) + if scheme == "file": + remote_conf = utils.load_yaml_from_file(endpoint["path"]) - elif scheme in ['http', 'https']: + elif scheme in ["http", "https"]: remote_conf = utils.load_yaml_from_url(uri) - elif scheme == 'consul': + elif scheme == "consul": remote_conf = load_consul_config(endpoint) if isinstance(remote_conf, dict): @@ -143,24 +158,24 @@ def import_remote_conf(uri): def load_consul_config(endpoint): - hostname = endpoint.get('hostname') - port = endpoint.get('port') - key = endpoint.get('path', '')[1:] + hostname = endpoint.get("hostname") + port = endpoint.get("port") + key = endpoint.get("path", "")[1:] try: conf = {} if hostname: - conf['host'] = hostname + conf["host"] = hostname if port: - conf['port'] = port + conf["port"] = port c = consul.Consul(**conf) index, data = c.kv.get(key) if data: - json_str = data['Value'].decode('utf-8') + json_str = data["Value"].decode("utf-8") return utils.load_json(json_str) return {} except Exception as e: - raise Exception(f'Consul Call Error: {e}') + raise Exception(f"Consul Call Error: {e}") diff --git a/src/spaceone/core/fastapi/server.py b/src/spaceone/core/fastapi/server.py index 1577bc5..7e8f848 100644 --- a/src/spaceone/core/fastapi/server.py +++ b/src/spaceone/core/fastapi/server.py @@ -11,24 +11,30 @@ def _get_router_conf(): package = config.get_package() - router_conf_module = __import__(f'{package}.conf.router_conf', fromlist=['router_conf']) - return getattr(router_conf_module, 'ROUTER', []) + router_conf_module = __import__( + f"{package}.conf.router_conf", fromlist=["router_conf"] + ) + return getattr(router_conf_module, "ROUTER", []) def _get_sub_app_conf(): package = config.get_package() - router_conf_module = __import__(f'{package}.conf.router_conf', fromlist=['router_conf']) - return getattr(router_conf_module, 'SUB_APP', {}) + router_conf_module = __import__( + f"{package}.conf.router_conf", fromlist=["router_conf"] + ) + return getattr(router_conf_module, "SUB_APP", {}) def _get_router(path): try: - module_path, router_name = path.split(':') - module_name = module_path.rsplit('.')[-1:] + module_path, router_name = path.split(":") + module_name = module_path.rsplit(".")[-1:] router_module = __import__(module_path, fromlist=[module_name]) return getattr(router_module, router_name) except Exception as e: - _LOGGER.warning(f'[_get_router] Invalid router path. (router_path = {path})', exc_info=True) + _LOGGER.warning( + f"[_get_router] Invalid router path. (router_path = {path})", exc_info=True + ) def _mount_sub_apps(app, sub_apps): @@ -36,14 +42,14 @@ def _mount_sub_apps(app, sub_apps): for sub_app_name, sub_app_options in sub_app_conf.items(): sub_app = sub_apps.get(sub_app_name) if sub_app: - sub_app_path = sub_app_options.get('path') + sub_app_path = sub_app_options.get("path") app.mount(path=sub_app_path, app=sub_app) def _create_sub_app(sub_app_options): - title = sub_app_options.get('title', 'FastAPI') - description = sub_app_options.get('description', '') - contact = sub_app_options.get('contact', {}) + title = sub_app_options.get("title", "FastAPI") + description = sub_app_options.get("description", "") + contact = sub_app_options.get("contact", {}) return FastAPI(title=title, description=description, contact=contact) @@ -58,12 +64,14 @@ def _include_routers(app): # App Routers for router_conf in routers_conf: - sub_app_name = router_conf.get('sub_app') - router_path = router_conf.get('router_path') - router_options = router_conf.get('router_options', {}) + sub_app_name = router_conf.get("sub_app") + router_path = router_conf.get("router_path") + router_options = router_conf.get("router_options", {}) if router_path is None: - _LOGGER.warning(f'[include_routers] Undefined router_path. (router = {router_conf})') + _LOGGER.warning( + f"[include_routers] Undefined router_path. (router = {router_conf})" + ) continue if sub_app_name in sub_apps_conf: @@ -78,10 +86,10 @@ def _include_routers(app): all_routers_path.append(router_path) # Extension Routers - ext_routers = config.get_global('REST_EXTENSION_ROUTERS', []) + ext_routers = config.get_global("REST_EXTENSION_ROUTERS", []) for router in ext_routers: - router_path = router.get('router_path') - router_options = router.get('router_options', {}) + router_path = router.get("router_path") + router_options = router.get("router_options", {}) _append_router(app, router_path, router_options) all_routers_path.append(router_path) @@ -89,8 +97,8 @@ def _include_routers(app): # Mount Sub Applications _mount_sub_apps(app, sub_apps) - all_routers_path_str = '\n\t - '.join(all_routers_path) - _LOGGER.debug(f'Loaded Routers: \n\t - {all_routers_path_str}') + all_routers_path_str = "\n\t - ".join(all_routers_path) + _LOGGER.debug(f"Loaded Routers: \n\t - {all_routers_path_str}") return app @@ -98,19 +106,16 @@ def _include_routers(app): def _append_router(app, router_path, router_options): router = _get_router(router_path) - app.include_router( - router, - **router_options - ) + app.include_router(router, **router_options) def _add_middlewares(app): app.add_middleware( CORSMiddleware, - allow_origins=['*'], + allow_origins=["*"], allow_credentials=True, - allow_methods=['*'], - allow_headers=['*'], + allow_methods=["*"], + allow_headers=["*"], ) return app @@ -119,11 +124,11 @@ def _init_fast_api(): global_conf = config.get_global() return FastAPI( - title=global_conf.get('REST_TITLE', 'Document'), - version='x.y.z', + title=global_conf.get("REST_TITLE", "Document"), + version="x.y.z", # version=server_info.get_version(), - contact=global_conf.get('REST_CONTACT', {}), - description=global_conf.get('REST_DESCRIPTION', ''), + contact=global_conf.get("REST_CONTACT", {}), + description=global_conf.get("REST_DESCRIPTION", ""), ) @@ -136,11 +141,18 @@ def fast_api_app(): def serve(app_path: str = None): conf = config.get_global() - app_path = conf['REST_APP_PATH'] + app_path = conf["REST_APP_PATH"] - uvicorn_options = conf.get('UVICORN_OPTIONS', {}) + uvicorn_options = conf.get("UVICORN_OPTIONS", {}) - _LOGGER.info(f'Start REST Server ({config.get_service()}): ' - f'host={conf["HOST"]} port={conf["PORT"]} options={uvicorn_options}') + _LOGGER.info( + f"Start REST Server ({config.get_service()}): " + f'host={conf["HOST"]} port={conf["PORT"]} options={uvicorn_options}' + ) - uvicorn.run('spaceone.core.fastapi.server:fast_api_app', host=conf['HOST'], port=conf['PORT'], **uvicorn_options) + uvicorn.run( + "spaceone.core.fastapi.server:fast_api_app", + host=conf["HOST"], + port=conf["PORT"], + **uvicorn_options, + ) diff --git a/src/spaceone/core/pygrpc/server.py b/src/spaceone/core/pygrpc/server.py index 92c3239..e92148b 100644 --- a/src/spaceone/core/pygrpc/server.py +++ b/src/spaceone/core/pygrpc/server.py @@ -10,9 +10,7 @@ class _ServerInterceptor(grpc.ServerInterceptor): - _SKIP_METHODS = ( - '/grpc.reflection.v1alpha.ServerReflection/ServerReflectionInfo' - ) + _SKIP_METHODS = "/grpc.reflection.v1alpha.ServerReflection/ServerReflectionInfo" def _check_skip_method(self, method): is_skip = False @@ -37,17 +35,16 @@ def intercept_service(self, continuation, handler_call_details): class GRPCServer(object): - def __init__(self): conf = config.get_global() - self._service = conf['SERVICE'] - self._port = conf['PORT'] - self._max_workers = conf['MAX_WORKERS'] + self._service = conf["SERVICE"] + self._port = conf["PORT"] + self._max_workers = conf["MAX_WORKERS"] self._service_names = [] server_interceptor = _ServerInterceptor() self._server = grpc.server( - futures.ThreadPoolExecutor(max_workers=conf['MAX_WORKERS']), + futures.ThreadPoolExecutor(max_workers=conf["MAX_WORKERS"]), interceptors=(server_interceptor,), ) @@ -61,36 +58,40 @@ def service_names(self) -> List[str]: def add_service(self, servicer_cls: Union[Type[BaseAPI], Type[object]]): servicer = servicer_cls() - getattr(servicer.pb2_grpc_module, f'add_{servicer.name}Servicer_to_server')(servicer, self.server) + getattr(servicer.pb2_grpc_module, f"add_{servicer.name}Servicer_to_server")( + servicer, self.server + ) self.service_names.append(servicer.service_name) def run(self): - service_names_str = '\n\t - '.join(self.service_names) - _LOGGER.debug(f'Loaded Services: \n\t - {service_names_str}') + service_names_str = "\n\t - ".join(self.service_names) + _LOGGER.debug(f"Loaded Services: \n\t - {service_names_str}") reflection.enable_server_reflection(self.service_names, self.server) - self.server.add_insecure_port(f'[::]:{self._port}') - _LOGGER.info(f'Start gRPC Server ({self._service}): ' - f'port={self._port}, max_workers={self._max_workers}') + self.server.add_insecure_port(f"[::]:{self._port}") + _LOGGER.info( + f"Start gRPC Server ({self._service}): " + f"port={self._port}, max_workers={self._max_workers}" + ) self.server.start() self.server.wait_for_termination() def _get_grpc_app() -> GRPCServer: package: str = config.get_package() - app_path: str = config.get_global('GRPC_APP_PATH') + app_path: str = config.get_global("GRPC_APP_PATH") app_path = app_path.format(package=package) - module_path, app_name = app_path.split(':') + module_path, app_name = app_path.split(":") try: app_module = __import__(module_path, fromlist=[app_name]) - if not hasattr(app_module, 'app'): - raise ImportError(f'App is not defined. (app_path = {package}.{app_path})') + if not hasattr(app_module, "app"): + raise ImportError(f"App is not defined. (app_path = {package}.{app_path})") - return getattr(app_module, 'app') + return getattr(app_module, "app") except Exception as e: - raise ImportError(f'Cannot import app: {e}') + raise ImportError(f"Cannot import app: {e}") def _import_module(module_path, servicer_name): @@ -98,13 +99,16 @@ def _import_module(module_path, servicer_name): try: module = __import__(module_path, fromlist=[servicer_name]) except Exception as e: - _LOGGER.warning(f'[_import_module] Cannot import grpc servicer module. (reason = {e})', exc_info=True) + _LOGGER.warning( + f"[_import_module] Cannot import grpc servicer module. (reason = {e})", + exc_info=True, + ) return module def add_extension_services(app): - ext_proto_conf = config.get_global('GRPC_EXTENSION_SERVICERS', {}) + ext_proto_conf = config.get_global("GRPC_EXTENSION_SERVICERS", {}) for module_path, servicer_names in ext_proto_conf.items(): for servicer_name in servicer_names: if api_module := _import_module(module_path, servicer_name): @@ -113,8 +117,10 @@ def add_extension_services(app): app.add_service(servicer_cls) else: - _LOGGER.warning(f'[_add_services] Failed to add service. ' - f'(module_path={module_path}, servicer_name={servicer_name})') + _LOGGER.warning( + f"[_add_services] Failed to add service. " + f"(module_path={module_path}, servicer_name={servicer_name})" + ) return app