> ## 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.

# Python

> Requests para scripts, agentes y pipelines.

# Python

## Archivo local

```python theme={null}
import requests

API_URL = "https://api.markpdf.tech"
API_KEY = "TU_API_KEY"

with open("informe.pdf", "rb") as f:
    response = requests.post(
        f"{API_URL}/convert/raw",
        params={"filename": "informe.pdf", "mode": "fast"},
        headers={"x-api-key": API_KEY, "content-type": "application/pdf"},
        data=f,
        timeout=300,
    )

response.raise_for_status()
markdown = response.text
```

## URL firmada

```python theme={null}
import requests

response = requests.post(
    "https://api.markpdf.tech/convert/from-url",
    headers={"x-api-key": "TU_API_KEY"},
    json={
        "url": "https://bucket.s3.amazonaws.com/informe.pdf?X-Amz-Signature=...",
        "filename": "informe.pdf",
        "mode": "fast",
    },
    timeout=300,
)

response.raise_for_status()
print(response.text)
```

## Manejo de 202 (auto-async)

Cuando todos los backends están saturados, la API devuelve `202` con un `job_id`. Pollea hasta obtener el resultado:

```python theme={null}
import requests
import time

API_URL = "https://api.markpdf.tech"
API_KEY = "TU_API_KEY"


def convert_with_retry(pdf_path: str) -> str:
    with open(pdf_path, "rb") as f:
        res = requests.post(
            f"{API_URL}/convert/raw",
            params={"filename": pdf_path, "mode": "fast"},
            headers={"x-api-key": API_KEY, "content-type": "application/pdf"},
            data=f,
            timeout=300,
        )

    if res.status_code == 200:
        return res.text

    if res.status_code == 202:
        job = res.json()
        job_id = job["job_id"]
        delay = job.get("retry_after_seconds", 5)

        while True:
            time.sleep(delay)
            poll = requests.get(
                f"{API_URL}/jobs/{job_id}",
                headers={"x-api-key": API_KEY},
                timeout=30,
            )
            data = poll.json()

            if data["status"] == "completed":
                return data["body"]
            if data["status"] == "failed":
                raise RuntimeError(f"Job {job_id} failed: {data.get('error')}")

    res.raise_for_status()
```

### Versión async (httpx)

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

API_URL = "https://api.markpdf.tech"
API_KEY = "TU_API_KEY"


async def convert_async(pdf_bytes: bytes, filename: str) -> str:
    async with httpx.AsyncClient(timeout=300) as client:
        res = await client.post(
            f"{API_URL}/convert/raw",
            params={"filename": filename, "mode": "fast"},
            headers={"x-api-key": API_KEY, "content-type": "application/pdf"},
            content=pdf_bytes,
        )

        if res.status_code == 200:
            return res.text

        if res.status_code == 202:
            job = res.json()
            job_id = job["job_id"]

            while True:
                await asyncio.sleep(job.get("retry_after_seconds", 5))
                poll = await client.get(
                    f"{API_URL}/jobs/{job_id}",
                    headers={"x-api-key": API_KEY},
                )
                data = poll.json()

                if data["status"] == "completed":
                    return data["body"]
                if data["status"] == "failed":
                    raise RuntimeError(data.get("error"))

        res.raise_for_status()
```
