|
1 | 1 | import logging
|
2 | 2 | import uvicorn
|
3 |
| -import json |
4 |
| -import os |
5 | 3 |
|
6 |
| -from fastapi import FastAPI, Request |
| 4 | +from fastapi import FastAPI |
7 | 5 | from fastapi.middleware.cors import CORSMiddleware
|
8 |
| -from fastapi.openapi.docs import get_swagger_ui_html |
9 |
| -from fastapi.responses import HTMLResponse |
10 | 6 |
|
11 | 7 | from spaceone.core import config
|
12 | 8 | from spaceone.core.logger import set_logger
|
13 | 9 | from spaceone.core.opentelemetry import set_tracer, set_metric
|
14 | 10 | from spaceone.core.extension.server_info import ServerInfoManager
|
| 11 | +from spaceone.core.fastapi.openapi import add_external_swagger |
15 | 12 |
|
16 | 13 | _LOGGER = logging.getLogger(__name__)
|
17 | 14 |
|
@@ -134,107 +131,11 @@ def _init_fast_api():
|
134 | 131 | )
|
135 | 132 |
|
136 | 133 |
|
137 |
| -def _get_all_services_from_openapi_json_files(openapi_json_path): |
138 |
| - services = [] |
139 |
| - openapi_json_files = os.listdir(openapi_json_path) |
140 |
| - for openapi_json_file in openapi_json_files: |
141 |
| - services.append('_'.join(openapi_json_file.split('_')[:-1]).lower()) |
142 |
| - return services |
143 |
| - |
144 |
| - |
145 |
| -def _sort_services(services): |
146 |
| - return sorted(services, key=lambda x: ('identity' not in x, 'inventory' not in x, 'cost-analysis' not in x, |
147 |
| - 'monitoring' not in x, 'notification' not in x, 'repository' not in x, x)) |
148 |
| - |
149 |
| - |
150 |
| -def _create_openapi_json(app, service_name): |
151 |
| - swagger_path = config.get_global('EXTENSION_SWAGGER_PATH') |
152 |
| - swagger_path = os.path.join(swagger_path, f"{service_name.replace('-', '_')}_openapi.json") |
153 |
| - try: |
154 |
| - with open(swagger_path, 'r') as f: |
155 |
| - custom_openapi_schema = json.loads(f.read()) |
156 |
| - custom_openapi_schema['openapi'] = app.openapi().get('openapi') |
157 |
| - description = custom_openapi_schema['info']['summary'] |
158 |
| - app.openapi()['info']['description'] += f"| **{service_name.replace('-', ' ').title()}** | {description} | [/{service_name}/docs](/{service_name}/docs) |\n" |
159 |
| - |
160 |
| - with open(swagger_path, 'w') as f: |
161 |
| - json.dump(custom_openapi_schema, f, indent=2) |
162 |
| - except Exception as e: |
163 |
| - _LOGGER.error(f'[_create_openapi_json] {swagger_path} : {e}', exc_info=True) |
164 |
| - |
165 |
| - |
166 |
| -def _override_openapi(app): |
167 |
| - extension_swagger_path = config.get_global('EXTENSION_SWAGGER_PATH') |
168 |
| - if not os.path.exists(extension_swagger_path): |
169 |
| - _LOGGER.info(f'[_override_openapi] Extension Swagger Path is not exists. (path = {extension_swagger_path})') |
170 |
| - return app |
171 |
| - |
172 |
| - services = _get_all_services_from_openapi_json_files(extension_swagger_path) |
173 |
| - services = _sort_services(services) |
174 |
| - _openapi_info = app.openapi().get('info') |
175 |
| - _openapi_version = app.openapi().get('openapi') |
176 |
| - |
177 |
| - app.openapi()['info']['description'] += "\n<br><br>\n" |
178 |
| - app.openapi()['info']['description'] += "\n## List of Services\n" |
179 |
| - app.openapi()['info']['description'] += "\n[Home](/docs)\n" |
180 |
| - app.openapi()['info']['description'] += "| **Service** | **Description** | **URL** |\n" |
181 |
| - app.openapi()['info']['description'] += "|:---|:--- |:---|\n" |
182 |
| - |
183 |
| - for service in services: |
184 |
| - service = service.replace('_', '-') |
185 |
| - _create_openapi_json(app, service_name=service) |
186 |
| - build_docs(app, prefix=f"/{service}", service_name=service) |
187 |
| - |
188 |
| - app.openapi()['info'][ |
189 |
| - 'description'] += "| **Console API** | Service that offers features exclusive to the Console API. | [/docs](/docs#console-api%20%3E%20api) |\n" |
190 |
| - |
191 |
| - return app |
192 |
| - |
193 |
| - |
194 |
| -def build_docs( |
195 |
| - app: FastAPI, |
196 |
| - prefix: str, |
197 |
| - service_name: str |
198 |
| -) -> None: |
199 |
| - async def get_openapi(): |
200 |
| - swagger_path = config.get_global('EXTENSION_SWAGGER_PATH') |
201 |
| - swagger_path = os.path.join(swagger_path, f"{service_name.replace('-','_')}_openapi.json") |
202 |
| - with open(swagger_path, 'r') as f: |
203 |
| - custom_openapi_schema = json.loads(f.read()) |
204 |
| - return custom_openapi_schema |
205 |
| - |
206 |
| - get_openapi.__name__ = get_openapi.__name__ + prefix |
207 |
| - app.add_api_route(prefix + "/openapi.json", get_openapi, include_in_schema=False) |
208 |
| - |
209 |
| - async def swagger_ui_html() -> HTMLResponse: |
210 |
| - return get_swagger_ui_html( |
211 |
| - openapi_url=prefix + "/openapi.json", |
212 |
| - title=f'{service_name.title().replace("-"," ")} API' + ' - Swagger UI', |
213 |
| - oauth2_redirect_url=app.swagger_ui_oauth2_redirect_url, |
214 |
| - init_oauth=app.swagger_ui_init_oauth, |
215 |
| - ) |
216 |
| - |
217 |
| - swagger_ui_html.__name__ = swagger_ui_html.__name__ + prefix |
218 |
| - app.add_api_route(prefix + "/docs", swagger_ui_html, include_in_schema=False) |
219 |
| - |
220 |
| - |
221 |
| -def _get_all_services_list(app): |
222 |
| - services = [] |
223 |
| - for route in app.routes: |
224 |
| - path = route.path.split('/') |
225 |
| - if len(path) == 4: |
226 |
| - services.append(path[1].replace('-', '_')) |
227 |
| - |
228 |
| - services = list(set(services)) |
229 |
| - sorted_services = sorted(services, key=lambda x: ('identity' not in x, 'inventory' not in x, 'cost_analysis' not in x, x)) |
230 |
| - return sorted_services |
231 |
| - |
232 |
| - |
233 | 134 | def fast_api_app():
|
234 | 135 | app = _init_fast_api()
|
235 | 136 | app = _add_middlewares(app)
|
236 | 137 | app = _include_routers(app)
|
237 |
| - app = _override_openapi(app) |
| 138 | + app = add_external_swagger(app) |
238 | 139 | return app
|
239 | 140 |
|
240 | 141 |
|
|
0 commit comments