Skip to main content

siphon-control (Python)

Python client for the SIPhon external control plane (siphon-control.v1) — an ARI/ESL-class rail for driving handed-over calls out of process. Built with PyO3 over the async Rust client, so the wire is hidden: no manual JSON, no request-id bookkeeping.

Two connection modes

The plane runs in one of two modes; both are exposed here and share the SAME @on_call decorator and the SAME Call handle — only the transport differs.

  • Inbound-persistent (ControlClient) — the app dials siphon and holds one long-lived socket (does the hello handshake). Simplest to reason about; use it for development and single-process controllers.
  • Per-call-connect (ControlServer) — siphon dials the app per handed-over call, so the app is a WebSocket server. Each accepted connection owns exactly one call and the first frame is a pushed StasisStart (no hello). This is the documented production default for multi-pod controllers: because the accepting socket is the call, "the audio lands on the wrong pod" can't happen.

Inbound-persistent

import asyncio
from siphon_control import ControlClient, ControlError

client = ControlClient(app="ivr-app", token="s3cr3t",
                       url="ws://siphon:9090/control/ws")

@client.on_call
async def handle(call):
    await call.answer()
    try:
        await call.transfer("sip:agent@pbx")   # REFER, awaits correlated reply
    except ControlError as error:
        print("transfer rejected:", error.code)

async def main():
    async with client:          # closes on the way out — see Shutdown below
        await client.run()

asyncio.run(main())

Per-call-connect

import asyncio
from siphon_control import ControlServer, ControlError

server = ControlServer(app="ivr-app", token="s3cr3t", bind="0.0.0.0:8790")

@server.on_call
async def handle(call):
    await call.answer()
    try:
        await call.transfer("sip:agent@pbx")
    except ControlError as error:
        print("transfer rejected:", error.code)

async def main():
    async with server:
        await server.serve()

asyncio.run(main())

Shutdown

Both classes are async context managers, and async with is the recommended shape. close() is the same thing explicitly.

It matters more than it looks. run() / serve() are driven by a background tokio task, and every handed-over call is dispatched from another one. Nothing joins those tasks and the runtime outlives the interpreter, so an app that finishes without closing leaves them delivering results into an asyncio loop — and then into a Python — that is no longer there. Closing first means there is nothing in flight to strand.

Not closing is handled rather than fatal: a handover arriving after the loop or interpreter has gone is dropped, and a handler cancelled during teardown is not reported as a failure. That is damage control, not a substitute for closing.

API

ControlClient (inbound-persistent)

  • ControlClient(app, token, url=…, protocol=1, reply_timeout_ms=…, reconnect_backoff_ms=…)
  • @client.on_call — register an async (or sync) per-call handler.
  • await client.connect() / await client.run() — connect / drive (reconnect + resync).
  • await client.command(verb, module=None, target=None, args=None) — the generic {module, verb, target, args} primitive for any adapter (SIP today; SMPP/SS7 later).
  • await client.describe() — adapter schema.
  • client.shutdown() — stop the client and unblock run().
  • client.close() — shutdown, plus drop the handler so nothing else is dispatched. async with client: does this on the way out. See Shutdown above.

ControlServer (per-call-connect)

  • ControlServer(app, token, bind="0.0.0.0:8790", reply_timeout_ms=…) — bind is the address the app listens on for siphon to dial; the token is validated on the incoming upgrade.
  • @server.on_call — the SAME decorator + Call handle as ControlClient.
  • await server.bind() — bind the listener; resolves to the bound address string (bind to …:0 to learn the ephemeral port before siphon dials in).
  • server.local_addr — the bound address once bind() / serve() has run, else None.
  • await server.serve() / await server.run() — accept siphon's per-call dials forever (stop by cancelling the task).
  • server.close() — drop the handler so no further accepted call is dispatched. async with server: does this on the way out. See Shutdown above.

Call (shared by both modes)

  • Call verbs: answer(), answer_with(code, …), progress(), reject(code, reason), hangup(reason=None), refer(to) / transfer(to), set_header(name, value), get_header(name), set_var(key, value), get_var(key), command(verb, args=None), next_event().
  • Media verbs play_file(file) / dtmf(digits) raise ControlError with code == "unsupported_verb" until the server implements media.

Errors

A rejected command raises ControlError carrying a stable .code (not_found, forbidden, unsupported_verb, unauthorized, …).

Build

maturin develop        # into the active venv
maturin build --release

The target interpreter is free-threaded CPython 3.14t (the SIPhon runtime); the wheel also loads on a standard GIL build.

License

MIT

Release files for siphon-control 0.1.3

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

Source distribution (sdist)

Source distribution for siphon-control 0.1.3
File Size Uploaded
siphon_control-0.1.3.tar.gz 81.3 kB Details

Built distributions (wheels)

Table of built distributions (wheels) for siphon-control 0.1.3
File
siphon_control-0.1.3-cp314-cp314t-win_amd64.whl CPython 3.14 CPython 3.14 free-threading Windows x86-64 Details
siphon_control-0.1.3-cp314-cp314t-manylinux_2_17_x86_64.manylinux2014_x86_64.whl CPython 3.14 CPython 3.14 free-threading Linux glibc 2.17+ x86-64 Details
siphon_control-0.1.3-cp314-cp314t-manylinux_2_17_aarch64.manylinux2014_aarch64.whl CPython 3.14 CPython 3.14 free-threading Linux glibc 2.17+ ARM64 Details
siphon_control-0.1.3-cp314-cp314t-macosx_11_0_arm64.whl CPython 3.14 CPython 3.14 free-threading macOS 11.0+ ARM64 Details
siphon_control-0.1.3-cp314-cp314-win_amd64.whl CPython 3.14 CPython 3.14 Windows x86-64 Details
siphon_control-0.1.3-cp314-cp314-manylinux_2_17_x86_64.manylinux2014_x86_64.whl CPython 3.14 CPython 3.14 Linux glibc 2.17+ x86-64 Details
siphon_control-0.1.3-cp314-cp314-manylinux_2_17_aarch64.manylinux2014_aarch64.whl CPython 3.14 CPython 3.14 Linux glibc 2.17+ ARM64 Details
siphon_control-0.1.3-cp314-cp314-macosx_11_0_arm64.whl CPython 3.14 CPython 3.14 macOS 11.0+ ARM64 Details

Total release size: 15.2 MB

Release files / siphon_control-0.1.3.tar.gz

Download URL siphon_control-0.1.3.tar.gz
Size 81.3 kB
Tags Source
SHA-256 checksum
How to use checksums
17dc0df6d9a8a9695ae79fdc5bba4f320c1b2d249b5db0efccd90c70a92a80e1
BLAKE2b-256 checksum
How to use checksums
bc33a661b96518a91f7073fa7be5c5c4dd4564ec3468a2d7d5c6632148aa52c0
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
Yes
Uploaded via twine/7.0.0 CPython/3.13.14

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.

PyPI Publish Attestation

PyPI verified that this artifact, at this checksum, originated from the publisher listed below.

Signed by GitHub Actions, verified by PyPI on Sep 7, 2026.

Transparency log

Release files / siphon_control-0.1.3-cp314-cp314t-win_amd64.whl

Download URL siphon_control-0.1.3-cp314-cp314t-win_amd64.whl
Size 1.7 MB
Tags CPython 3.14 CPython 3.14 free-threading Windows x86-64
SHA-256 checksum
How to use checksums
b75e753f56228fc2d0c508c3083c49bdd57bef176029e056ee620d6bcd6814e2
BLAKE2b-256 checksum
How to use checksums
2a7fe5f8b1b56ca0853364366cfdeb3104748d567fc0732432247226e089ce1f
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
Yes
Uploaded via twine/7.0.0 CPython/3.13.14

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.

PyPI Publish Attestation

PyPI verified that this artifact, at this checksum, originated from the publisher listed below.

Signed by GitHub Actions, verified by PyPI on Sep 7, 2026.

Transparency log

Release files / siphon_control-0.1.3-cp314-cp314t-manylinux_2_17_x86_64.manylinux2014_x86_64.whl

Download URL siphon_control-0.1.3-cp314-cp314t-manylinux_2_17_x86_64.manylinux2014_x86_64.whl
Size 1.9 MB
Tags CPython 3.14 CPython 3.14 free-threading Linux glibc 2.17+ x86-64
SHA-256 checksum
How to use checksums
140a3222def8922a3b8ae573d24c349b881b2874e2bc4adba70796342a3d7dad
BLAKE2b-256 checksum
How to use checksums
4b92cbbddbe7499c088911dc5843091ce98bd1de79e1c50fa1572a73fd3831bd
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
Yes
Uploaded via twine/7.0.0 CPython/3.13.14

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.

PyPI Publish Attestation

PyPI verified that this artifact, at this checksum, originated from the publisher listed below.

Signed by GitHub Actions, verified by PyPI on Sep 7, 2026.

Transparency log

Release files / siphon_control-0.1.3-cp314-cp314t-manylinux_2_17_aarch64.manylinux2014_aarch64.whl

Download URL siphon_control-0.1.3-cp314-cp314t-manylinux_2_17_aarch64.manylinux2014_aarch64.whl
Size 2.1 MB
Tags CPython 3.14 CPython 3.14 free-threading Linux glibc 2.17+ ARM64
SHA-256 checksum
How to use checksums
8954e0f9972c95bcca9da937f335bab857a1a6a1f2fef626fa227abdc7a0edc5
BLAKE2b-256 checksum
How to use checksums
4df349ac29398d7ac6a8dae5aee3b3b455fca32e286e8cd563abd7e24a04b802
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
Yes
Uploaded via twine/7.0.0 CPython/3.13.14

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.

PyPI Publish Attestation

PyPI verified that this artifact, at this checksum, originated from the publisher listed below.

Signed by GitHub Actions, verified by PyPI on Sep 7, 2026.

Transparency log

Release files / siphon_control-0.1.3-cp314-cp314t-macosx_11_0_arm64.whl

Download URL siphon_control-0.1.3-cp314-cp314t-macosx_11_0_arm64.whl
Size 1.8 MB
Tags CPython 3.14 CPython 3.14 free-threading macOS 11.0+ ARM64
SHA-256 checksum
How to use checksums
fa34949bfdd8679a1d50caf4b6ad21d0368742c63d56a719a313d2d5bd7b1c53
BLAKE2b-256 checksum
How to use checksums
2d17130d34396e7cd820a062e1ea94c118abc0c8f682add93912be9daa0bfd77
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
Yes
Uploaded via twine/7.0.0 CPython/3.13.14

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.

PyPI Publish Attestation

PyPI verified that this artifact, at this checksum, originated from the publisher listed below.

Signed by GitHub Actions, verified by PyPI on Sep 7, 2026.

Transparency log

Release files / siphon_control-0.1.3-cp314-cp314-win_amd64.whl

Download URL siphon_control-0.1.3-cp314-cp314-win_amd64.whl
Size 1.7 MB
Tags CPython 3.14 Windows x86-64
SHA-256 checksum
How to use checksums
79ca2b692e3266631fe974e1a2cb4bcf1944bcd66918654f94865ba1f4b07277
BLAKE2b-256 checksum
How to use checksums
5d00a9b95c2935a92a9f34284fabfb8e37d099e3a12aa5e605440cfd73b4d3b9
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
Yes
Uploaded via twine/7.0.0 CPython/3.13.14

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.

PyPI Publish Attestation

PyPI verified that this artifact, at this checksum, originated from the publisher listed below.

Signed by GitHub Actions, verified by PyPI on Sep 7, 2026.

Transparency log

Release files / siphon_control-0.1.3-cp314-cp314-manylinux_2_17_x86_64.manylinux2014_x86_64.whl

Download URL siphon_control-0.1.3-cp314-cp314-manylinux_2_17_x86_64.manylinux2014_x86_64.whl
Size 1.9 MB
Tags CPython 3.14 Linux glibc 2.17+ x86-64
SHA-256 checksum
How to use checksums
cc354627be8ce755f70e3ea2458b21d85f386bb9e02a877fe75a46f34f5077e6
BLAKE2b-256 checksum
How to use checksums
270198e4312cb1a3ceb976f244415791090fade9a582a1701d597ef8299a5af5
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
Yes
Uploaded via twine/7.0.0 CPython/3.13.14

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.

PyPI Publish Attestation

PyPI verified that this artifact, at this checksum, originated from the publisher listed below.

Signed by GitHub Actions, verified by PyPI on Sep 7, 2026.

Transparency log

Release files / siphon_control-0.1.3-cp314-cp314-manylinux_2_17_aarch64.manylinux2014_aarch64.whl

Download URL siphon_control-0.1.3-cp314-cp314-manylinux_2_17_aarch64.manylinux2014_aarch64.whl
Size 2.1 MB
Tags CPython 3.14 Linux glibc 2.17+ ARM64
SHA-256 checksum
How to use checksums
cb16040296ea1a6d89dee782017c6ca18a7b4f8faeb3245f9d030dcca29e53c8
BLAKE2b-256 checksum
How to use checksums
7aaaf78253f12662db717d0a8020b9d7d6a12b91240051a3ee5c04656819a7f3
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
Yes
Uploaded via twine/7.0.0 CPython/3.13.14

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.

PyPI Publish Attestation

PyPI verified that this artifact, at this checksum, originated from the publisher listed below.

Signed by GitHub Actions, verified by PyPI on Sep 7, 2026.

Transparency log

Release files / siphon_control-0.1.3-cp314-cp314-macosx_11_0_arm64.whl

Download URL siphon_control-0.1.3-cp314-cp314-macosx_11_0_arm64.whl
Size 1.8 MB
Tags CPython 3.14 macOS 11.0+ ARM64
SHA-256 checksum
How to use checksums
7e24b5e740402a8119112f7383f5d821b5fddec21db504f53d9d151cb1b035f9
BLAKE2b-256 checksum
How to use checksums
1a4067f5d3cc01d72f62586bdf9ad7e9ba82d826decd75309eb638acd21cf809
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
Yes
Uploaded via twine/7.0.0 CPython/3.13.14

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.

PyPI Publish Attestation

PyPI verified that this artifact, at this checksum, originated from the publisher listed below.

Signed by GitHub Actions, verified by PyPI on Sep 7, 2026.

Transparency log

Release history Release notifications | RSS feed

0.5.0

9 release files

0.4.0

9 release files

0.3.0

9 release files

0.2.0

9 release files

This release

0.1.3 This release

9 release files

0.1.2

9 release files

0.1.1

9 release files

0.1.0

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