Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
32 changes: 18 additions & 14 deletions pygeoapi/api/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -206,12 +206,12 @@ def __init__(self, request, supported_locales):
self._raw_locale, self._locale = self._get_locale(request.headers,
supported_locales)

# Determine format
self._format = self._get_format(request.headers)

# Get received headers
self._headers = self.get_request_headers(request.headers)

# Determine format
self._format = self._get_format()

@classmethod
def from_flask(cls, request, supported_locales) -> 'APIRequest':
"""Factory class similar to with_data, but only for flask requests"""
Expand Down Expand Up @@ -298,12 +298,10 @@ def _get_locale(self, headers: dict,

return raw, default_locale

def _get_format(self, headers: dict,
extra_formats: dict = {}) -> Union[str, None]:
def _get_format(self, extra_formats: dict = {}) -> Union[str, None]:
"""
Get `Request` format type from query parameters or headers.

:param headers: Dict of Request headers
:param extra_formats: Dict of extra dataset specific formats

:returns: format value or None if not found/specified
Expand All @@ -317,19 +315,25 @@ def _get_format(self, headers: dict,

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

merged_format_types = FORMAT_TYPES | extra_formats

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

# Lookup formatter by mimetype
mimes = {
merged_format_types[k].split(';')[0]: k
for k in merged_format_types
}
for type_ in types_:
if type_ in mimes2:
idx_ = mimes2.index(type_)
return fmts[idx_]
if type_ in mimes:
return mimes[type_]

@property
def data(self) -> bytes:
Expand Down
4 changes: 2 additions & 2 deletions pygeoapi/api/collection.py
Original file line number Diff line number Diff line change
Expand Up @@ -265,8 +265,8 @@ def gen_collection(api, request, dataset: str,
data['links'].append({
'type': value.mimetype,
'rel': 'items',
'title': l10n.translate(f'Items as {key}', locale_), # noqa
'href': f'{api.get_collections_url()}/{dataset}/items?f={value.f}' # noqa
'title': l10n.translate(f'Items as {value.name}', locale_), # noqa
'href': f'{api.get_collections_url()}/{dataset}/items?f={key}' # noqa
})

# OAPIF Part 2 - list supported CRSs and StorageCRS
Expand Down
15 changes: 6 additions & 9 deletions pygeoapi/api/environmental_data_retrieval.py
Original file line number Diff line number Diff line change
Expand Up @@ -298,13 +298,11 @@ def get_collection_edr_query(api: API, request: APIRequest,

if dataset_formatters:
LOGGER.debug(f'Dataset formatters: {dataset_formatters}')
request._format = request._get_format(
request.get_request_headers(request.headers),
{v.f: v.mimetype for v in dataset_formatters.values()})
request._format = request._get_format(dataset_formatters)

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

if not request.is_valid(dataset_formatters.keys()):
if not request.is_valid(dataset_formatters):
return api.get_format_exception(request)

crs_transform_spec = None
Expand Down Expand Up @@ -475,9 +473,8 @@ def get_collection_edr_query(api: API, request: APIRequest,
content = render_j2_template(api.tpl_config, tpl_config,
'collections/edr/query.html', data,
api.default_locale)
elif request.format in [df.f for df in dataset_formatters.values()]:
formatter = [v for v in dataset_formatters.values() if
v.f == request.format][0]
elif request.format in dataset_formatters:
formatter = dataset_formatters[request.format]

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

# Add data formatters to OAS
dataset_formatters = get_dataset_formatters(v)
coll_f_parameter = deepcopy(get_oas_30_parameters(cfg, locale))['f'] # noqa
for key, value in dataset_formatters.items():
coll_f_parameter['schema']['enum'].append(value.f)
coll_f_parameter['schema']['enum'].extend(dataset_formatters)

paths[eqe['path']] = {
'get': {
Expand Down
19 changes: 8 additions & 11 deletions pygeoapi/api/itemtypes.py
Original file line number Diff line number Diff line change
Expand Up @@ -358,13 +358,11 @@ def get_collection_items(

if dataset_formatters:
LOGGER.debug(f'Dataset formatters: {dataset_formatters}')
request._format = request._get_format(
request.get_request_headers(request.headers),
{v.f: v.mimetype for v in dataset_formatters.values()})
request._format = request._get_format(dataset_formatters)

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

if not request.is_valid(dataset_formatters.keys()):
if not request.is_valid(dataset_formatters):
return api.get_format_exception(request)

crs_transform_spec = None
Expand Down Expand Up @@ -600,8 +598,8 @@ def get_collection_items(
content['links'].append({
'type': value.mimetype,
'rel': 'alternate',
'title': f'This document as {key}',
'href': f'{uri}?f={value.name}{serialized_query_params}'
'title': f'This document as {value.name}',
'href': f'{uri}?f={key}{serialized_query_params}'
})

next_link = False
Expand Down Expand Up @@ -685,9 +683,8 @@ def get_collection_items(
'collections/items/index.html',
content, request.locale)
return headers, HTTPStatus.OK, content
elif request.format in [df.f for df in dataset_formatters.values()]:
formatter = [v for v in dataset_formatters.values() if
v.f == request.format][0]
elif request.format in dataset_formatters:
formatter = dataset_formatters[request.format]

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

# Add data formatters to OAS
dataset_formatters = get_dataset_formatters(v)
coll_f_parameter = deepcopy(oas_30_parameters)['f']
for key, value in dataset_formatters.items():
coll_f_parameter['schema']['enum'].append(value.f)
coll_f_parameter['schema']['enum'].extend(dataset_formatters)

paths[items_path] = {
'get': {
Expand Down
6 changes: 4 additions & 2 deletions pygeoapi/formatter/base.py
Original file line number Diff line number Diff line change
Expand Up @@ -56,14 +56,16 @@ def __init__(self, formatter_def: dict):
self.geom = formatter_def.get('geom', False)
self.attachment = formatter_def.get('attachment', False)

def write(self, options: dict = {}, data: dict | None = None) -> str:
def write(
self, options: dict = {}, data: dict | None = None
) -> str | bytes:
"""
Generate data in specified format

:param options: formatting options
:param data: dict representation of GeoJSON object

:returns: string representation of format
:returns: string or bytes representation of format
"""

raise NotImplementedError()
Expand Down
6 changes: 3 additions & 3 deletions pygeoapi/util.py
Original file line number Diff line number Diff line change
Expand Up @@ -768,17 +768,17 @@ def get_dataset_formatters(dataset: dict) -> dict:
dataset_formatters = {}
provider_type = get_provider_default(dataset['providers'])['type']

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

df2 = load_plugin('formatter', {'name': key})
dataset_formatters[key] = df2
dataset_formatters[df2.f] = df2

for df in dataset.get('formatters', []):
df2 = load_plugin('formatter', df)
dataset_formatters[df2.name] = df2
dataset_formatters[df2.f] = df2

return dataset_formatters

Expand Down
Loading