mirror of
https://github.com/galaxyproject/galaxy.git
synced 2026-10-24 02:04:04 +08:00
Include non-FastAPI routes in api/docs
This commit is contained in:
@@ -705,6 +705,7 @@ class UniverseApplication(StructuredApp, GalaxyManagerApplication):
|
||||
self.server_starttime = int(time.time()) # used for cachebusting
|
||||
# Limit lifetime of tool shed repository cache to app startup
|
||||
self.tool_shed_repository_cache = None
|
||||
self.api_spec = None
|
||||
log.info(f"Galaxy app startup finished {startup_timer}")
|
||||
|
||||
def _shutdown_queue_worker(self):
|
||||
|
||||
@@ -5,6 +5,7 @@ import inspect
|
||||
import logging
|
||||
import os
|
||||
import random
|
||||
import re
|
||||
import socket
|
||||
import string
|
||||
import time
|
||||
@@ -106,27 +107,28 @@ class WebApplication(base.WebApplication):
|
||||
Traverse all route paths starting with "api" and create an APISpec instance.
|
||||
"""
|
||||
# API specification builder
|
||||
apispec = APISpec(title=self.name,
|
||||
version="0.0.0-unsupported", # galaxy_app.config.version_major,
|
||||
openapi_version="3.0.2")
|
||||
import re, sys
|
||||
from apispec import yaml_utils
|
||||
RE_URL = re.compile(r"""
|
||||
apispec = APISpec(
|
||||
title=self.name, version="0.0.0-unsupported", openapi_version="3.0.2" # galaxy_app.config.version_major,
|
||||
)
|
||||
RE_URL = re.compile(
|
||||
r"""
|
||||
(?::\(|{)
|
||||
(\w*)
|
||||
(?::.*)?
|
||||
(?:\)|})""", re.X)
|
||||
(?:\)|})""",
|
||||
re.X,
|
||||
)
|
||||
for rule in self.mapper.matchlist:
|
||||
if rule.routepath.endswith(".:(format)") or not rule.routepath.startswith("api/"):
|
||||
continue
|
||||
# Try to replace routes various ways to encode variables with simple swagger {form}
|
||||
swagger_path = "/%s" % RE_URL.sub(r'{\1}', rule.routepath)
|
||||
controller = rule.defaults.get('controller', '')
|
||||
action = rule.defaults.get('action', '')
|
||||
swagger_path = "/%s" % RE_URL.sub(r"{\1}", rule.routepath)
|
||||
controller = rule.defaults.get("controller", "")
|
||||
action = rule.defaults.get("action", "")
|
||||
# Get the list of methods for the route
|
||||
methods = []
|
||||
if rule.conditions:
|
||||
m = rule.conditions.get('method', [])
|
||||
m = rule.conditions.get("method", [])
|
||||
methods = type(m) is str and [m] or m
|
||||
# Find the controller class
|
||||
if controller not in self.api_controllers:
|
||||
@@ -137,12 +139,14 @@ class WebApplication(base.WebApplication):
|
||||
log.warning("No action found for '%s' in class '%s' while building API spec", action, controller_class)
|
||||
continue
|
||||
action_method = getattr(controller_class, action)
|
||||
# First try to load method docs from docstring
|
||||
operations = yaml_utils.load_operations_from_docstring(action_method.__doc__)
|
||||
operations = {}
|
||||
# Add methods that have routes but are not documents
|
||||
for method in methods:
|
||||
if method.lower() not in operations:
|
||||
operations[method.lower()] = {}
|
||||
operations[method.lower()] = {
|
||||
"description": f"This route has not yet been ported to FastAPI. The documentation may not be complete.\n{action_method.__doc__}",
|
||||
"tags": ["routes"],
|
||||
}
|
||||
# Store the swagger path
|
||||
apispec.path(path=swagger_path, operations=operations)
|
||||
return apispec
|
||||
|
||||
@@ -1,9 +0,0 @@
|
||||
from galaxy import web
|
||||
from galaxy.webapps.base.controller import BaseAPIController
|
||||
|
||||
|
||||
class GenomesController(BaseAPIController):
|
||||
|
||||
@web.expose_api_raw
|
||||
def index(self, trans, **kwd):
|
||||
return trans.webapp.build_apispec().to_yaml()
|
||||
@@ -260,6 +260,7 @@ def app_pair(global_conf, load_app_kwds=None, wsgi_preflight=True, **kwargs):
|
||||
# ==== Done
|
||||
# Indicate that all configuration settings have been provided
|
||||
webapp.finalize_config()
|
||||
app.api_spec = webapp.build_apispec()
|
||||
|
||||
# Wrap the webapp in some useful middleware
|
||||
if kwargs.get("middleware", True):
|
||||
|
||||
@@ -6,12 +6,14 @@ from fastapi import (
|
||||
FastAPI,
|
||||
Request,
|
||||
)
|
||||
from fastapi.openapi.utils import get_openapi
|
||||
from starlette.middleware.cors import CORSMiddleware
|
||||
from starlette.responses import (
|
||||
FileResponse,
|
||||
Response,
|
||||
)
|
||||
|
||||
from galaxy.version import VERSION
|
||||
from galaxy.webapps.base.api import (
|
||||
add_exception_handler,
|
||||
add_request_id_middleware,
|
||||
@@ -121,6 +123,21 @@ def add_galaxy_middleware(app: FastAPI, gx_app):
|
||||
return response
|
||||
|
||||
|
||||
def include_legacy_openapi(app, gx_app):
|
||||
if app.openapi_schema:
|
||||
return app.openapi_schema
|
||||
openapi_schema = get_openapi(
|
||||
title="Galaxy API Documentation",
|
||||
version=VERSION,
|
||||
routes=app.routes,
|
||||
)
|
||||
legacy_openapi = gx_app.api_spec.to_dict()
|
||||
legacy_openapi["paths"].update(openapi_schema["paths"])
|
||||
openapi_schema["paths"] = legacy_openapi["paths"]
|
||||
app.openapi_schema = openapi_schema
|
||||
return app.openapi_schema
|
||||
|
||||
|
||||
def initialize_fast_app(gx_wsgi_webapp, gx_app):
|
||||
app = FastAPI(
|
||||
title="Galaxy API",
|
||||
@@ -131,6 +148,7 @@ def initialize_fast_app(gx_wsgi_webapp, gx_app):
|
||||
add_galaxy_middleware(app, gx_app)
|
||||
add_request_id_middleware(app)
|
||||
include_all_package_routers(app, "galaxy.webapps.galaxy.api")
|
||||
include_legacy_openapi(app, gx_app)
|
||||
wsgi_handler = WSGIMiddleware(gx_wsgi_webapp)
|
||||
app.mount("/", wsgi_handler)
|
||||
if gx_app.config.galaxy_url_prefix != "/":
|
||||
|
||||
Reference in New Issue
Block a user