geopython / pygeoapi

pygeoapi is a Python server implementation of the OGC API suite of standards. The project emerged as part of the next generation OGC API efforts in 2018 and provides the capability for organizations to deploy a RESTful OGC API endpoint using OpenAPI, GeoJSON, and HTML. pygeoapi is open source and released under an MIT license.
https://pygeoapi.io
MIT License
474 stars 255 forks source link

'Invalid format' error #89

Closed justb4 closed 5 years ago

justb4 commented 5 years ago

Running plain pygeoapi in virtualenv Python 3.7.1 Ubuntu 18.04 and requesting any URL via the browser all requests return:

                InvalidParameterValue
                Invalid format

We expect collections etc.

Inspecting the code it appears to come out of the function pygeoapi.py: check_format(), in particular this line will return a list of accept formats so the check on this line will always fail.

Have tested and will make a PR, replacing the check_format() function with something like:

def check_format(args, headers):
    """
    check format requested from arguments or headers

    :param args: dict of request keyword value pairs
    :param headers: dict of request headers

    :returns: format value
    """

    # Optional f=html or f=json query param
    # overrides accept
    format_ = args.get('f')
    if format_:
        return format_

    # Format not specified: get from accept headers
    format_ = 'text/html'

    if 'accept' in headers.keys():
        format_ = headers['accept']
    elif 'Accept' in headers.keys():
        format_ = headers['Accept']

    format_ = format_.split(',')

    if 'text/html' in format_:
        format_ = 'html'
    elif 'application/json' in format_:
        format_ = 'json'

    return format_

This works for us, both with query parm, and even default (neither f= nor accept headers).

justb4 commented 5 years ago

To be complete some tests need to be added in test_check_format() for "browser Accept Header" where we initially ran into and was the reason for this issue. A typical browser Accept Header may look like:

Accept: text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,image/apng,*/*;q=0.8,application/signed-exchange;v=b3

A PR is a bit overkill to add lines in test_check_format() :

headers_['Accept'] = 'text/html,application/xhtml+xml,application/xml;q=0.9,'
assert check_format({}, headers_) == 'html'

headers_['accept'] = 'text/html,application/xhtml+xml,application/xml;q=0.9,'
assert check_format({}, headers_) == 'html'
tomkralidis commented 5 years ago

Thanks @justb4; added in 20c96a8f4756aabad60fb0a39704de2b715715c6