From 3ec05702746614894709fcec2c84424628ebd9b7 Mon Sep 17 00:00:00 2001 From: Francesco Bartoli Date: Tue, 30 Jun 2020 11:16:18 +0200 Subject: [PATCH 1/2] Add spectral command to travis for linting the openapi document Fix trailing slash in server url Fix tag not declared in the root mapping key Fix missing operationId Add spectral command to travis for linting the openapi document --- .travis.yml | 2 + pygeoapi-config.yml | 2 +- pygeoapi/openapi.py | 96 +++++++++++++++++++++++++++------------------ 3 files changed, 60 insertions(+), 40 deletions(-) diff --git a/.travis.yml b/.travis.yml index d4b8a9c..0a6c43b 100644 --- a/.travis.yml +++ b/.travis.yml @@ -82,6 +82,8 @@ script: - pytest --cov=pygeoapi - make -C ./docs html - find . -type f -name "*.py" | xargs flake8 + # run linting openapi document through dockerized spectral cli + - docker run --rm -it -v $(pwd):/tmp stoplight/spectral lint "/tmp/pygeoapi-openapi.yml" # run docker image with cite configuration - docker run -d -p 5001:5001 --network host --add-host="localhost:127.0.0.1" --rm -it -v $(pwd)/tests/cite/ogcapi-features/cite.config.yml:/pygeoapi/local.config.yml --name pygeoapi-travis-master geopython/pygeoapi:latest run - docker ps | grep -wq 'pygeoapi-travis-master' diff --git a/pygeoapi-config.yml b/pygeoapi-config.yml index e9db193..74895a8 100644 --- a/pygeoapi-config.yml +++ b/pygeoapi-config.yml @@ -31,7 +31,7 @@ server: bind: host: 0.0.0.0 port: 5000 - url: http://localhost:5000/ + url: http://localhost:5000 mimetype: application/json; charset=UTF-8 encoding: utf-8 language: en-US diff --git a/pygeoapi/openapi.py b/pygeoapi/openapi.py index 9d5e134..528ce45 100644 --- a/pygeoapi/openapi.py +++ b/pygeoapi/openapi.py @@ -153,13 +153,14 @@ def get_oas_30(cfg): 'summary': 'Landing page', 'description': 'Landing page', 'tags': ['server'], + 'operationId': 'getRoot', 'parameters': [ {'$ref': '#/components/parameters/f'} ], 'responses': { - 200: {'$ref': '{}#/components/responses/LandingPage'.format(OPENAPI_YAML['oapif'])}, # noqa - 400: {'$ref': '{}#/components/responses/InvalidParameter'.format(OPENAPI_YAML['oapif'])}, # noqa - 500: {'$ref': '{}#/components/responses/ServerError'.format(OPENAPI_YAML['oapif'])} # noqa + '200': {'$ref': '{}#/components/responses/LandingPage'.format(OPENAPI_YAML['oapif'])}, # noqa + '400': {'$ref': '{}#/components/responses/InvalidParameter'.format(OPENAPI_YAML['oapif'])}, # noqa + '500': {'$ref': '{}#/components/responses/ServerError'.format(OPENAPI_YAML['oapif'])} # noqa } } } @@ -169,12 +170,13 @@ def get_oas_30(cfg): 'summary': 'This document', 'description': 'This document', 'tags': ['server'], + 'operationId': 'getOpenapi', 'parameters': [ {'$ref': '#/components/parameters/f'} ], 'responses': { - 200: {'$ref': '#/components/responses/200'}, - 400: {'$ref': '{}#/components/responses/InvalidParameter'.format(OPENAPI_YAML['oapif'])}, # noqa + '200': {'$ref': '#/components/responses/200'}, + '400': {'$ref': '{}#/components/responses/InvalidParameter'.format(OPENAPI_YAML['oapif'])}, # noqa 'default': {'$ref': '#/components/responses/default'} } } @@ -185,13 +187,14 @@ def get_oas_30(cfg): 'summary': 'API conformance definition', 'description': 'API conformance definition', 'tags': ['server'], + 'operationId': 'getConformance', 'parameters': [ {'$ref': '#/components/parameters/f'} ], 'responses': { - 200: {'$ref': '{}#/components/responses/ConformanceDeclaration'.format(OPENAPI_YAML['oapif'])}, # noqa - 400: {'$ref': '{}#/components/responses/InvalidParameter'.format(OPENAPI_YAML['oapif'])}, # noqa - 500: {'$ref': '{}#/components/responses/ServerError'.format(OPENAPI_YAML['oapif'])} # noqa + '200': {'$ref': '{}#/components/responses/ConformanceDeclaration'.format(OPENAPI_YAML['oapif'])}, # noqa + '400': {'$ref': '{}#/components/responses/InvalidParameter'.format(OPENAPI_YAML['oapif'])}, # noqa + '500': {'$ref': '{}#/components/responses/ServerError'.format(OPENAPI_YAML['oapif'])} # noqa } } } @@ -201,23 +204,29 @@ def get_oas_30(cfg): 'summary': 'Collections', 'description': 'Collections', 'tags': ['server'], + 'operationId': 'getCollections', 'parameters': [ {'$ref': '#/components/parameters/f'} ], 'responses': { - 200: {'$ref': '{}#/components/responses/Collections'.format(OPENAPI_YAML['oapif'])}, # noqa - 400: {'$ref': '{}#/components/responses/InvalidParameter'.format(OPENAPI_YAML['oapif'])}, # noqa - 500: {'$ref': '{}#/components/responses/ServerError'.format(OPENAPI_YAML['oapif'])} # noqa + '200': {'$ref': '{}#/components/responses/Collections'.format(OPENAPI_YAML['oapif'])}, # noqa + '400': {'$ref': '{}#/components/responses/InvalidParameter'.format(OPENAPI_YAML['oapif'])}, # noqa + '500': {'$ref': '{}#/components/responses/ServerError'.format(OPENAPI_YAML['oapif'])} # noqa } } } oas['tags'].append({ - 'name': 'server', - 'description': cfg['metadata']['identification']['description'], - 'externalDocs': { - 'description': 'information', - 'url': cfg['metadata']['identification']['url']} + 'name': 'server', + 'description': cfg['metadata']['identification']['description'], + 'externalDocs': { + 'description': 'information', + 'url': cfg['metadata']['identification']['url']} + } + ) + oas['tags'].append({ + 'name': 'stac', + 'description': 'SpatioTemporal Asset Catalog' } ) @@ -227,8 +236,8 @@ def get_oas_30(cfg): 'description': 'successful operation', }, 'default': { - 'description': 'Unexpected error', - 'content': gen_media_type_object('application/json', 'oapip', 'schemas/exception.yaml') # noqa + 'description': 'Unexpected error', + 'content': gen_media_type_object('application/json', 'oapip', 'schemas/exception.yaml') # noqa } }, 'parameters': { @@ -301,14 +310,15 @@ def get_oas_30(cfg): 'summary': 'Get collection metadata'.format(v['title']), # noqa 'description': v['description'], 'tags': [k], + 'operationId': 'get{}Collection'.format(k.capitalize()), 'parameters': [ {'$ref': '#/components/parameters/f'} ], 'responses': { - 200: {'$ref': '{}#/components/responses/Collection'.format(OPENAPI_YAML['oapif'])}, # noqa - 400: {'$ref': '{}#/components/responses/InvalidParameter'.format(OPENAPI_YAML['oapif'])}, # noqa - 404: {'$ref': '{}#/components/responses/NotFound'.format(OPENAPI_YAML['oapif'])}, # noqa - 500: {'$ref': '{}#/components/responses/ServerError'.format(OPENAPI_YAML['oapif'])} # noqa + '200': {'$ref': '{}#/components/responses/Collection'.format(OPENAPI_YAML['oapif'])}, # noqa + '400': {'$ref': '{}#/components/responses/InvalidParameter'.format(OPENAPI_YAML['oapif'])}, # noqa + '404': {'$ref': '{}#/components/responses/NotFound'.format(OPENAPI_YAML['oapif'])}, # noqa + '500': {'$ref': '{}#/components/responses/ServerError'.format(OPENAPI_YAML['oapif'])} # noqa } } } @@ -320,6 +330,7 @@ def get_oas_30(cfg): 'summary': 'Get {} items'.format(v['title']), 'description': v['description'], 'tags': [k], + 'operationId': 'get{}CollectionItems'.format(k.capitalize()), 'parameters': [ items_f, {'$ref': '{}#/components/parameters/bbox'.format(OPENAPI_YAML['oapif'])}, # noqa @@ -328,10 +339,10 @@ def get_oas_30(cfg): {'$ref': '#/components/parameters/startindex'} ], 'responses': { - 200: {'$ref': '{}#/components/responses/Features'.format(OPENAPI_YAML['oapif'])}, # noqa - 400: {'$ref': '{}#/components/responses/InvalidParameter'.format(OPENAPI_YAML['oapif'])}, # noqa - 404: {'$ref': '{}#/components/responses/NotFound'.format(OPENAPI_YAML['oapif'])}, # noqa - 500: {'$ref': '{}#/components/responses/ServerError'.format(OPENAPI_YAML['oapif'])} # noqa + '200': {'$ref': '{}#/components/responses/Features'.format(OPENAPI_YAML['oapif'])}, # noqa + '400': {'$ref': '{}#/components/responses/InvalidParameter'.format(OPENAPI_YAML['oapif'])}, # noqa + '404': {'$ref': '{}#/components/responses/NotFound'.format(OPENAPI_YAML['oapif'])}, # noqa + '500': {'$ref': '{}#/components/responses/ServerError'.format(OPENAPI_YAML['oapif'])} # noqa } } } @@ -346,14 +357,15 @@ def get_oas_30(cfg): 'summary': 'Get {} queryables'.format(v['title']), 'description': v['description'], 'tags': [k], + 'operationId': 'get{}Queryables'.format(k.capitalize()), 'parameters': [ items_f, ], 'responses': { - 200: {'$ref': '{}#/components/responses/Features'.format(OPENAPI_YAML['oapif'])}, # noqa - 400: {'$ref': '{}#/components/responses/InvalidParameter'.format(OPENAPI_YAML['oapif'])}, # noqa - 404: {'$ref': '{}#/components/responses/NotFound'.format(OPENAPI_YAML['oapif'])}, # noqa - 500: {'$ref': '{}#/components/responses/ServerError'.format(OPENAPI_YAML['oapif'])} # noqa + '200': {'$ref': '{}#/components/responses/Features'.format(OPENAPI_YAML['oapif'])}, # noqa + '400': {'$ref': '{}#/components/responses/InvalidParameter'.format(OPENAPI_YAML['oapif'])}, # noqa + '404': {'$ref': '{}#/components/responses/NotFound'.format(OPENAPI_YAML['oapif'])}, # noqa + '500': {'$ref': '{}#/components/responses/ServerError'.format(OPENAPI_YAML['oapif'])} # noqa } } } @@ -403,15 +415,16 @@ def get_oas_30(cfg): 'summary': 'Get {} item by id'.format(v['title']), 'description': v['description'], 'tags': [k], + 'operationId': 'get{}CollectionItem'.format(k.capitalize()), 'parameters': [ {'$ref': '{}#/components/parameters/featureId'.format(OPENAPI_YAML['oapif'])}, # noqa {'$ref': '#/components/parameters/f'} ], 'responses': { - 200: {'$ref': '{}#/components/responses/Feature'.format(OPENAPI_YAML['oapif'])}, # noqa - 400: {'$ref': '{}#/components/responses/InvalidParameter'.format(OPENAPI_YAML['oapif'])}, # noqa - 404: {'$ref': '{}#/components/responses/NotFound'.format(OPENAPI_YAML['oapif'])}, # noqa - 500: {'$ref': '{}#/components/responses/ServerError'.format(OPENAPI_YAML['oapif'])} # noqa + '200': {'$ref': '{}#/components/responses/Feature'.format(OPENAPI_YAML['oapif'])}, # noqa + '400': {'$ref': '{}#/components/responses/InvalidParameter'.format(OPENAPI_YAML['oapif'])}, # noqa + '404': {'$ref': '{}#/components/responses/NotFound'.format(OPENAPI_YAML['oapif'])}, # noqa + '500': {'$ref': '{}#/components/responses/ServerError'.format(OPENAPI_YAML['oapif'])} # noqa } } } @@ -422,9 +435,10 @@ def get_oas_30(cfg): 'summary': 'SpatioTemporal Asset Catalog', 'description': 'SpatioTemporal Asset Catalog', 'tags': ['stac'], + 'operationId': 'getSTACCatalog', 'parameters': [], 'responses': { - 200: {'$ref': '#/components/responses/200'}, + '200': {'$ref': '#/components/responses/200'}, 'default': {'$ref': '#/components/responses/default'} } } @@ -436,11 +450,12 @@ def get_oas_30(cfg): 'summary': 'Processes', 'description': 'Processes', 'tags': ['server'], + 'operationId': 'getProcesses', 'parameters': [ {'$ref': '#/components/parameters/f'} ], 'responses': { - 200: {'$ref': '#/components/responses/200'}, + '200': {'$ref': '#/components/responses/200'}, 'default': {'$ref': '#/components/responses/default'} } } @@ -473,11 +488,12 @@ def get_oas_30(cfg): 'summary': 'Get process metadata', 'description': p.metadata['description'], 'tags': [k], + 'operationId': 'get{}Process'.format(k.capitalize()), 'parameters': [ {'$ref': '#/components/parameters/f'} ], 'responses': { - 200: {'$ref': '#/components/responses/200'}, + '200': {'$ref': '#/components/responses/200'}, 'default': {'$ref': '#/components/responses/default'} } } @@ -487,8 +503,9 @@ def get_oas_30(cfg): 'summary': 'Retrieve job list for process', 'description': p.metadata['description'], 'tags': [k], + 'operationId': 'get{}Jobs'.format(k.capitalize()), 'responses': { - 200: {'$ref': '#/components/responses/200'}, + '200': {'$ref': '#/components/responses/200'}, 'default': {'$ref': '#/components/responses/default'} } }, @@ -497,9 +514,10 @@ def get_oas_30(cfg): p.metadata['title']), 'description': p.metadata['description'], 'tags': [k], + 'operationId': 'execute{}Job'.format(k.capitalize()), 'parameters': [], 'responses': { - 200: {'$ref': '#/components/responses/200'}, + '200': {'$ref': '#/components/responses/200'}, 'default': {'$ref': '#/components/responses/default'} }, 'requestBody': { From 90a5751707bd2a3532b3a5547439dafdb3afd838 Mon Sep 17 00:00:00 2001 From: Francesco Bartoli Date: Thu, 2 Jul 2020 17:37:12 +0200 Subject: [PATCH 2/2] Align operationId names to ogc api examples --- pygeoapi/openapi.py | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/pygeoapi/openapi.py b/pygeoapi/openapi.py index 528ce45..a54f972 100644 --- a/pygeoapi/openapi.py +++ b/pygeoapi/openapi.py @@ -153,7 +153,7 @@ def get_oas_30(cfg): 'summary': 'Landing page', 'description': 'Landing page', 'tags': ['server'], - 'operationId': 'getRoot', + 'operationId': 'getLandingPage', 'parameters': [ {'$ref': '#/components/parameters/f'} ], @@ -187,7 +187,7 @@ def get_oas_30(cfg): 'summary': 'API conformance definition', 'description': 'API conformance definition', 'tags': ['server'], - 'operationId': 'getConformance', + 'operationId': 'getConformanceDeclaration', 'parameters': [ {'$ref': '#/components/parameters/f'} ], @@ -310,7 +310,7 @@ def get_oas_30(cfg): 'summary': 'Get collection metadata'.format(v['title']), # noqa 'description': v['description'], 'tags': [k], - 'operationId': 'get{}Collection'.format(k.capitalize()), + 'operationId': 'describe{}Collection'.format(k.capitalize()), 'parameters': [ {'$ref': '#/components/parameters/f'} ], @@ -330,7 +330,7 @@ def get_oas_30(cfg): 'summary': 'Get {} items'.format(v['title']), 'description': v['description'], 'tags': [k], - 'operationId': 'get{}CollectionItems'.format(k.capitalize()), + 'operationId': 'get{}Features'.format(k.capitalize()), 'parameters': [ items_f, {'$ref': '{}#/components/parameters/bbox'.format(OPENAPI_YAML['oapif'])}, # noqa @@ -415,7 +415,7 @@ def get_oas_30(cfg): 'summary': 'Get {} item by id'.format(v['title']), 'description': v['description'], 'tags': [k], - 'operationId': 'get{}CollectionItem'.format(k.capitalize()), + 'operationId': 'get{}Feature'.format(k.capitalize()), 'parameters': [ {'$ref': '{}#/components/parameters/featureId'.format(OPENAPI_YAML['oapif'])}, # noqa {'$ref': '#/components/parameters/f'} @@ -435,7 +435,7 @@ def get_oas_30(cfg): 'summary': 'SpatioTemporal Asset Catalog', 'description': 'SpatioTemporal Asset Catalog', 'tags': ['stac'], - 'operationId': 'getSTACCatalog', + 'operationId': 'getStacCatalog', 'parameters': [], 'responses': { '200': {'$ref': '#/components/responses/200'}, @@ -488,7 +488,7 @@ def get_oas_30(cfg): 'summary': 'Get process metadata', 'description': p.metadata['description'], 'tags': [k], - 'operationId': 'get{}Process'.format(k.capitalize()), + 'operationId': 'describe{}Process'.format(k.capitalize()), 'parameters': [ {'$ref': '#/components/parameters/f'} ],