Skip to main content

FlowCastle Python SDK

flowcastle is a protocol-v2 SDK with a framework-neutral core and optional thin adapters for aiogram 3.x and python-telegram-bot 21+.

pip install 'flowcastle[aiogram]'
# or
pip install 'flowcastle[python-telegram-bot]'

The package itself does not import either framework. Its adapters receive the framework update object, convert it to the Bot API JSON shape, and delegate all routing, privacy and FlowCastle HTTP work to FlowCastleCore.

from flowcastle import FlowCastleCore, FlowCastleOptions
from flowcastle.adapters.aiogram import AiogramAdapter

core = FlowCastleCore(FlowCastleOptions(api_key='fc_sdk_…', runtime_enabled=True))
adapter = AiogramAdapter(core)

# Run once before polling/webhook startup, then install the middleware.
await adapter.ready()
adapter.install(dispatcher)

For python-telegram-bot, install the adapter in an early handler group. Matched updates stop before customer handlers; unmatched updates continue normally with context.flowcastle available:

from flowcastle.adapters.python_telegram_bot import PythonTelegramBotAdapter

adapter = PythonTelegramBotAdapter(core)
await adapter.ready()
adapter.install(application)

Use code and no-code flows together

Keep framework-native commands and custom business logic in the Python bot, and build complementary onboarding, campaign, follow-up, or support automations in FlowCastle's no-code editor. Both kinds appear in the same Automation workspace:

  • Observed flows are read-only maps reconstructed from SDK traffic. They make code-owned behavior visible without pretending the canvas is its source of truth.
  • FlowCastle-authored flows are editable and deployable from the no-code editor. They can claim matching updates or be started explicitly with run_flow.

Unmatched updates continue through aiogram or python-telegram-bot normally, so one bot can use both models without a rewrite.

The installed framework middleware/handler starts background event delivery, continuous claim and manifest refresh, heartbeat, and leased job delivery as soon as it receives the framework Bot instance. If you call handle_update directly, start it explicitly with await adapter.start(bot). During graceful shutdown, call await adapter.stop().

Performance boundary

Ordinary commands, callbacks, and other unmatched updates do not wait for a FlowCastle network request. After local privacy filtering and manifest matching, the SDK places the observed event in a bounded in-memory queue and immediately continues to your framework handler. goal, identify, and request_live_agent use the same fire-and-forget queue even though their async method signatures remain unchanged for compatibility.

The queue holds at most 500 events, drops the oldest event if full, flushes every three seconds or at 20 events, and sends at most 50 events per request. A transient network or 5xx failure is retried once in the background and then dropped. This prevents FlowCastle availability from creating latency or unbounded memory growth in the host bot.

Two operations intentionally remain on the request path:

  • A manifest- or claim-matched update awaits FlowCastle ingestion because the flow owns that update and the SDK must not let the customer handler reply too. If the hand-off fails, its sanitized event enters a separate bounded runtime outage spool for replay; it does not fall through and risk a duplicate reply.
  • run_flow awaits server acceptance because its return value contains the new execution id.

Async privacy transformers are also awaited locally before enqueueing so raw content can never race past redaction. Call await adapter.flush() when a test or application checkpoint needs deterministic delivery. adapter.stop() performs a bounded final flush; configure shutdown_flush_timeout_ms to change its 2000 ms default. flush_interval_ms and max_batch_size default to 3000 and 20 respectively.

FlowCastleContext exposes async goal, identify, request_live_agent, and run_flow methods. run_flow is only available when runtime_enabled=True.

Privacy is fail-closed for transform failures/timeouts. Passing privacy={} uses routing-only content and no optional contact fields; omitting privacy retains full-content compatibility behavior. The runtime matches a local, server-supplied manifest and consumes matched/claimed updates. It only executes the documented Bot API allowlist; polling/webhook/token/lifecycle methods are permanently refused.

from flowcastle import PrivacyOptions

async def redact(context):
    return context['value'].replace('customer-secret', '[REDACTED]')

options = FlowCastleOptions(
    api_key='fc_sdk_…',
    runtime_enabled=True,
    privacy=PrivacyOptions(
        contact_fields=('username',),
        message_content='full',
        transform_text=redact,
        transform_timeout_ms=750,
    ),
)

Telegram user id and operational chat/update/message ids are always retained. Application-authored values passed to goal, identify, live-agent notes, or run_flow(inputs=...) are explicit developer inputs and are not transformed by the automatic Telegram privacy policy.

Runtime media jobs accept only inline $flowcastleFile markers containing a filename and validated base64 content, capped at 20 MiB. Each adapter converts the bytes to its framework-native upload type; no server-supplied filesystem path is opened and no arbitrary Bot method is invoked.

For testability, pass an AsyncHttpClient implementation to FlowCastleCore. The default client uses only the standard library (urllib) in a worker thread.

From the repository root, run all Python adapter tests with:

pnpm sdk:test:python
python3 -m mypy --config-file packages/sdk-python/pyproject.toml packages/sdk-python/src/flowcastle

Metadata

Release files for flowcastle 0.1.0

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

Source distribution (sdist)

Source distribution for flowcastle 0.1.0
File Size Uploaded
flowcastle-0.1.0.tar.gz 22.6 kB Details

Built distribution (wheel)

Table of built distributions (wheels) for flowcastle 0.1.0
File Interpreter ABI Platform
flowcastle-0.1.0-py3-none-any.whl Python 3 none any Details

Total release size: 44.2 kB

Release files / flowcastle-0.1.0.tar.gz

Download URL flowcastle-0.1.0.tar.gz
Size 22.6 kB
Tags Source
SHA-256 checksum
How to use checksums
995431aee08b9b9ebde47fcef3b7b770898c755bd2c6de911c87ed238244c314
BLAKE2b-256 checksum
How to use checksums
f4120155e9ba3d9dd8a529a7675220fa1496a6bcd49f79a15dddcf763bbd750a
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
No
Uploaded via uv/0.10.6 {"installer":{"name":"uv","version":"0.10.6","subcommand":["publish"]},"python":null,"implementation":{"name":null,"version":null},"distro":{"name":"macOS","version":null,"id":null,"libc":null},"system":{"name":null,"release":null},"cpu":null,"openssl_version":null,"setuptools_version":null,"rustc_version":null,"ci":null}

Release files / flowcastle-0.1.0-py3-none-any.whl

Download URL flowcastle-0.1.0-py3-none-any.whl
Size 21.6 kB
Tags Python 3
SHA-256 checksum
How to use checksums
e92c3a2713d501477606b3154e0a2bafcc2f6c04ef19694ff437642b965b7303
BLAKE2b-256 checksum
How to use checksums
01be1b79882aa7a59f54b450d215f8923d32552a3a556b7c6159b5fededcd4d5
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
No
Uploaded via uv/0.10.6 {"installer":{"name":"uv","version":"0.10.6","subcommand":["publish"]},"python":null,"implementation":{"name":null,"version":null},"distro":{"name":"macOS","version":null,"id":null,"libc":null},"system":{"name":null,"release":null},"cpu":null,"openssl_version":null,"setuptools_version":null,"rustc_version":null,"ci":null}

Release history Release notifications | RSS feed

This release

0.1.0 This release

2 release files

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