@@ -29,28 +29,35 @@ def __init__(
2929 api_key : Optional [str ] = None ,
3030 api_secret : Optional [str ] = None ,
3131 * ,
32+ token : Optional [str ] = None ,
3233 timeout : Optional [aiohttp .ClientTimeout ] = None ,
3334 session : Optional [aiohttp .ClientSession ] = None ,
3435 failover : bool = True ,
3536 ):
3637 """Create a new LiveKitAPI instance.
3738
39+ Authenticate with an API key and secret (recommended for backend use).
40+ For token auth (client-side use, where the API secret must not be
41+ exposed), prefer the :meth:`with_token` constructor.
42+
3843 Args:
3944 url: LiveKit server URL (read from `LIVEKIT_URL` environment variable if not provided)
4045 api_key: API key (read from `LIVEKIT_API_KEY` environment variable if not provided)
4146 api_secret: API secret (read from `LIVEKIT_API_SECRET` environment variable if not provided)
47+ token: Pre-signed access token (read from `LIVEKIT_TOKEN` environment variable if not provided)
4248 timeout: Request timeout (default: 10 seconds)
4349 session: aiohttp.ClientSession instance to use for requests, if not provided, a new one will be created
4450 """
4551 url = url or os .getenv ("LIVEKIT_URL" )
52+ token = token or os .getenv ("LIVEKIT_TOKEN" )
4653 api_key = api_key or os .getenv ("LIVEKIT_API_KEY" )
4754 api_secret = api_secret or os .getenv ("LIVEKIT_API_SECRET" )
4855
4956 if not url :
5057 raise ValueError ("url must be set" )
5158
52- if not api_key or not api_secret :
53- raise ValueError ("api_key and api_secret must be set" )
59+ if not token and ( not api_key or not api_secret ) :
60+ raise ValueError ("either token, or api_key and api_secret, must be set" )
5461
5562 self ._custom_session = True
5663 self ._session = session
@@ -60,14 +67,51 @@ def __init__(
6067 timeout = aiohttp .ClientTimeout (total = 10 )
6168 self ._session = aiohttp .ClientSession (timeout = timeout )
6269
63- self ._room = RoomService (self ._session , url , api_key , api_secret , failover )
64- self ._ingress = IngressService (self ._session , url , api_key , api_secret , failover )
65- self ._egress = EgressService (self ._session , url , api_key , api_secret , failover )
66- self ._sip = SipService (self ._session , url , api_key , api_secret , failover )
67- self ._agent_dispatch = AgentDispatchService (
68- self ._session , url , api_key , api_secret , failover
69- )
70- self ._connector = ConnectorService (self ._session , url , api_key , api_secret , failover )
70+ # In token mode there is no key/secret; pass empty strings and rely on
71+ # the token, injected into each service below.
72+ key = api_key or ""
73+ secret = api_secret or ""
74+ self ._room = RoomService (self ._session , url , key , secret , failover )
75+ self ._ingress = IngressService (self ._session , url , key , secret , failover )
76+ self ._egress = EgressService (self ._session , url , key , secret , failover )
77+ self ._sip = SipService (self ._session , url , key , secret , failover )
78+ self ._agent_dispatch = AgentDispatchService (self ._session , url , key , secret , failover )
79+ self ._connector = ConnectorService (self ._session , url , key , secret , failover )
80+
81+ if token :
82+ for svc in (
83+ self ._room ,
84+ self ._ingress ,
85+ self ._egress ,
86+ self ._sip ,
87+ self ._agent_dispatch ,
88+ self ._connector ,
89+ ):
90+ svc ._token = token
91+
92+ @classmethod
93+ def with_token (
94+ cls ,
95+ token : str ,
96+ url : Optional [str ] = None ,
97+ * ,
98+ timeout : Optional [aiohttp .ClientTimeout ] = None ,
99+ session : Optional [aiohttp .ClientSession ] = None ,
100+ failover : bool = True ,
101+ ) -> "LiveKitAPI" :
102+ """Create a LiveKitAPI authenticated with a pre-signed token.
103+
104+ The token is sent verbatim and must already carry the grants for the calls
105+ it's used with. Since it needs no secret, this is suitable for client-side
106+ use. `url` falls back to the `LIVEKIT_URL` environment variable.
107+
108+ Args:
109+ token: Pre-signed access token
110+ url: LiveKit server URL (read from `LIVEKIT_URL` if not provided)
111+ timeout: Request timeout (default: 10 seconds)
112+ session: aiohttp.ClientSession to use; a new one is created if omitted
113+ """
114+ return cls (url , token = token , timeout = timeout , session = session , failover = failover )
71115
72116 @property
73117 def agent_dispatch (self ) -> AgentDispatchService :
0 commit comments