Documentación
Documentación
Python SDK
A single-file module you can copy into any Python project. No pip install needed.
Installation
Copy the Renderful class below into your project, or save it as renderful.py. Requires requests (pip install requests).
The Module
import os, time, requests
class Renderful:
"""Renderful API client — copy this class into your project."""
BASE = "https://api.renderful.ai/api/v1"
def __init__(self, api_key: str | None = None):
self.api_key = api_key or os.environ["RENDERFUL_API_KEY"]
self.session = requests.Session()
self.session.headers.update({
"Authorization": f"Bearer {self.api_key}",
"Content-Type": "application/json",
})
# --- core methods ---
def create(self, body: dict) -> dict:
"""Submit a generation task. Returns the task object."""
r = self.session.post(f"{self.BASE}/generations", json=body)
r.raise_for_status()
return r.json()
def get(self, task_id: str) -> dict:
"""Fetch current status of a task."""
r = self.session.get(f"{self.BASE}/generations/{task_id}")
r.raise_for_status()
return r.json()
def poll(self, task_id: str, interval: float = 3, timeout: float = 300) -> dict:
"""Poll until completed or failed. Returns final task object."""
deadline = time.time() + timeout
while time.time() < deadline:
data = self.get(task_id)
if data["status"] in ("completed", "failed"):
return data
time.sleep(interval)
raise TimeoutError(f"Task {task_id} did not finish within {timeout}s")
def run(self, body: dict, **poll_kw) -> dict:
"""Create + poll in one call. Returns completed task."""
task = self.create(body)
return self.poll(task["id"], **poll_kw)
# --- file upload ---
def upload(self, file_path: str) -> str:
"""Upload a local file and return its URL for use in requests."""
with open(file_path, "rb") as f:
r = self.session.post(
f"{self.BASE}/uploads",
files={"file": f},
headers={"Authorization": f"Bearer {self.api_key}"},
)
r.raise_for_status()
return r.json()["url"]Authentication
# Set in your shell: export RENDERFUL_API_KEY="rf_..."
client = Renderful() # reads from env automaticallyUsage Examples
Text to Image
from renderful import Renderful
client = Renderful()
result = client.run({
"type": "text-to-image",
"model": "flux-dev",
"prompt": "A cyberpunk cityscape at night",
})
print(result["outputs"]) # ["https://..."]Text to Video
result = client.run({
"type": "text-to-video",
"model": "wan-2.6",
"prompt": "A drone flyover of a tropical island",
})
print(result["outputs"]) # ["https://...mp4"]Image to Video
# Upload a local image first
image_url = client.upload("photo.jpg")
result = client.run({
"type": "image-to-video",
"model": "wan-2.6-i2v",
"image_url": image_url,
"prompt": "Slow zoom into the scene",
})
print(result["outputs"])Text to Text (LLM)
result = client.run({
"type": "text-to-text",
"model": "kimi-k2.5",
"prompt": "Explain quantum computing in 3 sentences",
"max_tokens": 256,
})
print(result["outputs"][0])Error Handling
from requests.exceptions import HTTPError
try:
result = client.run({
"type": "text-to-image",
"model": "flux-dev",
"prompt": "A sunset",
})
except HTTPError as e:
print(f"API error {e.response.status_code}: {e.response.text}")
except TimeoutError:
print("Generation took too long")
# Check for failed tasks
if result["status"] == "failed":
print("Task failed:", result.get("error"))Fire-and-Forget Mode
Use create() instead of run() if you prefer webhooks over polling.
task = client.create({
"type": "text-to-image",
"model": "flux-dev",
"prompt": "A sunset",
"webhook_url": "https://your-app.com/webhooks/renderful",
})
print(f"Task submitted: {task['id']}")
# Your webhook endpoint will receive the result