77# Colin Blackburn <[email protected] > 88# Ricardo Garcia Silva <[email protected] > 99#
10- # Copyright (c) 2025 Tom Kralidis
10+ # Copyright (c) 2026 Tom Kralidis
1111# Copyright (c) 2025 Francesco Bartoli
1212# Copyright (c) 2022 John A Stevenson and Colin Blackburn
1313# Copyright (c) 2023 Ricardo Garcia Silva
5555 set_content_crs_header )
5656from pygeoapi .formatter .base import FormatterSerializationError
5757from pygeoapi .linked_data import geojson2jsonld
58+ from pygeoapi .openapi import get_oas_30_parameters
5859from pygeoapi .plugin import load_plugin , PLUGINS
5960from pygeoapi .provider .base import (
6061 ProviderGenericError , ProviderTypeError , SchemaType )
6162
6263from pygeoapi .util import (filter_providers_by_type , to_json ,
6364 filter_dict_by_key_value , str2bool ,
64- get_provider_by_type , render_j2_template )
65+ get_provider_by_type , render_j2_template ,
66+ get_dataset_formatters )
6567
6668from . import (
6769 APIRequest , API , SYSTEM_LOCALE , F_JSON , FORMAT_TYPES , F_HTML , F_JSONLD ,
@@ -241,9 +243,6 @@ def get_collection_items(
241243 :returns: tuple of headers, status code, content
242244 """
243245
244- if not request .is_valid (PLUGINS ['formatter' ].keys ()):
245- return api .get_format_exception (request )
246-
247246 # Set Content-Language to system locale until provider locale
248247 # has been determined
249248 headers = request .get_response_headers (SYSTEM_LOCALE ,
@@ -352,6 +351,20 @@ def get_collection_items(
352351 err .http_status_code , headers , request .format ,
353352 err .ogc_exception_code , err .message )
354353
354+ LOGGER .debug ('Validating requested format' )
355+ dataset_formatters = get_dataset_formatters (collections [dataset ])
356+
357+ if dataset_formatters :
358+ LOGGER .debug (f'Dataset formatters: { dataset_formatters } ' )
359+ request ._format = request ._get_format (
360+ request .get_request_headers (request .headers ),
361+ {v .f : v .mimetype for v in dataset_formatters .values ()})
362+
363+ LOGGER .debug (f'Request format: { request .format } ' )
364+
365+ if not request .is_valid (dataset_formatters .keys ()):
366+ return api .get_format_exception (request )
367+
355368 crs_transform_spec = None
356369 if provider_type == 'feature' :
357370 # crs query parameter is only available for OGC API - Features
@@ -581,6 +594,14 @@ def get_collection_items(
581594 'href' : f'{ uri } ?f={ F_HTML } { serialized_query_params } '
582595 }])
583596
597+ for key , value in dataset_formatters .items ():
598+ content ['links' ].append ({
599+ 'type' : value .mimetype ,
600+ 'rel' : 'alternate' ,
601+ 'title' : f'This document as { key } ' ,
602+ 'href' : f'{ uri } ?f={ value .name } { serialized_query_params } '
603+ })
604+
584605 next_link = False
585606 prev_link = False
586607
@@ -656,9 +677,9 @@ def get_collection_items(
656677 'collections/items/index.html' ,
657678 content , request .locale )
658679 return headers , HTTPStatus .OK , content
659- elif request .format == 'csv' : # render
660- formatter = load_plugin ( 'formatter' ,
661- { 'name' : 'CSV' , 'geom' : True })
680+ elif request .format in [ df . f for df in dataset_formatters . values ()]:
681+ formatter = [ v for v in dataset_formatters . values () if
682+ v . f == request . format ][ 0 ]
662683
663684 try :
664685 content = formatter .write (
@@ -677,13 +698,14 @@ def get_collection_items(
677698
678699 headers ['Content-Type' ] = formatter .mimetype
679700
680- if p .filename is None :
681- filename = f'{ dataset } .csv'
682- else :
683- filename = f'{ p .filename } '
701+ if formatter .attachment :
702+ if p .filename is None :
703+ filename = f'{ dataset } .{ formatter .extension } '
704+ else :
705+ filename = f'{ p .filename } '
684706
685- cd = f'attachment; filename="{ filename } "'
686- headers ['Content-Disposition' ] = cd
707+ cd = f'attachment; filename="{ filename } "'
708+ headers ['Content-Disposition' ] = cd
687709
688710 return headers , HTTPStatus .OK , content
689711
@@ -1073,14 +1095,19 @@ def get_oas_30(cfg: dict, locale: str) -> tuple[list[dict[str, str]], dict[str,
10731095 v .get ('limits' , {})
10741096 )
10751097
1098+ dataset_formatters = get_dataset_formatters (v )
1099+ coll_f_parameter = deepcopy (get_oas_30_parameters (cfg , locale ))['f' ] # noqa
1100+ for key , value in dataset_formatters .items ():
1101+ coll_f_parameter ['schema' ]['enum' ].append (value .f )
1102+
10761103 paths [items_path ] = {
10771104 'get' : {
10781105 'summary' : f'Get { title } items' ,
10791106 'description' : description ,
10801107 'tags' : [k ],
10811108 'operationId' : f'get{ k .capitalize ()} Features' ,
10821109 'parameters' : [
1083- { '$ref' : '#/components/parameters/f' } ,
1110+ coll_f_parameter ,
10841111 {'$ref' : '#/components/parameters/lang' },
10851112 {'$ref' : '#/components/parameters/bbox' },
10861113 coll_limit ,
0 commit comments