A high-performance media generation library for rendering Quranic Arabic text and translations into customizable, professional-grade images.
Requirements: Python 3.13+
📌 Table of Contents
User Guide
Installation
# Install from PyPI (recommended)
pip install quranmedialib
# Or clone and install from source
git clone https://github.com/AtTheZenith/quranmedialib.git
cd quranmedialib
# Install with uv (recommended)
uv pip install -e .
Quick Start
from quranmedialib import DatabaseManager, VerseWorkflow, LANDSCAPE_PRESET
# Initialize database manager
db = DatabaseManager()
# Load a 1080p Landscape preset
preset = LANDSCAPE_PRESET["default"]["1080p"]
workflow = VerseWorkflow(preset)
# Render Surah 1, Ayah 1
translations = ["In the name of Allah,", "the Entirely Merciful, the Especially Merciful."]
pages = list(workflow.get_iterator(surah=1, ayah=1, translations=translations))
# Save first page
pages[0][0].save("output.png")
db.close()
Presets Reference
The library uses a resolution-independent system. All sizing parameters scale linearly from a 1080p baseline.
| Aspect Ratio | Preset | Resolutions | Modes |
|---|---|---|---|
| 16:9 | LANDSCAPE_PRESET |
720p, 1080p, 1440p, 2160p | default, arabic, translation |
| 9:16 | STORY_PRESET |
720p, 1080p, 1440p, 2160p | default, arabic, translation |
| 1:1 | SQUARE_PRESET |
720p, 1080p, 1440p, 2160p | default, arabic, translation |
Built-in Workflows
Workflows are high-level orchestrators that handle data retrieval, layout, and rendering.
SurahWorkflow
Processes an entire surah page by page.
from quranmedialib import SurahWorkflow, LANDSCAPE_PRESET
preset = LANDSCAPE_PRESET["default"]["1080p"]
workflow = SurahWorkflow(preset)
for page_num, page_images in enumerate(workflow.get_iterator(surah=112), 1):
for img in page_images:
img.save(f"surah112_p{page_num}.png")
VerseRangeWorkflow
Processes a range of verses with support for parallel rendering.
from quranmedialib import VerseRangeWorkflow, SQUARE_PRESET
preset = SQUARE_PRESET["default"]["1080p"]
workflow = VerseRangeWorkflow(preset)
# translations: list[list[str]] -> [verse_index][page_index]
translations = [["Trans V1"], ["Trans V2"]]
iterator = workflow.get_iterator(surah=1, start_ayah=1, end_ayah=2, translations=translations)
Demo Gallery
Visual examples of generated content:
| Preset | Image |
|---|---|
| Landscape (1080p) | |
| Story (1080p) | |
| Square (1080p) |
Developer Guide
Architecture
graph TD
DB[(SQLite Database)] --> WF[Workflow Orchestrator]
WF --> Layout[Layout Engine: VImage]
Layout --> Pipe[Rendering Pipeline]
Pipe --> Mask[Mask-First Rendering]
Mask --> Comp[Composition: Frame]
Comp --> Out[Final Image]
subgraph Config
FC[FrameConfig] -.-> Comp
VC[VerseConfig] -.-> Layout
WC[WordConfig] -.-> Pipe
TC[TextConfig] -.-> Pipe
end
Core Thesis
QuranMediaLib is built on the "Boring Code" philosophy: prioritizing linear, obvious logic over clever abstractions to ensure long-term maintainability.
Key Engineering Pillars:
- Resolution Independence: Layouts are defined relative to a 1080p height and scaled linearly.
- Memory Efficiency: Use of
__slots__for high-frequency objects andlru_cachefor database queries. - Performance: Mask-first rendering minimizes expensive RGBA operations.
Core API Reference
DatabaseManager
A thread-safe singleton managing SQLite connections to Quranic databases.
get_verse(surah, ayah): Retrieves verse text.get_verses_from_surah(surah): Retrieves all verses in a surah.minimize_caches(): Explicitly clears internal LRU caches.
Configuration
Preset: Unified config container (preset.frame,preset.word,preset.verse,preset.text).FrameConfig: Controls frame dimensions, background, and alignment.VerseConfig: Controls word spacing, row spacing, max rows, and wrapping.WordConfig: Defines Arabic font, size, colors, and spacing.TextConfig: Defines translation font, size, and rich-text formatting.
Resource Management
Custom assets can be loaded via:
FontResource.from_path("path/to/font.ttf")DatabaseConfig.from_path("path/to/db.sqlite")
Rich Text Formatting
Translation text supports rich styling through inline tags.
Syntax:: #<style>#<color>#text# — the closing # is mandatory.
| Part | Value |
|---|---|
style |
b (bold), i (italic), or bi (bold-italic) |
color |
6-digit (RRGGBB) or 8-digit (RRGGBBAA) hex |
text |
The content to render |
Examples:
"#b#ff0000ff#Bold red text#"
"#i#00ff00#Italic green text#"
"#bi#0000ffff#Bold italic blue text#"
A # that does not form a valid tag (e.g. a missing color or a stray hash) is
rendered literally and logs a WARNING that points out the malformed tag and the
expected syntax. Suppress that warning with
TextConfig(ignore_non_token_hashtags=True), which still parses valid tags while
leaving the rest as literal text.
See the API reference for the full TextConfig surface.
Text Balancing
Multi-line translation now balances line lengths instead of greedy left-fill.
TextConfig.balancing_mode selects the solver (default SMOOTH):
| Mode | Solver | Use |
|---|---|---|
FORWARD |
Greedy max-fill | Fast, single-pass; always valid |
SMOOTH (default) |
Global flattest-split pyramid | Best visual balance for paragraphs |
KNUTH_PLASS |
Optimized guarded quadratic-slack DP | The global optimum at higher CPU cost |
TEX |
Micro-optimized faithful TeX port | Byte-identical to TeX for small inputs |
A word wider than the container always lands on its own line, and greedy is the unconditional fallback: if the chosen solver cannot satisfy the constraints, the library logs a reason (with a short text preview) and renders greedy. It returns an infeasible layout only when greedy itself is unsatisfiable.
Output & Input Limits
To keep rendering robust against untrusted input, every text input is bounded before measurement:
MAX_TEXT_CHARS(10,000) — rejects a single text string longer than this.MAX_TEXT_WORDS(1,000) — rejects a text string with more tokens than this.MAX_CANVAS_DIMENSION(5,000) — a rendered canvas is clamped to this, so a single over-wide word cannot force an unbounded image allocation.
Violations raise ValueError (char/word) or clamp with a WARNING (canvas).
Advanced Workflows
IsolateWordsWorkflow
Used to isolate individual words within their layout context, useful for word-by-word study tools.
from quranmedialib import IsolateWordsWorkflow, LANDSCAPE_PRESET
preset = LANDSCAPE_PRESET["default"]["1080p"]
workflow = IsolateWordsWorkflow(preset)
# Isolates each word of the verse
iterator = workflow.get_iterator(
surah=1,
verse_words=["الله", "الرحمن", "الرحيم"],
translations=["Allah", "The Merciful", "The Compassionate"]
)
Performance & Parallelism
For bulk rendering, the library provides ParallelRenderer, which distributes tasks across CPU cores.
- Execution Modes:
ExecutionMode.PROCESS(recommended for CPU-heavy tasks) orExecutionMode.THREAD. - Memory Guard: Per-process RSS enforcement via
worker_heartbeat()every 10 verses. Workers crash immediately if they exceed 256MB. Aggregate RSS ~700MB during parallel renders is safe — no aggregate monitor needed.
Development Suite
quranmedialib.check — Validation, Benchmarking & Reference Management
The check module is the canonical entrypoint for all regression testing. It wraps pixel validation, performance benchmarks, and unit tests into a single command.
| Subcommand | Description |
|---|---|
list |
Enumerate canonical validation scenarios |
run |
Quick pixel validation (no benchmarks, no unit tests) |
test |
Full suite: pixel validation + benchmarks + unit tests |
update |
(Re)generate reference images for a specific version |
compare |
Cross-version pixel comparison (e.g., v4.0.0 vs v4.1.0) |
benchmark |
Standalone performance benchmarks |
# Install dev dependencies (uv sync installs the dev group: ruff, pytest, psutil)
uv sync
# Full suite (pixel validation + benchmarks + unit tests)
uv run -m quranmedialib.check test
# Quick pixel validation only (no benchmarks)
uv run -m quranmedialib.check test --no-benchmark
# Unit tests only (skip pixel validation and benchmarks)
uv run -m quranmedialib.check test --unit
# (Re)generate reference images for v4.1.0
uv run -m quranmedialib.check update --version v4.1.0
# Cross-version pixel comparison
uv run -m quranmedialib.check compare v4.0.0 v4.1.0
# Standalone benchmark run
uv run -m quranmedialib.check benchmark
# List all canonical validation scenarios
uv run -m quranmedialib.check list
Reference pipeline: The update command renders all canonical scenarios to PNG files under src/quranmedialib/check/references/<version>/. Each reference set includes scenarios.json (metadata), sha256sums (integrity hashes), and a perf.json benchmark artifact. The compare command performs pixel-level diffs between versions.
Performance benchmarks: The benchmark path runs file-based rendering (saves PNGs to disk via parallel async I/O, counts pages) to avoid deserializing ~3.8GB of RGBA image bytes over IPC. Memory is checked every 10 verses via worker_heartbeat() (per-process 256MB limit). Batch sizes use natural chunking (ceil(tasks / workers)) with adaptive down-capping in bytes IPC mode via _bytes_mode_max_batch(). No aggregate memory monitor — per-process enforcement catches leaks before they cascade.
Lint and Format
uv run -m ruff check .
uv run -m ruff format .
Community & License
We welcome contributions from developers who value engineering rigor and performance.
- Contribute: See
CONTRIBUTING.mdfor technical standards. - Conduct: See
CODE_OF_CONDUCT.md. - License: Apache License 2.0 - see LICENSE.
Release files for quranmedialib 4.2.0
For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.
Source distribution (sdist)
| File | Size | Uploaded | |
|---|---|---|---|
| quranmedialib-4.2.0.tar.gz | 3.4 MB | Details |
Built distribution (wheel)
| File | Interpreter | ABI | Platform | Reset |
|---|---|---|---|---|
| quranmedialib-4.2.0-py3-none-any.whl | Python 3 | none | any | Details |
Total release size: 6.8 MB
Release files / quranmedialib-4.2.0.tar.gz
| Download URL | quranmedialib-4.2.0.tar.gz |
|---|---|
| Size | 3.4 MB |
| Tags | Source |
|
SHA-256 checksum How to use checksums |
26a404d09563d98d9a8d90bee390e310797f97a12a63780f10361b4fe1522f91
|
|
BLAKE2b-256 checksum How to use checksums |
b3655acd64de8d767abdf7e74eaf120e830ccfbc3f9febff662c56d8f11875fe
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
No |
| Uploaded via |
uv/0.6.17
|
Release files / quranmedialib-4.2.0-py3-none-any.whl
| Download URL | quranmedialib-4.2.0-py3-none-any.whl |
|---|---|
| Size | 3.4 MB |
| Tags | Python 3 |
|
SHA-256 checksum How to use checksums |
0e74bae9f7d33e90f6552ae2dd95797fdab0cb48d26a7f497ef0ca6ea443d4da
|
|
BLAKE2b-256 checksum How to use checksums |
730282140c611401d53b14c760bf5f690b4ce9af2e391f659f667e045fadbbe2
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
No |
| Uploaded via |
uv/0.6.17
|