A helper library for FreJun Teler
Project description
Teler
This library offers a lightweight and developer-friendly abstraction over the FreJun Teler API.
Media Streaming
With the launch of the first minor version, the library introduces an intuitive interface for integrating real-time call audio streams from Teler into your application, unlocking advanced capabilities such as Conversational AI, Real-time transcription, and Actionable insights.
StreamConnector
This class lets you bridge the call audio stream to an endpoint of your choice. It handles the message relaying between the 2 streams via pluggable handlers, making it highly customizable. It also handles graceful shutdown of the media streams in case of any unexpected errors.
It takes the following 4 parameters:
- stream_type - Only
StreamType.BIDIRECTIONALis supported for now. - remote_url - The remote websocket URL where the call audio stream needs to be bridged.
- call_stream_handler - A
StreamHandlercoroutine that handles the call audio stream. - remote_stream_handler - A
StreamHandlercoroutine that handles the remote audio stream.
StreamHandler
A StreamHandler coroutine receives the incoming messages on the websocket, processes them and returns a tuple of (str, StreamOp). StreamOp is an operation flag that decides the subsequent action the StreamConnector will take.
StreamOp can be one of:
- StreamOp.RELAY - Relays the message to the other stream. The message needs to be supplied as a string as the first item in the returned tuple.
- StreamOp.PASS - Does not relay any message to the other stream. Any message in the returned tuple will be ignored.
- StreamOp.STOP - Stops both streams, ends the call and exits gracefully. Any message in the returned tuple will be ignored.
Sample Usage - FastAPI Echo Server
The following setup bridges the call audio stream to a dummy endpoint that echoes back all incoming messages. As a result, the caller will hear their own voice played back in real time, effectively creating an audio loopback.
import json
import logging
from fastapi import APIRouter, WebSocket, WebSocketDisconnect
from teler.streams import StreamConnector, StreamOp, StreamType
router = APIRouter()
logger = logging.getLogger(__name__)
TEST_WEBSOCKET_URL = "wss://{SERVER_DOMAIN}/test-remote-ws"
async def call_stream_handler(message: str):
msg = json.loads(message)
if msg["type"] == "audio":
payload = json.dumps(
{
"type": "audio",
"audio_b64": msg["data"]["audio_b64"],
"chunk_id": msg["message_id"],
}
)
return (payload, StreamOp.RELAY)
return ({}, StreamOp.PASS)
async def remote_stream_handler(message: str):
msg = json.loads(message)
if msg["type"] == "audio":
payload = json.dumps(
{
"type": "audio",
"audio_b64": msg["audio_b64"],
"chunk_id": msg["chunk_id"],
}
)
return (payload, StreamOp.RELAY)
return ({}, StreamOp.PASS)
connector = StreamConnector(
stream_type=StreamType.BIDIRECTIONAL,
remote_url=TEST_WEBSOCKET_URL,
call_stream_handler=call_stream_handler,
remote_stream_handler=remote_stream_handler,
)
@router.websocket("/media-stream")
async def handle_media_stream(websocket: WebSocket):
await websocket.accept()
logger.info("WebSocket connected.")
await connector.bridge_stream(websocket)
@router.websocket("/test-remote-ws")
async def test_remote_ws(websocket: WebSocket):
await websocket.accept()
logger.info("WebSocket connected.")
try:
async for data in websocket.iter_text():
await websocket.send_text(data)
except WebSocketDisconnect:
print("Client disconnected")
Project details
Release history Release notifications | RSS feed
Download files
Download the file for your platform. If you're not sure which to choose, learn more about installing packages.
Source Distribution
Built Distribution
Filter files by name, interpreter, ABI, and platform.
If you're not sure about the file name format, learn more about wheel file names.
Copy a direct link to the current filters
File details
Details for the file teler-0.1.0.tar.gz.
File metadata
- Download URL: teler-0.1.0.tar.gz
- Upload date:
- Size: 4.7 kB
- Tags: Source
- Uploaded using Trusted Publishing? No
- Uploaded via: twine/6.1.0 CPython/3.11.0
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
f8f2304f200b3ca18905dd36aa60734616aba2fce21f2b343b3c947ffd2c39d7
|
|
| MD5 |
588c92265010f42bab8e85a8b6ea5e99
|
|
| BLAKE2b-256 |
7595f349461d6577d9a586316d2b20df7bcfcdaf405f84ce6a9233d8a303d1dc
|
File details
Details for the file teler-0.1.0-py3-none-any.whl.
File metadata
- Download URL: teler-0.1.0-py3-none-any.whl
- Upload date:
- Size: 5.8 kB
- Tags: Python 3
- Uploaded using Trusted Publishing? No
- Uploaded via: twine/6.1.0 CPython/3.11.0
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
f0b90a14eccbceaf29d8c78f4bd1e3a3fefeb44994c3fcc5ee0e629d1bb25efa
|
|
| MD5 |
8960f6c87bee170f9dab9f9eb7a00a59
|
|
| BLAKE2b-256 |
d88360dd572114a541b4bfa078930077c8e14537179fad19ff08d37b5abcd491
|