RELAY SDK for Python

View as Markdown

The RELAY v4 is the most up-to-date version of the Realtime RELAY SDK. Consider upgrading to take advantage of the latest features and improvements.

About RELAY Realtime SDK v2

The SignalWire Realtime SDK v2 provides multi-language support for building real-time communication applications with persistent WebSocket connections.

Capabilities

  • Voice (Calling): Make and receive calls, control call flow, play audio, record calls, detect answering machines, and implement complex IVR systems
  • Messaging: Send and receive SMS/MMS messages with delivery tracking and media support
  • Tasking: Queue and process background jobs with reliable delivery

SDK Components

The SDK provides three components for connecting to RELAY:

  • Consumer: Long-running process for handling incoming events. Recommended for most use cases.
  • Task: Queue jobs for Consumers from short-lived processes (e.g., web requests). Useful when you can’t maintain a persistent connection.
  • Client: Lower-level connection for outbound-only scripts or when you need custom control over the connection.

Contexts

RELAY uses Contexts to route events to specific consumers. A context is a named string that categorizes requests, allowing you to:

  • Write consumers for specific types of calls or messages
  • Scale different workloads independently
  • Separate traffic based on business rules

For example, configure a support phone number with the support context and a personal number with personal context. RELAY delivers events only to consumers listening for those contexts.

Getting Started

The RELAY SDK for Python enables developers to connect and use SignalWire’s RELAY APIs within their own Python code.

Installation

Install the package using either pip or pipenv:

Using pip:

$pip install signalwire

Using pipenv:

$pipenv install signalwire

Minimum Requirements

The Python SDK is build on top of asyncio and requires at least Python 3.6 to be run.
We suggest to use Python 3.7 or above.

Using the SDK

To use the SDK, you need your project and token from your SignalWire dashboard.

RELAY Consumer

A Relay.Consumer creates a long running process, allowing you to respond to incoming requests and events in realtime. RELAY Consumers abstract all the setup of connecting to RELAY and automatically dispatches workers to handle requests; so you can concentrate on writing your code without having to worry about multi-threading or blocking, everything just works. Think of RELAY Consumers like a background worker system for all your calling and messaging needs.

RELAY Consumers can scale easily, simply by running multiple instances of your Relay.Consumer process. Each event will only be delivered to a single consumer, so as your volume increases, just scale up! This process works well whether you are using Docker Swarm, a Procfile on Heroku, your own webserver, and most other environments.

Setting up a new consumer is the easiest way to get up and running:

1from signalwire.relay.consumer import Consumer
2
3class CustomConsumer(Consumer):
4 def setup(self):
5 self.project = 'XXXXXXXX-XXXX-XXXX-XXXX-XXXXXXXXXXXX'
6 self.token = 'PTXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX'
7 self.contexts = ['home', 'office']
8
9 async def ready(self):
10 # Consumer is successfully connected with Relay.
11 # You can make calls or send messages here..
12
13 async def on_incoming_call(self, call):
14 result = await call.answer()
15 if result.successful:
16 print('Call answered..')
17
18# Run your consumer..
19consumer = CustomConsumer()
20consumer.run()

Learn more about RELAY Consumers

RELAY Task

A Relay.Task is simple way to send jobs to your Relay.Consumers from a short lived process, like a web framework. RELAY Tasks allow you to pass commands down to your Consumers without blocking your short lived request. Think of a RELAY Task as a way to queue a job for your background workers to processes asynchronously.

For example, if you wanted to make an outbound call and play a message when your user clicks a button on your web application, since RELAY is a realtime protocol and relies on you to tell it what to do in realtime, if you did this within your web application, your web server would block until the call was finished… this may take a long time! Instead, simply create a new RELAY Task. This task will be handled by a running RELAY Consumer process and your web application can respond back to your user immediately.

Send a task in the office context with custom data:

1# create-task.py
2from signalwire.relay.task import Task
3
4project = 'XXXXXXXX-XXXX-XXXX-XXXX-XXXXXXXXXXXX'
5token = 'PTXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX'
6task = Task(project=project, token=token)
7success = task.deliver('office', {
8 'uuid': 'unique id',
9 'data': 'data for your job'
10})
11if success:
12 print('Task delivered')
13else:
14 print('Error delivering task..')

Handle the task in a Consumer:

1# consumer-task.py
2from signalwire.relay.consumer import Consumer
3
4class CustomConsumer(Consumer):
5 def setup(self):
6 self.project = 'XXXXXXXX-XXXX-XXXX-XXXX-XXXXXXXXXXXX'
7 self.token = 'PTXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX'
8 self.contexts = ['office']
9
10 async def on_task(self, message):
11 print('Handle inbound task')
12 print(message['uuid']) # => 'unique id'
13 print(message['data']) # => 'data for your job'
14
15consumer = CustomConsumer()
16consumer.run()

Learn more about RELAY Tasks

RELAY Client

Relay.Client is a lower level object, giving you a basic connection to RELAY but that is all. It is best used when you are creating a script only concerned with sending outbound requests or you want complete control over the RELAY connection yourself.

Setting up a new client and make an outbound call:

1from signalwire.relay.client import Client
2
3async def ready(client):
4 call = client.calling.new_call(from_number='+1XXXXXXXXXX', to_number='+1YYYYYYYYYY')
5 result = await call.dial()
6 if result.successful:
7 print('Your call has been answered..')
8
9project = 'XXXXXXXX-XXXX-XXXX-XXXX-XXXXXXXXXXXX'
10token = 'PTXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX'
11client = Client(project=project, token=token)
12client.on('ready', ready)
13client.connect()

Learn more about RELAY Clients