1
0
mirror of https://github.com/ilri/dspace-statistics-api.git synced 2024-11-24 23:30:18 +01:00

Re-work Swagger UI configuration
All checks were successful
continuous-integration/drone/push Build is passing

It turns out that Swagger UI mostly does the "right" thing for our
use cases here, but it assumes that API paths are relative to the
root of the host where it is being served. This works in the local
development environment because we are serving on "/", but it does
not work in production where the API is deployed beneath the DSpace
REST API, for example at "/rest/statistics".

The solution here is to allow configuration of the DSpace Statistics
API path and use that when registering the Swagger UI as well as in
a new "server" block in the OpenAPI JSON schema.

By default it is configured to work out of the box in a development
environment. Set the DSPACE_STATISTICS_API_URL environment variable
to something like "/rest/statistics" when running in production.
This commit is contained in:
Alan Orth 2020-12-23 13:25:17 +02:00
parent 70b2ba83ba
commit be83514de1
Signed by: alanorth
GPG Key ID: 0FB860CC9C45B1B9
2 changed files with 40 additions and 14 deletions

View File

@ -1,13 +1,13 @@
import json
import falcon import falcon
import psycopg2.extras import psycopg2.extras
from falcon_swagger_ui import register_swaggerui_app from falcon_swagger_ui import register_swaggerui_app
from .config import DSPACE_STATISTICS_API_URL, VERSION
from .database import DatabaseManager from .database import DatabaseManager
from .stats import get_downloads, get_views from .stats import get_downloads, get_views
from .util import set_statistics_scope, validate_post_parameters from .util import set_statistics_scope, validate_post_parameters
from .config import VERSION
from .config import SWAGGERUI_URL
from .config import SWAGGERUI_SCHEMA_URL
class RootResource: class RootResource:
@ -31,7 +31,20 @@ class OpenAPIJSONResource:
resp.status = falcon.HTTP_200 resp.status = falcon.HTTP_200
resp.content_type = "text/html" resp.content_type = "text/html"
with open("dspace_statistics_api/docs/openapi.json", "r") as f: with open("dspace_statistics_api/docs/openapi.json", "r") as f:
resp.body = f.read() # Load the openapi.json schema
data = json.load(f)
# Swagger assumes your API is at the root of the current host unless
# you configure a "servers" block in the schema. The problem is that
# I want this to work in both development and production, so we need
# to make this configurable.
#
# If the DSPACE_STATISTICS_API_URL is configured then we will add a
# server entry to the openapi.json schema before sending it.
if DSPACE_STATISTICS_API_URL != "":
data["servers"] = [{"url": DSPACE_STATISTICS_API_URL}]
resp.body = json.dumps(data)
class AllStatisticsResource: class AllStatisticsResource:
@ -199,16 +212,29 @@ api.add_route("/community/{id_:uuid}", SingleStatisticsResource())
api.add_route("/collections", AllStatisticsResource()) api.add_route("/collections", AllStatisticsResource())
api.add_route("/collection/{id_:uuid}", SingleStatisticsResource()) api.add_route("/collection/{id_:uuid}", SingleStatisticsResource())
# Swagger configuration # Route to the Swagger UI OpenAPI schema
api.add_route(SWAGGERUI_SCHEMA_URL, OpenAPIJSONResource()) api.add_route("/docs/openapi.json", OpenAPIJSONResource())
# Path to host the Swagger UI. Keep in mind that Falcon will add a route for
# this automatically when we register Swagger and the path will be relative
# to the Falcon app like all other routes, not the absolute root.
SWAGGERUI_PATH = "/swagger"
# The *absolute* path to the OpenJSON schema. This must be absolute because
# it will be requested by the client and must resolve absolutely. Note: the
# name of this variable is misleading because it is actually the schema URL
# but we pass it into the register_swaggerui_app() function as the api_url
# parameter.
SWAGGERUI_API_URL = f"{DSPACE_STATISTICS_API_URL}/docs/openapi.json"
register_swaggerui_app( register_swaggerui_app(
api, api,
SWAGGERUI_URL, SWAGGERUI_PATH,
SWAGGERUI_SCHEMA_URL, SWAGGERUI_API_URL,
config={ config={
"supportedSubmitMethods": ["get", "post"], "supportedSubmitMethods": ["get", "post"],
}, },
uri_prefix=DSPACE_STATISTICS_API_URL,
) )
# vim: set sw=4 ts=4 expandtab: # vim: set sw=4 ts=4 expandtab:

View File

@ -9,12 +9,12 @@ DATABASE_PASS = os.environ.get("DATABASE_PASS", "dspacestatistics")
DATABASE_HOST = os.environ.get("DATABASE_HOST", "localhost") DATABASE_HOST = os.environ.get("DATABASE_HOST", "localhost")
DATABASE_PORT = os.environ.get("DATABASE_PORT", "5432") DATABASE_PORT = os.environ.get("DATABASE_PORT", "5432")
# SwaggerUI configuration # URL to DSpace Statistics API, which will be used as a prefix to API calls in
# the Swagger UI. An empty string will allow this to work out of the box in a
# URI path where the Swagger UI should be available (without trailing slash) # local development environment, but for production it should be set to a value
SWAGGERUI_URL = os.environ.get("SWAGGERUI_URL", "/swagger") # like "/rest/statistics", assuming that the statistics API is deployed next to
# URI path to the OpenAPI JSON schema # the vanilla DSpace REST API.
SWAGGERUI_SCHEMA_URL = os.environ.get("SWAGGERUI_SCHEMA_URL", "/docs/openapi.json") DSPACE_STATISTICS_API_URL = os.environ.get("DSPACE_STATISTICS_API_URL", "")
VERSION = "1.4.0-dev" VERSION = "1.4.0-dev"