buble-ai
Official Python SDK for the Buble AI public API. Use it from server-side Python code to create AI image and video generation tasks, run preconfigured Buble apps, upload source media, and call Buble chat models through OpenAI, Anthropic, or Gemini-compatible endpoints.
buble-ai is not related to the existing buble package on PyPI.
Keep your API key on the server. Do not expose BUBLE_API_KEY in browser or client-side code.
Installation
pip install buble-ai
Quick Start
from buble_ai import Buble
client = Buble(api_key="sk_...")
task = client.generations.create(
model="google/nano-banana",
mode="text_to_image",
prompt="A cinematic product photo of a matte black espresso cup",
aspect_ratio="1:1",
output_format="png",
)
result = client.generations.wait(task["data"]["id"])
print(result["data"]["result"]["images"][0]["url"])
The client reads BUBLE_API_KEY and BUBLE_BASE_URL from the environment when omitted.
Discover Media Models
models = client.media_models.list(media_type="video")
for model in models["data"]:
print(model["model"], [op["mode"] for op in model.get("operations", [])])
Use media_models.list() as the source of truth for model keys, modes, required inputs, and public parameters.
Upload Files
uploaded = client.files.upload(
"reference.png",
file_type="image",
model="google/nano-banana",
mode="image_to_image",
)
task = client.generations.create(
model="google/nano-banana",
mode="image_to_image",
prompt="Turn this reference into a polished ecommerce hero image.",
image_urls=[uploaded["data"]["url"]],
)
Uploads support paths, bytes, bytearray, and binary file objects. Paths are streamed from disk instead of being read fully into memory.
Video Generation
task = client.generations.create(
model="doubao/seedance-2.0-fast",
mode="text_to_video",
prompt="A cinematic wide shot of a futuristic train station at sunrise.",
duration="8s",
resolution="720p",
aspect_ratio="16:9",
)
result = client.generations.wait(task["data"]["id"], interval=2.0, timeout=600.0)
print(result["data"]["result"]["videos"][0]["url"])
Generation request bodies are flat JSON. Do not send internal Buble fields such as input, options, scene, sub_mode_id, provider, mediaType, or media_type.
Apps
app = client.apps.retrieve("video-background-remover")
print(app["data"]["input_parameters"])
task = client.apps.generations.create(
"video-background-remover",
source_video=["https://example.com/source.mp4"],
refine_foreground_edges=True,
subject_is_person=True,
)
result = client.apps.generations.wait("video-background-remover", task["data"]["id"])
print(result["data"]["result"]["videos"][0]["url"])
Apps are preconfigured workflows. Only send parameter names returned by apps.list() or apps.retrieve().
Chat
OpenAI-Compatible
completion = client.chat.completions.create(
model="openai/gpt-5.5",
messages=[{"role": "user", "content": "Write a short launch summary."}],
reasoning=True,
max_completion_tokens=800,
)
print(completion["choices"][0]["message"]["content"])
Streaming
for text in client.chat.completions.stream_text(
model="openai/gpt-5.5",
messages=[{"role": "user", "content": "Write one sentence at a time."}],
):
print(text, end="")
Anthropic-Compatible
message = client.chat.messages.create(
model="openai/gpt-5.5",
system="You are concise.",
messages=[{"role": "user", "content": "Summarize this release."}],
max_tokens=800,
)
Gemini-Compatible
response = client.chat.gemini.generate_content(
"openai/gpt-5.5",
contents=[
{
"role": "user",
"parts": [{"text": "Write a short launch summary."}],
}
],
)
Gemini streaming uses stream_generate_content, not stream=True on generate_content.
Async Client
from buble_ai import AsyncBuble
async with AsyncBuble() as client:
models = await client.chat.models.list()
Error Handling
from buble_ai import BubleAPIError, BubleGenerationError
try:
client.generations.create(model="missing/model", mode="text_to_image")
except BubleAPIError as error:
print(error.status_code, error.code, error.message, error.details)
try:
client.generations.wait("task_id")
except BubleGenerationError as error:
print(error.task)
Development
python -m pip install -e ".[dev]"
pytest
python -m build
python -m twine check dist/*
Live smoke test:
BUBLE_API_KEY=sk_... python scripts/live_smoke.py
The live smoke test does not create billable generation tasks.
Metadata
Release files for buble-ai 0.1.0
For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.
Source distribution (sdist)
| File | Size | Uploaded | |
|---|---|---|---|
| buble_ai-0.1.0.tar.gz | 15.2 kB | Details |
Built distribution (wheel)
| File | Interpreter | ABI | Platform | Reset |
|---|---|---|---|---|
| buble_ai-0.1.0-py3-none-any.whl | Python 3 | none | any | Details |
Total release size: 32.6 kB
Release files / buble_ai-0.1.0.tar.gz
| Download URL | buble_ai-0.1.0.tar.gz |
|---|---|
| Size | 15.2 kB |
| Tags | Source |
|
SHA-256 checksum How to use checksums |
68aa0a506c22c6111f5c711c6018c8d2e9d434ce93fd0b60789027230a7cfe26
|
|
BLAKE2b-256 checksum How to use checksums |
12a73a30af3ae2981c809fd292826057e0290a41874f68f208767ec6d7d076a6
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
No |
| Uploaded via |
twine/6.2.0 CPython/3.14.0
|
Release files / buble_ai-0.1.0-py3-none-any.whl
| Download URL | buble_ai-0.1.0-py3-none-any.whl |
|---|---|
| Size | 17.4 kB |
| Tags | Python 3 |
|
SHA-256 checksum How to use checksums |
858a174c04623761171831e22a8376a515826243c30e05763afba2be6cb162b0
|
|
BLAKE2b-256 checksum How to use checksums |
487f2983d46e75e0c2c58c7871796528429345f1661b2ae71df07be45d3b0179
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
No |
| Uploaded via |
twine/6.2.0 CPython/3.14.0
|