""" Router "image" provides: - listing image files - finding image files by name prefix - getting image files in a uniform format by name prefix """ import re from io import BytesIO from typing import Iterator from fastapi import APIRouter, Depends from fastapi.responses import StreamingResponse from PIL import Image from ..config import Config from ..dav_file import DavFile from ._common import FileNameLister, PrefixFinder, PrefixUnique router = APIRouter(prefix="/image", tags=["image"]) _lister = FileNameLister( remote_path="img", re=re.compile( r"\.(gif|jpe?g|tiff?|png|bmp)$", flags=re.IGNORECASE, ), ) _finder = PrefixFinder(_lister) _unique = PrefixUnique(_finder) @router.get( "/list", response_model=list[str], responses=_lister.responses, ) async def list_images( names: Iterator[str] = Depends(_lister), ) -> list[str]: return list(names) @router.get( "/find/{prefix}", response_model=list[str], responses=_finder.responses, ) async def find_images( names: Iterator[str] = Depends(_finder), ) -> list[str]: return list(names) @router.get( "/get/{prefix}", response_class=StreamingResponse, responses=_unique.responses, ) async def get_image( prefix: str, name: str = Depends(_unique), ) -> str: cfg = await Config.get() dav_file = DavFile(f"{_lister.remote_path}/{name}") img = Image.open( BytesIO(await dav_file.bytes) ).convert( cfg.image.mode ) img_buffer = BytesIO() img.save(img_buffer, **cfg.image.save_params) img_buffer.seek(0) return StreamingResponse( content=img_buffer, media_type="image/jpeg", headers={ "Content-Disposition": f"filename={prefix}.jpg" }, )