-
Notifications
You must be signed in to change notification settings - Fork 122
consistent error class ServerError, test suite #744
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: main
Are you sure you want to change the base?
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -29,28 +29,41 @@ def __init__( | |
| api_key: Optional[str] = None, | ||
| api_secret: Optional[str] = None, | ||
| *, | ||
| token: Optional[str] = None, | ||
| timeout: Optional[aiohttp.ClientTimeout] = None, | ||
| session: Optional[aiohttp.ClientSession] = None, | ||
| failover: bool = True, | ||
| ): | ||
| """Create a new LiveKitAPI instance. | ||
|
|
||
| Authenticate with an API key and secret (recommended for backend use). | ||
| For token auth (client-side use, where the API secret must not be | ||
| exposed), prefer the :meth:`with_token` constructor. | ||
|
|
||
| Args: | ||
| url: LiveKit server URL (read from `LIVEKIT_URL` environment variable if not provided) | ||
| api_key: API key (read from `LIVEKIT_API_KEY` environment variable if not provided) | ||
| api_secret: API secret (read from `LIVEKIT_API_SECRET` environment variable if not provided) | ||
| token: Pre-signed access token (read from `LIVEKIT_TOKEN` environment variable if not provided) | ||
| timeout: Request timeout (default: 10 seconds) | ||
| session: aiohttp.ClientSession instance to use for requests, if not provided, a new one will be created | ||
| """ | ||
| url = url or os.getenv("LIVEKIT_URL") | ||
| api_key = api_key or os.getenv("LIVEKIT_API_KEY") | ||
| api_secret = api_secret or os.getenv("LIVEKIT_API_SECRET") | ||
|
|
||
| # Only fall back to environment credentials when none were provided | ||
| # explicitly, so an ambient LIVEKIT_TOKEN can't silently override an | ||
| # explicit api_key/secret (or vice versa). | ||
| if not token and not api_key and not api_secret: | ||
| token = os.getenv("LIVEKIT_TOKEN") | ||
| if not token and not api_key and not api_secret: | ||
| api_key = os.getenv("LIVEKIT_API_KEY") | ||
| api_secret = os.getenv("LIVEKIT_API_SECRET") | ||
|
Comment on lines
+56
to
+60
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. 🔍 Environment variable fallback for credentials is now all-or-nothing The old code resolved Was this helpful? React with 👍 or 👎 to provide feedback. |
||
|
|
||
| if not url: | ||
| raise ValueError("url must be set") | ||
|
|
||
| if not api_key or not api_secret: | ||
| raise ValueError("api_key and api_secret must be set") | ||
| if not token and (not api_key or not api_secret): | ||
| raise ValueError("either token, or api_key and api_secret, must be set") | ||
|
|
||
| self._custom_session = True | ||
| self._session = session | ||
|
|
@@ -60,14 +73,51 @@ def __init__( | |
| timeout = aiohttp.ClientTimeout(total=10) | ||
| self._session = aiohttp.ClientSession(timeout=timeout) | ||
|
|
||
| self._room = RoomService(self._session, url, api_key, api_secret, failover) | ||
| self._ingress = IngressService(self._session, url, api_key, api_secret, failover) | ||
| self._egress = EgressService(self._session, url, api_key, api_secret, failover) | ||
| self._sip = SipService(self._session, url, api_key, api_secret, failover) | ||
| self._agent_dispatch = AgentDispatchService( | ||
| self._session, url, api_key, api_secret, failover | ||
| ) | ||
| self._connector = ConnectorService(self._session, url, api_key, api_secret, failover) | ||
| # In token mode there is no key/secret; pass empty strings and rely on | ||
| # the token, injected into each service below. | ||
| key = api_key or "" | ||
| secret = api_secret or "" | ||
| self._room = RoomService(self._session, url, key, secret, failover) | ||
| self._ingress = IngressService(self._session, url, key, secret, failover) | ||
| self._egress = EgressService(self._session, url, key, secret, failover) | ||
| self._sip = SipService(self._session, url, key, secret, failover) | ||
| self._agent_dispatch = AgentDispatchService(self._session, url, key, secret, failover) | ||
| self._connector = ConnectorService(self._session, url, key, secret, failover) | ||
|
|
||
| if token: | ||
| for svc in ( | ||
| self._room, | ||
| self._ingress, | ||
| self._egress, | ||
| self._sip, | ||
| self._agent_dispatch, | ||
| self._connector, | ||
| ): | ||
| svc._token = token | ||
|
|
||
| @classmethod | ||
| def with_token( | ||
| cls, | ||
| token: str, | ||
| url: Optional[str] = None, | ||
| *, | ||
| timeout: Optional[aiohttp.ClientTimeout] = None, | ||
| session: Optional[aiohttp.ClientSession] = None, | ||
| failover: bool = True, | ||
| ) -> "LiveKitAPI": | ||
| """Create a LiveKitAPI authenticated with a pre-signed token. | ||
|
|
||
| The token is sent verbatim and must already carry the grants for the calls | ||
| it's used with. Since it needs no secret, this is suitable for client-side | ||
| use. `url` falls back to the `LIVEKIT_URL` environment variable. | ||
|
|
||
| Args: | ||
| token: Pre-signed access token | ||
| url: LiveKit server URL (read from `LIVEKIT_URL` if not provided) | ||
| timeout: Request timeout (default: 10 seconds) | ||
| session: aiohttp.ClientSession to use; a new one is created if omitted | ||
| """ | ||
| return cls(url, token=token, timeout=timeout, session=session, failover=failover) | ||
|
|
||
| @property | ||
| def agent_dispatch(self) -> AgentDispatchService: | ||
|
|
||
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
🚩 accept_whatsapp_call timeout lacks the RINGING_TIMEOUT_MARGIN used by SIP service
The
accept_whatsapp_callmethod usesDEFAULT_RINGING_TIMEOUT(30s) as the request timeout whenwait_until_answeredis set, without addingRINGING_TIMEOUT_MARGIN(2s). In contrast, the SIP service'screate_sip_participantusesring + RINGING_TIMEOUT_MARGINto ensure the HTTP request outlasts the ringing window. If the server takes exactly 30s to ring, the connector request could time out at the boundary. This is pre-existing behavior (unchanged by this PR) but the inconsistency is worth noting since the PR cleaned up theDialRequestunion that previously includedAcceptWhatsAppCallRequest.Was this helpful? React with 👍 or 👎 to provide feedback.