diff --git a/backend/open_webui/env.py b/backend/open_webui/env.py
index 7380f3eb3e..3d2cabdf18 100644
--- a/backend/open_webui/env.py
+++ b/backend/open_webui/env.py
@@ -251,8 +251,6 @@ if FROM_INIT_PY:
STATIC_DIR = Path(os.getenv('STATIC_DIR', OPEN_WEBUI_DIR / 'static'))
-FONTS_DIR = Path(os.getenv('FONTS_DIR', OPEN_WEBUI_DIR / 'static' / 'fonts'))
-
FRONTEND_BUILD_DIR = Path(os.getenv('FRONTEND_BUILD_DIR', BASE_DIR / 'build')).resolve()
if FROM_INIT_PY:
diff --git a/backend/open_webui/models/chats.py b/backend/open_webui/models/chats.py
index fc972cb4bc..508b0d0b4e 100644
--- a/backend/open_webui/models/chats.py
+++ b/backend/open_webui/models/chats.py
@@ -267,11 +267,6 @@ class ChatsImportForm(BaseModel):
chats: list[ChatImportForm]
-class ChatTitleMessagesForm(BaseModel):
- title: str
- messages: list[dict]
-
-
class ChatTitleForm(BaseModel):
title: str
diff --git a/backend/open_webui/routers/utils.py b/backend/open_webui/routers/utils.py
index dcad54f4b1..48e9cc3e5c 100644
--- a/backend/open_webui/routers/utils.py
+++ b/backend/open_webui/routers/utils.py
@@ -3,15 +3,13 @@ from __future__ import annotations
import logging
import black
-from fastapi import APIRouter, Depends, HTTPException, Request, Response, status
+from fastapi import APIRouter, Depends, HTTPException, Request, status
from open_webui.config import DATA_DIR, ENABLE_ADMIN_EXPORT
from open_webui.constants import ERROR_MESSAGES
-from open_webui.models.chats import ChatTitleMessagesForm
from open_webui.models.config import Config
from open_webui.utils.auth import get_admin_user, get_verified_user
from open_webui.utils.code_interpreter import execute_code_jupyter
from open_webui.utils.misc import get_gravatar_url
-from open_webui.utils.pdf_generator import PDFGenerator
from pydantic import BaseModel
from starlette.responses import FileResponse
@@ -73,26 +71,6 @@ async def execute_code(request: Request, form_data: CodeForm, user=Depends(get_v
)
-class ChatForm(BaseModel):
- title: str
- messages: list[dict]
-
-
-@router.post('/pdf')
-async def download_chat_as_pdf(form_data: ChatTitleMessagesForm, user=Depends(get_verified_user)):
- try:
- pdf_bytes = PDFGenerator(form_data).generate_chat_pdf()
-
- return Response(
- content=pdf_bytes,
- media_type='application/pdf',
- headers={'Content-Disposition': 'attachment;filename=chat.pdf'},
- )
- except Exception as e:
- log.exception(f'Error generating PDF: {e}')
- raise HTTPException(status_code=400, detail=str(e))
-
-
@router.get('/db/download')
async def download_db(user=Depends(get_admin_user)):
"""Download the raw SQLite database file (admin-only, SQLite deployments only)."""
diff --git a/backend/open_webui/static/assets/pdf-style.css b/backend/open_webui/static/assets/pdf-style.css
deleted file mode 100644
index 68c10b9d1a..0000000000
--- a/backend/open_webui/static/assets/pdf-style.css
+++ /dev/null
@@ -1,295 +0,0 @@
-/* HTML and Body */
-@font-face {
- font-family: 'NotoSansSC-Regular';
- src: url('fonts/NotoSansSC-Regular.ttf');
-}
-
-html {
- font-family:
- -apple-system, BlinkMacSystemFont, 'Segoe UI', 'NotoSans', 'NotoSansJP', 'NotoSansKR',
- 'NotoSansSC', 'Twemoji', 'STSong-Light', 'MSung-Light', 'HeiseiMin-W3', 'HYSMyeongJo-Medium',
- Roboto, 'Helvetica Neue', Arial, sans-serif;
- font-size: 14px; /* Default font size */
- line-height: 1.5;
-}
-
-*,
-*::before,
-*::after {
- box-sizing: inherit;
-}
-
-body {
- margin: 0;
- padding: 0;
- background-color: #fff;
- width: auto;
-}
-
-/* Typography */
-h1,
-h2,
-h3,
-h4,
-h5,
-h6 {
- font-weight: 500;
- margin: 0;
-}
-
-h1 {
- font-size: 2.5rem;
-}
-
-h2 {
- font-size: 2rem;
-}
-
-h3 {
- font-size: 1.75rem;
-}
-
-h4 {
- font-size: 1.5rem;
-}
-
-h5 {
- font-size: 1.25rem;
-}
-
-h6 {
- font-size: 1rem;
-}
-
-p {
- margin-top: 0;
- margin-bottom: 1rem;
-}
-
-/* Grid System */
-.container {
- width: 100%;
- padding-right: 15px;
- padding-left: 15px;
- margin-right: auto;
- margin-left: auto;
-}
-
-/* Utilities */
-.text-center {
- text-align: center;
-}
-
-/* Additional Text Utilities */
-.text-muted {
- color: #6c757d; /* Muted text color */
-}
-
-/* Small Text */
-small {
- font-size: 80%; /* Smaller font size relative to the base */
- color: #6c757d; /* Lighter text color for secondary information */
- margin-bottom: 0;
- margin-top: 0;
-}
-
-/* Strong Element Styles */
-strong {
- font-weight: bolder; /* Ensures the text is bold */
- color: inherit; /* Inherits the color from its parent element */
-}
-
-/* link */
-a {
- color: #007bff;
- text-decoration: none;
- background-color: transparent;
-}
-
-a:hover {
- color: #0056b3;
- text-decoration: underline;
-}
-
-/* General styles for lists */
-ol,
-ul,
-li {
- padding-left: 40px; /* Increase padding to move bullet points to the right */
- margin-left: 20px; /* Indent lists from the left */
-}
-
-/* Ordered list styles */
-ol {
- list-style-type: decimal; /* Use numbers for ordered lists */
- margin-bottom: 10px; /* Space after each list */
-}
-
-ol li {
- margin-bottom: 0.5rem; /* Space between ordered list items */
-}
-
-/* Unordered list styles */
-ul {
- list-style-type: disc; /* Use bullets for unordered lists */
- margin-bottom: 10px; /* Space after each list */
-}
-
-ul li {
- margin-bottom: 0.5rem; /* Space between unordered list items */
-}
-
-/* List item styles */
-li {
- margin-bottom: 5px; /* Space between list items */
- line-height: 1.5; /* Line height for better readability */
-}
-
-/* Nested lists */
-ol ol,
-ol ul,
-ul ol,
-ul ul {
- padding-left: 20px;
- margin-left: 30px; /* Further indent nested lists */
- margin-bottom: 0; /* Remove extra margin at the bottom of nested lists */
-}
-
-/* Code blocks */
-pre {
- background-color: #f4f4f4;
- padding: 10px;
- overflow-x: auto;
- max-width: 100%; /* Ensure it doesn't overflow the page */
- width: 80%; /* Set a specific width for a container-like appearance */
- margin: 0 1em; /* Center the pre block */
- box-sizing: border-box; /* Include padding in the width */
- border: 1px solid #ccc; /* Optional: Add a border for better definition */
- border-radius: 4px; /* Optional: Add rounded corners */
-}
-
-code {
- font-family: 'Courier New', Courier, monospace;
- background-color: #f4f4f4;
- padding: 2px 4px;
- border-radius: 4px;
- box-sizing: border-box; /* Include padding in the width */
-}
-
-.message {
- margin-top: 8px;
- margin-bottom: 8px;
- max-width: 100%;
- overflow-wrap: break-word;
-}
-
-/* Table Styles */
-table {
- width: 100%;
- margin-bottom: 1rem;
- color: #212529;
- border-collapse: collapse; /* Removes the space between borders */
-}
-
-th,
-td {
- margin: 0;
- padding: 0.75rem;
- vertical-align: top;
- border-top: 1px solid #dee2e6;
-}
-
-thead th {
- vertical-align: bottom;
- border-bottom: 2px solid #dee2e6;
-}
-
-tbody + tbody {
- border-top: 2px solid #dee2e6;
-}
-
-/* markdown-section styles */
-.markdown-section blockquote,
-.markdown-section h1,
-.markdown-section h2,
-.markdown-section h3,
-.markdown-section h4,
-.markdown-section h5,
-.markdown-section h6,
-.markdown-section p,
-.markdown-section pre,
-.markdown-section table,
-.markdown-section ul {
- /* Give most block elements margin top and bottom */
- margin-top: 1rem;
-}
-
-/* Remove top margin if it's the first child */
-.markdown-section blockquote:first-child,
-.markdown-section h1:first-child,
-.markdown-section h2:first-child,
-.markdown-section h3:first-child,
-.markdown-section h4:first-child,
-.markdown-section h5:first-child,
-.markdown-section h6:first-child,
-.markdown-section p:first-child,
-.markdown-section pre:first-child,
-.markdown-section table:first-child,
-.markdown-section ul:first-child {
- margin-top: 0;
-}
-
-/* Remove top margin of
following a */
-.markdown-section p + ul {
- margin-top: 0;
-}
-
-/* Remove bottom margin of
if it is followed by a
*/
-/* Note: :has is not supported in CSS, so you would need JavaScript for this behavior */
-.markdown-section p {
- margin-bottom: 0;
-}
-
-/* List item styles */
-.markdown-section li {
- padding: 2px;
-}
-
-.markdown-section li p {
- margin-bottom: 0;
- padding: 0;
-}
-
-/* Avoid margins for nested lists */
-.markdown-section li > ul {
- margin-top: 0;
- margin-bottom: 0;
-}
-
-/* Table styles */
-.markdown-section table {
- width: 100%;
- border-collapse: collapse;
- margin: 1rem 0;
-}
-
-.markdown-section th,
-.markdown-section td {
- border: 1px solid #ddd;
- padding: 0.5rem;
- text-align: left;
-}
-
-.markdown-section th {
- background-color: #f2f2f2;
-}
-
-.markdown-section pre {
- padding: 10px;
- margin: 10px;
-}
-
-.markdown-section pre code {
- position: relative;
- color: rgb(172, 0, 95);
-}
diff --git a/backend/open_webui/static/fonts/NotoSans-Bold.ttf b/backend/open_webui/static/fonts/NotoSans-Bold.ttf
deleted file mode 100644
index d84248ed10..0000000000
Binary files a/backend/open_webui/static/fonts/NotoSans-Bold.ttf and /dev/null differ
diff --git a/backend/open_webui/static/fonts/NotoSans-Italic.ttf b/backend/open_webui/static/fonts/NotoSans-Italic.ttf
deleted file mode 100644
index c40c3562c3..0000000000
Binary files a/backend/open_webui/static/fonts/NotoSans-Italic.ttf and /dev/null differ
diff --git a/backend/open_webui/static/fonts/NotoSans-Regular.ttf b/backend/open_webui/static/fonts/NotoSans-Regular.ttf
deleted file mode 100644
index fa4cff505e..0000000000
Binary files a/backend/open_webui/static/fonts/NotoSans-Regular.ttf and /dev/null differ
diff --git a/backend/open_webui/static/fonts/NotoSansJP-Regular.ttf b/backend/open_webui/static/fonts/NotoSansJP-Regular.ttf
deleted file mode 100644
index 1583096a2d..0000000000
Binary files a/backend/open_webui/static/fonts/NotoSansJP-Regular.ttf and /dev/null differ
diff --git a/backend/open_webui/static/fonts/NotoSansKR-Regular.ttf b/backend/open_webui/static/fonts/NotoSansKR-Regular.ttf
deleted file mode 100644
index 1b14d32473..0000000000
Binary files a/backend/open_webui/static/fonts/NotoSansKR-Regular.ttf and /dev/null differ
diff --git a/backend/open_webui/static/fonts/NotoSansSC-Regular.ttf b/backend/open_webui/static/fonts/NotoSansSC-Regular.ttf
deleted file mode 100644
index 7056f5e97a..0000000000
Binary files a/backend/open_webui/static/fonts/NotoSansSC-Regular.ttf and /dev/null differ
diff --git a/backend/open_webui/static/fonts/Twemoji.ttf b/backend/open_webui/static/fonts/Twemoji.ttf
deleted file mode 100644
index 281d356d91..0000000000
Binary files a/backend/open_webui/static/fonts/Twemoji.ttf and /dev/null differ
diff --git a/backend/open_webui/utils/pdf_generator.py b/backend/open_webui/utils/pdf_generator.py
deleted file mode 100644
index 64652392ff..0000000000
--- a/backend/open_webui/utils/pdf_generator.py
+++ /dev/null
@@ -1,140 +0,0 @@
-import site
-from datetime import datetime
-from html import escape
-from io import BytesIO
-from pathlib import Path
-from typing import Any, Dict, List
-
-from fpdf import FPDF
-from markdown import markdown
-from open_webui.env import FONTS_DIR, STATIC_DIR
-from open_webui.models.chats import ChatTitleMessagesForm
-
-
-class PDFGenerator:
- """
- Description:
- The `PDFGenerator` class is designed to create PDF documents from chat messages.
- The process involves transforming markdown content into HTML and then into a PDF format
-
- Attributes:
- - `form_data`: An instance of `ChatTitleMessagesForm` containing title and messages.
-
- """
-
- def __init__(self, form_data: ChatTitleMessagesForm):
- self.html_body = None
- self.messages_html = None
- self.form_data = form_data
-
- self.css = Path(STATIC_DIR / 'assets' / 'pdf-style.css').read_text()
-
- def format_timestamp(self, timestamp: float) -> str:
- """Convert a UNIX timestamp to a formatted date string."""
- try:
- date_time = datetime.fromtimestamp(timestamp)
- return date_time.strftime('%Y-%m-%d, %H:%M:%S')
- except (ValueError, TypeError) as e:
- # Log the error if necessary
- return ''
-
- def _build_html_message(self, message: Dict[str, Any]) -> str:
- """Build HTML for a single message."""
- role = escape(message.get('role', 'user'))
- content = escape(message.get('content', ''))
- timestamp = message.get('timestamp')
-
- model = escape(message.get('model') if role == 'assistant' else '')
-
- date_str = escape(self.format_timestamp(timestamp) if timestamp else '')
-
- # extends pymdownx extension to convert markdown to html.
- # - https://facelessuser.github.io/pymdown-extensions/usage_notes/
- # html_content = markdown(content, extensions=["pymdownx.extra"])
-
- content = content.replace('\n', '
')
- html_message = f"""
-
-
-
- {role.title()}
- {model}
-
-
{date_str}
-
-
-
-
-
- {content}
-
-
-
- """
- return html_message
-
- def _generate_html_body(self) -> str:
- """Generate the full HTML body for the PDF."""
- escaped_title = escape(self.form_data.title)
- return f"""
-
-
-
-
-
-
-
-
{escaped_title}
- {self.messages_html}
-
-
-
-
- """
-
- def generate_chat_pdf(self) -> bytes:
- """
- Generate a PDF from chat messages.
- """
- try:
- global FONTS_DIR
-
- pdf = FPDF()
- pdf.add_page()
-
- # When running using `pip install` the static directory is in the site packages.
- if not FONTS_DIR.exists():
- FONTS_DIR = Path(site.getsitepackages()[0]) / 'static/fonts'
- # When running using `pip install -e .` the static directory is in the site packages.
- # This path only works if `open-webui serve` is run from the root of this project.
- if not FONTS_DIR.exists():
- FONTS_DIR = Path('.') / 'backend' / 'static' / 'fonts'
-
- pdf.add_font('NotoSans', '', f'{FONTS_DIR}/NotoSans-Regular.ttf')
- pdf.add_font('NotoSans', 'b', f'{FONTS_DIR}/NotoSans-Bold.ttf')
- pdf.add_font('NotoSans', 'i', f'{FONTS_DIR}/NotoSans-Italic.ttf')
- pdf.add_font('NotoSansKR', '', f'{FONTS_DIR}/NotoSansKR-Regular.ttf')
- pdf.add_font('NotoSansJP', '', f'{FONTS_DIR}/NotoSansJP-Regular.ttf')
- pdf.add_font('NotoSansSC', '', f'{FONTS_DIR}/NotoSansSC-Regular.ttf')
- pdf.add_font('Twemoji', '', f'{FONTS_DIR}/Twemoji.ttf')
-
- pdf.set_font('NotoSans', size=12)
- pdf.set_fallback_fonts(['NotoSansKR', 'NotoSansJP', 'NotoSansSC', 'Twemoji'])
-
- pdf.set_auto_page_break(auto=True, margin=15)
-
- # Build HTML messages
- messages_html_list: List[str] = [self._build_html_message(msg) for msg in self.form_data.messages]
- self.messages_html = '' + ''.join(messages_html_list) + '
'
-
- # Generate full HTML body
- self.html_body = self._generate_html_body()
-
- pdf.write_html(self.html_body)
-
- # Save the pdf with name .pdf
- pdf_bytes = pdf.output()
-
- return bytes(pdf_bytes)
- except Exception as e:
- raise e
diff --git a/backend/requirements-slim.txt b/backend/requirements-slim.txt
index 92e04118e5..31c7f78689 100644
--- a/backend/requirements-slim.txt
+++ b/backend/requirements-slim.txt
@@ -60,7 +60,6 @@ fake-useragent==2.2.0
ftfy==6.3.1
chardet==7.4.3
-fpdf2==2.8.7
Markdown==3.10.2
beautifulsoup4==4.14.3
diff --git a/backend/requirements.txt b/backend/requirements.txt
index 306885cec6..ded3b1d24d 100644
--- a/backend/requirements.txt
+++ b/backend/requirements.txt
@@ -66,7 +66,6 @@ einops==0.8.2
ftfy==6.3.1
chardet==7.4.3
pypdf==6.7.5
-fpdf2==2.8.7
docx2txt==0.9
python-docx==1.2.0
python-pptx==1.0.2
diff --git a/pyproject.toml b/pyproject.toml
index 647128b4f2..f1c6f4c283 100644
--- a/pyproject.toml
+++ b/pyproject.toml
@@ -75,7 +75,6 @@ dependencies = [
"ftfy==6.3.1",
"chardet==7.4.3",
"pypdf==6.7.5",
- "fpdf2==2.8.7",
"docx2txt==0.9",
"python-docx==1.2.0",
"python-pptx==1.0.2",
diff --git a/src/lib/apis/utils/index.ts b/src/lib/apis/utils/index.ts
index f38f10ae0b..3bb1795f39 100644
--- a/src/lib/apis/utils/index.ts
+++ b/src/lib/apis/utils/index.ts
@@ -95,33 +95,6 @@ export const formatPythonCode = async (token: string, code: string) => {
return res;
};
-export const downloadChatAsPDF = async (token: string, title: string, messages: object[]) => {
- let error = null;
-
- const blob = await fetch(`${WEBUI_API_BASE_URL}/utils/pdf`, {
- method: 'POST',
- headers: {
- 'Content-Type': 'application/json',
- Authorization: `Bearer ${token}`
- },
- body: JSON.stringify({
- title: title,
- messages: messages
- })
- })
- .then(async (res) => {
- if (!res.ok) throw await res.json();
- return res.blob();
- })
- .catch((err) => {
- console.error(err);
- error = err;
- return null;
- });
-
- return blob;
-};
-
export const downloadDatabase = async (token: string) => {
let error = null;
diff --git a/src/lib/components/layout/Navbar/Menu.svelte b/src/lib/components/layout/Navbar/Menu.svelte
index d862580ab5..b4cacf50c0 100644
--- a/src/lib/components/layout/Navbar/Menu.svelte
+++ b/src/lib/components/layout/Navbar/Menu.svelte
@@ -5,7 +5,6 @@
import fileSaver from 'file-saver';
const { saveAs } = fileSaver;
- import { downloadChatAsPDF } from '$lib/apis/utils';
import { copyToClipboard, createMessagesList } from '$lib/utils';
import { getOutputText } from '$lib/components/chat/Messages/structuredOutput';
diff --git a/src/lib/components/layout/Sidebar/ChatMenu.svelte b/src/lib/components/layout/Sidebar/ChatMenu.svelte
index 17e8cc4403..509b171f9a 100644
--- a/src/lib/components/layout/Sidebar/ChatMenu.svelte
+++ b/src/lib/components/layout/Sidebar/ChatMenu.svelte
@@ -17,7 +17,6 @@
import { chats, folders, settings, theme, user } from '$lib/stores';
import { createMessagesList } from '$lib/utils';
import { getOutputText } from '$lib/components/chat/Messages/structuredOutput';
- import { downloadChatAsPDF } from '$lib/apis/utils';
import ArchiveBoxIcon from '$lib/components/icons/ArchiveBox.svelte';
import CopyIcon from './icons/Copy.svelte';
import DownloadIcon from './icons/Download.svelte';
diff --git a/uv.lock b/uv.lock
index ffc5934945..0cf032981f 100644
--- a/uv.lock
+++ b/uv.lock
@@ -3,10 +3,10 @@ revision = 3
requires-python = ">=3.11, <3.13.0"
resolution-markers = [
"python_full_version >= '3.12' and sys_platform == 'win32'",
- "python_full_version < '3.12' and sys_platform == 'win32'",
"python_full_version >= '3.12' and sys_platform == 'emscripten'",
- "python_full_version < '3.12' and sys_platform == 'emscripten'",
"python_full_version >= '3.12' and sys_platform != 'emscripten' and sys_platform != 'win32'",
+ "python_full_version < '3.12' and sys_platform == 'win32'",
+ "python_full_version < '3.12' and sys_platform == 'emscripten'",
"python_full_version < '3.12' and sys_platform != 'emscripten' and sys_platform != 'win32'",
]
@@ -936,7 +936,7 @@ name = "cuda-bindings"
version = "13.3.1"
source = { registry = "https://pypi.org/simple" }
dependencies = [
- { name = "cuda-pathfinder", marker = "sys_platform != 'emscripten' and sys_platform != 'win32'" },
+ { name = "cuda-pathfinder" },
]
wheels = [
{ url = "https://files.pythonhosted.org/packages/51/6b/457ca12dad3ee9bfcc9a545cfd6b64b359ba49de40f776f6e028e678f262/cuda_bindings-13.3.1-cp311-cp311-manylinux_2_24_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:c5879712accf6e14bb01aa5e67440eb84998b8d104b509cc7a6dc0b8f656a474", size = 6053539, upload-time = "2026-05-29T23:11:43.19Z" },
@@ -963,34 +963,34 @@ wheels = [
[package.optional-dependencies]
cudart = [
- { name = "nvidia-cuda-runtime", marker = "sys_platform == 'linux'" },
+ { name = "nvidia-cuda-runtime" },
]
cufft = [
- { name = "nvidia-cufft", marker = "sys_platform == 'linux'" },
+ { name = "nvidia-cufft" },
]
cufile = [
- { name = "nvidia-cufile", marker = "sys_platform == 'linux'" },
+ { name = "nvidia-cufile" },
]
cupti = [
- { name = "nvidia-cuda-cupti", marker = "sys_platform == 'linux'" },
+ { name = "nvidia-cuda-cupti" },
]
curand = [
- { name = "nvidia-curand", marker = "sys_platform == 'linux'" },
+ { name = "nvidia-curand" },
]
cusolver = [
- { name = "nvidia-cusolver", marker = "sys_platform == 'linux'" },
+ { name = "nvidia-cusolver" },
]
cusparse = [
- { name = "nvidia-cusparse", marker = "sys_platform == 'linux'" },
+ { name = "nvidia-cusparse" },
]
nvjitlink = [
- { name = "nvidia-nvjitlink", marker = "sys_platform == 'linux'" },
+ { name = "nvidia-nvjitlink" },
]
nvrtc = [
- { name = "nvidia-cuda-nvrtc", marker = "sys_platform == 'linux'" },
+ { name = "nvidia-cuda-nvrtc" },
]
nvtx = [
- { name = "nvidia-nvtx", marker = "sys_platform == 'linux'" },
+ { name = "nvidia-nvtx" },
]
[[package]]
@@ -1272,45 +1272,6 @@ wheels = [
{ url = "https://files.pythonhosted.org/packages/e8/2d/d2a548598be01649e2d46231d151a6c56d10b964d94043a335ae56ea2d92/flatbuffers-25.12.19-py2.py3-none-any.whl", hash = "sha256:7634f50c427838bb021c2d66a3d1168e9d199b0607e6329399f04846d42e20b4", size = 26661, upload-time = "2025-12-19T23:16:13.622Z" },
]
-[[package]]
-name = "fonttools"
-version = "4.63.0"
-source = { registry = "https://pypi.org/simple" }
-sdist = { url = "https://files.pythonhosted.org/packages/84/69/c97f2c18e0db87d2c7b15da1974dace76ae938f1cfa22e2727a648b7ed43/fonttools-4.63.0.tar.gz", hash = "sha256:caeb583deeb5168e694b65cda8b4ee62abedfa66cf88488734466f2366b9c4e0", size = 3597189, upload-time = "2026-05-14T12:04:30.958Z" }
-wheels = [
- { url = "https://files.pythonhosted.org/packages/75/2b/a7f1545bdf5da69c4bda0cea2a5781f0ad2a6623e0277267672db43c5fe6/fonttools-4.63.0-cp311-cp311-macosx_10_9_universal2.whl", hash = "sha256:2b8ae05d9eacf6081414d759c0a352769ac28ce31280d6bb8e77b03f9e3c449f", size = 2881793, upload-time = "2026-05-14T12:02:56.645Z" },
- { url = "https://files.pythonhosted.org/packages/49/50/965308c703f085f225db2886813b27e015b8b3438c350b22dd65b52c2a2c/fonttools-4.63.0-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:79cdc9f567aec74a72918fd060283911406750cbc9fd28c1316023deb6ce31a9", size = 2428130, upload-time = "2026-05-14T12:02:58.891Z" },
- { url = "https://files.pythonhosted.org/packages/d8/38/6937fbd7f2dc3a6b48725851bc2c15ec949b9af14d9bbcb5fe83cdf9bdf9/fonttools-4.63.0-cp311-cp311-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:2c14b4fd138c4bafcca294765c547914e1aa431ae1ca94ab99d8db08c958bd3b", size = 5111952, upload-time = "2026-05-14T12:03:01.263Z" },
- { url = "https://files.pythonhosted.org/packages/0b/43/a81f20050a3115b57d62c8e781446949512eac36690dc384ccea65ff4cc1/fonttools-4.63.0-cp311-cp311-manylinux2014_x86_64.manylinux_2_17_x86_64.whl", hash = "sha256:d76ac49f929aecaf82d83250b8347e099d7aecba0f4726c1d9b6df3b8bb5fe18", size = 5082308, upload-time = "2026-05-14T12:03:03.211Z" },
- { url = "https://files.pythonhosted.org/packages/67/00/cdd9d4944ca6ae280d01e69cc37bde3bf663630b837a6fc6d2cd65d80e0e/fonttools-4.63.0-cp311-cp311-musllinux_1_2_aarch64.whl", hash = "sha256:dcf076a4474fe0d7367e5bbf5b052c7284fa1feca729c04176ce513521afd8a0", size = 5087932, upload-time = "2026-05-14T12:03:05.147Z" },
- { url = "https://files.pythonhosted.org/packages/f5/f1/0aa0dbea778c75adbef223c42019fd47d22262b905974d62d829545d485f/fonttools-4.63.0-cp311-cp311-musllinux_1_2_x86_64.whl", hash = "sha256:7dd683fef0663e9f0f45cf541d788d24caa3ec9db50796b588e1757d8b3bc007", size = 5213271, upload-time = "2026-05-14T12:03:07.238Z" },
- { url = "https://files.pythonhosted.org/packages/a8/99/253e4056e1f0e67b9390125a154b73b5eb73ad521bece95c004858fdeec2/fonttools-4.63.0-cp311-cp311-win32.whl", hash = "sha256:afefc1ed0a59785a7fb06ea7e1678e849c193e1e387db783579bc7b3056fcfcb", size = 2304473, upload-time = "2026-05-14T12:03:09.271Z" },
- { url = "https://files.pythonhosted.org/packages/08/60/defa5e69641db890a63be281f41345f4c33b157824eaf0b9fad3e08b0dcb/fonttools-4.63.0-cp311-cp311-win_amd64.whl", hash = "sha256:063e08bd17bd5a90127a14123de0d6a952dbc847695fd98b63c043d58057f90c", size = 2356389, upload-time = "2026-05-14T12:03:11.53Z" },
- { url = "https://files.pythonhosted.org/packages/08/ef/b3c6b9b5be2f82416d73fe2ed2e96e2793cd80e7510bd6a17ca79cdd88ec/fonttools-4.63.0-cp312-cp312-macosx_10_13_universal2.whl", hash = "sha256:37dd23e621e3b0aef1baa70a303b80aaf38449632cfc8fd2a55fb285bbccfc02", size = 2881131, upload-time = "2026-05-14T12:03:13.386Z" },
- { url = "https://files.pythonhosted.org/packages/44/a0/c815bea63117fa63e4e1c01f8a1110d2112fa003f838e6467094ec2432ce/fonttools-4.63.0-cp312-cp312-macosx_10_13_x86_64.whl", hash = "sha256:a9faff9e0c1f76f9fd55899d2ce785832efebab37eb8ae13995853aef178bef0", size = 2426704, upload-time = "2026-05-14T12:03:15.801Z" },
- { url = "https://files.pythonhosted.org/packages/44/04/0b91d8e916e92ad1fac9e4624760baf0fd5ff2ead614c2f68fb21373f03f/fonttools-4.63.0-cp312-cp312-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:ef3048ef05dbb552b89817713d9cac912e00d0fde4a3105c00d29e52e10c89af", size = 5044298, upload-time = "2026-05-14T12:03:18.085Z" },
- { url = "https://files.pythonhosted.org/packages/77/c7/2342da9830e3e9d4870305ca5d2091d2a83284f2953079b7bdd3b5e029d8/fonttools-4.63.0-cp312-cp312-manylinux2014_x86_64.manylinux_2_17_x86_64.whl", hash = "sha256:58dc6bb86a78d782f00f9190ca02c119cf5bbe2807536e361e18d42019f877d8", size = 4999800, upload-time = "2026-05-14T12:03:20.161Z" },
- { url = "https://files.pythonhosted.org/packages/e6/6d/67fe16c48d7ce050979b33f47e0d28a318f02da030602e944c34f7a16ef3/fonttools-4.63.0-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:ee08ebfa58f6e1aeff5697ab9582105bb620008c1caafb681e4c557e7483027b", size = 4982666, upload-time = "2026-05-14T12:03:22.87Z" },
- { url = "https://files.pythonhosted.org/packages/f2/00/3bbab338c07c71fa56269953845e92c951a61457bbbb0f1022551ea266d9/fonttools-4.63.0-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:27fdc65af8da6f88b9c6121c47a464cbe359fcfff7ff6fc2d37a1f395d755b78", size = 5133598, upload-time = "2026-05-14T12:03:25.168Z" },
- { url = "https://files.pythonhosted.org/packages/62/f2/aa27c7f98db5b064883dadcc5283947e81e034de42e22a33675878d98b54/fonttools-4.63.0-cp312-cp312-win32.whl", hash = "sha256:af2fd1664d00a397d75f806985ddb36282091c2131a73a6485c23b4a34722263", size = 2292575, upload-time = "2026-05-14T12:03:27.496Z" },
- { url = "https://files.pythonhosted.org/packages/87/36/cccb9bc2a6ab63d1b2980374f0dca72ce95ae267c9b4cfe77455bb70d0d4/fonttools-4.63.0-cp312-cp312-win_amd64.whl", hash = "sha256:59ac449f8cca9b4ffa08d2e7bbadad87ce710d69d1eda5c3c1ce579baa987272", size = 2343211, upload-time = "2026-05-14T12:03:30.057Z" },
- { url = "https://files.pythonhosted.org/packages/2c/47/c99d5268f354002ce80f8d029cd9d7d872969da1de8b93d32de4dc56d6f4/fonttools-4.63.0-py3-none-any.whl", hash = "sha256:445af2eab030a16b9171ea8bdda7ebf7d96bda2df88ee182a464252f6e05e20d", size = 1164562, upload-time = "2026-05-14T12:04:29.092Z" },
-]
-
-[[package]]
-name = "fpdf2"
-version = "2.8.7"
-source = { registry = "https://pypi.org/simple" }
-dependencies = [
- { name = "defusedxml" },
- { name = "fonttools" },
- { name = "pillow" },
-]
-sdist = { url = "https://files.pythonhosted.org/packages/27/f2/72feae0b2827ed38013e4307b14f95bf0b3d124adfef4d38a7d57533f7be/fpdf2-2.8.7.tar.gz", hash = "sha256:7060ccee5a9c7ab0a271fb765a36a23639f83ef8996c34e3d46af0a17ede57f9", size = 362351, upload-time = "2026-02-28T05:39:16.456Z" }
-wheels = [
- { url = "https://files.pythonhosted.org/packages/66/0a/cf50ecffa1e3747ed9380a3adfc829259f1f86b3fdbd9e505af789003141/fpdf2-2.8.7-py3-none-any.whl", hash = "sha256:d391fc508a3ce02fc43a577c830cda4fe6f37646f2d143d489839940932fbc19", size = 327056, upload-time = "2026-02-28T05:39:14.619Z" },
-]
-
[[package]]
name = "frozenlist"
version = "1.8.0"
@@ -2607,7 +2568,7 @@ name = "nvidia-cublas"
version = "13.1.1.3"
source = { registry = "https://pypi.org/simple" }
dependencies = [
- { name = "nvidia-cuda-nvrtc", marker = "sys_platform != 'emscripten' and sys_platform != 'win32'" },
+ { name = "nvidia-cuda-nvrtc" },
]
wheels = [
{ url = "https://files.pythonhosted.org/packages/a7/a1/0bd24ee8c8d03adac032fd2909426a00c88f8c57961b1277ded97f91119f/nvidia_cublas-13.1.1.3-py3-none-manylinux_2_27_aarch64.whl", hash = "sha256:b7a210458267ac818974c53038fbec2e969d5c99f305ab15c72522fa9f001dd5", size = 542848918, upload-time = "2026-04-08T18:46:22.985Z" },
@@ -2646,7 +2607,7 @@ name = "nvidia-cudnn-cu13"
version = "9.20.0.48"
source = { registry = "https://pypi.org/simple" }
dependencies = [
- { name = "nvidia-cublas", marker = "sys_platform != 'emscripten' and sys_platform != 'win32'" },
+ { name = "nvidia-cublas" },
]
wheels = [
{ url = "https://files.pythonhosted.org/packages/56/c5/83384d846b2fd17c44bd499b36c75a45ed4f095fbbb2252294e89cea5c5c/nvidia_cudnn_cu13-9.20.0.48-py3-none-manylinux_2_27_aarch64.whl", hash = "sha256:e31454ae00094b0c55319d9d15b6fa2fc50a9e1c0f5c8c80fb75258234e731e1", size = 444574296, upload-time = "2026-03-09T19:28:27.751Z" },
@@ -2658,7 +2619,7 @@ name = "nvidia-cufft"
version = "12.0.0.61"
source = { registry = "https://pypi.org/simple" }
dependencies = [
- { name = "nvidia-nvjitlink", marker = "sys_platform != 'emscripten' and sys_platform != 'win32'" },
+ { name = "nvidia-nvjitlink" },
]
wheels = [
{ url = "https://files.pythonhosted.org/packages/8b/ae/f417a75c0259e85c1d2f83ca4e960289a5f814ed0cea74d18c353d3e989d/nvidia_cufft-12.0.0.61-py3-none-manylinux2014_aarch64.manylinux_2_17_aarch64.whl", hash = "sha256:2708c852ef8cd89d1d2068bdbece0aa188813a0c934db3779b9b1faa8442e5f5", size = 214053554, upload-time = "2025-09-04T08:31:38.196Z" },
@@ -2688,9 +2649,9 @@ name = "nvidia-cusolver"
version = "12.0.4.66"
source = { registry = "https://pypi.org/simple" }
dependencies = [
- { name = "nvidia-cublas", marker = "sys_platform != 'emscripten' and sys_platform != 'win32'" },
- { name = "nvidia-cusparse", marker = "sys_platform != 'emscripten' and sys_platform != 'win32'" },
- { name = "nvidia-nvjitlink", marker = "sys_platform != 'emscripten' and sys_platform != 'win32'" },
+ { name = "nvidia-cublas" },
+ { name = "nvidia-cusparse" },
+ { name = "nvidia-nvjitlink" },
]
wheels = [
{ url = "https://files.pythonhosted.org/packages/c8/c3/b30c9e935fc01e3da443ec0116ed1b2a009bb867f5324d3f2d7e533e776b/nvidia_cusolver-12.0.4.66-py3-none-manylinux_2_27_aarch64.whl", hash = "sha256:02c2457eaa9e39de20f880f4bd8820e6a1cfb9f9a34f820eb12a155aa5bc92d2", size = 223467760, upload-time = "2025-09-04T08:33:04.222Z" },
@@ -2702,7 +2663,7 @@ name = "nvidia-cusparse"
version = "12.6.3.3"
source = { registry = "https://pypi.org/simple" }
dependencies = [
- { name = "nvidia-nvjitlink", marker = "sys_platform != 'emscripten' and sys_platform != 'win32'" },
+ { name = "nvidia-nvjitlink" },
]
wheels = [
{ url = "https://files.pythonhosted.org/packages/f8/94/5c26f33738ae35276672f12615a64bd008ed5be6d1ebcb23579285d960a9/nvidia_cusparse-12.6.3.3-py3-none-manylinux2014_aarch64.manylinux_2_17_aarch64.whl", hash = "sha256:80bcc4662f23f1054ee334a15c72b8940402975e0eab63178fc7e670aa59472c", size = 162155568, upload-time = "2025-09-04T08:33:42.864Z" },
@@ -2841,7 +2802,6 @@ dependencies = [
{ name = "fake-useragent" },
{ name = "fastapi" },
{ name = "faster-whisper" },
- { name = "fpdf2" },
{ name = "ftfy" },
{ name = "google-cloud-storage" },
{ name = "google-genai" },
@@ -2969,7 +2929,6 @@ requires-dist = [
{ name = "fake-useragent", specifier = "==2.2.0" },
{ name = "fastapi", specifier = "==0.136.3" },
{ name = "faster-whisper", specifier = "==1.2.1" },
- { name = "fpdf2", specifier = "==2.8.7" },
{ name = "ftfy", specifier = "==6.3.1" },
{ name = "google-cloud-storage", specifier = "==3.9.0" },
{ name = "google-genai", specifier = "==1.66.0" },
@@ -4708,7 +4667,7 @@ resolution-markers = [
"python_full_version < '3.12' and sys_platform != 'emscripten' and sys_platform != 'win32'",
]
dependencies = [
- { name = "numpy", marker = "python_full_version < '3.12'" },
+ { name = "numpy" },
]
sdist = { url = "https://files.pythonhosted.org/packages/7a/97/5a3609c4f8d58b039179648e62dd220f89864f56f7357f5d4f45c29eb2cc/scipy-1.17.1.tar.gz", hash = "sha256:95d8e012d8cb8816c226aef832200b1d45109ed4464303e997c5b13122b297c0", size = 30573822, upload-time = "2026-02-23T00:26:24.851Z" }
wheels = [
@@ -4744,7 +4703,7 @@ resolution-markers = [
"python_full_version >= '3.12' and sys_platform != 'emscripten' and sys_platform != 'win32'",
]
dependencies = [
- { name = "numpy", marker = "python_full_version >= '3.12'" },
+ { name = "numpy" },
]
sdist = { url = "https://files.pythonhosted.org/packages/a7/25/c2700dfaf6442b4effaa91af24ebce5dc9d31bb4a69706313aae70d72cd0/scipy-1.18.0.tar.gz", hash = "sha256:67b2ad2ad54c72ca6d04975a9b2df8c3638c34ddd5b28738e94fc2b57929d378", size = 30774447, upload-time = "2026-06-19T15:01:43.456Z" }
wheels = [