Skip to main content

sahifa

Python client for Sahifa, the HTML-to-PDF and screenshot API that gets Arabic and right-to-left text right and processes documents in Saudi Arabia.

No arabic_reshaper, no python-bidi, no fonts to install: write HTML, get a PDF with joined Arabic letters, correct word order and mixed Arabic and English, rendered by Chromium in Jeddah.

pip install sahifa

Quick start

Get a free API key at sahifa.dev: 100 renders a month, no card needed.

from sahifa import Sahifa, arabic_document

sahifa = Sahifa()  # reads SAHIFA_API_KEY

pdf = sahifa.pdf(
    arabic_document('<h1>فاتورة ضريبية مبسطة</h1><p>الإجمالي: <bdi dir="ltr">1,150.00 SAR</bdi></p>'),
    format="A4",
    margin="15mm",
    footer={"source": '<div style="width:100%;text-align:center;font-size:9px">صفحة {{page}} من {{total}}</div>'},
)
with open("invoice.pdf", "wb") as f:
    f.write(pdf)

PDF

sahifa.pdf(source, **options) calls POST /v3/convert/pdf (PDFShift v3 compatible) and returns bytes. source is HTML or a URL.

Options: format, landscape, margin, header={"source": ...}, footer={"source": ...}, css, javascript, delay (milliseconds), wait_for, pages, zoom. See the PDF reference.

Django

from django.http import HttpResponse
from django.template.loader import render_to_string
from sahifa import Sahifa

sahifa = Sahifa()

def invoice_pdf(request, pk):
    html = render_to_string("invoices/detail.html", {"invoice": Invoice.objects.get(pk=pk)})
    return HttpResponse(sahifa.pdf(html, format="A4"), content_type="application/pdf")

FastAPI

from fastapi import FastAPI, Response
from sahifa import Sahifa

app, sahifa = FastAPI(), Sahifa()

@app.get("/invoices/{number}.pdf")
def invoice(number: str):
    html = templates.get_template("invoice.html").render(number=number)
    return Response(sahifa.pdf(html), media_type="application/pdf")

Screenshots

png = sahifa.screenshot(url="https://example.com", full_page=True, block_cookie_banners=True)
jpg = sahifa.screenshot(html="<h1 dir='rtl'>مرحبا</h1>", format="jpeg")

Pass exactly one of url= or html=. Options: format (png, jpeg, webp, pdf), full_page, viewport_width, viewport_height, device_scale_factor, selector, dark_mode, delay (seconds), block_ads, block_cookie_banners. See the screenshot reference.

Errors and retries

Failures raise SahifaError with .status, .code and the API's message. Busy and rate-limit responses (429, 502, 503, 504) and network errors are retried up to max_retries times (default 3), waiting for Retry-After.

from sahifa import SahifaError

try:
    sahifa.pdf(html)
except SahifaError as e:
    if e.status == 402:
        print("Monthly allowance used up")
    else:
        raise

Options

Sahifa(api_key="sk_live_...", base_url="https://api.sahifa.dev", max_retries=3, timeout=120)

The client can be used as a context manager (with Sahifa() as s:), which closes the HTTP connection pool.

Arabic tips

  • arabic_document(fragment) wraps HTML in a full document with dir="rtl", UTF-8 and Arabic fonts.
  • Wrap left-to-right parts (IBANs, VAT numbers, amounts, e-mails) in <bdi dir="ltr">…</bdi>.
  • Use text-align: start / end rather than left / right.

Documentation · Examples in five languages · Pricing · Data residency · Support: support@sahifa.dev

MIT License. Sahifa is a service of Yimello LLC.

Metadata

Release files for sahifa 1.0.0

For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.

Source distribution (sdist)

Source distribution for sahifa 1.0.0
File Size Uploaded
sahifa-1.0.0.tar.gz 6.7 kB Details

Built distribution (wheel)

Table of built distributions (wheels) for sahifa 1.0.0
File Interpreter ABI Platform
sahifa-1.0.0-py3-none-any.whl Python 3 none any Details

Total release size: 12.9 kB

Release files / sahifa-1.0.0.tar.gz

Download URL sahifa-1.0.0.tar.gz
Size 6.7 kB
Tags Source
SHA-256 checksum
How to use checksums
5e025186a196f3ba187e97899122f5d33fb5b4b178718914a32e1838502e9e81
BLAKE2b-256 checksum
How to use checksums
7470b55d4617e6e096522d4a44934c10356ea735f5719d9bb2a582946972fde1
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
Yes
Uploaded via twine/7.0.0 CPython/3.13.14

Provenance

Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.

PyPI Publish Attestation

PyPI verified that this artifact, at this checksum, originated from the publisher listed below.

Signed by GitHub Actions, verified by PyPI on Sep 27, 2026.

Transparency log

Release files / sahifa-1.0.0-py3-none-any.whl

Download URL sahifa-1.0.0-py3-none-any.whl
Size 6.2 kB
Tags Python 3
SHA-256 checksum
How to use checksums
27ea0a6014f547a79049a3c609e120596ca0c75ee0779cce58c802ef4dd9de5d
BLAKE2b-256 checksum
How to use checksums
571a0fc856384fad0a076c1f51e84a3eae1bb85f1501f0867d2de005a05f89a0
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
Yes
Uploaded via twine/7.0.0 CPython/3.13.14

Provenance

Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.

PyPI Publish Attestation

PyPI verified that this artifact, at this checksum, originated from the publisher listed below.

Signed by GitHub Actions, verified by PyPI on Sep 27, 2026.

Transparency log

Release history Release notifications | RSS feed

This release

1.0.0 This release

2 release files

Anthropic, PBC Visionary sponsor Bloomberg Visionary sponsor Hudson River Trading Visionary sponsor Meta Visionary sponsor NVIDIA Visionary sponsor Microsoft Sustainability sponsor Depot Continuous Integration AWS Cloud computing and Security Sponsor Datadog Monitoring Fastly CDN Google Download Analytics Sentry Error logging StatusPage Status page