diff --git a/backend/gradio_webrtc/__init__.py b/backend/gradio_webrtc/__init__.py index 806216e..edb1140 100644 --- a/backend/gradio_webrtc/__init__.py +++ b/backend/gradio_webrtc/__init__.py @@ -1,6 +1,20 @@ -from .reply_on_pause import ReplyOnPause, AlgoOptions, SileroVadOptions +from .credentials import ( + get_hf_turn_credentials, + get_turn_credentials, + get_twilio_turn_credentials, +) +from .reply_on_pause import AlgoOptions, ReplyOnPause, SileroVadOptions from .utils import AdditionalOutputs from .webrtc import StreamHandler, WebRTC -__all__ = ["AlgoOptions", "AdditionalOutputs", "ReplyOnPause", - "SileroVadOptions", "StreamHandler", "WebRTC"] +__all__ = [ + "AlgoOptions", + "AdditionalOutputs", + "get_hf_turn_credentials", + "get_twilio_turn_credentials", + "get_turn_credentials", + "ReplyOnPause", + "SileroVadOptions", + "StreamHandler", + "WebRTC", +] diff --git a/backend/gradio_webrtc/credentials.py b/backend/gradio_webrtc/credentials.py new file mode 100644 index 0000000..ea5e83a --- /dev/null +++ b/backend/gradio_webrtc/credentials.py @@ -0,0 +1,52 @@ +import os +from typing import Literal + +import requests + + +def get_hf_turn_credentials(token=None): + if token is None: + token = os.getenv("HF_TOKEN") + credentials = requests.get( + "https://freddyaboulton-turn-server-login.hf.space/credentials", + headers={"X-HF-Access-Token": token}, + ) + if not credentials.status_code == 200: + raise ValueError("Failed to get credentials from HF turn server") + return { + "iceServers": [ + { + "urls": "turn:gradio-turn.com:80", + **credentials.json(), + }, + ] + } + + +def get_twilio_turn_credentials(twilio_sid=None, twilio_token=None): + try: + from twilio.rest import Client + except ImportError: + raise ImportError("Please install twilio with `pip install twilio`") + + if not twilio_sid and not twilio_token: + twilio_sid = os.environ.get("TWILIO_ACCOUNT_SID") + twilio_token = os.environ.get("TWILIO_AUTH_TOKEN") + + client = Client(twilio_sid, twilio_token) + + token = client.tokens.create() + + return { + "iceServers": token.ice_servers, + "iceTransportPolicy": "relay", + } + + +def get_turn_credentials(method: Literal["hf", "twilio"] = "hf", **kwargs): + if method == "hf": + return get_hf_turn_credentials(**kwargs) + elif method == "twilio": + return get_twilio_turn_credentials(**kwargs) + else: + raise ValueError("Invalid method. Must be 'hf' or 'twilio'") diff --git a/backend/gradio_webrtc/reply_on_pause.py b/backend/gradio_webrtc/reply_on_pause.py index bc23111..3146230 100644 --- a/backend/gradio_webrtc/reply_on_pause.py +++ b/backend/gradio_webrtc/reply_on_pause.py @@ -1,10 +1,10 @@ +import asyncio +import inspect from dataclasses import dataclass from functools import lru_cache from logging import getLogger from threading import Event -import inspect from typing import Any, Callable, Generator, Literal, Union, cast -import asyncio import numpy as np diff --git a/docs/deployment.md b/docs/deployment.md index f87899b..2ab85b9 100644 --- a/docs/deployment.md +++ b/docs/deployment.md @@ -1,5 +1,36 @@ When deploying in a cloud environment (like Hugging Face Spaces, EC2, etc), you need to set up a TURN server to relay the WebRTC traffic. +## Community Server + +Hugging Face graciously provides a TURN server for the community. +In order to use it, you need to first create a Hugging Face account by going to the [huggingface.co](https://huggingface.co/). + +Then navigate to this [space](https://huggingface.co/spaces/freddyaboulton/turn-server-login) and follow the instructions on the page. You just have to click the "Log in" button and then the "Sign Up" button. + +![turn_login](https://github.com/user-attachments/assets/d077c3a3-7059-45d6-8e50-eb3d8a4aa43f) + +Then you can use the `get_hf_turn_credentials` helper to get your credentials: + +```python +from gradio_webrtc import get_hf_turn_credentials, WebRTC + +# Pass a valid access token for your Hugging Face account +# or set the HF_TOKEN environment variable +credentials = get_hf_turn_credentials(token=None) + +with gr.Blcocks() as demo: + webrtc = WebRTC(rtc_configuration=credentials) + ... + +demo.launch() +``` + +!!! warning + + This is a shared resource so we make no latency/availability guarantees. + For more robust options, see the Twilio and self-hosting options below. + + ## Twilio API The easiest way to do this is to use a service like Twilio. @@ -28,6 +59,18 @@ with gr.Blocks() as demo: ... ``` +!!! tip "Automatic Login" + + You can log in automatically with the `get_twilio_turn_credentials` helper + + ```python + from gradio_webrtc import get_twilio_turn_credentials + + # Will automatically read the TWILIO_ACCOUNT_SID and TWILIO_AUTH_TOKEN + # env variables but you can also pass in the tokens as parameters + rtc_configuration = get_twilio_turn_credentials() + ``` + ## Self Hosting We have developed a script that can automatically deploy a TURN server to Amazon Web Services (AWS). You can follow the instructions [here](https://github.com/freddyaboulton/turn-server-deploy) or this guide. diff --git a/mkdocs.yml b/mkdocs.yml index 560f46d..ad02f7b 100644 --- a/mkdocs.yml +++ b/mkdocs.yml @@ -34,4 +34,6 @@ markdown_extensions: - md_in_html - pymdownx.emoji: emoji_index: !!python/name:material.extensions.emoji.twemoji - emoji_generator: !!python/name:material.extensions.emoji.to_svg \ No newline at end of file + emoji_generator: !!python/name:material.extensions.emoji.to_svg + - admonition + - pymdownx.details \ No newline at end of file diff --git a/pyproject.toml b/pyproject.toml index a31a9fd..0448b7c 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -8,7 +8,7 @@ build-backend = "hatchling.build" [project] name = "gradio_webrtc" -version = "0.0.13" +version = "0.0.14" description = "Stream images in realtime with webrtc" readme = "README.md" license = "apache-2.0"