app mount updates (#548)
* refactor WSGI mounting and add docs * fix ref * fix Starlette routing for OACov
This commit is contained in:
+43
-1
@@ -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
@@ -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
@@ -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
@@ -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
|
||||
|
||||
Reference in New Issue
Block a user