Skip to content
Last updated

Python SDK (bria-client)

bria-client is Bria's official Python SDK. It wraps the v2 REST API with a synchronous and an asynchronous client, handles the async job lifecycle (submit, poll, webhooks), retries transient failures, and converts local images to API inputs for you.

  • Source and issues: github.com/Bria-AI/bria-client (MIT)
  • Python 3.10 or newer
  • Covers every v2 endpoint. Legacy /v1 endpoints are not reachable through the SDK; call them over HTTP.

Install and authenticate

pip install bria-client
export BRIA_API_TOKEN="<your-bria-api-token>"

The client reads BRIA_API_TOKEN from the environment. You can also pass api_token= to the constructor, or override it per call with api_token= on any method. Get a token from the Bria Console.

Your first call

from bria_client import BriaSyncClient
from bria_client.toolkit import Image

client = BriaSyncClient()

response = client.run(
    endpoint="image/edit/remove_background",
    payload={"image": Image("https://labs-assets.bria.ai/sandbox-example-inputs/remove_background_example.jpg").as_bria_api_input},
)

print(response.status)            # COMPLETED
print(response.result.image_url)  # URL of the cutout

endpoint is the v2 path without the /v2/ prefix, exactly as it appears in the API reference: image/generate, image/edit/remove_background, video/edit/remove_background, and so on.

Two clients

ClientUse when
BriaSyncClientScripts, notebooks, CLIs, traditional web frameworks
BriaAsyncClientasyncio applications and high-concurrency pipelines

Both expose the same methods; the async client awaits them. Both work as context managers (with / async with) so connections are closed cleanly.

import asyncio
from bria_client import BriaAsyncClient

async def main():
    async with BriaAsyncClient() as client:
        response = await client.run(
            endpoint="image/generate",
            payload={"prompt": "a matte black travel mug on a white seamless backdrop"},
        )
        print(response.result.image_url)

asyncio.run(main())

Three request methods

Bria's v2 endpoints are asynchronous by default. The SDK gives you three ways to work with that:

MethodWhat it doesReturns
client.run(endpoint, payload)Sends the request with sync: true and blocks until the result is ready. Simplest for interactive use.BriaResponse with result
client.submit(endpoint, payload, webhook_url=None)Sends the request with sync: false and returns immediately.BriaResponse with request_id and status_url
client.poll(response_or_request_id, interval=1, timeout=60)Polls the status endpoint until the job finishes. Raises TimeoutError when the timeout elapses.BriaResponse with result

Do not put sync in your payload; run and submit set it for you and raise if you pass it.

# Submit now, collect later
job = client.submit(endpoint="video/segment/mask_by_prompt", payload={"video": video_url, "prompt": "the red car"})
print("submitted:", job.request_id)

final = client.poll(job, interval=2, timeout=600)
print(final.result.video_url)

client.status(request_id) returns just the current status string (IN_PROGRESS, COMPLETED, ERROR, UNKNOWN) if you manage polling yourself.

Responses and errors

Every method returns a BriaResponse:

FieldDescription
request_idJob identifier; also the deduplication key for webhooks
statusIN_PROGRESS, COMPLETED, ERROR or UNKNOWN
resultEndpoint result. Access fields as attributes: result.image_url, result.video_url, result.seed, result.structured_prompt
errorcode, message, details when the request failed
status_urlPolling URL for async jobs

Pass raise_for_status=True to turn API errors into a BriaException instead of inspecting response.error:

from bria_client.toolkit import BriaException

try:
    response = client.run(endpoint="image/generate", payload={"prompt": "..."}, raise_for_status=True)
    print(response.result.image_url)
except TimeoutError:
    print("timed out waiting for the result")
except BriaException as e:
    print("Bria API error:", e)

Transient HTTP failures are retried automatically (3 attempts with exponential backoff). Pass retry= to the constructor to change that.

Images: URLs, files, arrays

Image from bria_client.toolkit turns any of these into the string the API expects, either the URL as-is or a raw base64 payload without the data: prefix:

from bria_client.toolkit import Image
from PIL import Image as PILImage
import numpy as np

Image("https://example.com/photo.jpg").as_bria_api_input   # public URL, passed through
Image("./photo.png").as_bria_api_input                      # local path, encoded to base64
Image(PILImage.open("photo.png")).as_bria_api_input         # PIL image
Image(np.zeros((512, 512, 3), dtype="uint8")).as_bria_api_input  # numpy array

The client also strips None values from payloads, so optional parameters can be left as None without being sent.

Webhooks

Instead of polling, ask Bria to POST the result to your server when the job completes. webhook_url is a keyword argument of submit, not part of the payload:

job = client.submit(
    endpoint="image/generate",
    payload={"prompt": "a serene mountain landscape at dawn"},
    webhook_url="https://your-app.example.com/api/bria/webhook",
)

Verify every delivery with the bundled HMAC-SHA256 helper before acting on it:

import os
from bria_client.toolkit import verify_webhook_signature

def handle(request):  # any framework: use the raw body bytes and the three Bria-Webhook-* headers
    ok = verify_webhook_signature(
        payload=request.body,
        webhook_id=request.headers["Bria-Webhook-Id"],
        timestamp=request.headers["Bria-Webhook-Timestamp"],
        signature_header=request.headers["Bria-Webhook-Signature"],
        api_token=os.environ["BRIA_API_TOKEN"],
    )
    if not ok:
        return 401
    ...

See webhooks for the delivery contract, retries and a complete FastAPI receiver.

Video upload

Video endpoints take a hosted URL. client.upload() wraps the Video Upload Service: it requests a presigned upload, uploads the file, and returns a URL that stays valid for about 24 hours.

file_url = client.upload("path/to/video.mp4", media_type="video/mp4")

job = client.submit(endpoint="video/edit/remove_background", payload={"video": file_url})
result = client.poll(job, timeout=600)
print(result.result.video_url)

Treat the returned URL as a secret: anyone holding it can download the file.

Batch processing

Submit everything first, then poll:

from bria_client import BriaSyncClient
from bria_client.toolkit import Image

client = BriaSyncClient()
paths = ["sku-1.jpg", "sku-2.jpg", "sku-3.jpg"]

jobs = [
    client.submit(endpoint="image/edit/remove_background", payload={"image": Image(p).as_bria_api_input})
    for p in paths
]
results = [client.poll(job, timeout=120) for job in jobs]
for path, r in zip(paths, results):
    print(path, r.result.image_url)

With BriaAsyncClient, use asyncio.gather over client.run(...) calls for the same effect with a single event loop. Stay within your plan's rate limits.

Configuration reference

SettingConstructor argumentEnvironment variableDefault
API tokenapi_tokenBRIA_API_TOKENrequired
Base URLbase_urlBRIA_BASE_URLhttps://engine.prod.bria-api.com
Retriesretry (an httpx_retries.Retry)3 attempts, backoff factor 2

Contributions and bug reports are welcome on GitHub; the repository README covers the development setup.