Skip to main content
Pre-release

This release is a pre-release and may not be stable for production use.

reflex-build-sdk

Python client for the Reflex Build API, with synchronous and asynchronous interfaces.

Install it with the HTTP library the client should send requests with:

pip install "reflex-build-sdk[httpx2]"   # ReflexBuild and AsyncReflexBuild
pip install "reflex-build-sdk[aiohttp]"  # AsyncReflexBuild only
pip install "reflex-build-sdk[httpx]"    # ReflexBuild and AsyncReflexBuild

Without any of them, pass the client a transport of your own.

from reflex_build_sdk import ReflexBuild

with ReflexBuild() as client:
    me = client.auth.me()
    print(me.email, me.tier)
from reflex_build_sdk import AsyncReflexBuild

async with AsyncReflexBuild() as client:
    me = await client.auth.me()

Apps and projects

from reflex_build_sdk import ReflexBuild

with ReflexBuild() as client:
    projects = client.projects.search("default")
    project = projects[0] if projects else client.projects.create("default")
    app = client.apps.create("dashboard", project_id=project.id)
    client.apps.secrets.set(app.id, {"OPENAI_API_KEY": "sk-..."})

    for deployment in client.apps.history(app.id):
        print(deployment.status, deployment.url)

    for record in client.apps.logs(app.id, search="error"):
        print(record.timestamp, record.message)

client.apps lists, creates, renames, moves, starts, stops, pauses, scales, rolls back and deletes apps, changes their settings, and reads their status, running deployment, deployment history and runtime logs; client.apps.secrets manages their secrets. client.projects lists, searches, creates, renames and deletes projects and reads their audit logs, with projects.roles (including custom roles), projects.members and projects.teams for access control. AsyncReflexBuild has the same methods as coroutines, with logs as an async iterator.

Custom domains

for record in client.apps.domains.add(app.id, "app.example.com").values():
    print(record.type, record.name, record.value)

domain = client.apps.domains.get(app.id)
print(domain.status, domain.status_detail)

domains.add returns the DNS records to create, and domains.get checks them and reports whether the domain is ready to serve the app. Custom domains need the Pro or Enterprise plan.

Deploying

from reflex_build_sdk import DeploymentFailedError, ReflexBuild

with ReflexBuild() as client:
    urls = client.apps.reserve_hostname(app.id, app.name)
    # Export the app against urls.frontend_url and urls.backend_url, e.g. with
    # `reflex export`, producing backend.zip and frontend.zip.
    deployment_id = client.deployments.create(
        app.id,
        backend="backend.zip",
        frontend="frontend.zip",
        regions={"sjc": 1},
        on_upload_progress=lambda sent, total: print(f"{sent}/{total} bytes"),
    )
    try:
        report = client.deployments.wait(deployment_id, on_status=print, timeout=900)
    except DeploymentFailedError as error:
        print(error.report.reason, error.report.guidance)
        print(error.report.build_log_excerpt)
        raise

deployments.create streams the archives straight to storage, then submits the deployment. deployments.wait returns the deployment's report once it is running, or awaiting approval (report.status == "AwaitingApproval"), and raises DeploymentFailedError if it fails. deployments.status, report and build_logs read a deployment's progress, and regions and vm_types list what can be deployed to.

Environments

Give an app a pipeline of a dev and a production environment:

pipeline = client.apps.environments.enable(app.id)
production_id = pipeline.production_environment_id

An app that has a pipeline already is read rather than enabled again, which fails:

dev, production = client.apps.environments.list(app.id)
production_id = production.id

Deployments go to the first environment, and later ones run a version promoted from the one before:

deployment_id = client.deployments.create(
    app.id, backend="backend.zip", frontend="frontend.zip"
)
client.deployments.wait(deployment_id)
promotion = client.apps.environments.promote(app.id, production_id)
client.deployments.wait(promotion.deployment_id)

Each environment has its own secrets and URL, and production keeps the app's own id and history. environments.create, update, reorder, copy_missing_secrets and delete manage the rest of the pipeline. Pipelines need the Enterprise plan.

Managed database

database = client.apps.database.create(app.id)
print(database.masked_connection_string)

client.apps.database creates a Postgres database for an app, shared by all of its environments, and sets its connection strings as secrets, DATABASE_URL among them, which each environment picks up on its next deployment. Creating or deleting a database needs a token with full access, which reflex login tokens are not, and an app with its own DATABASE_URL secret is refused.

Signing users in

client.apps.sign_in.enable(app.id)
client.apps.sign_in.set_audience(app.id, "invited")
client.apps.sign_in.invite(app.id, "someone@example.com")

client.apps.sign_in lets an app's users sign in with their Reflex accounts, through rxe.AuthPlugin from reflex-enterprise. It sets the app's sign-in settings as secrets, which take effect when the app is next deployed with rxe.AuthPlugin, chooses who may sign in, and lists, exports and blocks the app's users. Restricting who may sign in and inviting addresses need the Pro or Enterprise plan. Changing sign-in needs a token with full access; tokens from reflex login are refused.

Third-party connections

# Inside a deployed app, which is started with its own access token.
with ReflexBuild() as client:
    token = client.apps.connections.credential(app_id, "openai").access_token
    # ... and for one of the app's users:
    token = client.apps.connections.credential(
        app_id, "openai", end_user=user_id
    ).access_token

client.apps.connections calls third-party services an app is connected to without the app holding their keys: Reflex Build stores the credentials and hands out a live one per call, so read one for each call rather than storing it. connect_link starts a connection and returns the page to send someone to, status and list report what is connected, and disconnect ends it. A connection belongs either to the app or to one of its users, named with end_user. These need the app's own token, so a client built with no arguments inside a deployed app is already the right one.

Authentication

The client uses the token argument, or the REFLEX_ACCESS_TOKEN environment variable when none is passed.

To log in through the browser:

import webbrowser

from reflex_build_sdk import ReflexBuild

with ReflexBuild() as client:
    login = client.auth.begin_login()
    print(f"Approve the login at {login.url}")
    webbrowser.open(login.url)
    token = client.auth.finish_login(login, timeout=600)

with ReflexBuild(token=token) as client:
    print(client.auth.me().email)

client.auth.tokens.revoke_self() revokes the client's own token, which any token may do. Create a token for CI with client.auth.tokens.create("ci", expires_in_days=30), whose .token holds the value, and rotate or revoke one with client.auth.tokens.refresh(token), whose .token holds the new value, and client.auth.tokens.revoke(token). If a refresh answers previous_revoked=False, the old token is still live and needs revoking. Managing other tokens needs a token with full access, which reflex login tokens are not.

client.usage.balance() reports how much of the organization's plan allowance is used, and client.usage.history() iterates over its charges and credits.

Pointing at another deployment

The client sends its requests to https://build.reflex.dev, or to the base_url argument, the REFLEX_BUILD_BACKEND_URL environment variable or REFLEX_CLOUD_BACKEND_URL, in that order. begin_login builds its approval URL the same way, from ui_url, REFLEX_BUILD_URL or REFLEX_CLOUD_URL, and falls back to the client's base_url. reflex-hosting-cli reads only the REFLEX_CLOUD_* names, so set those too for reflex deploy to reach the same deployment.

Security reviews

review_id = client.security_reviews.submit("source.zip")
result = client.security_reviews.wait(review_id, timeout=600)
for violation in result.violations:
    print(violation.severity, violation.file_path, violation.line, violation.message)

Security reviews need the Pro or Enterprise plan.

Google Cloud

Apps can run on an organization's own Google Cloud instead of Reflex Build:

status = client.providers.gcp_status(client.auth.me().org_id)
if status.configured and status.allowed:
    client.apps.set_provider(app.id, "gcp")
    client.apps.set_instance_bounds(app.id, min_instances=1, max_instances=10)

Running on Google Cloud needs the Enterprise plan. client.apps.set_full_deploy also serves an app's frontend from Google Cloud, and client.providers.cloud_run_manifest() returns the Dockerfile and script to deploy to Cloud Run yourself.

Organization admins connect Google Cloud projects with a service account key:

with open("key.json") as key_file:
    client.providers.connect_gcp(
        client.auth.me().org_id,
        service_account_key=key_file.read(),
        project_number="123456789012",
        region="us-central1",
    )

client.providers.gcp_connections adds, updates, verifies and removes further projects, rotates their keys and chooses the default, and client.providers.disconnect_gcp removes them all. These need a token with full access.

Errors

Every exception derives from reflex_build_sdk.ReflexBuildError. Error responses raise a subclass of APIStatusError matching the status code (AuthenticationError, NotFoundError, ...), carrying status_code, the server's detail, the code naming the condition where the API names one (e.g. "not_connected"), and the request_id to quote to support. Failed requests are retried up to max_retries times when repeating them cannot apply them twice: requests that never reached the server or were turned away with 408 or 429, and requests that are harmless to repeat (GET, HEAD, OPTIONS and PUT requests, and calls such as apps.environments.update that settle on the same result) that timed out, lost their connection, or got a 500, 502, 503 or 504 response.

Transports

AsyncReflexBuild sends requests with the first installed of aiohttp, httpx2 and httpx, and ReflexBuild with httpx2, or httpx if httpx2 is not installed. Pass a transport from reflex_build_sdk.transports to configure the HTTP client, e.g. for proxies, or to pick the HTTP library:

import aiohttp
import httpx2
from reflex_build_sdk import AsyncReflexBuild, ReflexBuild
from reflex_build_sdk.transports import (
    AiohttpTransport,
    AsyncHttpx2Transport,
    Httpx2Transport,
)

# Reads HTTP_PROXY, HTTPS_PROXY and NO_PROXY from the environment.
async with aiohttp.ClientSession(trust_env=True) as session:
    async with AsyncReflexBuild(transport=AiohttpTransport(session)) as client:
        ...

client = AsyncReflexBuild(transport=AsyncHttpx2Transport())
client = ReflexBuild(
    transport=Httpx2Transport(httpx2.Client(proxy="http://proxy:8080"))
)

To use another HTTP library, implement the Transport or AsyncTransport protocol.

To wrap the synchronous SDK's default transport without choosing an HTTP library, call reflex_build_sdk.transports.default_transport(). It selects httpx2 when installed, otherwise httpx. Close the returned transport when finished; clients leave explicitly supplied transports open.

Metadata

Release files for reflex-build-sdk 0.1.1a1

For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.

Source distribution (sdist)

Source distribution for reflex-build-sdk 0.1.1a1
File Size Uploaded Provenance
reflex_build_sdk-0.1.1a1.tar.gz 87.0 kB Without provenance Details

Built distribution (wheel)

Table of built distributions (wheels) for reflex-build-sdk 0.1.1a1
File Interpreter ABI Platform
reflex_build_sdk-0.1.1a1-py3-none-any.whl Python 3 none any Details

Total release size: 199.1 kB

Release files / reflex_build_sdk-0.1.1a1.tar.gz

Download URL reflex_build_sdk-0.1.1a1.tar.gz
Size 87.0 kB
Tags Source
SHA-256 checksum
How to use checksums
85bb6a141747b935fed7e3eee2ecb0199d4f837830e3942b0f6dc2b584b85e40
BLAKE2b-256 checksum
How to use checksums
f2907eb0410c30e29d95a291f29fcc64d85eaa46d38ace751e2d7c32793b74e1
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
Yes
Uploaded via uv/0.12.5 {"installer":{"name":"uv","version":"0.12.5","subcommand":["publish"]},"python":null,"implementation":{"name":null,"version":null},"distro":{"name":"Ubuntu","version":"24.04","id":"noble","libc":null},"system":{"name":null,"release":null},"cpu":null,"openssl_version":null,"setuptools_version":null,"rustc_version":null,"ci":true}

Release files / reflex_build_sdk-0.1.1a1-py3-none-any.whl

Download URL reflex_build_sdk-0.1.1a1-py3-none-any.whl
Size 112.0 kB
Tags Python 3
SHA-256 checksum
How to use checksums
1589c805fa0231e9572f781b2a26f8035b1881691f95df6ccc1b0478f460ce1f
BLAKE2b-256 checksum
How to use checksums
c0ecfbbda8b64c0074fa057fdd19bb05b324b7d7578a1ed0e264ef6fc8f69ebf
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
Yes
Uploaded via uv/0.12.5 {"installer":{"name":"uv","version":"0.12.5","subcommand":["publish"]},"python":null,"implementation":{"name":null,"version":null},"distro":{"name":"Ubuntu","version":"24.04","id":"noble","libc":null},"system":{"name":null,"release":null},"cpu":null,"openssl_version":null,"setuptools_version":null,"rustc_version":null,"ci":true}

Security for reflex-build-sdk 0.1.1a1

Provenance

Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.

No provenance found

None of the files in this release were uploaded with provenance metadata.

A note on package security

PyPI is a repository for distributing packages, not a service for auditing them. While third-party security researchers and our staff do their best to detect and remove malicious packages, PyPI cannot guarantee the quality, security or suitability of any given package.

To learn more about protecting yourself from malicious actors, visit our package security documentation.

Anthropic, PBC Visionary sponsor Bloomberg Visionary sponsor Hudson River Trading Visionary sponsor Meta Visionary sponsor NVIDIA Visionary sponsor Microsoft Sustainability sponsor Depot Continuous Integration AWS Cloud computing and Security Sponsor Datadog Monitoring Fastly CDN Google Download Analytics Sentry Error logging StatusPage Status page