Skip to content

WebP image saving broken from 10.3.0 to 10.4.0 #8198

@jax-b

Description

@jax-b

What did you do?

Installed the latest version of 10.4.0 to my AWS lambda test environment

What did you expect to happen?

No issues opening and saving webp files

What actually happened?

WebP files failed to open without changing to a intermediary BytesIO
After changing to a intermediary BytesIO i still had trouble saving the image

Reverting Pillow to 10.3.0 restores operation

What are your OS, Python and Pillow versions?

  • OS: AWS Linux 2
  • Python: 3.10.0
  • Pillow: 10.4.0

pil features

10.4.0
--------------------------------------------------------------------
Pillow 10.4.0
Python 3.10.14 (main, May 24 2024, 16:11:37) [GCC 7.3.1 20180712 (Red Hat 7.3.1-17)]
--------------------------------------------------------------------
Python executable is /var/lang/bin/python3.10
System Python files loaded from /var/lang
--------------------------------------------------------------------
Python Pillow modules loaded from /opt/python/PIL
Binary Pillow modules loaded from /opt/python/PIL
--------------------------------------------------------------------
--- PIL CORE support ok, compiled for 10.4.0
*** TKINTER support not installed
--- FREETYPE2 support ok, loaded 2.13.2
--- LITTLECMS2 support ok, loaded 2.16
/opt/python/PIL/features.py:42: UserWarning: /lib64/libm.so.6: version `GLIBC_2.27' not found (required by /opt/python/PIL/../pillow.libs/libsharpyuv-898c0cb5.so.0.1.0)
warnings.warn(str(ex))
*** WEBP support not installed
/opt/python/PIL/features.py:154: UserWarning: /lib64/libm.so.6: version `GLIBC_2.27' not found (required by /opt/python/PIL/../pillow.libs/libsharpyuv-898c0cb5.so.0.1.0)
warnings.warn(str(ex))
*** WEBP Transparency support not installed
*** WEBPMUX support not installed
*** WEBP Animation support not installed
--- JPEG support ok, compiled for libjpeg-turbo 3.0.3
--- OPENJPEG (JPEG2000) support ok, loaded 2.5.2
--- ZLIB (PNG/ZIP) support ok, loaded 1.2.7
--- LIBTIFF support ok, loaded 4.6.0
*** RAQM (Bidirectional Text) support not installed
*** LIBIMAGEQUANT (Quantization method) support not installed
--- XCB (X protocol) support ok
--------------------------------------------------------------------
10.3.0
--------------------------------------------------------------------
Pillow 10.3.0
Python 3.10.14 (main, May 24 2024, 16:11:37) [GCC 7.3.1 20180712 (Red Hat 7.3.1-17)]
--------------------------------------------------------------------
Python executable is /var/lang/bin/python3.10
System Python files loaded from /var/lang
--------------------------------------------------------------------
Python Pillow modules loaded from /opt/python/PIL
Binary Pillow modules loaded from /opt/python/PIL
--------------------------------------------------------------------
--- PIL CORE support ok, compiled for 10.3.0
*** TKINTER support not installed
--- FREETYPE2 support ok, loaded 2.13.2
--- LITTLECMS2 support ok, loaded 2.16
--- WEBP support ok, loaded 1.3.2
--- WEBP Transparency support ok
--- WEBPMUX support ok
--- WEBP Animation support ok
--- JPEG support ok, compiled for libjpeg-turbo 3.0.2
--- OPENJPEG (JPEG2000) support ok, loaded 2.5.2
--- ZLIB (PNG/ZIP) support ok, loaded 1.2.7
--- LIBTIFF support ok, loaded 4.6.0
*** RAQM (Bidirectional Text) support not installed
*** LIBIMAGEQUANT (Quantization method) support not installed
--- XCB (X protocol) support ok
--------------------------------------------------------------------

Test Code

from io import BytesIO
from PIL import UnidentifiedImageError
from PIL.WebPImagePlugin import Image
from fastapi import (
    APIRouter,
    File,
    Path,
    UploadFile,
    FastAPI, 
    Request
)
from typing import Annotated

router = APIRouter()

@router.post("/{id}/images")
async def images_post(
    upload_file: Annotated[UploadFile, File()],
    id: Annotated[
        str,
        Path(),
    ],
) -> str | None:
    try:
        # Load Image
        img = Image.open(BytesIO(await upload_file.read()))
    except UnidentifiedImageError as e:
        raise HTTPException(
            status_code=status.HTTP_400_BAD_REQUEST,
            detail="File uploaded is not a image",
        ) from e
    except Exception as e:
        raise HTTPException(
            status_code=status.HTTP_500_INTERNAL_SERVER_ERROR,
            detail="Error on uploading the file (server side)",
        ) from e

    full_size_bytes = BytesIO()
    img.save(full_size_bytes, format="webp")

app = FastAPI()
@app.exception_handler(RequestValidationError)
async def validation_exception_hander(request: Request, exc: Exception) -> dict:
    error_message = f"Unexpected error occurred: {exc}"
    return JSONResponse(status_code=422, content={"detail": error_message})

app.include_router(router)
Traceback

Traceback is from my cloudwatch logs which use Mangum as a intermediary to run the API

 File "/opt/python/mangum/protocols/http.py", line 58, in run
    await app(self.scope, self.receive, self.send)
  File "/opt/python/fastapi/applications.py", line 1054, in __call__
    await super().__call__(scope, receive, send)
  File "/opt/python/starlette/applications.py", line 123, in __call__
    await self.middleware_stack(scope, receive, send)
  File "/opt/python/starlette/middleware/errors.py", line 186, in __call__
    raise exc
  File "/opt/python/starlette/middleware/errors.py", line 164, in __call__
    await self.app(scope, receive, _send)
  File "/opt/python/starlette/middleware/cors.py", line 93, in __call__
    await self.simple_response(scope, receive, send, request_headers=headers)
  File "/opt/python/starlette/middleware/cors.py", line 148, in simple_response
    await self.app(scope, receive, send)
  File "/opt/python/starlette/middleware/exceptions.py", line 65, in __call__
    await wrap_app_handling_exceptions(self.app, conn)(scope, receive, send)
  File "/opt/python/starlette/_exception_handler.py", line 64, in wrapped_app
    raise exc
  File "/opt/python/starlette/_exception_handler.py", line 53, in wrapped_app
    await app(scope, receive, sender)
  File "/opt/python/starlette/routing.py", line 756, in __call__
    await self.middleware_stack(scope, receive, send)
  File "/opt/python/starlette/routing.py", line 776, in app
    await route.handle(scope, receive, send)
  File "/opt/python/starlette/routing.py", line 297, in handle
    await self.app(scope, receive, send)
  File "/opt/python/starlette/routing.py", line 77, in app
    await wrap_app_handling_exceptions(app, request)(scope, receive, send)
  File "/opt/python/starlette/_exception_handler.py", line 64, in wrapped_app
    raise exc
  File "/opt/python/starlette/_exception_handler.py", line 53, in wrapped_app
    await app(scope, receive, sender)
  File "/opt/python/starlette/routing.py", line 72, in app
    response = await func(request)
  File "/opt/python/fastapi/routing.py", line 278, in app
    raw_response = await run_endpoint_function(
  File "/opt/python/fastapi/routing.py", line 191, in run_endpoint_function
    return await dependant.call(**values)
  File "/var/task/src/source_file.py", line 1590, in images_post
    img.save(full_size_bytes, format="webp")
  File "/opt/python/PIL/Image.py", line 2553, in save
    save_handler = SAVE[format.upper()]

Metadata

Metadata

Assignees

No one assigned

    Labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions