Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

"SyntaxError: not a PNG file" in maps.map() call with 204 response #89

Open
dfloer opened this issue Sep 7, 2021 · 1 comment
Open

Comments

@dfloer
Copy link

dfloer commented Sep 7, 2021

I'm getting the following traceback (trimmed from pytest run) when pygbif gets a HTTP 204 error back from the GBIF API. According to the documentation, maps.map() returns a GbifMap object and doesn't raise any exceptions. What I'm seeing it it blowing up instead.

/pygbif/maps/map.py:172: in map
    return GbifMap(out)
/pygbif/maps/map.py:193: in __init__
    self.img = self.__prep_plot()
/pygbif/maps/map.py:203: in __prep_plot
    img = mpimg.imread(self.path)
/matplotlib/image.py:1501: in imread
    with img_open(fname) as image:
/PIL/ImageFile.py:121: in __init__
    self._open()
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _

self = <PIL.PngImagePlugin.PngImageFile image mode= size=0x0 at 0x7FA7DA8A64F0>

    def _open(self):

        if not _accept(self.fp.read(8)):
>           raise SyntaxError("not a PNG file")
E           SyntaxError: not a PNG file
/PIL/PngImagePlugin.py:676: SyntaxError

Here's a command that triggers it for me now: pygbif.maps.map(z=10, x=10, y=10). It appears that the API is returning a 204 when there's no data to return for a query. Unfortunately, there's no upstream documentation on what HTTP status codes are allowed for the mapping API, so I puzzled out that this is probably when there aren't any occurrences of the taxon to show, but I also seemed to get it in possible error cases.

This is caused by not checking if there was actually a PNG received from the API before opening it:

if has(self.response.headers["Content-Type"], "png"):

The API responds saying that the content type is image/png (not png as the code above incorrectly assumes), but has no Content-Length header and a 0 byte body. The API returning an invalid PNG file is an API issue, it shouldn't do that, but that case should also be checked for.

Versions:
Python: 3.8.12 (old, needed for another dependency)
pygbif: 0.6.0
pillow: 8.3.2

@dfloer
Copy link
Author

dfloer commented Sep 8, 2021

The monkey patch I ended up applying to work around #87 also removes the attempt to plot, so the allows me to properly get the "empty" response.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

1 participant