Skip to content

Commit 57df549

Browse files
authored
make support for features/records extra query parameters configurable (#2071)
* make features/records extra query parameters configurable * remove debugging statement * set max_items for CITE demo * remove print statement * adjust comment
1 parent 6158ed5 commit 57df549

9 files changed

Lines changed: 60 additions & 6 deletions

File tree

docs/source/configuration.rst

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -250,6 +250,7 @@ default.
250250
mimetype: application/json # required: format mimetype
251251
options: # optional options to pass to provider (i.e. GDAL creation)
252252
option_name: option_value
253+
include_extra_query_parameters: false # include extra query parameters that are not part of the collection properties (default: false)
253254
254255
hello-world: # name of process
255256
type: process # REQUIRED (collection, process, or stac-collection)

docs/source/data-publishing/ogcapi-features.rst

Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -804,6 +804,32 @@ To publish a TinyDB (`see website <https://tinydb.readthedocs.io>`_) index, the
804804
id_field: identifier
805805
time_field: datetimefield
806806
807+
.. _including-extra-query-parameters:
808+
809+
Including extra query parameters
810+
--------------------------------
811+
812+
By default, pygeoapi ignores any extra query parameters. For example, for a given ``.../items`` query, the query key-value pair ``foo1=bar1`` (if ``foo1`` is not a valid property of a given collection) would be ignored by pygeoapi as well as the underlying provider.
813+
814+
To include/accept extra query parameters, the ``include_extra_query_parameters`` directive can be set in provider configuration:
815+
816+
.. code-block:: yaml
817+
818+
providers:
819+
- type: feature
820+
editable: true|false # optional, default is false
821+
name: TinyDB
822+
data: /path/to/file.db
823+
id_field: identifier
824+
time_field: datetimefield
825+
include_extra_query_parameters: true
826+
827+
828+
With the above configuration, pygeoapi will pass ``foo1=bar1`` to the underlying provider. If the underlying provider does not have ``foo1`` as a queryable property, then an exception will be returned citing an unknown property.
829+
830+
Extra query parameters are useful for custom providers who may wish for specific functionality to be triggered by query parameters that are not bound to a given collection's properties.
831+
832+
807833
Controlling the order of properties
808834
-----------------------------------
809835

docs/source/data-publishing/ogcapi-records.rst

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -96,6 +96,11 @@ CSW Record core model is supported as a baseline.
9696
title_field: title
9797
9898
99+
Including extra query parameters
100+
--------------------------------
101+
102+
See the :ref:`publishing vector section <including-extra-query-parameters>` for more information on including extra query parameters.
103+
99104
Metadata search examples
100105
------------------------
101106

pygeoapi/api/itemtypes.py

Lines changed: 7 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -415,13 +415,16 @@ def get_collection_items(
415415

416416
LOGGER.debug('processing property parameters')
417417
for k, v in request.params.items():
418+
include_query_param = False
418419
if k not in reserved_fieldnames:
419-
if k in list(p.fields.keys()):
420-
LOGGER.debug(f'Adding property filter {k}={v}')
421-
else:
422-
LOGGER.debug(f'Adding additional property filter {k}={v}')
420+
if k in list(p.fields.keys()) or p.include_extra_query_parameters:
421+
include_query_param = True
423422

423+
if include_query_param:
424+
LOGGER.debug(f'Including query parameter {k}={v}')
424425
properties.append((k, v))
426+
else:
427+
LOGGER.debug(f'Discarding query parameter {k}={v}')
425428

426429
LOGGER.debug('processing sort parameter')
427430
val = request.params.get('sortby')

pygeoapi/formatter/csv_.py

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -82,7 +82,6 @@ def write(self, options: dict = {}, data: dict = None) -> str:
8282
# TODO: implement wkt geometry serialization
8383
LOGGER.debug('not a point geometry, skipping')
8484

85-
print("JJJ", fields)
8685
LOGGER.debug(f'CSV fields: {fields}')
8786

8887
try:

pygeoapi/provider/base.py

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -74,6 +74,7 @@ def __init__(self, provider_def):
7474
self.title_field = provider_def.get('title_field')
7575
self.properties = provider_def.get('properties', [])
7676
self.file_types = provider_def.get('file_types', [])
77+
self.include_extra_query_parameters = provider_def.get('include_extra_query_parameters', False) # noqa
7778
self._fields = {}
7879
self.filename = None
7980

pygeoapi/schemas/config/pygeoapi-config-0.x.yml

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -573,6 +573,10 @@ properties:
573573
year in the Gregorian calendar.
574574
example:
575575
2017-03-25 in the Gregorian calendar is epoch 2017.23
576+
include_extra_query_parameters:
577+
type: boolean
578+
description: whether to include extra query parameters
579+
default: false
576580
required:
577581
- type
578582
- name

tests/api/test_itemtypes.py

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -385,6 +385,21 @@ def test_get_collection_items(config, api_):
385385
assert code == HTTPStatus.BAD_REQUEST
386386

387387

388+
def test_get_collection_items_include_extra_query_parameters(config, api_):
389+
req = mock_api_request()
390+
rsp_headers, code, response = get_collection_items(api_, req, 'obs')
391+
392+
assert code == HTTPStatus.OK
393+
response = json.loads(response)
394+
assert response['numberMatched'] == 5
395+
396+
api_.config['resources']['obs']['providers'][0]['include_extra_query_parameters'] = True # noqa
397+
req = mock_api_request({'foo': 'bar'})
398+
rsp_headers, code, response = get_collection_items(api_, req, 'obs')
399+
400+
assert code == HTTPStatus.BAD_REQUEST
401+
402+
388403
def test_collection_items_gzip_csv(config, api_, openapi):
389404
# Add gzip to server
390405
config['server']['gzip'] = True

tests/cite/cite.config.yml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,7 @@ server:
1010
pretty_print: true
1111
limits:
1212
default_items: 10
13-
max_items: 10
13+
max_items: 50
1414
# templates: /path/to/templates
1515
map:
1616
url: https://tile.openstreetmap.org/{z}/{x}/{y}.png

0 commit comments

Comments
 (0)