From 5e7b95d9e43c704ad349a04151a8fdb9ce5dbf18 Mon Sep 17 00:00:00 2001 From: Donald Gray Date: Tue, 21 Oct 2025 14:54:42 +0100 Subject: [PATCH] Add JPEG_QUALITY envvar --- README.md | 7 +++++++ appetiser/convert/config.py | 2 ++ appetiser/convert/image.py | 7 ++++--- appetiser/convert/operations.py | 1 + appetiser/main.py | 2 ++ 5 files changed, 16 insertions(+), 3 deletions(-) diff --git a/README.md b/README.md index 5033b2d..3cd6b92 100644 --- a/README.md +++ b/README.md @@ -56,3 +56,10 @@ These tests are dependent on `pytest-docker`, and use the [./tests/docker-compos OpenAPI docs for the appetiser API can be found at [http://localhost:8000/docs](http://localhost:8000/docs) on a locally running instance of appetiser. These provide documentation and examples for the `convert/` endpoint, along with expected types. +## Customising + +The following environment variables can be used to configure the service + +| EnvVar | Description | Default | +| -------------- | ----------------------------------------------- | ------- | +| `JPEG_QUALITY` | Integer, 0-100, controls thumbnail jpeg quality | 90 | \ No newline at end of file diff --git a/appetiser/convert/config.py b/appetiser/convert/config.py index 3283fce..25e9b5c 100644 --- a/appetiser/convert/config.py +++ b/appetiser/convert/config.py @@ -1,3 +1,4 @@ +from pydantic import conint from pydantic_settings import BaseSettings, SettingsConfigDict from pathlib import Path @@ -7,4 +8,5 @@ class ConvertConfig(BaseSettings): KDU_EXPAND: Path KDU_LIB: Path OUTPUT_DIR: Path + JPEG_QUALITY: conint(ge=0, le=100) = 90 model_config = SettingsConfigDict(case_sensitive=True) diff --git a/appetiser/convert/image.py b/appetiser/convert/image.py index bf28116..d6896b6 100644 --- a/appetiser/convert/image.py +++ b/appetiser/convert/image.py @@ -8,6 +8,7 @@ ) from PIL.Image import Image as PILImage +from .config import ConvertConfig from .kdu import IMAGE_MODES logger = logging.getLogger(__name__) @@ -278,7 +279,7 @@ def scale_dimensions_to_fit( def resize_and_save_img( - img: PILImage, width: int, height: int, dest_path: Path + img: PILImage, width: int, height: int, dest_path: Path, config: ConvertConfig ) -> PILImage: """Resize a PIL Image so that it fits within a square of the provided size, and saves this file to the provided dest_path. @@ -287,6 +288,6 @@ def resize_and_save_img( """ img = img.resize((width, height), resample=Image.LANCZOS) logger.debug(f"Image resized: {width=}, {height=})") - img.save(dest_path, quality=90) - logger.debug(f"Resized image saved to: {dest_path}") + img.save(dest_path, quality=config.JPEG_QUALITY) + logger.debug(f"Resized image saved to: {dest_path}. Quality: {config.JPEG_QUALITY}") return img diff --git a/appetiser/convert/operations.py b/appetiser/convert/operations.py index 8eeef97..b8663cc 100644 --- a/appetiser/convert/operations.py +++ b/appetiser/convert/operations.py @@ -240,6 +240,7 @@ def create_thumbnails( width=calc_thumb_info.width, height=calc_thumb_info.height, dest_path=calc_thumb_info.path, + config=config ) thumbnail_info.append( ThumbInfo( diff --git a/appetiser/main.py b/appetiser/main.py index e4751b2..b3e651e 100644 --- a/appetiser/main.py +++ b/appetiser/main.py @@ -25,6 +25,8 @@ def get_convert_config(): return ConvertConfig() +# call to validate config is correct +get_convert_config() @app.get("/ping") def ping():