From 58aec49efd733ca80ad057d742970011b76b9747 Mon Sep 17 00:00:00 2001 From: Oliver Lambson Date: Mon, 26 Aug 2024 04:49:24 +0200 Subject: [PATCH] base64url encode figure ids --- bored-charts/boredcharts/__init__.py | 2 +- bored-charts/boredcharts/jinja.py | 5 ++++- bored-charts/boredcharts/utils.py | 28 ++++++++++++++++++++++++++++ 3 files changed, 33 insertions(+), 2 deletions(-) diff --git a/bored-charts/boredcharts/__init__.py b/bored-charts/boredcharts/__init__.py index b3aa7f5..85da412 100644 --- a/bored-charts/boredcharts/__init__.py +++ b/bored-charts/boredcharts/__init__.py @@ -1,4 +1,4 @@ -__version__ = "0.13.0" +__version__ = "0.13.1" from boredcharts.router import FigureRouter from boredcharts.webapp import boredcharts diff --git a/bored-charts/boredcharts/jinja.py b/bored-charts/boredcharts/jinja.py index 262eaf3..0544e0e 100644 --- a/bored-charts/boredcharts/jinja.py +++ b/bored-charts/boredcharts/jinja.py @@ -15,6 +15,8 @@ from markupsafe import Markup from plotly.graph_objects import Figure +from boredcharts.utils import uuid_to_urlid + logger = logging.getLogger("boredcharts") @@ -68,7 +70,8 @@ def plotly_to_html(fig: Figure) -> Markup: def altair_to_html(chart: alt.typing.ChartType) -> Markup: """Renders an Altair Chart as HTML.""" - figid = f"vis-{uuid.uuid4()}" # html id can't start with digit + id_ = uuid_to_urlid(uuid.uuid4()) + figid = f"vis-{id_}" # html id can't start with digit return Markup( chart.to_html( fullhtml=False, diff --git a/bored-charts/boredcharts/utils.py b/bored-charts/boredcharts/utils.py index 12663bc..3f0388a 100644 --- a/bored-charts/boredcharts/utils.py +++ b/bored-charts/boredcharts/utils.py @@ -1,5 +1,7 @@ from __future__ import annotations +import base64 +import uuid from pathlib import Path from typing import NamedTuple @@ -38,3 +40,29 @@ def to_url_path(path: Path) -> str: if path.name: path = path.with_suffix("") return str(Path("/") / path) + + +def uuid_to_urlid(uuid_: uuid.UUID) -> str: + """Convert a UUID to a short URL-safe string. + + >>> import base64 + >>> import uuid + >>> id_ = uuid.UUID('5d98d578-2731-4a4d-b666-70ca16f10aa2') + >>> url_id = uuid_to_urlid(id_) + >>> print(url_id) + XZjVeCcxSk22ZnDKFvEKog + """ + return base64.urlsafe_b64encode(uuid_.bytes).rstrip(b"=").decode("utf-8") + + +def urlid_to_uuid(url: str) -> uuid.UUID: + """Convert a base64url encoded UUID string to a UUID. + + >>> import base64 + >>> import uuid + >>> url_id = 'XZjVeCcxSk22ZnDKFvEKog' + >>> id_ = urlid_to_uuid(url_id) + >>> print(id_) + 5d98d578-2731-4a4d-b666-70ca16f10aa2 + """ + return uuid.UUID(bytes=base64.urlsafe_b64decode(url + "=" * (len(url) % 4)))