From e55daf275e1f8c974f30968d3cafbdbee27bcf35 Mon Sep 17 00:00:00 2001 From: Dom Date: Sun, 26 Apr 2026 09:52:19 +0200 Subject: [PATCH] =?UTF-8?q?fix(ui):=20shim=20de=20compatibilit=C3=A9=20pou?= =?UTF-8?q?r=20streamlit-drawable-canvas=200.9.3?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit streamlit-drawable-canvas 0.9.3 (dernière version disponible sur PyPI) utilise l'API privée `streamlit.elements.image.image_to_url` qui a été retirée à partir de Streamlit ≈ 1.49. Sur Streamlit 1.56 (installé ici), le canvas plante à l'ouverture du mode "🔧 Calibration zones" : AttributeError: module 'streamlit.elements.image' has no attribute 'image_to_url' Plutôt que de downgrader Streamlit globalement (impact sur les autres features de l'overlay), on injecte une implémentation locale de `image_to_url` au tout début de pipeline/ui_overlay.py si elle est absente. L'implémentation produit un data URI base64 que le canvas consomme directement côté navigateur, sans toucher au système de fichiers media. À retirer dès qu'une version > 0.9.3 de streamlit-drawable-canvas publiera un correctif officiel. Co-Authored-By: Claude Opus 4.7 (1M context) --- pipeline/ui_overlay.py | 30 ++++++++++++++++++++++++++++++ 1 file changed, 30 insertions(+) diff --git a/pipeline/ui_overlay.py b/pipeline/ui_overlay.py index 005292d..c64e1fc 100644 --- a/pipeline/ui_overlay.py +++ b/pipeline/ui_overlay.py @@ -27,6 +27,36 @@ if str(_REPO_ROOT) not in sys.path: import streamlit as st from PIL import Image +# ---------------------------------------------------------------------------- +# Compatibility shim : streamlit-drawable-canvas 0.9.3 utilise l'API privée +# `streamlit.elements.image.image_to_url` qui a été retirée à partir de +# Streamlit ≈ 1.49. On réinjecte une implémentation équivalente fondée sur +# un data URI base64, ce qui permet au canvas de continuer à fonctionner +# sans downgrader Streamlit globalement. +# +# Remplacer ce shim par l'upgrade de streamlit-drawable-canvas si une version +# > 0.9.3 est publiée. +# ---------------------------------------------------------------------------- +import base64 as _b64 +import io as _io +from streamlit.elements import image as _st_image # type: ignore + +if not hasattr(_st_image, "image_to_url"): + def _image_to_url_compat(image, width, clamp, channels, output_format, + image_id): + """Convertit une PIL.Image en data URI compatible avec drawable-canvas.""" + fmt = (output_format or "PNG").upper() + if fmt == "JPG": + fmt = "JPEG" + buf = _io.BytesIO() + image.save(buf, format=fmt) + b64 = _b64.b64encode(buf.getvalue()).decode("ascii") + mime = "image/jpeg" if fmt == "JPEG" else f"image/{fmt.lower()}" + return f"data:{mime};base64,{b64}" + + _st_image.image_to_url = _image_to_url_compat # type: ignore[attr-defined] +# ---------------------------------------------------------------------------- + from pipeline.ingest import pdf_to_images from pipeline.zones_config import load_config, save_config, DEFAULT_CONFIG_PATH