Skip to content
This repository was archived by the owner on Mar 15, 2026. It is now read-only.
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
27 changes: 13 additions & 14 deletions .builds/python3.11.yml
Original file line number Diff line number Diff line change
@@ -1,27 +1,26 @@
image: alpine/3.19
image: debian/bookworm
packages:
- alpine-sdk
- cairo-dev
- gcc
- gdk-pixbuf-dev
- jpeg-dev
- build-essential
- fonts-dejavu
- libcairo2-dev
- libffi-dev
- font-dejavu
- musl-dev
- pango-dev
- py3-tox
- zlib-dev
- libgdk-pixbuf2.0-dev
- libjpeg-dev
- libpango1.0-dev
- python3-dev
- tox
- zlib1g-dev
sources:
- https://github.com/whyNotHugo/django-renderpdf
environment:
FORCE_COLOR: yes
CI: true
tasks:
- check-python:
python --version | grep 'Python 3.11'
python3 --version | grep 'Python 3.11'
- tests: |
cd django-renderpdf
tox -e py
tox -e py311
- lint: |
cd django-renderpdf
tox -e lint
tox -e lint
2 changes: 1 addition & 1 deletion .builds/python3.13.yml → .builds/python3.14.yml
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@ environment:
CI: true
tasks:
- check-python:
python --version | grep 'Python 3.13'
python --version | grep 'Python 3.14'
- tests: |
cd django-renderpdf
tox -e py
Expand Down
66 changes: 35 additions & 31 deletions django_renderpdf/helpers.py
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
import mimetypes
from collections.abc import Callable
from collections.abc import Sequence
from contextlib import suppress
from typing import IO

from django.conf import settings
Expand All @@ -20,6 +21,31 @@ class InvalidRelativeUrl(ValueError): # noqa: N818
"""Raised when a relative URL cannot be handled by Django."""


def _read_staticfile(url: str, base_url: str) -> dict:
filename = url.replace(base_url, "", 1)
data = None

path = finders.find(filename)
if path:
# Read static files from source (e.g.: the file that's bundled with the Django
# app that provides it. This also picks up uncollected staticfiles which is
# useful when developing / in DEBUG mode.
with open(path, "rb") as f:
data = f.read()
else:
# File was not found by a finder. This commonly happens when running in
# DEBUG=True with a storage that uses Manifests or alike, since the filename
# won't match with the source file. In these cases, use the _storage_ to find
# the file instead:
with staticfiles_storage.open(filename) as f:
data = f.read()

return {
"mime_type": mimetypes.guess_type(url)[0],
"string": data,
}


def django_url_fetcher(url: str) -> dict:
# TODO: define a TypedDict with the return type and upstream it.
"""Returns the file for a given URL.
Expand All @@ -38,39 +64,17 @@ def django_url_fetcher(url: str) -> dict:
resources data as a string and ``mime_type``, which is the identified
mime type for the resource.
"""

# If the URL looks like a staticfile, try to load it as such.
# Reading it from the storage avoids a network call in many cases (unless the
# storage is remote, in which case this improves nothing:
# Reading it from the storage avoids the HTTP round-trip in many cases.
try:
base_url = getattr(staticfiles_storage, "base_url", None)
if base_url is not None and url.startswith(base_url):
filename = url.replace(base_url, "", 1)
data = None

path = finders.find(filename)
if path:
# Read static files from source (e.g.: the file that's bundled with the
# Django app that provides it.
# This also picks up uncollected staticfiles (useful when developing /
# in DEBUG mode).
with open(path, "rb") as f:
data = f.read()
else:
# File was not found by a finder. This commonly happens when running in
# DEBUG=True with a storage that uses Manifests or alike, since the
# filename won't match with the source file.
# In these cases, use the _storage_ to find the file instead:
with staticfiles_storage.open(filename) as f:
data = f.read()

return {
"mime_type": mimetypes.guess_type(url)[0],
"string": data,
}
except (ValueError, FileNotFoundError):
# Looks like this wasn't a staticfile (or maybe it was a missing one?)
# Let it resolve as a normal URL.
pass
static_base_url = staticfiles_storage.base_url # type: ignore[attr-defined]
except AttributeError:
pass # Storage has no attribute base_url; fall back.
else:
if url.startswith(static_base_url):
with suppress(ValueError, FileNotFoundError):
return _read_staticfile(url, static_base_url)

try:
# If the URL is a relative URL, use Django's resolver to figure out how Django
Expand Down
1 change: 1 addition & 0 deletions pyproject.toml
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
[build-system]
build-backend = "setuptools.build_meta"
requires = ["setuptools>=45", "wheel", "setuptools_scm>=6.2"]

[project]
Expand Down
1 change: 1 addition & 0 deletions tox.ini
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
[tox]
isolated_build = True
envlist =
py{310,311,312}-django42
py{310,311,312,313}-django51
Expand Down
Loading