> ## Documentation Index
> Fetch the complete documentation index at: https://docs.markpdf.tech/llms.txt
> Use this file to discover all available pages before exploring further.

# Ejemplos

> Casos de uso reales de Python SDK: cargas, archivos PDF grandes, BYOS, RAG y ZIP.

# Ejemplos

## Convertir una carga de usuario (FastAPI)

```python theme={null}
from fastapi import FastAPI, UploadFile
import markpdf

app = FastAPI()
client = markpdf.AsyncClient(api_key="YOUR_API_KEY")

@app.post("/upload")
async def upload(file: UploadFile):
    content = await file.read()
    markdown = await client.convert_raw_bytes(
        content,
        filename=file.filename,
        mode="fast",
    )
    return {"markdown": markdown}
```

<Note>
  `convert_raw_bytes(data, filename=..., **params)` es la variante de `convert_file` para cuando ya tienes el contenido en la memoria (por ejemplo, una FastAPI `UploadFile`) y no quieres escribirlo en el disco primero.
</Note>

## PDF grande con rango de páginas

```python theme={null}
markdown = client.convert_from_url(
    "https://bucket.example.com/manual-800-papages.pdf?sig=...",
    pages="120-145",
    mode="fast",
)
```

Combínelo con [`pdf_index`](/docs/public/es/sdks/python/reference#pdf_index) para saber qué rango ordenar sin descargar todo el PDF del lado del cliente.

## BYOS: sube el resultado directamente a tu almacenamiento

```python theme={null}
result = client.convert_from_url(
    pdf_url,
    output_url=presigned_put_url,       # pre-signed PUT to your bucket
    output_head_url=presigned_head_url,  # optional: detect cache hits
)

print(result.cached)      # True si ya existía y no se reprocesó
print(result.output_url)  # URL final del Markdown subido
```

Con `output_url`, API carga Markdown directamente a su almacenamiento (S3, R2, Supabase Storage, GCS) y devuelve un JSON liviano en lugar del cuerpo completo, útil para canalizaciones por lotes donde no desea que Markdown pase por su propio backend. Consulte [Compresión](/docs/public/es/concepts/compression) para conocer los valores de `output_encoding`.

## Canalización RAG con `/pdf/index`

```python theme={null}
import markpdf

client = markpdf.Client(api_key="YOUR_API_KEY")
PDF = "https://bucket.example.com/informe-anual.pdf?sig=..."

# 1. Index without converting the entire document
spine = client.pdf_index(PDF)
print(f"{spine.page_count} pápages, ~{spine.estimated_tokens_full} full tokens")

# 2. The agent decides which section he is interested in
target = next(s for s in spine.sections if "Resultados" in s.text)
following = next((s for s in spine.sections if s.page > target.page), None)
end_page = (following.page - 1) if following else spine.page_count

# 3. Bring Markdown only from that section
markdown = client.convert_from_url(PDF, pages=f"{target.page}-{end_page}", mode="fast")
```

Este flujo evita pagar el costo (tokens + latencia) de convertir 500 páginas cuando el agente solo necesita 12. Consulte el [PDF Índice para agentes IA](/docs/public/es/concepts/pdf-index-for-ai-agents).

## Procesar un ZIP

```python theme={null}
result = client.convert_file(
    "documents.zip",
    input_format="zip",
    response_format="json",
)

print(result.markdown)  # Markdown concatenated from the supported documents inside the ZIP
```

<Warning>
  Los límites de tamaño y cantidad de archivos dentro de ZIP están documentados en [Límites](/docs/public/es/concepts/limits). Un ZIP fuera de rango devuelve `413`, que SDK convierte en `MarkpdfPayloadTooLargeError`.
</Warning>

## Convertir muchos archivos en paralelo (asíncrono)

```python theme={null}
import asyncio
import markpdf

async def convert_all(paths: list[str]) -> list[str]:
    async with markpdf.AsyncClient(api_key="YOUR_API_KEY", max_retries=3) as client:
        tasks = [client.convert_file(p, mode="fast") for p in paths]
        return await asyncio.gather(*tasks, return_exceptions=True)

results = asyncio.run(convert_all(["a.pdf", "b.docx", "c.pdf"]))
for path, result in zip(["a.pdf", "b.docx", "c.pdf"], results):
    if isinstance(result, Exception):
        print(f"{path} falló: {result}")
    else:
        print(f"{path}: {len(result)} caracteres")
```

<Tip>
  `AsyncClient` reutiliza una única conexión subyacente HTTP/2, por lo que iniciar conversiones paralelas con `asyncio.gather` es más eficiente que abrir un `Client` sincrónico por archivo.
</Tip>
