Skip to content

Commit a5af1d4

Browse files
committed
Use formatter filetype as dataset_formatters key
Cleanup implementation and reduce amount of list comprehension
1 parent 4809c11 commit a5af1d4

6 files changed

Lines changed: 38 additions & 40 deletions

File tree

pygeoapi/api/__init__.py

Lines changed: 18 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -206,12 +206,12 @@ def __init__(self, request, supported_locales):
206206
self._raw_locale, self._locale = self._get_locale(request.headers,
207207
supported_locales)
208208

209-
# Determine format
210-
self._format = self._get_format(request.headers)
211-
212209
# Get received headers
213210
self._headers = self.get_request_headers(request.headers)
214211

212+
# Determine format
213+
self._format = self._get_format()
214+
215215
@classmethod
216216
def from_flask(cls, request, supported_locales) -> 'APIRequest':
217217
"""Factory class similar to with_data, but only for flask requests"""
@@ -298,12 +298,10 @@ def _get_locale(self, headers: dict,
298298

299299
return raw, default_locale
300300

301-
def _get_format(self, headers: dict,
302-
extra_formats: dict = {}) -> Union[str, None]:
301+
def _get_format(self, extra_formats: dict = {}) -> Union[str, None]:
303302
"""
304303
Get `Request` format type from query parameters or headers.
305304
306-
:param headers: Dict of Request headers
307305
:param extra_formats: Dict of extra dataset specific formats
308306
309307
:returns: format value or None if not found/specified
@@ -317,19 +315,25 @@ def _get_format(self, headers: dict,
317315

318316
# Format not specified: get from Accept headers (MIME types)
319317
# e.g. Accept: 'text/html;q=0.5,application/ld+json'
320-
types_ = get_choice_from_headers(headers, 'accept', all=True)
318+
types_ = get_choice_from_headers(self.headers, 'accept', all=True)
321319
if types_ is None:
322320
return
323321

324-
merged_format_types = FORMAT_TYPES | extra_formats
325-
326-
(fmts, mimes) = zip(*merged_format_types.items())
327-
mimes2 = [m.split(';')[0] for m in mimes]
322+
# Add formatters to accepted format types
323+
extra_formats_mimes = {
324+
k: v.mimetype for k, v in extra_formats.items()
325+
if hasattr(v, 'mimetype')
326+
}
327+
merged_format_types = FORMAT_TYPES | extra_formats_mimes
328328

329+
# Lookup formatter by mimetype
330+
mimes = {
331+
merged_format_types[k].split(';')[0]: k
332+
for k in merged_format_types
333+
}
329334
for type_ in types_:
330-
if type_ in mimes2:
331-
idx_ = mimes2.index(type_)
332-
return fmts[idx_]
335+
if type_ in mimes:
336+
return mimes[type_]
333337

334338
@property
335339
def data(self) -> bytes:

pygeoapi/api/collection.py

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -265,8 +265,8 @@ def gen_collection(api, request, dataset: str,
265265
data['links'].append({
266266
'type': value.mimetype,
267267
'rel': 'items',
268-
'title': l10n.translate(f'Items as {key}', locale_), # noqa
269-
'href': f'{api.get_collections_url()}/{dataset}/items?f={value.f}' # noqa
268+
'title': l10n.translate(f'Items as {value.name}', locale_), # noqa
269+
'href': f'{api.get_collections_url()}/{dataset}/items?f={key}' # noqa
270270
})
271271

272272
# OAPIF Part 2 - list supported CRSs and StorageCRS

pygeoapi/api/environmental_data_retrieval.py

Lines changed: 6 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -298,13 +298,11 @@ def get_collection_edr_query(api: API, request: APIRequest,
298298

299299
if dataset_formatters:
300300
LOGGER.debug(f'Dataset formatters: {dataset_formatters}')
301-
request._format = request._get_format(
302-
request.get_request_headers(request.headers),
303-
{v.f: v.mimetype for v in dataset_formatters.values()})
301+
request._format = request._get_format(dataset_formatters)
304302

305303
LOGGER.debug(f'Request format: {request.format}')
306304

307-
if not request.is_valid(dataset_formatters.keys()):
305+
if not request.is_valid(dataset_formatters):
308306
return api.get_format_exception(request)
309307

310308
crs_transform_spec = None
@@ -475,9 +473,8 @@ def get_collection_edr_query(api: API, request: APIRequest,
475473
content = render_j2_template(api.tpl_config, tpl_config,
476474
'collections/edr/query.html', data,
477475
api.default_locale)
478-
elif request.format in [df.f for df in dataset_formatters.values()]:
479-
formatter = [v for v in dataset_formatters.values() if
480-
v.f == request.format][0]
476+
elif request.format in dataset_formatters:
477+
formatter = dataset_formatters[request.format]
481478

482479
try:
483480
content = formatter.write(
@@ -581,10 +578,10 @@ def get_oas_30(cfg: dict, locale: str) -> tuple[list[dict[str, str]], dict[str,
581578
'$ref': f"{OPENAPI_YAML['oaedr']}/parameters/{eqe['qt']}Coords.yaml" # noqa
582579
}
583580

581+
# Add data formatters to OAS
584582
dataset_formatters = get_dataset_formatters(v)
585583
coll_f_parameter = deepcopy(get_oas_30_parameters(cfg, locale))['f'] # noqa
586-
for key, value in dataset_formatters.items():
587-
coll_f_parameter['schema']['enum'].append(value.f)
584+
coll_f_parameter['schema']['enum'].extend(dataset_formatters)
588585

589586
paths[eqe['path']] = {
590587
'get': {

pygeoapi/api/itemtypes.py

Lines changed: 8 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -358,13 +358,11 @@ def get_collection_items(
358358

359359
if dataset_formatters:
360360
LOGGER.debug(f'Dataset formatters: {dataset_formatters}')
361-
request._format = request._get_format(
362-
request.get_request_headers(request.headers),
363-
{v.f: v.mimetype for v in dataset_formatters.values()})
361+
request._format = request._get_format(dataset_formatters)
364362

365363
LOGGER.debug(f'Request format: {request.format}')
366364

367-
if not request.is_valid(dataset_formatters.keys()):
365+
if not request.is_valid(dataset_formatters):
368366
return api.get_format_exception(request)
369367

370368
crs_transform_spec = None
@@ -600,8 +598,8 @@ def get_collection_items(
600598
content['links'].append({
601599
'type': value.mimetype,
602600
'rel': 'alternate',
603-
'title': f'This document as {key}',
604-
'href': f'{uri}?f={value.name}{serialized_query_params}'
601+
'title': f'This document as {value.name}',
602+
'href': f'{uri}?f={key}{serialized_query_params}'
605603
})
606604

607605
next_link = False
@@ -685,9 +683,8 @@ def get_collection_items(
685683
'collections/items/index.html',
686684
content, request.locale)
687685
return headers, HTTPStatus.OK, content
688-
elif request.format in [df.f for df in dataset_formatters.values()]:
689-
formatter = [v for v in dataset_formatters.values() if
690-
v.f == request.format][0]
686+
elif request.format in dataset_formatters:
687+
formatter = dataset_formatters[request.format]
691688

692689
try:
693690
content = formatter.write(
@@ -1109,10 +1106,10 @@ def get_oas_30(cfg: dict, locale: str) -> tuple[list[dict[str, str]], dict[str,
11091106
v.get('limits', {})
11101107
)
11111108

1109+
# Add data formatters to OAS
11121110
dataset_formatters = get_dataset_formatters(v)
11131111
coll_f_parameter = deepcopy(oas_30_parameters)['f']
1114-
for key, value in dataset_formatters.items():
1115-
coll_f_parameter['schema']['enum'].append(value.f)
1112+
coll_f_parameter['schema']['enum'].extend(dataset_formatters)
11161113

11171114
paths[items_path] = {
11181115
'get': {

pygeoapi/formatter/base.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -65,7 +65,7 @@ def write(
6565
:param options: formatting options
6666
:param data: dict representation of GeoJSON object
6767
68-
:returns: string representation of format
68+
:returns: string or bytes representation of format
6969
"""
7070

7171
raise NotImplementedError()

pygeoapi/util.py

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -768,17 +768,17 @@ def get_dataset_formatters(dataset: dict) -> dict:
768768
dataset_formatters = {}
769769
provider_type = get_provider_default(dataset['providers'])['type']
770770

771-
for key, value in PLUGINS['formatter'].items():
771+
for key in PLUGINS['formatter']:
772772
# workaround to keep items-based collections supporting CSV
773773
if provider_type not in ['feature', 'record']:
774774
continue
775775

776776
df2 = load_plugin('formatter', {'name': key})
777-
dataset_formatters[key] = df2
777+
dataset_formatters[df2.f] = df2
778778

779779
for df in dataset.get('formatters', []):
780780
df2 = load_plugin('formatter', df)
781-
dataset_formatters[df2.name] = df2
781+
dataset_formatters[df2.f] = df2
782782

783783
return dataset_formatters
784784

0 commit comments

Comments
 (0)