[Git][debian-gis-team/pygeoapi][upstream] New upstream version 0.16.1
Angelos Tzotsos (@kalxas-guest)
gitlab at salsa.debian.org
Fri Apr 5 13:57:44 BST 2024
Angelos Tzotsos pushed to branch upstream at Debian GIS Project / pygeoapi
Commits:
4f2e4bb8 by Angelos Tzotsos at 2024-04-05T15:51:05+03:00
New upstream version 0.16.1
- - - - -
6 changed files:
- docs/source/administration.rst
- docs/source/conf.py
- docs/source/openapi.rst
- pygeoapi/__init__.py
- pygeoapi/flask_app.py
- pygeoapi/openapi.py
Changes:
=====================================
docs/source/administration.rst
=====================================
@@ -49,6 +49,10 @@ To generate the OpenAPI document as JSON, run:
property names and their data types. Whenever you make changes to your pygeoapi configuration,
always refresh the accompanying OpenAPI document.
+.. note::
+ By default, pygeoapi OpenAPI document generation will fail on any collection whose provider is improperly
+ configured or when encountering a connection issue. To skip failing collections, use the
+ --no-fail-on-invalid-collection flag. The OpenAPI document will then be generated without the failing collection(s)
.. seealso::
:ref:`openapi` for more information on pygeoapi's OpenAPI support
=====================================
docs/source/conf.py
=====================================
@@ -112,7 +112,7 @@ today_fmt = '%Y-%m-%d'
# built documents.
#
# The short X.Y version.
-version = '0.16.0'
+version = '0.16.1'
# The full version, including alpha/beta/rc tags.
release = version
=====================================
docs/source/openapi.rst
=====================================
@@ -13,7 +13,7 @@ The official OpenAPI specification can be found `on GitHub <https://github.com/O
pygeoapi supports OpenAPI version 3.0.2.
As described in :ref:`administration`, the pygeoapi OpenAPI document is automatically generated based on the
-configuration file:
+configuration file.
The API is accessible at the ``/openapi`` endpoint, providing a Swagger-based webpage of the API description..
=====================================
pygeoapi/__init__.py
=====================================
@@ -30,7 +30,7 @@
#
# =================================================================
-__version__ = '0.16.0'
+__version__ = '0.16.1'
import click
try:
=====================================
pygeoapi/flask_app.py
=====================================
@@ -101,8 +101,11 @@ if (OGC_SCHEMAS_LOCATION is not None and
dirname_ = os.path.dirname(full_filepath)
basename_ = os.path.basename(full_filepath)
- # TODO: better sanitization?
- path_ = dirname_.replace('..', '').replace('//', '')
+ path_ = dirname_.replace('..', '').replace('//', '').replace('./', '')
+
+ if '..' in path_:
+ return 'Invalid path', 400
+
return send_from_directory(path_, basename_,
mimetype=get_mimetype(basename_))
=====================================
pygeoapi/openapi.py
=====================================
@@ -37,7 +37,7 @@ import json
import logging
import os
from pathlib import Path
-from typing import Union
+from typing import Tuple, Union
import click
from jsonschema import validate as jsonschema_validate
@@ -68,7 +68,14 @@ OPENAPI_YAML = {
THISDIR = os.path.dirname(os.path.realpath(__file__))
-def get_ogc_schemas_location(server_config):
+def get_ogc_schemas_location(server_config: dict) -> str:
+ """
+ Determine OGC schemas location
+
+ :param server_config: `dict` of server configuration
+
+ :returns: `str` of OGC schemas location
+ """
osl = server_config.get('ogc_schemas_location')
@@ -85,7 +92,7 @@ def get_ogc_schemas_location(server_config):
# TODO: remove this function once OGC API - Processing is final
-def gen_media_type_object(media_type, api_type, path):
+def gen_media_type_object(media_type: str, api_type: str, path: str) -> dict:
"""
Generates an OpenAPI Media Type Object
@@ -110,7 +117,8 @@ def gen_media_type_object(media_type, api_type, path):
# TODO: remove this function once OGC API - Processing is final
-def gen_response_object(description, media_type, api_type, path):
+def gen_response_object(description: str, media_type: str,
+ api_type: str, path: str) -> dict:
"""
Generates an OpenAPI Response Object
@@ -129,13 +137,15 @@ def gen_response_object(description, media_type, api_type, path):
return response
-def get_oas_30(cfg):
+def get_oas_30(cfg: dict, fail_on_invalid_collection: bool = True) -> dict:
"""
Generates an OpenAPI 3.0 Document
:param cfg: configuration object
+ :param fail_on_invalid_collection: `bool` of whether to fail on an invalid
+ collection
- :returns: OpenAPI definition YAML dict
+ :returns: dict of OpenAPI definition
"""
paths = {}
@@ -297,6 +307,16 @@ def get_oas_30(cfg):
'schema': {'$ref': '#/components/schemas/queryables'}
}
}
+ },
+ 'Tiles': {
+ 'description': 'Retrieves the tiles description for this collection', # noqa
+ 'content': {
+ 'application/json': {
+ 'schema': {
+ '$ref': '#/components/schemas/tiles'
+ }
+ }
+ }
}
},
'parameters': {
@@ -492,1084 +512,1115 @@ def get_oas_30(cfg):
'items': {'$ref': '#/components/schemas/queryable'}
}
}
+ },
+ 'tilematrixsetlink': {
+ 'type': 'object',
+ 'required': ['tileMatrixSet'],
+ 'properties': {
+ 'tileMatrixSet': {
+ 'type': 'string'
+ },
+ 'tileMatrixSetURI': {
+ 'type': 'string'
+ }
+ }
+ },
+ 'tiles': {
+ 'type': 'object',
+ 'required': [
+ 'tileMatrixSetLinks',
+ 'links'
+ ],
+ 'properties': {
+ 'tileMatrixSetLinks': {
+ 'type': 'array',
+ 'items': {
+ '$ref': '#/components/schemas/tilematrixsetlink' # noqa
+ }
+ },
+ 'links': {
+ 'type': 'array',
+ 'items': {'$ref': f"{OPENAPI_YAML['oapit']}#/components/schemas/link"} # noqa
+ }
+ }
}
}
}
- items_f = deepcopy(oas['components']['parameters']['f'])
- items_f['schema']['enum'].append('csv')
- items_l = deepcopy(oas['components']['parameters']['lang'])
-
LOGGER.debug('setting up datasets')
collections = filter_dict_by_key_value(cfg['resources'],
'type', 'collection')
for k, v in collections.items():
- if v.get('visibility', 'default') == 'hidden':
- LOGGER.debug(f'Skipping hidden layer: {k}')
- continue
- name = l10n.translate(k, locale_)
- title = l10n.translate(v['title'], locale_)
- desc = l10n.translate(v['description'], locale_)
- collection_name_path = f'/collections/{k}'
- tag = {
- 'name': name,
- 'description': desc,
- 'externalDocs': {}
+ try:
+ LOGGER.debug(f'Generating OpenAPI tags/paths for collection {k}')
+ r_tags, r_paths = handle_collection(locale_, oas['components'],
+ k, v)
+ oas['tags'].extend(r_tags)
+ paths.update(r_paths)
+ except Exception as err:
+ if fail_on_invalid_collection:
+ raise
+ else:
+ LOGGER.warning(f'Resource {k} not added to OpenAPI: {err}')
+
+ LOGGER.debug('setting up STAC')
+ stac_collections = filter_dict_by_key_value(cfg['resources'],
+ 'type', 'stac-collection')
+ if stac_collections:
+ paths['/stac'] = {
+ 'get': {
+ 'summary': 'SpatioTemporal Asset Catalog',
+ 'description': 'SpatioTemporal Asset Catalog',
+ 'tags': ['stac'],
+ 'operationId': 'getStacCatalog',
+ 'parameters': [],
+ 'responses': {
+ '200': {'$ref': '#/components/responses/200'},
+ 'default': {'$ref': '#/components/responses/default'}
+ }
+ }
}
- for link in l10n.translate(v.get('links', []), locale_):
- if link['type'] == 'information':
- tag['externalDocs']['description'] = link['type']
- tag['externalDocs']['url'] = link['url']
- break
- if len(tag['externalDocs']) == 0:
- del tag['externalDocs']
- oas['tags'].append(tag)
+ process_manager = get_manager(cfg)
- paths[collection_name_path] = {
+ if len(process_manager.processes) > 0:
+ paths['/processes'] = {
'get': {
- 'summary': f'Get {title} metadata',
- 'description': desc,
- 'tags': [name],
- 'operationId': f'describe{name.capitalize()}Collection',
+ 'summary': 'Processes',
+ 'description': 'Processes',
+ 'tags': ['server'],
+ 'operationId': 'getProcesses',
'parameters': [
- {'$ref': '#/components/parameters/f'},
- {'$ref': '#/components/parameters/lang'}
+ {'$ref': '#/components/parameters/f'}
],
'responses': {
- '200': {'$ref': f"{OPENAPI_YAML['oapif-1']}#/components/responses/Collection"}, # noqa
- '400': {'$ref': f"{OPENAPI_YAML['oapif-1']}#/components/responses/InvalidParameter"}, # noqa
- '404': {'$ref': f"{OPENAPI_YAML['oapif-1']}#/components/responses/NotFound"}, # noqa
- '500': {'$ref': f"{OPENAPI_YAML['oapif-1']}#/components/responses/ServerError"} # noqa
+ '200': {'$ref': f"{OPENAPI_YAML['oapip']}/responses/ProcessList.yaml"}, # noqa
+ 'default': {'$ref': '#/components/responses/default'}
}
}
}
+ LOGGER.debug('setting up processes')
- LOGGER.debug('setting up collection endpoints')
- try:
- ptype = None
-
- if filter_providers_by_type(
- collections[k]['providers'], 'feature'):
- ptype = 'feature'
-
- if filter_providers_by_type(
- collections[k]['providers'], 'record'):
- ptype = 'record'
-
- p = load_plugin('provider', get_provider_by_type(
- collections[k]['providers'], ptype))
-
- items_path = f'{collection_name_path}/items'
-
- coll_properties = deepcopy(oas['components']['parameters']['properties']) # noqa
+ for k, v in process_manager.processes.items():
+ if k.startswith('_'):
+ LOGGER.debug(f'Skipping hidden layer: {k}')
+ continue
+ name = l10n.translate(k, locale_)
+ p = process_manager.get_processor(k)
+ md_desc = l10n.translate(p.metadata['description'], locale_)
+ process_name_path = f'/processes/{name}'
+ tag = {
+ 'name': name,
+ 'description': md_desc, # noqa
+ 'externalDocs': {}
+ }
+ for link in p.metadata.get('links', []):
+ if link['type'] == 'information':
+ translated_link = l10n.translate(link, locale_)
+ tag['externalDocs']['description'] = translated_link[
+ 'type']
+ tag['externalDocs']['url'] = translated_link['url']
+ break
+ if len(tag['externalDocs']) == 0:
+ del tag['externalDocs']
- coll_properties['schema']['items']['enum'] = list(p.fields.keys())
+ oas['tags'].append(tag)
- paths[items_path] = {
+ paths[process_name_path] = {
'get': {
- 'summary': f'Get {title} items',
- 'description': desc,
+ 'summary': 'Get process metadata',
+ 'description': md_desc,
'tags': [name],
- 'operationId': f'get{name.capitalize()}Features',
+ 'operationId': f'describe{name.capitalize()}Process',
'parameters': [
- items_f,
- items_l,
- {'$ref': '#/components/parameters/bbox'},
- {'$ref': f"{OPENAPI_YAML['oapif-1']}#/components/parameters/limit"}, # noqa
- {'$ref': '#/components/parameters/crs'}, # noqa
- {'$ref': '#/components/parameters/bbox-crs'}, # noqa
- coll_properties,
- {'$ref': '#/components/parameters/vendorSpecificParameters'}, # noqa
- {'$ref': '#/components/parameters/skipGeometry'},
- {'$ref': f"{OPENAPI_YAML['oapir']}/parameters/sortby.yaml"}, # noqa
- {'$ref': '#/components/parameters/offset'},
+ {'$ref': '#/components/parameters/f'}
],
'responses': {
- '200': {'$ref': f"{OPENAPI_YAML['oapif-1']}#/components/responses/Features"}, # noqa
- '400': {'$ref': f"{OPENAPI_YAML['oapif-1']}#/components/responses/InvalidParameter"}, # noqa
- '404': {'$ref': f"{OPENAPI_YAML['oapif-1']}#/components/responses/NotFound"}, # noqa
- '500': {'$ref': f"{OPENAPI_YAML['oapif-1']}#/components/responses/ServerError"} # noqa
- }
- },
- 'options': {
- 'summary': f'Options for {title} items',
- 'description': desc,
- 'tags': [name],
- 'operationId': f'options{name.capitalize()}Features',
- 'responses': {
- '200': {'description': 'options response'}
+ '200': {'$ref': '#/components/responses/200'},
+ 'default': {'$ref': '#/components/responses/default'}
}
}
}
- if p.editable:
- LOGGER.debug('Provider is editable; adding post')
-
- paths[items_path]['post'] = {
- 'summary': f'Add {title} items',
- 'description': desc,
+ paths[f'{process_name_path}/execution'] = {
+ 'post': {
+ 'summary': f"Process {l10n.translate(p.metadata['title'], locale_)} execution", # noqa
+ 'description': md_desc,
'tags': [name],
- 'operationId': f'add{name.capitalize()}Features',
+ 'operationId': f'execute{name.capitalize()}Job',
+ 'responses': {
+ '200': {'$ref': '#/components/responses/200'},
+ '201': {'$ref': f"{OPENAPI_YAML['oapip']}/responses/ExecuteAsync.yaml"}, # noqa
+ '404': {'$ref': f"{OPENAPI_YAML['oapip']}/responses/NotFound.yaml"}, # noqa
+ '500': {'$ref': f"{OPENAPI_YAML['oapip']}/responses/ServerError.yaml"}, # noqa
+ 'default': {'$ref': '#/components/responses/default'}
+ },
'requestBody': {
- 'description': 'Adds item to collection',
+ 'description': 'Mandatory execute request JSON',
+ 'required': True,
'content': {
- 'application/geo+json': {
- 'schema': {}
+ 'application/json': {
+ 'schema': {
+ '$ref': f"{OPENAPI_YAML['oapip']}/schemas/execute.yaml" # noqa
+ }
}
- },
- 'required': True
- },
- 'responses': {
- '201': {'description': 'Successful creation'},
- '400': {'$ref': f"{OPENAPI_YAML['oapif-1']}#/components/responses/InvalidParameter"}, # noqa
- '500': {'$ref': f"{OPENAPI_YAML['oapif-1']}#/components/responses/ServerError"} # noqa
+ }
}
}
+ }
+ if 'example' in p.metadata:
+ paths[f'{process_name_path}/execution']['post']['requestBody']['content']['application/json']['example'] = p.metadata['example'] # noqa
- try:
- schema_ref = p.get_schema(SchemaType.create)
- paths[items_path]['post']['requestBody']['content'][schema_ref[0]] = { # noqa
- 'schema': schema_ref[1]
- }
- except Exception as err:
- LOGGER.debug(err)
-
- if ptype == 'record':
- paths[items_path]['get']['parameters'].append(
- {'$ref': f"{OPENAPI_YAML['oapir']}/parameters/q.yaml"})
- if p.fields:
- schema_path = f'{collection_name_path}/schema'
-
- paths[schema_path] = {
- 'get': {
- 'summary': f'Get {title} schema',
- 'description': desc,
- 'tags': [name],
- 'operationId': f'get{name.capitalize()}Queryables',
- 'parameters': [
- items_f,
- items_l
- ],
- 'responses': {
- '200': {'$ref': '#/components/responses/Queryables'}, # noqa
- '400': {'$ref': f"{OPENAPI_YAML['oapif-1']}#/components/responses/InvalidParameter"}, # noqa
- '404': {'$ref': f"{OPENAPI_YAML['oapif-1']}#/components/responses/NotFound"}, # noqa
- '500': {'$ref': f"{OPENAPI_YAML['oapif-1']}#/components/responses/ServerError"}, # noqa
- }
- }
+ name_in_path = {
+ 'name': 'jobId',
+ 'in': 'path',
+ 'description': 'job identifier',
+ 'required': True,
+ 'schema': {
+ 'type': 'string'
}
+ }
- queryables_path = f'{collection_name_path}/queryables'
-
- paths[queryables_path] = {
- 'get': {
- 'summary': f'Get {title} queryables',
- 'description': desc,
- 'tags': [name],
- 'operationId': f'get{name.capitalize()}Queryables',
- 'parameters': [
- items_f,
- items_l
- ],
- 'responses': {
- '200': {'$ref': '#/components/responses/Queryables'}, # noqa
- '400': {'$ref': f"{OPENAPI_YAML['oapif-1']}#/components/responses/InvalidParameter"}, # noqa
- '404': {'$ref': f"{OPENAPI_YAML['oapif-1']}#/components/responses/NotFound"}, # noqa
- '500': {'$ref': f"{OPENAPI_YAML['oapif-1']}#/components/responses/ServerError"}, # noqa
- }
- }
+ paths['/jobs'] = {
+ 'get': {
+ 'summary': 'Retrieve jobs list',
+ 'description': 'Retrieve a list of jobs',
+ 'tags': ['jobs'],
+ 'operationId': 'getJobs',
+ 'responses': {
+ '200': {'$ref': '#/components/responses/200'},
+ '404': {'$ref': f"{OPENAPI_YAML['oapip']}/responses/NotFound.yaml"}, # noqa
+ 'default': {'$ref': '#/components/responses/default'}
}
+ }
+ }
- if p.time_field is not None:
- paths[items_path]['get']['parameters'].append(
- {'$ref': f"{OPENAPI_YAML['oapif-1']}#/components/parameters/datetime"}) # noqa
+ paths['/jobs/{jobId}'] = {
+ 'get': {
+ 'summary': 'Retrieve job details',
+ 'description': 'Retrieve job details',
+ 'tags': ['jobs'],
+ 'parameters': [
+ name_in_path,
+ {'$ref': '#/components/parameters/f'}
+ ],
+ 'operationId': 'getJob',
+ 'responses': {
+ '200': {'$ref': '#/components/responses/200'},
+ '404': {'$ref': f"{OPENAPI_YAML['oapip']}/responses/NotFound.yaml"}, # noqa
+ 'default': {'$ref': '#/components/responses/default'} # noqa
+ }
+ },
+ 'delete': {
+ 'summary': 'Cancel / delete job',
+ 'description': 'Cancel / delete job',
+ 'tags': ['jobs'],
+ 'parameters': [
+ name_in_path
+ ],
+ 'operationId': 'deleteJob',
+ 'responses': {
+ '204': {'$ref': '#/components/responses/204'},
+ '404': {'$ref': f"{OPENAPI_YAML['oapip']}/responses/NotFound.yaml"}, # noqa
+ 'default': {'$ref': '#/components/responses/default'} # noqa
+ }
+ },
+ }
- for field, type_ in p.fields.items():
+ paths['/jobs/{jobId}/results'] = {
+ 'get': {
+ 'summary': 'Retrieve job results',
+ 'description': 'Retrive job resiults',
+ 'tags': ['jobs'],
+ 'parameters': [
+ name_in_path,
+ {'$ref': '#/components/parameters/f'}
+ ],
+ 'operationId': 'getJobResults',
+ 'responses': {
+ '200': {'$ref': '#/components/responses/200'},
+ '404': {'$ref': f"{OPENAPI_YAML['oapip']}/responses/NotFound.yaml"}, # noqa
+ 'default': {'$ref': '#/components/responses/default'} # noqa
+ }
+ }
+ }
- if p.properties and field not in p.properties:
- LOGGER.debug('Provider specified not to advertise property') # noqa
- continue
+ tag = {
+ 'name': 'jobs',
+ 'description': 'Process jobs',
+ }
+ oas['tags'].insert(1, tag)
- if field == 'q' and ptype == 'record':
- LOGGER.debug('q parameter already declared, skipping')
- continue
+ oas['paths'] = paths
- if type_ == 'date':
- schema = {
- 'type': 'string',
- 'format': 'date'
- }
- elif type_ == 'float':
- schema = {
- 'type': 'number',
- 'format': 'float'
- }
- elif type_ == 'long':
- schema = {
- 'type': 'integer',
- 'format': 'int64'
- }
- else:
- schema = type_
+ if cfg['server'].get('admin', False):
+ schema_dict = get_config_schema()
+ oas['definitions'] = schema_dict['definitions']
+ LOGGER.debug('Adding admin endpoints')
+ oas['paths'].update(get_admin())
- path_ = f'{collection_name_path}/items'
- paths[path_]['get']['parameters'].append({
- 'name': field,
- 'in': 'query',
- 'required': False,
- 'schema': schema,
- 'style': 'form',
- 'explode': False
- })
+ return oas
- paths[f'{collection_name_path}/items/{{featureId}}'] = {
- 'get': {
- 'summary': f'Get {title} item by id',
- 'description': desc,
- 'tags': [name],
- 'operationId': f'get{name.capitalize()}Feature',
- 'parameters': [
- {'$ref': f"{OPENAPI_YAML['oapif-1']}#/components/parameters/featureId"}, # noqa
- {'$ref': '#/components/parameters/crs'}, # noqa
- {'$ref': '#/components/parameters/f'},
- {'$ref': '#/components/parameters/lang'}
- ],
- 'responses': {
- '200': {'$ref': f"{OPENAPI_YAML['oapif-1']}#/components/responses/Feature"}, # noqa
- '400': {'$ref': f"{OPENAPI_YAML['oapif-1']}#/components/responses/InvalidParameter"}, # noqa
- '404': {'$ref': f"{OPENAPI_YAML['oapif-1']}#/components/responses/NotFound"}, # noqa
- '500': {'$ref': f"{OPENAPI_YAML['oapif-1']}#/components/responses/ServerError"} # noqa
- }
- },
- 'options': {
- 'summary': f'Options for {title} item by id',
- 'description': desc,
- 'tags': [name],
- 'operationId': f'options{name.capitalize()}Feature',
- 'parameters': [
- {'$ref': f"{OPENAPI_YAML['oapif-1']}#/components/parameters/featureId"} # noqa
- ],
- 'responses': {
- '200': {'description': 'options response'}
- }
- }
- }
- try:
- schema_ref = p.get_schema()
- paths[f'{collection_name_path}/items/{{featureId}}']['get']['responses']['200'] = { # noqa
- 'content': {
- schema_ref[0]: {
- 'schema': schema_ref[1]
- }
- }
- }
- except Exception as err:
- LOGGER.debug(err)
+def get_config_schema() -> dict:
+ """
+ Get configuration schema
- if p.editable:
- LOGGER.debug('Provider is editable; adding put/delete')
- put_path = f'{collection_name_path}/items/{{featureId}}' # noqa
- paths[put_path]['put'] = { # noqa
- 'summary': f'Update {title} items',
- 'description': desc,
- 'tags': [name],
- 'operationId': f'update{name.capitalize()}Features',
- 'parameters': [
- {'$ref': f"{OPENAPI_YAML['oapif-1']}#/components/parameters/featureId"} # noqa
- ],
- 'requestBody': {
- 'description': 'Updates item in collection',
- 'content': {
- 'application/geo+json': {
- 'schema': {}
- }
- },
- 'required': True
- },
- 'responses': {
- '204': {'$ref': '#/components/responses/204'},
- '400': {'$ref': f"{OPENAPI_YAML['oapif-1']}#/components/responses/InvalidParameter"}, # noqa
- '500': {'$ref': f"{OPENAPI_YAML['oapif-1']}#/components/responses/ServerError"} # noqa
- }
- }
+ :returns: `dict` of configuration schema
+ """
- try:
- schema_ref = p.get_schema(SchemaType.replace)
- paths[put_path]['put']['requestBody']['content'][schema_ref[0]] = { # noqa
- 'schema': schema_ref[1]
- }
- except Exception as err:
- LOGGER.debug(err)
+ schema_file = os.path.join(THISDIR, 'schemas', 'config',
+ 'pygeoapi-config-0.x.yml')
- paths[f'{collection_name_path}/items/{{featureId}}']['delete'] = { # noqa
- 'summary': f'Delete {title} items',
- 'description': desc,
- 'tags': [name],
- 'operationId': f'delete{name.capitalize()}Features',
- 'parameters': [
- {'$ref': f"{OPENAPI_YAML['oapif-1']}#/components/parameters/featureId"}, # noqa
- ],
- 'responses': {
- '200': {'description': 'Successful delete'},
- '400': {'$ref': f"{OPENAPI_YAML['oapif-1']}#/components/responses/InvalidParameter"}, # noqa
- '500': {'$ref': f"{OPENAPI_YAML['oapif-1']}#/components/responses/ServerError"} # noqa
- }
- }
+ with open(schema_file) as fh2:
+ return yaml_load(fh2)
- except ProviderTypeError:
- LOGGER.debug('collection is not feature based')
- LOGGER.debug('setting up coverage endpoints')
- try:
- load_plugin('provider', get_provider_by_type(
- collections[k]['providers'], 'coverage'))
-
- coverage_path = f'{collection_name_path}/coverage'
+def get_admin() -> dict:
+ """
+ Generate admin paths for OpenAPI Document
- paths[coverage_path] = {
- 'get': {
- 'summary': f'Get {title} coverage',
- 'description': desc,
- 'tags': [name],
- 'operationId': f'get{name.capitalize()}Coverage',
- 'parameters': [
- items_f,
- items_l,
- {'$ref': '#/components/parameters/bbox'},
- {'$ref': '#/components/parameters/bbox-crs'}, # noqa
- ],
- 'responses': {
- '200': {'$ref': f"{OPENAPI_YAML['oapif-1']}#/components/responses/Features"}, # noqa
- '400': {'$ref': f"{OPENAPI_YAML['oapif-1']}#/components/responses/InvalidParameter"}, # noqa
- '404': {'$ref': f"{OPENAPI_YAML['oapif-1']}#/components/responses/NotFound"}, # noqa
- '500': {'$ref': f"{OPENAPI_YAML['oapif-1']}#/components/responses/ServerError"} # noqa
- }
- }
- }
+ :returns: `dict` of paths
+ """
- except ProviderTypeError:
- LOGGER.debug('collection is not coverage based')
+ schema_dict = get_config_schema()
- LOGGER.debug('setting up tiles endpoints')
- tile_extension = filter_providers_by_type(
- collections[k]['providers'], 'tile')
+ paths = {}
- if tile_extension:
- tp = load_plugin('provider', tile_extension)
- oas['components']['responses'].update({
- 'Tiles': {
- 'description': 'Retrieves the tiles description for this collection', # noqa
- 'content': {
- 'application/json': {
- 'schema': {
- '$ref': '#/components/schemas/tiles'
- }
- }
+ paths['/admin/config'] = {
+ 'get': {
+ 'summary': 'Get admin configuration',
+ 'description': 'Get admin configuration',
+ 'tags': ['admin'],
+ 'operationId': 'getAdminConfig',
+ 'parameters': [
+ {'$ref': '#/components/parameters/f'},
+ {'$ref': '#/components/parameters/lang'}
+ ],
+ 'responses': {
+ '200': {
+ 'content': {
+ 'application/json': {
+ 'schema': schema_dict
}
}
}
- )
-
- oas['components']['schemas'].update({
- 'tilematrixsetlink': {
- 'type': 'object',
- 'required': ['tileMatrixSet'],
- 'properties': {
- 'tileMatrixSet': {
- 'type': 'string'
- },
- 'tileMatrixSetURI': {
- 'type': 'string'
- }
- }
- },
- 'tiles': {
- 'type': 'object',
- 'required': [
- 'tileMatrixSetLinks',
- 'links'
- ],
- 'properties': {
- 'tileMatrixSetLinks': {
- 'type': 'array',
- 'items': {
- '$ref': '#/components/schemas/tilematrixsetlink' # noqa
- }
- },
- 'links': {
- 'type': 'array',
- 'items': {'$ref': f"{OPENAPI_YAML['oapit']}#/components/schemas/link"} # noqa
- }
- }
+ }
+ },
+ 'put': {
+ 'summary': 'Update admin configuration full',
+ 'description': 'Update admin configuration full',
+ 'tags': ['admin'],
+ 'operationId': 'putAdminConfig',
+ 'requestBody': {
+ 'description': 'Updates admin configuration',
+ 'content': {
+ 'application/json': {
+ 'schema': schema_dict
}
- }
- )
-
- tiles_path = f'{collection_name_path}/tiles'
-
- paths[tiles_path] = {
- 'get': {
- 'summary': f'Fetch a {title} tiles description',
- 'description': desc,
- 'tags': [name],
- 'operationId': f'describe{name.capitalize()}Tiles',
- 'parameters': [
- items_f,
- # items_l TODO: is this useful?
- ],
- 'responses': {
- '200': {'$ref': '#/components/responses/Tiles'},
- '400': {'$ref': f"{OPENAPI_YAML['oapif-1']}#/components/responses/InvalidParameter"}, # noqa
- '404': {'$ref': f"{OPENAPI_YAML['oapif-1']}#/components/responses/NotFound"}, # noqa
- '500': {'$ref': f"{OPENAPI_YAML['oapif-1']}#/components/responses/ServerError"} # noqa
+ },
+ 'required': True
+ },
+ 'responses': {
+ '204': {'$ref': '#/components/responses/204'},
+ '400': {'$ref': f"{OPENAPI_YAML['oapif-1']}#/components/responses/InvalidParameter"}, # noqa
+ '500': {'$ref': f"{OPENAPI_YAML['oapif-1']}#/components/responses/ServerError"} # noqa
+ }
+ },
+ 'patch': {
+ 'summary': 'Partially update admin configuration',
+ 'description': 'Partially update admin configuration',
+ 'tags': ['admin'],
+ 'operationId': 'patchAdminConfig',
+ 'requestBody': {
+ 'description': 'Updates admin configuration',
+ 'content': {
+ 'application/json': {
+ 'schema': schema_dict
}
- }
+ },
+ 'required': True
+ },
+ 'responses': {
+ '204': {'$ref': '#/components/responses/204'},
+ '400': {'$ref': f"{OPENAPI_YAML['oapif-1']}#/components/responses/InvalidParameter"}, # noqa
+ '500': {'$ref': f"{OPENAPI_YAML['oapif-1']}#/components/responses/ServerError"} # noqa
}
-
- tiles_data_path = f'{collection_name_path}/tiles/{{tileMatrixSetId}}/{{tileMatrix}}/{{tileRow}}/{{tileCol}}' # noqa
-
- paths[tiles_data_path] = {
- 'get': {
- 'summary': f'Get a {title} tile',
- 'description': desc,
- 'tags': [name],
- 'operationId': f'get{name.capitalize()}Tiles',
- 'parameters': [
- {'$ref': f"{OPENAPI_YAML['oapit']}#/components/parameters/tileMatrixSetId"}, # noqa
- {'$ref': f"{OPENAPI_YAML['oapit']}#/components/parameters/tileMatrix"}, # noqa
- {'$ref': f"{OPENAPI_YAML['oapit']}#/components/parameters/tileRow"}, # noqa
- {'$ref': f"{OPENAPI_YAML['oapit']}#/components/parameters/tileCol"}, # noqa
- {
- 'name': 'f',
- 'in': 'query',
- 'description': 'The optional f parameter indicates the output format which the server shall provide as part of the response document.', # noqa
- 'required': False,
- 'schema': {
- 'type': 'string',
- 'enum': [tp.format_type],
- 'default': tp.format_type
- },
- 'style': 'form',
- 'explode': False
+ }
+ }
+ paths['/admin/config/resources'] = {
+ 'get': {
+ 'summary': 'Get admin configuration resources',
+ 'description': 'Get admin configuration resources',
+ 'tags': ['admin'],
+ 'operationId': 'getAdminConfigResources',
+ 'parameters': [
+ {'$ref': '#/components/parameters/f'},
+ {'$ref': '#/components/parameters/lang'}
+ ],
+ 'responses': {
+ '200': {
+ 'content': {
+ 'application/json': {
+ 'schema': schema_dict['properties']['resources']['patternProperties']['^.*$'] # noqa
}
- ],
- 'responses': {
- '400': {'$ref': f"{OPENAPI_YAML['oapif-1']}#/components/responses/InvalidParameter"}, # noqa
- '404': {'$ref': f"{OPENAPI_YAML['oapif-1']}#/components/responses/NotFound"}, # noqa
- '500': {'$ref': f"{OPENAPI_YAML['oapif-1']}#/components/responses/ServerError"} # noqa
}
}
}
- mimetype = tile_extension['format']['mimetype']
- paths[tiles_data_path]['get']['responses']['200'] = {
- 'description': 'successful operation',
+ },
+ 'post': {
+ 'summary': 'Create admin configuration resource',
+ 'description': 'Create admin configuration resource',
+ 'tags': ['admin'],
+ 'operationId': 'postAdminConfigResource',
+ 'requestBody': {
+ 'description': 'Adds resource to configuration',
'content': {
- mimetype: {
- 'schema': {
- 'type': 'string',
- 'format': 'binary'
+ 'application/json': {
+ 'schema': schema_dict['properties']['resources']['patternProperties']['^.*$'] # noqa
+ }
+ },
+ 'required': True
+ },
+ 'responses': {
+ '201': {'description': 'Successful creation'},
+ '400': {'$ref': f"{OPENAPI_YAML['oapif-1']}#/components/responses/InvalidParameter"}, # noqa
+ '500': {'$ref': f"{OPENAPI_YAML['oapif-1']}#/components/responses/ServerError"} # noqa
+ }
+ },
+ }
+ paths['/admin/config/resources/{resourceId}'] = {
+ 'get': {
+ 'summary': 'Get admin configuration resource',
+ 'description': 'Get admin configuration resource',
+ 'tags': ['admin'],
+ 'operationId': 'getAdminConfigResource',
+ 'parameters': [
+ {'$ref': '#/components/parameters/resourceId'},
+ {'$ref': '#/components/parameters/f'},
+ {'$ref': '#/components/parameters/lang'}
+ ],
+ 'responses': {
+ '200': {
+ 'content': {
+ 'application/json': {
+ 'schema': schema_dict['properties']['resources']['patternProperties']['^.*$'] # noqa
}
}
}
}
+ },
+ 'put': {
+ 'summary': 'Update admin configuration resource',
+ 'description': 'Update admin configuration resource',
+ 'tags': ['admin'],
+ 'operationId': 'putAdminConfigResource',
+ 'parameters': [
+ {'$ref': '#/components/parameters/resourceId'},
+ ],
+ 'requestBody': {
+ 'description': 'Updates admin configuration resource',
+ 'content': {
+ 'application/json': {
+ 'schema': schema_dict['properties']['resources']['patternProperties']['^.*$'] # noqa
+ }
+ },
+ 'required': True
+ },
+ 'responses': {
+ '204': {'$ref': '#/components/responses/204'},
+ '400': {'$ref': f"{OPENAPI_YAML['oapif-1']}#/components/responses/InvalidParameter"}, # noqa
+ '500': {'$ref': f"{OPENAPI_YAML['oapif-1']}#/components/responses/ServerError"} # noqa
+ }
+ },
+ 'patch': {
+ 'summary': 'Partially update admin configuration resource',
+ 'description': 'Partially update admin configuration resource',
+ 'tags': ['admin'],
+ 'operationId': 'patchAdminConfigResource',
+ 'parameters': [
+ {'$ref': '#/components/parameters/resourceId'},
+ ],
+ 'requestBody': {
+ 'description': 'Updates admin configuration resource',
+ 'content': {
+ 'application/json': {
+ 'schema': schema_dict['properties']['resources']['patternProperties']['^.*$'] # noqa
+ }
+ },
+ 'required': True
+ },
+ 'responses': {
+ '204': {'$ref': '#/components/responses/204'},
+ '400': {'$ref': f"{OPENAPI_YAML['oapif-1']}#/components/responses/InvalidParameter"}, # noqa
+ '500': {'$ref': f"{OPENAPI_YAML['oapif-1']}#/components/responses/ServerError"} # noqa
+ }
+ },
+ 'delete': {
+ 'summary': 'Delete admin configuration resource',
+ 'description': 'Delete admin configuration resource',
+ 'tags': ['admin'],
+ 'operationId': 'deleteAdminConfigResource',
+ 'parameters': [
+ {'$ref': '#/components/parameters/resourceId'},
+ ],
+ 'responses': {
+ '204': {'$ref': '#/components/responses/204'},
+ '404': {'$ref': f"{OPENAPI_YAML['oapip']}/responses/NotFound.yaml"}, # noqa
+ 'default': {'$ref': '#/components/responses/default'} # noqa
+ }
+ }
+ }
- LOGGER.debug('setting up edr endpoints')
- edr_extension = filter_providers_by_type(
- collections[k]['providers'], 'edr')
+ return paths
- if edr_extension:
- ep = load_plugin('provider', edr_extension)
- edr_query_endpoints = []
+def handle_collection(locale_: str, components: dict, collection_id: str,
+ collection_def: dict) -> Tuple[list, dict]:
+ """
+ Generate relevant OpenAPI constructs for a given collection
- for qt in [qt for qt in ep.get_query_types() if qt != 'locations']:
- edr_query_endpoints.append({
- 'path': f'{collection_name_path}/{qt}',
- 'qt': qt,
- 'op_id': f'query{qt.capitalize()}{k.capitalize()}'
- })
- if ep.instances:
- edr_query_endpoints.append({
- 'path': f'{collection_name_path}/instances/{{instanceId}}/{qt}', # noqa
- 'qt': qt,
- 'op_id': f'query{qt.capitalize()}Instance{k.capitalize()}' # noqa
- })
-
- for eqe in edr_query_endpoints:
- if eqe['qt'] == 'cube':
- spatial_parameter = 'bbox'
- else:
- spatial_parameter = f"{eqe['qt']}Coords"
- paths[eqe['path']] = {
- 'get': {
- 'summary': f"query {v['description']} by {eqe['qt']}", # noqa
- 'description': v['description'],
- 'tags': [k],
- 'operationId': eqe['op_id'],
- 'parameters': [
- {'$ref': f"{OPENAPI_YAML['oaedr']}/parameters/{spatial_parameter}.yaml"}, # noqa
- {'$ref': f"{OPENAPI_YAML['oapif-1']}#/components/parameters/datetime"}, # noqa
- {'$ref': f"{OPENAPI_YAML['oaedr']}/parameters/parameter-name.yaml"}, # noqa
- {'$ref': f"{OPENAPI_YAML['oaedr']}/parameters/z.yaml"}, # noqa
- {'$ref': '#/components/parameters/f'}
- ],
- 'responses': {
- '200': {
- 'description': 'Response',
- 'content': {
- 'application/prs.coverage+json': {
- 'schema': {
- '$ref': f"{OPENAPI_YAML['oaedr']}/schemas/coverageJSON.yaml" # noqa
- }
- }
- }
- }
- }
- }
- }
- if 'locations' in ep.get_query_types():
- paths[f'{collection_name_path}/locations'] = {
- 'get': {
- 'summary': f"Get pre-defined locations of {v['description']}", # noqa
- 'description': v['description'],
- 'tags': [k],
- 'operationId': f'queryLOCATIONS{k.capitalize()}',
- 'parameters': [
- {'$ref': f"{OPENAPI_YAML['oaedr']}/parameters/bbox.yaml"}, # noqa
- {'$ref': f"{OPENAPI_YAML['oapif-1']}#/components/parameters/datetime"}, # noqa
- {'$ref': '#/components/parameters/f'}
- ],
- 'responses': {
- '200': {'$ref': f"{OPENAPI_YAML['oapif-1']}#/components/responses/Features"}, # noqa
- '400': {'$ref': f"{OPENAPI_YAML['oapif-1']}#/components/responses/InvalidParameter"}, # noqa
- '500': {'$ref': f"{OPENAPI_YAML['oapif-1']}#/components/responses/ServerError"} # noqa
- }
- }
- }
- paths[f'{collection_name_path}/locations/{{locId}}'] = {
- 'get': {
- 'summary': f"query {v['description']} by location", # noqa
- 'description': v['description'],
- 'tags': [k],
- 'operationId': f'queryLOCATIONSBYID{k.capitalize()}',
- 'parameters': [
- {'$ref': f"{OPENAPI_YAML['oaedr']}/parameters/{spatial_parameter}.yaml"}, # noqa
- {'$ref': f"{OPENAPI_YAML['oaedr']}/parameters/locationId.yaml"}, # noqa
- {'$ref': f"{OPENAPI_YAML['oapif-1']}#/components/parameters/datetime"}, # noqa
- {'$ref': f"{OPENAPI_YAML['oaedr']}/parameters/parameter-name.yaml"}, # noqa
- {'$ref': f"{OPENAPI_YAML['oaedr']}/parameters/z.yaml"}, # noqa
- {'$ref': '#/components/parameters/f'}
- ],
- 'responses': {
- '200': {
- 'description': 'Response',
- 'content': {
- 'application/prs.coverage+json': {
- 'schema': {
- '$ref': f"{OPENAPI_YAML['oaedr']}/schemas/coverageJSON.yaml" # noqa
- }
- }
- }
- }
- }
- }
- }
+ :param locale_: locale
+ :param components: OpenAPI components
+ :param collection_id: collection identifier
+ :param collection_def: collection definition
- LOGGER.debug('setting up maps endpoints')
- map_extension = filter_providers_by_type(
- collections[k]['providers'], 'map')
+ :returns: `tuple` of `list` of tags and `dict` of paths
+ """
- if map_extension:
- mp = load_plugin('provider', map_extension)
+ paths = {}
+ tags = []
- map_f = deepcopy(oas['components']['parameters']['f'])
- map_f['schema']['enum'] = [map_extension['format']['name']]
- map_f['schema']['default'] = map_extension['format']['name']
+ items_f = deepcopy(components['parameters']['f'])
+ items_f['schema']['enum'].append('csv')
+ items_l = deepcopy(components['parameters']['lang'])
- pth = f'/collections/{k}/map'
- paths[pth] = {
- 'get': {
- 'summary': 'Get map',
- 'description': f"{v['description']} map",
- 'tags': [k],
- 'operationId': 'getMap',
- 'parameters': [
- {'$ref': '#/components/parameters/bbox'},
- {'$ref': f"{OPENAPI_YAML['oapif-1']}#/components/parameters/datetime"}, # noqa
- {
- 'name': 'width',
- 'in': 'query',
- 'description': 'Response image width',
- 'required': False,
- 'schema': {
- 'type': 'integer',
- },
- 'style': 'form',
- 'explode': False
- },
- {
- 'name': 'height',
- 'in': 'query',
- 'description': 'Response image height',
- 'required': False,
- 'schema': {
- 'type': 'integer',
- },
- 'style': 'form',
- 'explode': False
- },
- {
- 'name': 'transparent',
- 'in': 'query',
- 'description': 'Background transparency of map (default=true).', # noqa
- 'required': False,
- 'schema': {
- 'type': 'boolean',
- 'default': True,
- },
- 'style': 'form',
- 'explode': False
- },
- {'$ref': '#/components/parameters/bbox-crs-epsg'},
- map_f
- ],
- 'responses': {
- '200': {
- 'description': 'Response',
- 'content': {
- 'application/json': {}
- }
- },
- '400': {'$ref': f"{OPENAPI_YAML['oapif-1']}#/components/responses/InvalidParameter"}, # noqa
- '500': {'$ref': f"{OPENAPI_YAML['oapif-1']}#/components/responses/ServerError"}, # noqa
- }
- }
- }
- if mp.time_field is not None:
- paths[pth]['get']['parameters'].append(
- {'$ref': f"{OPENAPI_YAML['oapif-1']}#/components/parameters/datetime"}) # noqa
+ if collection_def.get('visibility', 'default') == 'hidden':
+ LOGGER.debug(f'Skipping hidden layer: {collection_id}')
+ return [], {}
- LOGGER.debug('setting up STAC')
- stac_collections = filter_dict_by_key_value(cfg['resources'],
- 'type', 'stac-collection')
- if stac_collections:
- paths['/stac'] = {
- 'get': {
- 'summary': 'SpatioTemporal Asset Catalog',
- 'description': 'SpatioTemporal Asset Catalog',
- 'tags': ['stac'],
- 'operationId': 'getStacCatalog',
- 'parameters': [],
- 'responses': {
- '200': {'$ref': '#/components/responses/200'},
- 'default': {'$ref': '#/components/responses/default'}
- }
+ name = l10n.translate(collection_id, locale_)
+ title = l10n.translate(collection_def['title'], locale_)
+ desc = l10n.translate(collection_def['description'], locale_)
+ collection_name_path = f'/collections/{collection_id}'
+
+ tag = {
+ 'name': name,
+ 'description': desc,
+ 'externalDocs': {}
+ }
+
+ for link in l10n.translate(collection_def.get('links', []), locale_):
+ if link['type'] == 'information':
+ tag['externalDocs']['description'] = link['type']
+ tag['externalDocs']['url'] = link['url']
+ break
+
+ if len(tag['externalDocs']) == 0:
+ del tag['externalDocs']
+
+ tags.append(tag)
+
+ paths[collection_name_path] = {
+ 'get': {
+ 'summary': f'Get {title} metadata',
+ 'description': desc,
+ 'tags': [name],
+ 'operationId': f'describe{name.capitalize()}Collection',
+ 'parameters': [
+ {'$ref': '#/components/parameters/f'},
+ {'$ref': '#/components/parameters/lang'}
+ ],
+ 'responses': {
+ '200': {'$ref': f"{OPENAPI_YAML['oapif-1']}#/components/responses/Collection"}, # noqa
+ '400': {'$ref': f"{OPENAPI_YAML['oapif-1']}#/components/responses/InvalidParameter"}, # noqa
+ '404': {'$ref': f"{OPENAPI_YAML['oapif-1']}#/components/responses/NotFound"}, # noqa
+ '500': {'$ref': f"{OPENAPI_YAML['oapif-1']}#/components/responses/ServerError"} # noqa
}
}
+ }
- process_manager = get_manager(cfg)
+ LOGGER.debug('setting up collection endpoints')
+ try:
+ ptype = None
- if len(process_manager.processes) > 0:
- paths['/processes'] = {
+ if filter_providers_by_type(collection_def['providers'], 'feature'):
+ ptype = 'feature'
+
+ if filter_providers_by_type(collection_def['providers'], 'record'):
+ ptype = 'record'
+
+ p = load_plugin('provider', get_provider_by_type(
+ collection_def['providers'], ptype))
+
+ items_path = f'{collection_name_path}/items'
+
+ coll_properties = deepcopy(components['parameters']['properties']) # noqa
+
+ coll_properties['schema']['items']['enum'] = list(p.fields.keys())
+
+ paths[items_path] = {
'get': {
- 'summary': 'Processes',
- 'description': 'Processes',
- 'tags': ['server'],
- 'operationId': 'getProcesses',
+ 'summary': f'Get {title} items',
+ 'description': desc,
+ 'tags': [name],
+ 'operationId': f'get{name.capitalize()}Features',
'parameters': [
- {'$ref': '#/components/parameters/f'}
+ items_f,
+ items_l,
+ {'$ref': '#/components/parameters/bbox'},
+ {'$ref': f"{OPENAPI_YAML['oapif-1']}#/components/parameters/limit"}, # noqa
+ {'$ref': '#/components/parameters/crs'}, # noqa
+ {'$ref': '#/components/parameters/bbox-crs'}, # noqa
+ coll_properties,
+ {'$ref': '#/components/parameters/vendorSpecificParameters'}, # noqa
+ {'$ref': '#/components/parameters/skipGeometry'},
+ {'$ref': f"{OPENAPI_YAML['oapir']}/parameters/sortby.yaml"}, # noqa
+ {'$ref': '#/components/parameters/offset'},
],
'responses': {
- '200': {'$ref': f"{OPENAPI_YAML['oapip']}/responses/ProcessList.yaml"}, # noqa
- 'default': {'$ref': '#/components/responses/default'}
+ '200': {'$ref': f"{OPENAPI_YAML['oapif-1']}#/components/responses/Features"}, # noqa
+ '400': {'$ref': f"{OPENAPI_YAML['oapif-1']}#/components/responses/InvalidParameter"}, # noqa
+ '404': {'$ref': f"{OPENAPI_YAML['oapif-1']}#/components/responses/NotFound"}, # noqa
+ '500': {'$ref': f"{OPENAPI_YAML['oapif-1']}#/components/responses/ServerError"} # noqa
+ }
+ },
+ 'options': {
+ 'summary': f'Options for {title} items',
+ 'description': desc,
+ 'tags': [name],
+ 'operationId': f'options{name.capitalize()}Features',
+ 'responses': {
+ '200': {'description': 'options response'}
}
}
}
- LOGGER.debug('setting up processes')
- for k, v in process_manager.processes.items():
- if k.startswith('_'):
- LOGGER.debug(f'Skipping hidden layer: {k}')
- continue
- name = l10n.translate(k, locale_)
- p = process_manager.get_processor(k)
- md_desc = l10n.translate(p.metadata['description'], locale_)
- process_name_path = f'/processes/{name}'
- tag = {
- 'name': name,
- 'description': md_desc, # noqa
- 'externalDocs': {}
+ if p.editable:
+ LOGGER.debug('Provider is editable; adding post')
+
+ paths[items_path]['post'] = {
+ 'summary': f'Add {title} items',
+ 'description': desc,
+ 'tags': [name],
+ 'operationId': f'add{name.capitalize()}Features',
+ 'requestBody': {
+ 'description': 'Adds item to collection',
+ 'content': {
+ 'application/geo+json': {
+ 'schema': {}
+ }
+ },
+ 'required': True
+ },
+ 'responses': {
+ '201': {'description': 'Successful creation'},
+ '400': {'$ref': f"{OPENAPI_YAML['oapif-1']}#/components/responses/InvalidParameter"}, # noqa
+ '500': {'$ref': f"{OPENAPI_YAML['oapif-1']}#/components/responses/ServerError"} # noqa
+ }
}
- for link in p.metadata.get('links', []):
- if link['type'] == 'information':
- translated_link = l10n.translate(link, locale_)
- tag['externalDocs']['description'] = translated_link[
- 'type']
- tag['externalDocs']['url'] = translated_link['url']
- break
- if len(tag['externalDocs']) == 0:
- del tag['externalDocs']
- oas['tags'].append(tag)
+ try:
+ schema_ref = p.get_schema(SchemaType.create)
+ paths[items_path]['post']['requestBody']['content'][schema_ref[0]] = { # noqa
+ 'schema': schema_ref[1]
+ }
+ except Exception as err:
+ LOGGER.debug(err)
- paths[process_name_path] = {
+ if ptype == 'record':
+ paths[items_path]['get']['parameters'].append(
+ {'$ref': f"{OPENAPI_YAML['oapir']}/parameters/q.yaml"})
+ if p.fields:
+ schema_path = f'{collection_name_path}/schema'
+
+ paths[schema_path] = {
'get': {
- 'summary': 'Get process metadata',
- 'description': md_desc,
+ 'summary': f'Get {title} schema',
+ 'description': desc,
'tags': [name],
- 'operationId': f'describe{name.capitalize()}Process',
+ 'operationId': f'get{name.capitalize()}Queryables',
'parameters': [
- {'$ref': '#/components/parameters/f'}
+ items_f,
+ items_l
],
'responses': {
- '200': {'$ref': '#/components/responses/200'},
- 'default': {'$ref': '#/components/responses/default'}
+ '200': {'$ref': '#/components/responses/Queryables'}, # noqa
+ '400': {'$ref': f"{OPENAPI_YAML['oapif-1']}#/components/responses/InvalidParameter"}, # noqa
+ '404': {'$ref': f"{OPENAPI_YAML['oapif-1']}#/components/responses/NotFound"}, # noqa
+ '500': {'$ref': f"{OPENAPI_YAML['oapif-1']}#/components/responses/ServerError"}, # noqa
}
}
}
- paths[f'{process_name_path}/execution'] = {
- 'post': {
- 'summary': f"Process {l10n.translate(p.metadata['title'], locale_)} execution", # noqa
- 'description': md_desc,
+ queryables_path = f'{collection_name_path}/queryables'
+
+ paths[queryables_path] = {
+ 'get': {
+ 'summary': f'Get {title} queryables',
+ 'description': desc,
'tags': [name],
- 'operationId': f'execute{name.capitalize()}Job',
+ 'operationId': f'get{name.capitalize()}Queryables',
+ 'parameters': [
+ items_f,
+ items_l
+ ],
'responses': {
- '200': {'$ref': '#/components/responses/200'},
- '201': {'$ref': f"{OPENAPI_YAML['oapip']}/responses/ExecuteAsync.yaml"}, # noqa
- '404': {'$ref': f"{OPENAPI_YAML['oapip']}/responses/NotFound.yaml"}, # noqa
- '500': {'$ref': f"{OPENAPI_YAML['oapip']}/responses/ServerError.yaml"}, # noqa
- 'default': {'$ref': '#/components/responses/default'}
- },
- 'requestBody': {
- 'description': 'Mandatory execute request JSON',
- 'required': True,
- 'content': {
- 'application/json': {
- 'schema': {
- '$ref': f"{OPENAPI_YAML['oapip']}/schemas/execute.yaml" # noqa
- }
- }
- }
+ '200': {'$ref': '#/components/responses/Queryables'},
+ '400': {'$ref': f"{OPENAPI_YAML['oapif-1']}#/components/responses/InvalidParameter"}, # noqa
+ '404': {'$ref': f"{OPENAPI_YAML['oapif-1']}#/components/responses/NotFound"}, # noqa
+ '500': {'$ref': f"{OPENAPI_YAML['oapif-1']}#/components/responses/ServerError"}, # noqa
}
}
}
- if 'example' in p.metadata:
- paths[f'{process_name_path}/execution']['post']['requestBody']['content']['application/json']['example'] = p.metadata['example'] # noqa
- name_in_path = {
- 'name': 'jobId',
- 'in': 'path',
- 'description': 'job identifier',
- 'required': True,
- 'schema': {
- 'type': 'string'
- }
- }
+ if p.time_field is not None:
+ paths[items_path]['get']['parameters'].append(
+ {'$ref': f"{OPENAPI_YAML['oapif-1']}#/components/parameters/datetime"}) # noqa
- paths['/jobs'] = {
- 'get': {
- 'summary': 'Retrieve jobs list',
- 'description': 'Retrieve a list of jobs',
- 'tags': ['jobs'],
- 'operationId': 'getJobs',
- 'responses': {
- '200': {'$ref': '#/components/responses/200'},
- '404': {'$ref': f"{OPENAPI_YAML['oapip']}/responses/NotFound.yaml"}, # noqa
- 'default': {'$ref': '#/components/responses/default'}
+ for field, type_ in p.fields.items():
+
+ if p.properties and field not in p.properties:
+ LOGGER.debug('Provider specified not to advertise property')
+ continue
+
+ if field == 'q' and ptype == 'record':
+ LOGGER.debug('q parameter already declared, skipping')
+ continue
+
+ if type_ == 'date':
+ schema = {
+ 'type': 'string',
+ 'format': 'date'
}
- }
- }
+ elif type_ == 'float':
+ schema = {
+ 'type': 'number',
+ 'format': 'float'
+ }
+ elif type_ == 'long':
+ schema = {
+ 'type': 'integer',
+ 'format': 'int64'
+ }
+ else:
+ schema = type_
- paths['/jobs/{jobId}'] = {
+ path_ = f'{collection_name_path}/items'
+ paths[path_]['get']['parameters'].append({
+ 'name': field,
+ 'in': 'query',
+ 'required': False,
+ 'schema': schema,
+ 'style': 'form',
+ 'explode': False
+ })
+
+ paths[f'{collection_name_path}/items/{{featureId}}'] = {
'get': {
- 'summary': 'Retrieve job details',
- 'description': 'Retrieve job details',
- 'tags': ['jobs'],
+ 'summary': f'Get {title} item by id',
+ 'description': desc,
+ 'tags': [name],
+ 'operationId': f'get{name.capitalize()}Feature',
'parameters': [
- name_in_path,
- {'$ref': '#/components/parameters/f'}
+ {'$ref': f"{OPENAPI_YAML['oapif-1']}#/components/parameters/featureId"}, # noqa
+ {'$ref': '#/components/parameters/crs'}, # noqa
+ {'$ref': '#/components/parameters/f'},
+ {'$ref': '#/components/parameters/lang'}
],
- 'operationId': 'getJob',
'responses': {
- '200': {'$ref': '#/components/responses/200'},
- '404': {'$ref': f"{OPENAPI_YAML['oapip']}/responses/NotFound.yaml"}, # noqa
- 'default': {'$ref': '#/components/responses/default'} # noqa
+ '200': {'$ref': f"{OPENAPI_YAML['oapif-1']}#/components/responses/Feature"}, # noqa
+ '400': {'$ref': f"{OPENAPI_YAML['oapif-1']}#/components/responses/InvalidParameter"}, # noqa
+ '404': {'$ref': f"{OPENAPI_YAML['oapif-1']}#/components/responses/NotFound"}, # noqa
+ '500': {'$ref': f"{OPENAPI_YAML['oapif-1']}#/components/responses/ServerError"} # noqa
}
},
- 'delete': {
- 'summary': 'Cancel / delete job',
- 'description': 'Cancel / delete job',
- 'tags': ['jobs'],
+ 'options': {
+ 'summary': f'Options for {title} item by id',
+ 'description': desc,
+ 'tags': [name],
+ 'operationId': f'options{name.capitalize()}Feature',
'parameters': [
- name_in_path
+ {'$ref': f"{OPENAPI_YAML['oapif-1']}#/components/parameters/featureId"} # noqa
],
- 'operationId': 'deleteJob',
'responses': {
- '204': {'$ref': '#/components/responses/204'},
- '404': {'$ref': f"{OPENAPI_YAML['oapip']}/responses/NotFound.yaml"}, # noqa
- 'default': {'$ref': '#/components/responses/default'} # noqa
+ '200': {'description': 'options response'}
}
- },
+ }
}
- paths['/jobs/{jobId}/results'] = {
- 'get': {
- 'summary': 'Retrieve job results',
- 'description': 'Retrive job resiults',
- 'tags': ['jobs'],
+ try:
+ schema_ref = p.get_schema()
+ paths[f'{collection_name_path}/items/{{featureId}}']['get']['responses']['200'] = { # noqa
+ 'content': {
+ schema_ref[0]: {
+ 'schema': schema_ref[1]
+ }
+ }
+ }
+ except Exception as err:
+ LOGGER.debug(err)
+
+ if p.editable:
+ LOGGER.debug('Provider is editable; adding put/delete')
+ put_path = f'{collection_name_path}/items/{{featureId}}'
+ paths[put_path]['put'] = { # noqa
+ 'summary': f'Update {title} items',
+ 'description': desc,
+ 'tags': [name],
+ 'operationId': f'update{name.capitalize()}Features',
'parameters': [
- name_in_path,
- {'$ref': '#/components/parameters/f'}
+ {'$ref': f"{OPENAPI_YAML['oapif-1']}#/components/parameters/featureId"} # noqa
],
- 'operationId': 'getJobResults',
+ 'requestBody': {
+ 'description': 'Updates item in collection',
+ 'content': {
+ 'application/geo+json': {
+ 'schema': {}
+ }
+ },
+ 'required': True
+ },
'responses': {
- '200': {'$ref': '#/components/responses/200'},
- '404': {'$ref': f"{OPENAPI_YAML['oapip']}/responses/NotFound.yaml"}, # noqa
- 'default': {'$ref': '#/components/responses/default'} # noqa
+ '204': {'$ref': '#/components/responses/204'},
+ '400': {'$ref': f"{OPENAPI_YAML['oapif-1']}#/components/responses/InvalidParameter"}, # noqa
+ '500': {'$ref': f"{OPENAPI_YAML['oapif-1']}#/components/responses/ServerError"} # noqa
}
}
- }
- tag = {
- 'name': 'jobs',
- 'description': 'Process jobs',
- }
- oas['tags'].insert(1, tag)
+ try:
+ schema_ref = p.get_schema(SchemaType.replace)
+ paths[put_path]['put']['requestBody']['content'][schema_ref[0]] = { # noqa
+ 'schema': schema_ref[1]
+ }
+ except Exception as err:
+ LOGGER.debug(err)
- oas['paths'] = paths
+ paths[f'{collection_name_path}/items/{{featureId}}']['delete'] = {
+ 'summary': f'Delete {title} items',
+ 'description': desc,
+ 'tags': [name],
+ 'operationId': f'delete{name.capitalize()}Features',
+ 'parameters': [
+ {'$ref': f"{OPENAPI_YAML['oapif-1']}#/components/parameters/featureId"}, # noqa
+ ],
+ 'responses': {
+ '200': {'description': 'Successful delete'},
+ '400': {'$ref': f"{OPENAPI_YAML['oapif-1']}#/components/responses/InvalidParameter"}, # noqa
+ '500': {'$ref': f"{OPENAPI_YAML['oapif-1']}#/components/responses/ServerError"} # noqa
+ }
+ }
- if cfg['server'].get('admin', False):
- schema_dict = get_config_schema()
- oas['definitions'] = schema_dict['definitions']
- LOGGER.debug('Adding admin endpoints')
- oas['paths'].update(get_admin())
+ except ProviderTypeError:
+ LOGGER.debug('collection is not feature based')
- return oas
+ LOGGER.debug('setting up coverage endpoints')
+ try:
+ load_plugin('provider', get_provider_by_type(
+ collection_def['providers'], 'coverage'))
+ coverage_path = f'{collection_name_path}/coverage'
-def get_config_schema():
- schema_file = os.path.join(THISDIR, 'schemas', 'config',
- 'pygeoapi-config-0.x.yml')
+ paths[coverage_path] = {
+ 'get': {
+ 'summary': f'Get {title} coverage',
+ 'description': desc,
+ 'tags': [name],
+ 'operationId': f'get{name.capitalize()}Coverage',
+ 'parameters': [
+ items_f,
+ items_l,
+ {'$ref': '#/components/parameters/bbox'},
+ {'$ref': '#/components/parameters/bbox-crs'},
+ ],
+ 'responses': {
+ '200': {'$ref': f"{OPENAPI_YAML['oapif-1']}#/components/responses/Features"}, # noqa
+ '400': {'$ref': f"{OPENAPI_YAML['oapif-1']}#/components/responses/InvalidParameter"}, # noqa
+ '404': {'$ref': f"{OPENAPI_YAML['oapif-1']}#/components/responses/NotFound"}, # noqa
+ '500': {'$ref': f"{OPENAPI_YAML['oapif-1']}#/components/responses/ServerError"} # noqa
+ }
+ }
+ }
- with open(schema_file) as fh2:
- return yaml_load(fh2)
+ except ProviderTypeError:
+ LOGGER.debug('collection is not coverage based')
+ LOGGER.debug('setting up tiles endpoints')
+ tile_extension = filter_providers_by_type(
+ collection_def['providers'], 'tile')
-def get_admin():
+ if tile_extension:
+ tp = load_plugin('provider', tile_extension)
- schema_dict = get_config_schema()
+ tiles_path = f'{collection_name_path}/tiles'
+
+ paths[tiles_path] = {
+ 'get': {
+ 'summary': f'Fetch a {title} tiles description',
+ 'description': desc,
+ 'tags': [name],
+ 'operationId': f'describe{name.capitalize()}Tiles',
+ 'parameters': [
+ items_f,
+ # items_l TODO: is this useful?
+ ],
+ 'responses': {
+ '200': {'$ref': '#/components/responses/Tiles'},
+ '400': {'$ref': f"{OPENAPI_YAML['oapif-1']}#/components/responses/InvalidParameter"}, # noqa
+ '404': {'$ref': f"{OPENAPI_YAML['oapif-1']}#/components/responses/NotFound"}, # noqa
+ '500': {'$ref': f"{OPENAPI_YAML['oapif-1']}#/components/responses/ServerError"} # noqa
+ }
+ }
+ }
- paths = {}
+ tiles_data_path = f'{collection_name_path}/tiles/{{tileMatrixSetId}}/{{tileMatrix}}/{{tileRow}}/{{tileCol}}' # noqa
- paths['/admin/config'] = {
- 'get': {
- 'summary': 'Get admin configuration',
- 'description': 'Get admin configuration',
- 'tags': ['admin'],
- 'operationId': 'getAdminConfig',
- 'parameters': [
- {'$ref': '#/components/parameters/f'},
- {'$ref': '#/components/parameters/lang'}
- ],
- 'responses': {
- '200': {
- 'content': {
- 'application/json': {
- 'schema': schema_dict
- }
+ paths[tiles_data_path] = {
+ 'get': {
+ 'summary': f'Get a {title} tile',
+ 'description': desc,
+ 'tags': [name],
+ 'operationId': f'get{name.capitalize()}Tiles',
+ 'parameters': [
+ {'$ref': f"{OPENAPI_YAML['oapit']}#/components/parameters/tileMatrixSetId"}, # noqa
+ {'$ref': f"{OPENAPI_YAML['oapit']}#/components/parameters/tileMatrix"}, # noqa
+ {'$ref': f"{OPENAPI_YAML['oapit']}#/components/parameters/tileRow"}, # noqa
+ {'$ref': f"{OPENAPI_YAML['oapit']}#/components/parameters/tileCol"}, # noqa
+ {
+ 'name': 'f',
+ 'in': 'query',
+ 'description': 'The optional f parameter indicates the output format which the server shall provide as part of the response document.', # noqa
+ 'required': False,
+ 'schema': {
+ 'type': 'string',
+ 'enum': [tp.format_type],
+ 'default': tp.format_type
+ },
+ 'style': 'form',
+ 'explode': False
}
+ ],
+ 'responses': {
+ '400': {'$ref': f"{OPENAPI_YAML['oapif-1']}#/components/responses/InvalidParameter"}, # noqa
+ '404': {'$ref': f"{OPENAPI_YAML['oapif-1']}#/components/responses/NotFound"}, # noqa
+ '500': {'$ref': f"{OPENAPI_YAML['oapif-1']}#/components/responses/ServerError"} # noqa
}
}
- },
- 'put': {
- 'summary': 'Update admin configuration full',
- 'description': 'Update admin configuration full',
- 'tags': ['admin'],
- 'operationId': 'putAdminConfig',
- 'requestBody': {
- 'description': 'Updates admin configuration',
- 'content': {
- 'application/json': {
- 'schema': schema_dict
- }
- },
- 'required': True
- },
- 'responses': {
- '204': {'$ref': '#/components/responses/204'},
- '400': {'$ref': f"{OPENAPI_YAML['oapif-1']}#/components/responses/InvalidParameter"}, # noqa
- '500': {'$ref': f"{OPENAPI_YAML['oapif-1']}#/components/responses/ServerError"} # noqa
- }
- },
- 'patch': {
- 'summary': 'Partially update admin configuration',
- 'description': 'Partially update admin configuration',
- 'tags': ['admin'],
- 'operationId': 'patchAdminConfig',
- 'requestBody': {
- 'description': 'Updates admin configuration',
- 'content': {
- 'application/json': {
- 'schema': schema_dict
+ }
+ mimetype = tile_extension['format']['mimetype']
+ paths[tiles_data_path]['get']['responses']['200'] = {
+ 'description': 'successful operation',
+ 'content': {
+ mimetype: {
+ 'schema': {
+ 'type': 'string',
+ 'format': 'binary'
}
- },
- 'required': True
- },
- 'responses': {
- '204': {'$ref': '#/components/responses/204'},
- '400': {'$ref': f"{OPENAPI_YAML['oapif-1']}#/components/responses/InvalidParameter"}, # noqa
- '500': {'$ref': f"{OPENAPI_YAML['oapif-1']}#/components/responses/ServerError"} # noqa
+ }
}
}
- }
- paths['/admin/config/resources'] = {
- 'get': {
- 'summary': 'Get admin configuration resources',
- 'description': 'Get admin configuration resources',
- 'tags': ['admin'],
- 'operationId': 'getAdminConfigResources',
- 'parameters': [
- {'$ref': '#/components/parameters/f'},
- {'$ref': '#/components/parameters/lang'}
- ],
- 'responses': {
- '200': {
- 'content': {
- 'application/json': {
- 'schema': schema_dict['properties']['resources']['patternProperties']['^.*$'] # noqa
+
+ LOGGER.debug('setting up edr endpoints')
+ edr_extension = filter_providers_by_type(
+ collection_def['providers'], 'edr')
+
+ if edr_extension:
+ ep = load_plugin('provider', edr_extension)
+
+ edr_query_endpoints = []
+
+ for qt in [qt for qt in ep.get_query_types() if qt != 'locations']:
+ edr_query_endpoints.append({
+ 'path': f'{collection_name_path}/{qt}',
+ 'qt': qt,
+ 'op_id': f'query{qt.capitalize()}{collection_id.capitalize()}'
+ })
+ if ep.instances:
+ edr_query_endpoints.append({
+ 'path': f'{collection_name_path}/instances/{{instanceId}}/{qt}', # noqa
+ 'qt': qt,
+ 'op_id': f'query{qt.capitalize()}Instance{collection_id.capitalize()}' # noqa
+ })
+
+ for eqe in edr_query_endpoints:
+ if eqe['qt'] == 'cube':
+ spatial_parameter = 'bbox'
+ else:
+ spatial_parameter = f"{eqe['qt']}Coords"
+ paths[eqe['path']] = {
+ 'get': {
+ 'summary': f"query {collection_def['description']} by {eqe['qt']}", # noqa
+ 'description': collection_def['description'],
+ 'tags': [collection_id],
+ 'operationId': eqe['op_id'],
+ 'parameters': [
+ {'$ref': f"{OPENAPI_YAML['oaedr']}/parameters/{spatial_parameter}.yaml"}, # noqa
+ {'$ref': f"{OPENAPI_YAML['oapif-1']}#/components/parameters/datetime"}, # noqa
+ {'$ref': f"{OPENAPI_YAML['oaedr']}/parameters/parameter-name.yaml"}, # noqa
+ {'$ref': f"{OPENAPI_YAML['oaedr']}/parameters/z.yaml"},
+ {'$ref': '#/components/parameters/f'}
+ ],
+ 'responses': {
+ '200': {
+ 'description': 'Response',
+ 'content': {
+ 'application/prs.coverage+json': {
+ 'schema': {
+ '$ref': f"{OPENAPI_YAML['oaedr']}/schemas/coverageJSON.yaml" # noqa
+ }
+ }
+ }
}
}
}
}
- },
- 'post': {
- 'summary': 'Create admin configuration resource',
- 'description': 'Create admin configuration resource',
- 'tags': ['admin'],
- 'operationId': 'postAdminConfigResource',
- 'requestBody': {
- 'description': 'Adds resource to configuration',
- 'content': {
- 'application/json': {
- 'schema': schema_dict['properties']['resources']['patternProperties']['^.*$'] # noqa
+ if 'locations' in ep.get_query_types():
+ paths[f'{collection_name_path}/locations'] = {
+ 'get': {
+ 'summary': f"Get pre-defined locations of {v['description']}", # noqa
+ 'description': collection_def['description'],
+ 'tags': [collection_id],
+ 'operationId': f'queryLOCATIONS{collection_id.capitalize()}', # noqa
+ 'parameters': [
+ {'$ref': f"{OPENAPI_YAML['oaedr']}/parameters/bbox.yaml"}, # noqa
+ {'$ref': f"{OPENAPI_YAML['oapif-1']}#/components/parameters/datetime"}, # noqa
+ {'$ref': '#/components/parameters/f'}
+ ],
+ 'responses': {
+ '200': {'$ref': f"{OPENAPI_YAML['oapif-1']}#/components/responses/Features"}, # noqa
+ '400': {'$ref': f"{OPENAPI_YAML['oapif-1']}#/components/responses/InvalidParameter"}, # noqa
+ '500': {'$ref': f"{OPENAPI_YAML['oapif-1']}#/components/responses/ServerError"} # noqa
}
- },
- 'required': True
- },
- 'responses': {
- '201': {'description': 'Successful creation'},
- '400': {'$ref': f"{OPENAPI_YAML['oapif-1']}#/components/responses/InvalidParameter"}, # noqa
- '500': {'$ref': f"{OPENAPI_YAML['oapif-1']}#/components/responses/ServerError"} # noqa
+ }
}
- },
- }
- paths['/admin/config/resources/{resourceId}'] = {
- 'get': {
- 'summary': 'Get admin configuration resource',
- 'description': 'Get admin configuration resource',
- 'tags': ['admin'],
- 'operationId': 'getAdminConfigResource',
- 'parameters': [
- {'$ref': '#/components/parameters/resourceId'},
- {'$ref': '#/components/parameters/f'},
- {'$ref': '#/components/parameters/lang'}
- ],
- 'responses': {
- '200': {
- 'content': {
- 'application/json': {
- 'schema': schema_dict['properties']['resources']['patternProperties']['^.*$'] # noqa
+ paths[f'{collection_name_path}/locations/{{locId}}'] = {
+ 'get': {
+ 'summary': f"query {collection_defv['description']} by location", # noqa
+ 'description': collection_def['description'],
+ 'tags': [collection_id],
+ 'operationId': f'queryLOCATIONSBYID{collection_id.capitalize()}', # noqa
+ 'parameters': [
+ {'$ref': f"{OPENAPI_YAML['oaedr']}/parameters/{spatial_parameter}.yaml"}, # noqa
+ {'$ref': f"{OPENAPI_YAML['oaedr']}/parameters/locationId.yaml"}, # noqa
+ {'$ref': f"{OPENAPI_YAML['oapif-1']}#/components/parameters/datetime"}, # noqa
+ {'$ref': f"{OPENAPI_YAML['oaedr']}/parameters/parameter-name.yaml"}, # noqa
+ {'$ref': f"{OPENAPI_YAML['oaedr']}/parameters/z.yaml"},
+ {'$ref': '#/components/parameters/f'}
+ ],
+ 'responses': {
+ '200': {
+ 'description': 'Response',
+ 'content': {
+ 'application/prs.coverage+json': {
+ 'schema': {
+ '$ref': f"{OPENAPI_YAML['oaedr']}/schemas/coverageJSON.yaml" # noqa
+ }
+ }
+ }
}
}
}
}
- },
- 'put': {
- 'summary': 'Update admin configuration resource',
- 'description': 'Update admin configuration resource',
- 'tags': ['admin'],
- 'operationId': 'putAdminConfigResource',
- 'parameters': [
- {'$ref': '#/components/parameters/resourceId'},
- ],
- 'requestBody': {
- 'description': 'Updates admin configuration resource',
- 'content': {
- 'application/json': {
- 'schema': schema_dict['properties']['resources']['patternProperties']['^.*$'] # noqa
- }
- },
- 'required': True
- },
- 'responses': {
- '204': {'$ref': '#/components/responses/204'},
- '400': {'$ref': f"{OPENAPI_YAML['oapif-1']}#/components/responses/InvalidParameter"}, # noqa
- '500': {'$ref': f"{OPENAPI_YAML['oapif-1']}#/components/responses/ServerError"} # noqa
- }
- },
- 'patch': {
- 'summary': 'Partially update admin configuration resource',
- 'description': 'Partially update admin configuration resource',
- 'tags': ['admin'],
- 'operationId': 'patchAdminConfigResource',
- 'parameters': [
- {'$ref': '#/components/parameters/resourceId'},
- ],
- 'requestBody': {
- 'description': 'Updates admin configuration resource',
- 'content': {
- 'application/json': {
- 'schema': schema_dict['properties']['resources']['patternProperties']['^.*$'] # noqa
- }
- },
- 'required': True
- },
- 'responses': {
- '204': {'$ref': '#/components/responses/204'},
- '400': {'$ref': f"{OPENAPI_YAML['oapif-1']}#/components/responses/InvalidParameter"}, # noqa
- '500': {'$ref': f"{OPENAPI_YAML['oapif-1']}#/components/responses/ServerError"} # noqa
- }
- },
- 'delete': {
- 'summary': 'Delete admin configuration resource',
- 'description': 'Delete admin configuration resource',
- 'tags': ['admin'],
- 'operationId': 'deleteAdminConfigResource',
- 'parameters': [
- {'$ref': '#/components/parameters/resourceId'},
- ],
- 'responses': {
- '204': {'$ref': '#/components/responses/204'},
- '404': {'$ref': f"{OPENAPI_YAML['oapip']}/responses/NotFound.yaml"}, # noqa
- 'default': {'$ref': '#/components/responses/default'} # noqa
+
+ LOGGER.debug('setting up maps endpoints')
+ map_extension = filter_providers_by_type(
+ collection_def['providers'], 'map')
+
+ if map_extension:
+ mp = load_plugin('provider', map_extension)
+
+ map_f = deepcopy(components['parameters']['f'])
+ map_f['schema']['enum'] = [map_extension['format']['name']]
+ map_f['schema']['default'] = map_extension['format']['name']
+
+ pth = f'/collections/{collection_def}/map'
+ paths[pth] = {
+ 'get': {
+ 'summary': 'Get map',
+ 'description': f"{collection_def['description']} map",
+ 'tags': [collection_id],
+ 'operationId': 'getMap',
+ 'parameters': [
+ {'$ref': '#/components/parameters/bbox'},
+ {'$ref': f"{OPENAPI_YAML['oapif-1']}#/components/parameters/datetime"}, # noqa
+ {
+ 'name': 'width',
+ 'in': 'query',
+ 'description': 'Response image width',
+ 'required': False,
+ 'schema': {
+ 'type': 'integer',
+ },
+ 'style': 'form',
+ 'explode': False
+ },
+ {
+ 'name': 'height',
+ 'in': 'query',
+ 'description': 'Response image height',
+ 'required': False,
+ 'schema': {
+ 'type': 'integer',
+ },
+ 'style': 'form',
+ 'explode': False
+ },
+ {
+ 'name': 'transparent',
+ 'in': 'query',
+ 'description': 'Background transparency of map (default=true).', # noqa
+ 'required': False,
+ 'schema': {
+ 'type': 'boolean',
+ 'default': True,
+ },
+ 'style': 'form',
+ 'explode': False
+ },
+ {'$ref': '#/components/parameters/bbox-crs-epsg'},
+ map_f
+ ],
+ 'responses': {
+ '200': {
+ 'description': 'Response',
+ 'content': {
+ 'application/json': {}
+ }
+ },
+ '400': {'$ref': f"{OPENAPI_YAML['oapif-1']}#/components/responses/InvalidParameter"}, # noqa
+ '500': {'$ref': f"{OPENAPI_YAML['oapif-1']}#/components/responses/ServerError"}, # noqa
+ }
}
}
- }
+ if mp.time_field is not None:
+ paths[pth]['get']['parameters'].append(
+ {'$ref': f"{OPENAPI_YAML['oapif-1']}#/components/parameters/datetime"}) # noqa
- return paths
+ return tags, paths
-def get_oas(cfg, version='3.0'):
+def get_oas(cfg: dict, fail_on_invalid_collection: bool = True,
+ version='3.0') -> dict:
"""
Stub to generate OpenAPI Document
- :param cfg: configuration object
+ :param cfg: `dict` configuration
+ :param fail_on_invalid_collection: `bool` of whether to fail on an
+ invalid collection
:param version: version of OpenAPI (default 3.0)
- :returns: OpenAPI definition YAML dict
+ :returns: `dict` of OpenAPI definition
"""
if version == '3.0':
- return get_oas_30(cfg)
+ return get_oas_30(
+ cfg, fail_on_invalid_collection=fail_on_invalid_collection)
else:
raise RuntimeError('OpenAPI version not supported')
-def validate_openapi_document(instance_dict):
+def validate_openapi_document(instance_dict: dict) -> bool:
"""
Validate an OpenAPI document against the OpenAPI schema
@@ -1589,27 +1640,37 @@ def validate_openapi_document(instance_dict):
def generate_openapi_document(cfg_file: Union[Path, io.TextIOWrapper],
- output_format: OAPIFormat):
+ output_format: OAPIFormat,
+ fail_on_invalid_collection: bool = True) -> str:
"""
Generate an OpenAPI document from the configuration file
- :param cfg_file: configuration Path instance
+ :param cfg_file: configuration Path instance (`str` of filepath
+ or parsed `dict`)
+ :param fail_on_invalid_collection: `bool` of whether to fail on an
+ invalid collection
:param output_format: output format for OpenAPI document
- :returns: content of the OpenAPI document in the output
- format requested
+ :returns: `str` of the OpenAPI document in the output format requested
"""
+
+ LOGGER.debug(f'Loading configuration {cfg_file}')
+
if isinstance(cfg_file, Path):
with cfg_file.open(mode="r") as cf:
s = yaml_load(cf)
else:
s = yaml_load(cfg_file)
+
pretty_print = s['server'].get('pretty_print', False)
+ oas = get_oas(s, fail_on_invalid_collection=fail_on_invalid_collection)
+
if output_format == 'yaml':
- content = yaml.safe_dump(get_oas(s), default_flow_style=False)
+ content = yaml.safe_dump(oas, default_flow_style=False)
else:
- content = to_json(get_oas(s), pretty=pretty_print)
+ content = to_json(oas, pretty=pretty_print)
+
return content
@@ -1640,17 +1701,21 @@ def openapi():
@click.command()
@click.pass_context
@click.argument('config_file', type=click.File(encoding='utf-8'))
+ at click.option('--fail-on-invalid-collection/--no-fail-on-invalid-collection',
+ '-fic', default=True, help='Fail on invalid collection')
@click.option('--format', '-f', 'format_', type=click.Choice(['json', 'yaml']),
default='yaml', help='output format (json|yaml)')
@click.option('--output-file', '-of', type=click.File('w', encoding='utf-8'),
help='Name of output file')
-def generate(ctx, config_file, output_file, format_='yaml'):
+def generate(ctx, config_file, output_file, format_='yaml',
+ fail_on_invalid_collection=True):
"""Generate OpenAPI Document"""
if config_file is None:
raise click.ClickException('--config/-c required')
- content = generate_openapi_document(config_file, format_)
+ content = generate_openapi_document(
+ config_file, format_, fail_on_invalid_collection)
if output_file is None:
click.echo(content)
View it on GitLab: https://salsa.debian.org/debian-gis-team/pygeoapi/-/commit/4f2e4bb89d17023aa0791788a98e8621c7cd3031
--
View it on GitLab: https://salsa.debian.org/debian-gis-team/pygeoapi/-/commit/4f2e4bb89d17023aa0791788a98e8621c7cd3031
You're receiving this email because of your account on salsa.debian.org.
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://alioth-lists.debian.net/pipermail/pkg-grass-devel/attachments/20240405/bb1a6e12/attachment-0001.htm>
More information about the Pkg-grass-devel
mailing list