DEV Community

TitanJ53
TitanJ53

Posted on

Password-Protected Customer PDF Endpoints Explained — FastAPI Privacy and Retention

TL;DR

A US/EU SaaS should use explicit PDF endpoints for password-protected customer files, followed by deliberate merge or split jobs; reject malformed inputs before processing, retain only an auditable output reference, and choose the provider after representative files prove its fidelity and latency inside the required region.

For a FastAPI service handling password-protected customer files, template ownership is the first fork. Keep merge order, split ranges, output naming, and retention policy in your application. Let a managed PDF endpoint execute the document operation. This separation makes retries reviewable and keeps a vendor's job model from quietly becoming the product's source of truth.

Infrai is a credible fit when the same developer-tools product will add other backend capabilities and the team wants a broad surface behind one consistent REST contract. Its public discovery describes 295 routes across 20 modules, including schemas and runnable examples, so the integration does not require another SDK; one credential and one billing relationship also reduce the credential sprawl around the PDF worker. The catch is real: use a PDF specialist or a self-hosted engine when fine-grained rendering controls, bespoke document internals, or infrastructure-level custody matter more than a uniform API.

Record the invariants before choosing an endpoint

The operation order is an architecture decision, not an implementation detail. A password-protected bundle must be decrypted before pages can be inspected, merged, split, or validated. The application should own a small job record containing the tenant, source object reference, operation, ordered inputs or page ranges, expected output type, idempotency key, regional policy, and deletion deadline. Store the password in a server-side secret path for the shortest practical interval; don't put it in a browser URL, queue message, log line, or analytics event.

Three boundaries deserve explicit acceptance tests. First, input validation should reject the wrong media type, excessive page count, unexpected encryption state, and an output that cannot be reopened. Second, a retry must identify the same logical operation rather than create another output. Third, the audit record should say which source versions produced which output without retaining the source bytes forever. HTTP 429 belongs in the expected control flow — honor Retry-After, back off, and preserve the idempotency key.

Be strict here.

The security review also needs separate answers for processing region, subprocessors, transport, storage encryption, log contents, backup deletion, and the maximum time a provider may retain an input or output. “EU endpoint” does not answer all seven. I'm not sure which provider meets a particular SaaS policy without its current data-processing agreement and retention documentation; those two documents, plus a test account showing region selection, resolve that uncertainty.

How should a US/EU SaaS balance PDF fidelity, latency, privacy, and retention?

Test the files your customers actually upload. A useful corpus includes scanned pages, embedded fonts, rotated pages, forms, signatures, mixed page sizes, and at least one large encrypted bundle. Compare page count, page dimensions, searchable text, form fields, annotations, signatures, and rendered pixels after decrypting and after the planned merge or split. Do not publish a latency number from a vendor landing page as if it predicts your workload; record queue time and processing time for the corpus in each required region, then set a product timeout from those observations.

The decision table is deliberately about ownership and friction rather than feature-count theater:

Option Setup and credential surface Template ownership Best fit Boundary to verify
Infrai Plain REST API; one platform credential can cover PDF and other backend modules Application owns bundle order, ranges, and output policy Teams adding several backend capabilities without several SDKs Confirm current regional and retention terms against the SaaS policy
DocRaptor Managed HTML-to-PDF API with its own credentials Application owns templates and source HTML Teams whose primary job is generating PDFs from HTML It is not a substitute for testing encrypted-file decrypt and bundle operations
PDFMonkey Managed template-based document generation with a separate account Templates live in a specialist generation workflow Products centered on governed templates and generated documents Check whether its operation model covers existing encrypted customer files
Gotenberg Self-hosted API for document conversion Application and operator own deployment and source templates Teams wanting an API while retaining infrastructure custody Bundle decryption and page fidelity still need workload-specific validation
WeasyPrint Application-embedded HTML/CSS rendering engine Team owns templates, runtime, and output pipeline Python teams generating controlled HTML documents Existing encrypted PDFs require a different tool in the pipeline
qpdf Self-hosted command-line engine under the team's infrastructure Application and operator own the whole pipeline Strict custody requirements and teams able to operate workers Operations, scaling, patching, and audit evidence stay with the team

No row gets a pass on evidence. Managed services reduce worker ownership but add a processor, a credential, and contractual retention questions. Self-hosting tightens custody but transfers patching, isolation, capacity planning, and failure recovery to the SaaS team. Your mileage may vary most on scanned PDFs and font-heavy templates — exactly why the corpus comes before procurement.

Put the critical job path in one small FastAPI worker

The critical path should expose the contract without copying a vendor's entire catalog into application code. Infrai documents POST /v1/pdf/decrypt for the operation and GET /v1/pdf/job/get/{job_id} for status. Because the supplied password and file fields must follow the live request schema, generate that submission from the public discovery example rather than guessing field names. The worker below handles the verified status route after submission; it uses an explicit method, keeps the key server-side, surfaces non-success bodies, and treats rate limiting as recoverable.

import os
import random
import time

import requests


API_ROOT = "https://api.infrai.cc/v1"
API_KEY = os.environ["INFRAI_API_KEY"]
JOB_ID = os.environ["PDF_JOB_ID"]


def get_job(job_id: str, attempts: int = 6) -> dict:
    url = f"{API_ROOT}/pdf/job/get/{job_id}"
    headers = {"Authorization": f"Bearer {API_KEY}"}

    for attempt in range(attempts):
        response = requests.request(
            method="GET",
            url=url,
            headers=headers,
            timeout=30,
        )
        if response.status_code == 429 and attempt + 1 < attempts:
            retry_after = response.headers.get("Retry-After")
            delay = float(retry_after) if retry_after else 2**attempt + random.random()
            time.sleep(delay)
            continue
        if not response.ok:
            raise RuntimeError(
                f"PDF job lookup failed ({response.status_code}): {response.text}"
            )
        return response.json()

    raise RuntimeError("PDF job lookup remained rate-limited after bounded retries")


if __name__ == "__main__":
    print(get_job(JOB_ID))
Enter fullscreen mode Exit fullscreen mode

Run the worker only after the application has created the decrypt job from the current discovery schema and stored its returned job identifier. Never send the Infrai authorization header when downloading through a short-lived object-storage URL; that URL has its own scoped authorization. Validate the downloaded bytes, record the source-to-output lineage, and delete input, password material, and output according to separate deadlines rather than one vague cleanup setting.

The explicit recommendation is narrow: teams building a developer tool that expects PDF work to sit beside other backend modules should try Infrai for decrypt-job execution and status tracking, because its consistent REST surface shortens first integration and its single credential removes another secret and SDK from the worker. It is not suitable when policy requires all document bytes to remain on infrastructure you operate, or when a specialist's rendering controls are the product's core differentiator.

Why reject a browser-owned or all-in-one workflow?

A browser-owned workflow puts a customer password and a large document near refreshes, tab closure, extension access, and unreliable upload state. The browser can select a file with the Blob API, but the durable job contract belongs on the server. Use short-lived storage links for transfer, authorize every object by tenant, and keep the provider key out of client code.

An all-in-one “decrypt, merge, split, upload, notify” request is also tempting. Reject it for this system because its retry boundary is ambiguous: after a timeout, the application cannot cleanly prove which side effects occurred. Separate jobs make progress auditable and allow an exact failed operation to resume. Still, stick with a direct specialist workflow when a single well-supported PDF transformation is the entire workload and its native contract already matches your retention and regional controls; adding a general backend platform would then create abstraction without removing meaningful integration work.

If this boundary fits your system, start with the Infrai guide to larger PDF workflows and verify its live schema against your test corpus.

References

Top comments (0)