Skip to content

Commit

Permalink
implement CSW facade
Browse files Browse the repository at this point in the history
  • Loading branch information
tomkralidis committed Nov 1, 2023
1 parent 169450f commit 33e8617
Show file tree
Hide file tree
Showing 8 changed files with 510 additions and 40 deletions.
21 changes: 21 additions & 0 deletions docs/source/data-publishing/ogcapi-records.rst
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@ parameters.

`ElasticsearchCatalogue`_,✅,results/hits,✅,✅,✅,✅,❌
`TinyDBCatalogue`_,✅,results/hits,✅,✅,✅,✅,✅
`CSWFacade`_,✅,results/hits,✅,✅,✅,❌,❌


Below are specific connection examples based on supported providers.
Expand Down Expand Up @@ -70,6 +71,25 @@ To publish a TinyDB index, the following are required in your index:
id_field: identifier
time_field: datetimefield
CSWFacade
^^^^^^^^^

.. note::
Requires Python package `OWSLib`_

To publish a CSW using pygeoapi, the CSW base URL (`data`) is required. Note that the
CSW Record core model is supported as a baseline.

.. code-block:: yaml
providers:
- type: record
name: CSWFacade
data: https://demo.pycsw.org/cite/csw
id_field: identifier
time_field: datetime
title_field: title
Metadata search examples
------------------------
Expand Down Expand Up @@ -103,3 +123,4 @@ Metadata search examples

.. _`OGC API - Records`: https://ogcapi.ogc.org/records
.. _`OGC API - Records GeoJSON Features`: https://raw.githubusercontent.com/opengeospatial/ogcapi-records/master/core/openapi/schemas/recordGeoJSON.yaml
.. _`OWSLib`: https://geopython.github.io/OWSLib
72 changes: 36 additions & 36 deletions pygeoapi/api.py
Original file line number Diff line number Diff line change
Expand Up @@ -1116,7 +1116,7 @@ def describe_collections(self, request: Union[APIRequest, Any],
'coverage')
p = load_plugin('provider', provider_def)
except ProviderConnectionError:
msg = 'connection error (check logs)'
msg = f'connection error (check logs) {err}'

Check failure on line 1119 in pygeoapi/api.py

View workflow job for this annotation

GitHub Actions / flake8_py3

pygeoapi/api.py#L1119

[F821] undefined name
return self.get_exception(
HTTPStatus.INTERNAL_SERVER_ERROR,
headers, request.format,
Expand All @@ -1132,7 +1132,7 @@ def describe_collections(self, request: Union[APIRequest, Any],
tile = get_provider_by_type(v['providers'], 'tile')
p = load_plugin('provider', tile)
except ProviderConnectionError:
msg = 'connection error (check logs)'
msg = f'connection error (check logs) {err}'

Check failure on line 1135 in pygeoapi/api.py

View workflow job for this annotation

GitHub Actions / flake8_py3

pygeoapi/api.py#L1135

[F821] undefined name
return self.get_exception(
HTTPStatus.INTERNAL_SERVER_ERROR,
headers, request.format,
Expand Down Expand Up @@ -1206,7 +1206,7 @@ def describe_collections(self, request: Union[APIRequest, Any],
'href': f'{self.get_collections_url()}/{k}/{qt}?f={F_HTML}' # noqa
})
except ProviderConnectionError:
msg = 'connection error (check logs)'
msg = f'connection error (check logs) {err}'

Check failure on line 1209 in pygeoapi/api.py

View workflow job for this annotation

GitHub Actions / flake8_py3

pygeoapi/api.py#L1209

[F821] undefined name
return self.get_exception(
HTTPStatus.INTERNAL_SERVER_ERROR, headers,
request.format, 'NoApplicableCode', msg)
Expand Down Expand Up @@ -1302,12 +1302,12 @@ def get_collection_queryables(self, request: Union[APIRequest, Any],
p = load_plugin('provider', get_provider_by_type(
self.config['resources'][dataset]['providers'], 'record'))
except ProviderConnectionError:
msg = 'connection error (check logs)'
msg = f'connection error (check logs) {err}'

Check failure on line 1305 in pygeoapi/api.py

View workflow job for this annotation

GitHub Actions / flake8_py3

pygeoapi/api.py#L1305

[F821] undefined name
return self.get_exception(
HTTPStatus.INTERNAL_SERVER_ERROR, headers, request.format,
'NoApplicableCode', msg)
except ProviderQueryError:
msg = 'query error (check logs)'
msg = f'query error (check logs) {err}'

Check failure on line 1310 in pygeoapi/api.py

View workflow job for this annotation

GitHub Actions / flake8_py3

pygeoapi/api.py#L1310

[F821] undefined name
return self.get_exception(
HTTPStatus.INTERNAL_SERVER_ERROR, headers, request.format,
'NoApplicableCode', msg)
Expand Down Expand Up @@ -1483,12 +1483,12 @@ def get_collection_items(
HTTPStatus.BAD_REQUEST, headers, request.format,
'NoApplicableCode', msg)
except ProviderConnectionError:
msg = 'connection error (check logs)'
msg = f'connection error (check logs) {err}'

Check failure on line 1486 in pygeoapi/api.py

View workflow job for this annotation

GitHub Actions / flake8_py3

pygeoapi/api.py#L1486

[F821] undefined name
return self.get_exception(
HTTPStatus.INTERNAL_SERVER_ERROR, headers, request.format,
'NoApplicableCode', msg)
except ProviderQueryError:
msg = 'query error (check logs)'
msg = f'query error (check logs) {err}'

Check failure on line 1491 in pygeoapi/api.py

View workflow job for this annotation

GitHub Actions / flake8_py3

pygeoapi/api.py#L1491

[F821] undefined name
return self.get_exception(
HTTPStatus.INTERNAL_SERVER_ERROR, headers, request.format,
'NoApplicableCode', msg)
Expand Down Expand Up @@ -1661,19 +1661,19 @@ def get_collection_items(
'InvalidQuery', msg)
except ProviderConnectionError as err:
LOGGER.error(err)
msg = 'connection error (check logs)'
msg = f'connection error (check logs) {err}'
return self.get_exception(
HTTPStatus.INTERNAL_SERVER_ERROR, headers, request.format,
'NoApplicableCode', msg)
except ProviderQueryError as err:
LOGGER.error(err)
msg = 'query error (check logs)'
msg = f'query error (check logs) {err}'
return self.get_exception(
HTTPStatus.INTERNAL_SERVER_ERROR, headers, request.format,
'NoApplicableCode', msg)
except ProviderGenericError as err:
LOGGER.error(err)
msg = 'generic error (check logs)'
msg = f'generic error (check logs) {err}'
return self.get_exception(
HTTPStatus.INTERNAL_SERVER_ERROR, headers, request.format,
'NoApplicableCode', msg)
Expand Down Expand Up @@ -1931,12 +1931,12 @@ def post_collection_items(
HTTPStatus.BAD_REQUEST, headers, request.format,
'NoApplicableCode', msg)
except ProviderConnectionError:
msg = 'connection error (check logs)'
msg = 'connection error (check logs) {err}'
return self.get_exception(
HTTPStatus.INTERNAL_SERVER_ERROR, headers, request.format,
'NoApplicableCode', msg)
except ProviderQueryError:
msg = 'query error (check logs)'
msg = 'query error (check logs) {err}'
return self.get_exception(
HTTPStatus.INTERNAL_SERVER_ERROR, headers, request.format,
'NoApplicableCode', msg)
Expand Down Expand Up @@ -2268,12 +2268,12 @@ def get_collection_item(self, request: Union[APIRequest, Any],
HTTPStatus.BAD_REQUEST, headers, request.format,
'InvalidParameterValue', msg)
except ProviderConnectionError:
msg = 'connection error (check logs)'
msg = f'connection error (check logs) {err}'

Check failure on line 2271 in pygeoapi/api.py

View workflow job for this annotation

GitHub Actions / flake8_py3

pygeoapi/api.py#L2271

[F821] undefined name
return self.get_exception(
HTTPStatus.INTERNAL_SERVER_ERROR, headers, request.format,
'NoApplicableCode', msg)
except ProviderQueryError:
msg = 'query error (check logs)'
msg = f'query error (check logs) {err}'

Check failure on line 2276 in pygeoapi/api.py

View workflow job for this annotation

GitHub Actions / flake8_py3

pygeoapi/api.py#L2276

[F821] undefined name
return self.get_exception(
HTTPStatus.INTERNAL_SERVER_ERROR, headers, request.format,
'NoApplicableCode', msg)
Expand Down Expand Up @@ -2307,7 +2307,7 @@ def get_collection_item(self, request: Union[APIRequest, Any],
)
except ProviderConnectionError as err:
LOGGER.error(err)
msg = 'connection error (check logs)'
msg = f'connection error (check logs) {err}'
return self.get_exception(
HTTPStatus.INTERNAL_SERVER_ERROR, headers, request.format,
'NoApplicableCode', msg)
Expand All @@ -2317,13 +2317,13 @@ def get_collection_item(self, request: Union[APIRequest, Any],
request.format, 'NotFound', msg)
except ProviderQueryError as err:
LOGGER.error(err)
msg = 'query error (check logs)'
msg = f'query error (check logs) {err}'
return self.get_exception(
HTTPStatus.INTERNAL_SERVER_ERROR, headers, request.format,
'NoApplicableCode', msg)
except ProviderGenericError as err:
LOGGER.error(err)
msg = 'generic error (check logs)'
msg = f'generic error (check logs) {err}'
return self.get_exception(
HTTPStatus.INTERNAL_SERVER_ERROR, headers, request.format,
'NoApplicableCode', msg)
Expand Down Expand Up @@ -2454,7 +2454,7 @@ def get_collection_coverage(self, request: Union[APIRequest, Any],
HTTPStatus.BAD_REQUEST, headers, format_,
'NoApplicableCode', msg)
except ProviderConnectionError:
msg = 'connection error (check logs)'
msg = f'connection error (check logs) {err}'

Check failure on line 2457 in pygeoapi/api.py

View workflow job for this annotation

GitHub Actions / flake8_py3

pygeoapi/api.py#L2457

[F821] undefined name
return self.get_exception(
HTTPStatus.INTERNAL_SERVER_ERROR, headers, format_,
'NoApplicableCode', msg)
Expand Down Expand Up @@ -2550,7 +2550,7 @@ def get_collection_coverage(self, request: Union[APIRequest, Any],
HTTPStatus.NO_CONTENT, headers, format_,
'InvalidParameterValue', msg)
except ProviderQueryError:
msg = 'query error (check logs)'
msg = f'query error (check logs) {err}'

Check failure on line 2553 in pygeoapi/api.py

View workflow job for this annotation

GitHub Actions / flake8_py3

pygeoapi/api.py#L2553

[F821] undefined name
return self.get_exception(
HTTPStatus.INTERNAL_SERVER_ERROR, headers, format_,
'NoApplicableCode', msg)
Expand Down Expand Up @@ -2606,7 +2606,7 @@ def get_collection_coverage_domainset(
HTTPStatus.INTERNAL_SERVER_ERROR, headers, format_,
'NoApplicableCode', msg)
except ProviderConnectionError:
msg = 'connection error (check logs)'
msg = f'connection error (check logs) {err}'

Check failure on line 2609 in pygeoapi/api.py

View workflow job for this annotation

GitHub Actions / flake8_py3

pygeoapi/api.py#L2609

[F821] undefined name
return self.get_exception(
HTTPStatus.INTERNAL_SERVER_ERROR, headers, format_,
'NoApplicableCode', msg)
Expand Down Expand Up @@ -2663,7 +2663,7 @@ def get_collection_coverage_rangetype(
HTTPStatus.INTERNAL_SERVER_ERROR, headers, format_,
'NoApplicableCode', msg)
except ProviderConnectionError:
msg = 'connection error (check logs)'
msg = f'connection error (check logs) {err}'

Check failure on line 2666 in pygeoapi/api.py

View workflow job for this annotation

GitHub Actions / flake8_py3

pygeoapi/api.py#L2666

[F821] undefined name
return self.get_exception(
HTTPStatus.INTERNAL_SERVER_ERROR, headers, format_,
'NoApplicableCode', msg)
Expand Down Expand Up @@ -2721,12 +2721,12 @@ def get_collection_tiles(self, request: Union[APIRequest, Any],
HTTPStatus.BAD_REQUEST, headers, request.format,
'InvalidParameterValue', msg)
except ProviderConnectionError:
msg = 'connection error (check logs)'
msg = f'connection error (check logs) {err}'

Check failure on line 2724 in pygeoapi/api.py

View workflow job for this annotation

GitHub Actions / flake8_py3

pygeoapi/api.py#L2724

[F821] undefined name
return self.get_exception(
HTTPStatus.INTERNAL_SERVER_ERROR, headers, request.format,
'NoApplicableCode', msg)
except ProviderQueryError:
msg = 'query error (check logs)'
msg = f'query error (check logs) {err}'

Check failure on line 2729 in pygeoapi/api.py

View workflow job for this annotation

GitHub Actions / flake8_py3

pygeoapi/api.py#L2729

[F821] undefined name
return self.get_exception(
HTTPStatus.INTERNAL_SERVER_ERROR, headers, request.format,
'NoApplicableCode', msg)
Expand Down Expand Up @@ -2872,7 +2872,7 @@ def get_collection_tiles_data(
'InvalidParameterValue', msg)
except ProviderConnectionError as err:
LOGGER.error(err)
msg = 'connection error (check logs)'
msg = f'connection error (check logs) {err}'
return self.get_exception(
HTTPStatus.INTERNAL_SERVER_ERROR, headers, format_,
'NoApplicableCode', msg)
Expand All @@ -2888,12 +2888,12 @@ def get_collection_tiles_data(
'NoApplicableCode', msg)
except ProviderTileNotFoundError as err:
LOGGER.error(err)
msg = 'Tile not found (check logs)'
msg = f'Tile not found (check logs) {err}'
return self.get_exception(
HTTPStatus.NOT_FOUND, headers, format_, 'NoMatch', msg)
except ProviderGenericError as err:
LOGGER.error(err)
msg = 'Generic error (check logs)'
msg = f'Generic error (check logs) {err}'
return self.get_exception(
HTTPStatus.INTERNAL_SERVER_ERROR, headers, format_,
'NoApplicableCode', msg)
Expand Down Expand Up @@ -2937,12 +2937,12 @@ def get_collection_tiles_metadata(
HTTPStatus.BAD_REQUEST, headers, request.format,
'InvalidParameterValue', msg)
except ProviderConnectionError:
msg = 'connection error (check logs)'
msg = f'connection error (check logs) {err}'

Check failure on line 2940 in pygeoapi/api.py

View workflow job for this annotation

GitHub Actions / flake8_py3

pygeoapi/api.py#L2940

[F821] undefined name
return self.get_exception(
HTTPStatus.INTERNAL_SERVER_ERROR, headers, request.format,
'InvalidParameterValue', msg)
except ProviderQueryError:
msg = 'query error (check logs)'
msg = f'query error (check logs) {err}'

Check failure on line 2945 in pygeoapi/api.py

View workflow job for this annotation

GitHub Actions / flake8_py3

pygeoapi/api.py#L2945

[F821] undefined name
return self.get_exception(
HTTPStatus.INTERNAL_SERVER_ERROR, headers, request.format,
'InvalidParameterValue', msg)
Expand Down Expand Up @@ -3049,7 +3049,7 @@ def get_collection_map(self, request: Union[APIRequest, Any],
except ProviderConnectionError:
exception = {
'code': 'NoApplicableCode',
'description': 'connection error (check logs)'
'description': f'connection error (check logs) {err}'

Check failure on line 3052 in pygeoapi/api.py

View workflow job for this annotation

GitHub Actions / flake8_py3

pygeoapi/api.py#L3052

[F821] undefined name
}
headers['Content-type'] = 'application/json'
LOGGER.error(exception)
Expand Down Expand Up @@ -3135,7 +3135,7 @@ def get_collection_map(self, request: Union[APIRequest, Any],
except ProviderQueryError:
exception = {
'code': 'NoApplicableCode',
'description': 'query error (check logs)'
'description': f'query error (check logs) {err}'

Check failure on line 3138 in pygeoapi/api.py

View workflow job for this annotation

GitHub Actions / flake8_py3

pygeoapi/api.py#L3138

[F821] undefined name
}
LOGGER.error(exception)
headers['Content-type'] = 'application/json'
Expand Down Expand Up @@ -3202,7 +3202,7 @@ def get_collection_map_legend(
except ProviderConnectionError:
exception = {
'code': 'NoApplicableCode',
'description': 'connection error (check logs)'
'description': f'connection error (check logs) {err}'

Check failure on line 3205 in pygeoapi/api.py

View workflow job for this annotation

GitHub Actions / flake8_py3

pygeoapi/api.py#L3205

[F821] undefined name
}
LOGGER.error(exception)
return headers, HTTPStatus.INTERNAL_SERVER_ERROR, to_json(
Expand Down Expand Up @@ -3230,7 +3230,7 @@ def get_collection_map_legend(
except ProviderQueryError:
exception = {
'code': 'NoApplicableCode',
'description': 'query error (check logs)'
'description': f'query error (check logs) {err}'

Check failure on line 3233 in pygeoapi/api.py

View workflow job for this annotation

GitHub Actions / flake8_py3

pygeoapi/api.py#L3233

[F821] undefined name
}
LOGGER.error(exception)
return headers, HTTPStatus.INTERNAL_SERVER_ERROR, to_json(
Expand Down Expand Up @@ -3820,12 +3820,12 @@ def get_collection_edr_query(
HTTPStatus.INTERNAL_SERVER_ERROR, headers,
request.format, 'NoApplicableCode', msg)
except ProviderConnectionError:
msg = 'connection error (check logs)'
msg = f'connection error (check logs) {err}'

Check failure on line 3823 in pygeoapi/api.py

View workflow job for this annotation

GitHub Actions / flake8_py3

pygeoapi/api.py#L3823

[F821] undefined name
return self.get_exception(
HTTPStatus.INTERNAL_SERVER_ERROR, headers,
request.format, 'NoApplicableCode', msg)
except ProviderQueryError:
msg = 'query error (check logs)'
msg = f'query error (check logs) {err}'

Check failure on line 3828 in pygeoapi/api.py

View workflow job for this annotation

GitHub Actions / flake8_py3

pygeoapi/api.py#L3828

[F821] undefined name
return self.get_exception(
HTTPStatus.INTERNAL_SERVER_ERROR, headers,
request.format, 'NoApplicableCode', msg)
Expand Down Expand Up @@ -3875,7 +3875,7 @@ def get_collection_edr_query(
return self.get_exception(
HTTPStatus.NO_CONTENT, headers, request.format, 'NoMatch', msg)
except ProviderQueryError:
msg = 'query error (check logs)'
msg = f'query error (check logs) {err}'

Check failure on line 3878 in pygeoapi/api.py

View workflow job for this annotation

GitHub Actions / flake8_py3

pygeoapi/api.py#L3878

[F821] undefined name
return self.get_exception(
HTTPStatus.INTERNAL_SERVER_ERROR, headers, request.format,
'NoApplicableCode', msg)
Expand Down Expand Up @@ -3987,7 +3987,7 @@ def get_stac_path(self, request: Union[APIRequest, Any],
stac_collections[dataset]['providers'], 'stac'))
except ProviderConnectionError as err:
LOGGER.error(err)
msg = 'connection error (check logs)'
msg = f'connection error (check logs) {err}'
return self.get_exception(
HTTPStatus.INTERNAL_SERVER_ERROR, headers,
request.format, 'NoApplicableCode', msg)
Expand Down
1 change: 1 addition & 0 deletions pygeoapi/plugin.py
Original file line number Diff line number Diff line change
Expand Up @@ -40,6 +40,7 @@
'provider': {
'AzureBlobStorage': 'pygeoapi.provider.azure_.AzureBlobStorageProvider', # noqa
'CSV': 'pygeoapi.provider.csv_.CSVProvider',
'CSWFacade': 'pygeoapi.provider.csw_facade.CSWFacadeProvider',
'Elasticsearch': 'pygeoapi.provider.elasticsearch_.ElasticsearchProvider', # noqa
'ElasticsearchCatalogue': 'pygeoapi.provider.elasticsearch_.ElasticsearchCatalogueProvider', # noqa
'ERDDAPTabledap': 'pygeoapi.provider.erddap.TabledapProvider',
Expand Down
2 changes: 1 addition & 1 deletion pygeoapi/process/manager/base.py
Original file line number Diff line number Diff line change
Expand Up @@ -290,7 +290,7 @@ def _execute_handler_sync(self, p: BaseProcessor, job_id: str,
code = 'InvalidParameterValue'
outputs = {
'code': code,
'description': 'Error updating job'
'description': f'Error updating job: {err}'
}
LOGGER.error(err)
job_metadata = {
Expand Down
2 changes: 1 addition & 1 deletion pygeoapi/process/manager/dummy.py
Original file line number Diff line number Diff line change
Expand Up @@ -101,7 +101,7 @@ def execute_process(
except Exception as err:
outputs = {
'code': 'InvalidParameterValue',
'description': 'Error updating job'
'description': f'Error updating job: {err}'
}
current_status = JobStatus.failed
LOGGER.error(err)
Expand Down
Loading

0 comments on commit 33e8617

Please sign in to comment.