Skip to main content

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:

  1. stream_type - Only StreamType.BIDIRECTIONAL is supported for now.
  2. remote_url - The remote websocket URL where the call audio stream needs to be bridged.
  3. call_stream_handler - A StreamHandler coroutine that handles the call audio stream.
  4. remote_stream_handler - A StreamHandler coroutine 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:

  1. 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.
  2. StreamOp.PASS - Does not relay any message to the other stream. Any message in the returned tuple will be ignored.
  3. 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


Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distribution

teler-0.1.0.tar.gz (4.7 kB view details)

Uploaded Source

Built Distribution

If you're not sure about the file name format, learn more about wheel file names.

teler-0.1.0-py3-none-any.whl (5.8 kB view details)

Uploaded Python 3

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

Hashes for teler-0.1.0.tar.gz
Algorithm Hash digest
SHA256 f8f2304f200b3ca18905dd36aa60734616aba2fce21f2b343b3c947ffd2c39d7
MD5 588c92265010f42bab8e85a8b6ea5e99
BLAKE2b-256 7595f349461d6577d9a586316d2b20df7bcfcdaf405f84ce6a9233d8a303d1dc

See more details on using hashes here.

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

Hashes for teler-0.1.0-py3-none-any.whl
Algorithm Hash digest
SHA256 f0b90a14eccbceaf29d8c78f4bd1e3a3fefeb44994c3fcc5ee0e629d1bb25efa
MD5 8960f6c87bee170f9dab9f9eb7a00a59
BLAKE2b-256 d88360dd572114a541b4bfa078930077c8e14537179fad19ff08d37b5abcd491

See more details on using hashes here.

Supported by

AWS Cloud computing and Security Sponsor Datadog Monitoring Depot Continuous Integration Fastly CDN Google Download Analytics Pingdom Monitoring Sentry Error logging StatusPage Status page