Official SDK

Python

Full type hints and async/await support. Works with Python 3.8+ and integrates smoothly with your existing Python workflows.

Python 3.8+MIT licensed

Rename PDFs, split multi-page documents, and extract structured data using the official Python SDK for Renamed.to.

  1. 1Install with pip install renamed and initialize with your API key
  2. 2Call rename(), pdf_split(), or extract() with PDF bytes or file path
  3. 3Use sync or async client for AI-generated filenames, split documents, or structured JSON

MIT licensed, open source on GitHub, published on PyPI.

Installation

Shell
pip install renamed

Quickstart

Initialize the client and start making API calls.

main.py
Python
import osfrom renamed import RenamedClient# Initialize the clientclient = RenamedClient(api_key=os.environ["RENAMED_API_KEY"])# Rename a PDFwith open("invoice.pdf", "rb") as f:    result = client.rename(f.read())print(result.suggested_filename)# -> "2024-01-15_AcmeCorp_INV-1234.pdf"# Split a multi-page PDFwith open("documents.pdf", "rb") as f:    job = client.pdf_split(f.read(), mode="smart")print(job.documents)# -> [{"filename": "...", "download_url": "..."}, ...]# Extract structured datawith open("receipt.pdf", "rb") as f:    data = client.extract(f.read())print(data)# -> {"vendor": "...", "date": "...", "amount": "..."}

Rename a PDF

Pass PDF bytes or a file path to get an AI-generated filename. Use custom instructions to control the naming format.

rename.py
Python
import osfrom pathlib import Pathfrom renamed import RenamedClientclient = RenamedClient(api_key=os.environ["RENAMED_API_KEY"])# Rename from a local filepdf_path = Path("./documents/invoice.pdf")result = client.rename(pdf_path.read_bytes())print(result)# RenameResult(#     suggested_filename="2024-01-15_AcmeCorp_INV-1234.pdf",#     confidence=0.95,#     metadata={"vendor": "Acme Corp", "date": "2024-01-15", "type": "invoice"}# )# Use custom naming instructionscustom_result = client.rename(    pdf_path.read_bytes(),    instructions="Format: YYYY-MM-DD_VendorName_Amount")print(custom_result.suggested_filename)# -> "2024-01-15_AcmeCorp_$1250.pdf"# Async version with AsyncRenamedClientimport asynciofrom renamed import AsyncRenamedClientasync def rename_async():    async_client = AsyncRenamedClient(api_key=os.environ["RENAMED_API_KEY"])    result = await async_client.rename(pdf_path.read_bytes())    return result.suggested_filename# asyncio.run(rename_async())

Split a PDF

Split multi-page PDFs into separate documents. The API uses async jobs for large files—poll for completion or use the built-in wait helper.

split.py
Python
import osfrom pathlib import Pathfrom renamed import RenamedClientclient = RenamedClient(api_key=os.environ["RENAMED_API_KEY"])pdf_bytes = Path("./documents/combined.pdf").read_bytes()# Smart split: AI detects document boundariesjob = client.pdf_split(pdf_bytes, mode="smart")# Option 1: Wait for completion (built-in polling)completed = job.wait_for_completion()print(completed.documents)# [#     SplitDocument(filename="invoice_1.pdf", pages=[1, 2], download_url="..."),#     SplitDocument(filename="invoice_2.pdf", pages=[3, 4], download_url="..."),# ]# Option 2: Manual polling for progress updatesimport timestatus = client.get_job(job.job_id)while status.state == "processing":    print(f"Progress: {status.progress}%")    time.sleep(1)    status = client.get_job(job.job_id)# Download split documentsoutput_dir = Path("./output")output_dir.mkdir(exist_ok=True)for doc in completed.documents:    pdf_data = client.download_file(doc.download_url)    (output_dir / doc.filename).write_bytes(pdf_data)    print(f"Saved: {doc.filename}")# Async version with AsyncRenamedClientimport asynciofrom renamed import AsyncRenamedClientasync def split_async():    async_client = AsyncRenamedClient(api_key=os.environ["RENAMED_API_KEY"])    job = await async_client.pdf_split(pdf_bytes, mode="smart")    completed = await job.wait_for_completion()    return completed.documents# asyncio.run(split_async())

Extract Data

Extract structured data from invoices, receipts, and other documents. Use Pydantic models for type-safe extraction.

extract.py
Python
import osfrom pathlib import Pathfrom renamed import RenamedClientclient = RenamedClient(api_key=os.environ["RENAMED_API_KEY"])# Basic extraction (returns inferred fields as dict)pdf_bytes = Path("./documents/receipt.pdf").read_bytes()data = client.extract(pdf_bytes)print(data)# {"vendor": "Coffee Shop", "date": "2024-01-15", "total": "$4.50", ...}# Typed extraction with Pydantic modelfrom pydantic import BaseModelclass LineItem(BaseModel):    description: str    quantity: int    unit_price: floatclass Invoice(BaseModel):    invoice_number: str    vendor: str    date: str    line_items: list[LineItem]    subtotal: float    tax: float    total: floatinvoice = client.extract(pdf_bytes, schema=Invoice)# invoice is fully typed as Invoiceprint(f"Invoice #{invoice.invoice_number}")print(f"Vendor: {invoice.vendor}")print(f"Total: ${invoice.total:.2f}")for item in invoice.line_items:    print(f"  - {item.description}: {item.quantity} x ${item.unit_price:.2f}")# Output:# Invoice #INV-2024-1234# Vendor: Acme Corp# Total: $1,337.50#   - Widget Pro: 5 x $199.00#   - Support Plan: 1 x $342.50

Framework Integrations

Common integration patterns for popular frameworks.

FastAPI Endpoint

Use the async client in FastAPI for high-performance file uploads with automatic validation.

main.py
Python
# main.pyimport osfrom fastapi import FastAPI, UploadFile, HTTPExceptionfrom pydantic import BaseModelfrom renamed import AsyncRenamedClientapp = FastAPI()# Initialize the async client at startupclient = AsyncRenamedClient(api_key=os.environ["RENAMED_API_KEY"])class RenameResponse(BaseModel):    suggested_filename: str    confidence: float@app.post("/api/rename", response_model=RenameResponse)async def rename_pdf(file: UploadFile):    if not file.filename or not file.filename.endswith(".pdf"):        raise HTTPException(status_code=400, detail="File must be a PDF")    pdf_bytes = await file.read()    result = await client.rename(pdf_bytes)    return RenameResponse(        suggested_filename=result.suggested_filename,        confidence=result.confidence,    )@app.post("/api/split")async def split_pdf(file: UploadFile, mode: str = "smart"):    pdf_bytes = await file.read()    job = await client.pdf_split(pdf_bytes, mode=mode)    completed = await job.wait_for_completion()    return {        "job_id": completed.job_id,        "documents": [            {"filename": doc.filename, "pages": doc.pages}            for doc in completed.documents        ],    }

Flask Route

Integrate with Flask using the sync client for traditional web applications.

app.py
Python
# app.pyimport osfrom flask import Flask, request, jsonifyfrom werkzeug.utils import secure_filenamefrom renamed import RenamedClient, RenamedErrorapp = Flask(__name__)app.config["MAX_CONTENT_LENGTH"] = 16 * 1024 * 1024  # 16MB maxclient = RenamedClient(api_key=os.environ["RENAMED_API_KEY"])@app.route("/api/rename", methods=["POST"])def rename_pdf():    if "file" not in request.files:        return jsonify({"error": "No file provided"}), 400    file = request.files["file"]    if not file.filename or not file.filename.endswith(".pdf"):        return jsonify({"error": "File must be a PDF"}), 400    try:        pdf_bytes = file.read()        result = client.rename(pdf_bytes)        return jsonify({            "suggested_filename": result.suggested_filename,            "confidence": result.confidence,        })    except RenamedError as e:        return jsonify({"error": str(e)}), 500@app.route("/api/extract", methods=["POST"])def extract_data():    if "file" not in request.files:        return jsonify({"error": "No file provided"}), 400    file = request.files["file"]    pdf_bytes = file.read()    try:        data = client.extract(pdf_bytes)        return jsonify(data)    except RenamedError as e:        return jsonify({"error": str(e)}), 500if __name__ == "__main__":    app.run(debug=True)

Error Handling

The SDK raises typed exceptions that you can catch and handle appropriately.

error_handling.py
Python
from renamed import RenamedClient, RenamedError, RateLimitErrorclient = RenamedClient(api_key="...")try:    result = client.rename(pdf_bytes)except RateLimitError as e:    print(f"Rate limited. Retry after {e.retry_after} seconds")except RenamedError as e:    print(f"API Error: {e.code} - {e.message}")

Full documentation on GitHub

For more examples, advanced usage patterns, and detailed API documentation, see the full Python SDK README on GitHub.

Read the Python SDK docs

Frequently asked questions

What Python versions are supported?
The Python SDK supports Python 3.8 and above. It includes type hints for IDE autocompletion and static analysis.
Does the SDK support async/await?
Yes, the SDK provides both sync and async interfaces. Use the async client for better performance in asyncio applications.
How do I install extra dependencies?
The base package includes all required dependencies. No extras are needed for standard usage.

Related resources

Other languages