app mount updates (#548)

* refactor WSGI mounting and add docs

* fix ref

* fix Starlette routing for OACov
This commit is contained in:
Tom Kralidis
2020-09-30 07:07:41 -04:00
committed by GitHub
parent 90ab772c7c
commit 6d1dcece0e
4 changed files with 104 additions and 64 deletions
+43 -1
View File
@@ -38,6 +38,25 @@ The Flask WSGI server can be run as follows:
pygeoapi serve --flask
pygeoapi serve # uses Flask by default
To integrate pygeoapi as part of another Flask application, use Flask blueprints:
.. code-block:: python
from flask import Flask
from pygeoapi.flask_app import BLUEPRINT as pygeoapi_blueprint
app = Flask(__name__)
app.register_blueprint(pygeoapi_blueprint, url_prefix='/oapi')
@app.route('/')
def hello_world():
return 'Hello, World!'
As a result, your application will be available at http://localhost:5000/ and pygeoapi will be available
at http://localhost:5000/oapi
Starlette ASGI
^^^^^^^^^^^^^^
@@ -51,12 +70,35 @@ Starlette is an ASGI implementation which pygeoapi utilizes to communicate with
HTTP request <--> Starlette (pygeoapi/starlette_app.py) <--> pygeoapi API (pygeoapi/api.py)
The Flask WSGI server can be run as follows:
The Starlette ASGI server can be run as follows:
.. code-block:: bash
pygeoapi serve --starlette
To integrate pygeoapi as part of another Starlette application:
.. code-block:: python
from starlette.applications import Starlette
from starlette.responses import PlainTextResponse
from starlette.routing import Route
from pygeoapi.starlette_app import app as pygeoapi_app
async def homepage(request):
return PlainTextResponse('Hello, World!')
app = Starlette(debug=True, routes=[
Route('/', homepage),
])
app.mount('/oapi', pygeoapi_app)
As a result, your application will be available at http://localhost:5000/ and pygeoapi will be available
at http://localhost:5000/oapi
Running in production
---------------------
+1 -1
View File
@@ -1379,7 +1379,7 @@ class API:
headers_ = HEADERS.copy()
format_ = check_format(args, headers_)
format_ = check_format(args, headers)
if format_ is None:
format_ = 'json'
+21 -21
View File
@@ -39,7 +39,7 @@ from flask import Flask, Blueprint, make_response, request, send_from_directory
from pygeoapi.api import API
from pygeoapi.util import get_mimetype, yaml_load
routes = Blueprint('pygeoapi', __name__)
BLUEPRINT = Blueprint('pygeoapi', __name__)
CONFIG = None
@@ -95,7 +95,7 @@ if (OGC_SCHEMAS_LOCATION is not None and
mimetype=get_mimetype(basename_))
@routes.route('/')
@BLUEPRINT.route('/')
def landing_page():
"""
OGC API landing page endpoint
@@ -113,7 +113,7 @@ def landing_page():
return response
@routes.route('/openapi')
@BLUEPRINT.route('/openapi')
def openapi():
"""
OpenAPI endpoint
@@ -134,7 +134,7 @@ def openapi():
return response
@routes.route('/conformance')
@BLUEPRINT.route('/conformance')
def conformance():
"""
OGC API conformance endpoint
@@ -153,8 +153,8 @@ def conformance():
return response
@routes.route('/collections')
@routes.route('/collections/<collection_id>')
@BLUEPRINT.route('/collections')
@BLUEPRINT.route('/collections/<collection_id>')
def collections(collection_id=None):
"""
OGC API collections endpoint
@@ -175,7 +175,7 @@ def collections(collection_id=None):
return response
@routes.route('/collections/<collection_id>/queryables')
@BLUEPRINT.route('/collections/<collection_id>/queryables')
def collection_queryables(collection_id=None):
"""
OGC API collections querybles endpoint
@@ -196,8 +196,8 @@ def collection_queryables(collection_id=None):
return response
@routes.route('/collections/<collection_id>/items')
@routes.route('/collections/<collection_id>/items/<item_id>')
@BLUEPRINT.route('/collections/<collection_id>/items')
@BLUEPRINT.route('/collections/<collection_id>/items/<item_id>')
def collection_items(collection_id, item_id=None):
"""
OGC API collections items endpoint
@@ -223,7 +223,7 @@ def collection_items(collection_id, item_id=None):
return response
@routes.route('/collections/<collection_id>/coverage')
@BLUEPRINT.route('/collections/<collection_id>/coverage')
def collection_coverage(collection_id):
"""
OGC API - Coverages coverage endpoint
@@ -244,7 +244,7 @@ def collection_coverage(collection_id):
return response
@routes.route('/collections/<collection_id>/coverage/domainset')
@BLUEPRINT.route('/collections/<collection_id>/coverage/domainset')
def collection_coverage_domainset(collection_id):
"""
OGC API - Coverages coverage domainset endpoint
@@ -265,7 +265,7 @@ def collection_coverage_domainset(collection_id):
return response
@routes.route('/collections/<collection_id>/coverage/rangetype')
@BLUEPRINT.route('/collections/<collection_id>/coverage/rangetype')
def collection_coverage_rangetype(collection_id):
"""
OGC API - Coverages coverage rangetype endpoint
@@ -286,7 +286,7 @@ def collection_coverage_rangetype(collection_id):
return response
@routes.route('/collections/<collection_id>/tiles')
@BLUEPRINT.route('/collections/<collection_id>/tiles')
def get_collection_tiles(collection_id=None):
"""
OGC open api collections tiles access point
@@ -307,7 +307,7 @@ def get_collection_tiles(collection_id=None):
return response
@routes.route('/collections/<collection_id>/tiles/<tileMatrixSetId>/metadata')
@BLUEPRINT.route('/collections/<collection_id>/tiles/<tileMatrixSetId>/metadata') # noqa
def get_collection_tiles_metadata(collection_id=None, tileMatrixSetId=None):
"""
OGC open api collection tiles service metadata
@@ -329,7 +329,7 @@ def get_collection_tiles_metadata(collection_id=None, tileMatrixSetId=None):
return response
@routes.route('/collections/<collection_id>/tiles/\
@BLUEPRINT.route('/collections/<collection_id>/tiles/\
<tileMatrixSetId>/<tileMatrix>/<tileRow>/<tileCol>')
def get_collection_tiles_data(collection_id=None, tileMatrixSetId=None,
tileMatrix=None, tileRow=None, tileCol=None):
@@ -357,8 +357,8 @@ def get_collection_tiles_data(collection_id=None, tileMatrixSetId=None,
return response
@routes.route('/processes')
@routes.route('/processes/<process_id>')
@BLUEPRINT.route('/processes')
@BLUEPRINT.route('/processes/<process_id>')
def processes(process_id=None):
"""
OGC API - Processes description endpoint
@@ -378,7 +378,7 @@ def processes(process_id=None):
return response
@routes.route('/processes/<process_id>/jobs', methods=['GET', 'POST'])
@BLUEPRINT.route('/processes/<process_id>/jobs', methods=['GET', 'POST'])
def process_jobs(process_id=None):
"""
OGC API - Processes jobs endpoint
@@ -402,7 +402,7 @@ def process_jobs(process_id=None):
return response
@routes.route('/stac')
@BLUEPRINT.route('/stac')
def stac_catalog_root():
"""
STAC root endpoint
@@ -421,7 +421,7 @@ def stac_catalog_root():
return response
@routes.route('/stac/<path:path>')
@BLUEPRINT.route('/stac/<path:path>')
def stac_catalog_path(path):
"""
STAC path endpoint
@@ -442,7 +442,7 @@ def stac_catalog_path(path):
return response
APP.register_blueprint(routes)
APP.register_blueprint(BLUEPRINT)
@click.command()
+39 -41
View File
@@ -38,7 +38,6 @@ from starlette.staticfiles import StaticFiles
from starlette.applications import Starlette
from starlette.requests import Request
from starlette.responses import Response
from starlette.routing import Route
import uvicorn
from pygeoapi.api import API
@@ -75,18 +74,8 @@ if (OGC_SCHEMAS_LOCATION is not None and
api_ = API(CONFIG)
routes = []
def _route(path, methods=None):
def inner(func):
app.add_route(path, func, methods=methods)
routes.append(Route(path, func, methods=methods))
return func
return inner
@_route('/')
@app.route('/')
async def landing_page(request: Request):
"""
OGC API landing page endpoint
@@ -104,8 +93,8 @@ async def landing_page(request: Request):
return response
@_route('/openapi')
@_route('/openapi/')
@app.route('/openapi')
@app.route('/openapi/')
async def openapi(request: Request):
"""
OpenAPI endpoint
@@ -126,8 +115,8 @@ async def openapi(request: Request):
return response
@_route('/conformance')
@_route('/conformance/')
@app.route('/conformance')
@app.route('/conformance/')
async def conformance(request: Request):
"""
OGC API conformance endpoint
@@ -145,10 +134,10 @@ async def conformance(request: Request):
return response
@_route('/collections')
@_route('/collections/')
@_route('/collections/{collection_id}')
@_route('/collections/{collection_id}/')
@app.route('/collections')
@app.route('/collections/')
@app.route('/collections/{collection_id}')
@app.route('/collections/{collection_id}/')
async def collections(request: Request, collection_id=None):
"""
OGC API collections endpoint
@@ -170,8 +159,8 @@ async def collections(request: Request, collection_id=None):
return response
@_route('/collections/{collection_id}/queryables')
@_route('/collections/{collection_id}/queryables/')
@app.route('/collections/{collection_id}/queryables')
@app.route('/collections/{collection_id}/queryables/')
async def collection_queryables(request: Request, collection_id=None):
"""
OGC API collections queryables endpoint
@@ -193,8 +182,8 @@ async def collection_queryables(request: Request, collection_id=None):
return response
@_route('/collections/{name}/tiles')
@_route('/collections/{name}/tiles/')
@app.route('/collections/{name}/tiles')
@app.route('/collections/{name}/tiles/')
async def get_collection_tiles(request: Request, name=None):
"""
OGC open api collections tiles access point
@@ -216,9 +205,9 @@ async def get_collection_tiles(request: Request, name=None):
return response
@_route('/collections/{name}/tiles/\
@app.route('/collections/{name}/tiles/\
{tileMatrixSetId}/{tile_matrix}/{tileRow}/{tileCol}')
@_route('/collections/{name}/tiles/\
@app.route('/collections/{name}/tiles/\
{tileMatrixSetId}/{tile_matrix}/{tileRow}/{tileCol}/')
def get_collection_items_tiles(request: Request, name=None,
tileMatrixSetId=None, tile_matrix=None,
@@ -256,10 +245,10 @@ def get_collection_items_tiles(request: Request, name=None,
return response
@_route('/collections/{collection_id}/items')
@_route('/collections/{collection_id}/items/')
@_route('/collections/{collection_id}/items/{item_id}')
@_route('/collections/{collection_id}/items/{item_id}/')
@app.route('/collections/{collection_id}/items')
@app.route('/collections/{collection_id}/items/')
@app.route('/collections/{collection_id}/items/{item_id}')
@app.route('/collections/{collection_id}/items/{item_id}/')
async def collection_items(request: Request, collection_id=None, item_id=None):
"""
OGC API collections items endpoint
@@ -290,7 +279,7 @@ async def collection_items(request: Request, collection_id=None, item_id=None):
return response
@_route('/collections/<collection_id>/coverage')
@app.route('/collections/{collection_id}/coverage')
def collection_coverage(request: Request, collection_id):
"""
OGC API - Coverages coverage endpoint
@@ -300,6 +289,9 @@ def collection_coverage(request: Request, collection_id):
:returns: Starlette HTTP Response
"""
if 'collection_id' in request.path_params:
collection_id = request.path_params['collection_id']
headers, status_code, content = api_.get_collection_coverage(
request.headers, request.query_params, collection_id)
@@ -311,7 +303,7 @@ def collection_coverage(request: Request, collection_id):
return response
@_route('/collections/<collection_id>/coverage/domainset')
@app.route('/collections/{collection_id}/coverage/domainset')
def collection_coverage_domainset(request: Request, collection_id):
"""
OGC API - Coverages coverage domainset endpoint
@@ -321,6 +313,9 @@ def collection_coverage_domainset(request: Request, collection_id):
:returns: Starlette HTTP Response
"""
if 'collection_id' in request.path_params:
collection_id = request.path_params['collection_id']
headers, status_code, content = api_.get_collection_coverage_domainset(
request.headers, request.query_params, collection_id)
@@ -332,7 +327,7 @@ def collection_coverage_domainset(request: Request, collection_id):
return response
@_route('/collections/<collection_id>/coverage/rangetype')
@app.route('/collections/{collection_id}/coverage/rangetype')
def collection_coverage_rangetype(request: Request, collection_id):
"""
OGC API - Coverages coverage rangetype endpoint
@@ -342,6 +337,9 @@ def collection_coverage_rangetype(request: Request, collection_id):
:returns: Starlette HTTP Response
"""
if 'collection_id' in request.path_params:
collection_id = request.path_params['collection_id']
headers, status_code, content = api_.get_collection_coverage_rangetype(
request.headers, request.query_params, collection_id)
@@ -353,10 +351,10 @@ def collection_coverage_rangetype(request: Request, collection_id):
return response
@_route('/processes')
@_route('/processes/')
@_route('/processes/{process_id}')
@_route('/processes/{process_id}/')
@app.route('/processes')
@app.route('/processes/')
@app.route('/processes/{process_id}')
@app.route('/processes/{process_id}/')
async def processes(request: Request, process_id=None):
"""
OGC API - Processes description endpoint
@@ -376,8 +374,8 @@ async def processes(request: Request, process_id=None):
return response
@_route('/processes/{process_id}/jobs', methods=['GET', 'POST'])
@_route('/processes/{process_id}/jobs/', methods=['GET', 'POST'])
@app.route('/processes/{process_id}/jobs', methods=['GET', 'POST'])
@app.route('/processes/{process_id}/jobs/', methods=['GET', 'POST'])
async def process_jobs(request: Request, process_id=None):
"""
OGC API - Processes jobs endpoint
@@ -401,7 +399,7 @@ async def process_jobs(request: Request, process_id=None):
return response
@_route('/stac')
@app.route('/stac')
async def stac_catalog_root(request: Request):
"""
STAC root endpoint
@@ -420,7 +418,7 @@ async def stac_catalog_root(request: Request):
return response
@_route('/stac/{path:path}')
@app.route('/stac/{path:path}')
async def stac_catalog_path(request: Request):
"""
STAC endpoint