From 23bbb8cab7921aeff03a6e7e78ff3634164f17b9 Mon Sep 17 00:00:00 2001 From: aoife cassidy Date: Sat, 24 Aug 2024 16:06:46 -0700 Subject: [PATCH 1/2] plugins: add docstrings explaining API keys also provide envvar shims for openai.LLM alt providers --- .../livekit/plugins/anthropic/llm.py | 12 ++++ .../livekit/plugins/azure/stt.py | 7 ++ .../livekit/plugins/azure/tts.py | 7 ++ .../livekit/plugins/cartesia/tts.py | 7 ++ .../livekit/plugins/clova/stt.py | 7 ++ .../livekit/plugins/deepgram/stt.py | 7 ++ .../livekit/plugins/elevenlabs/tts.py | 7 ++ .../livekit/plugins/google/stt.py | 7 +- .../livekit/plugins/google/tts.py | 8 ++- .../livekit/plugins/openai/llm.py | 64 +++++++++++++++++++ .../livekit/plugins/openai/stt.py | 12 ++++ .../livekit/plugins/openai/tts.py | 12 ++++ 12 files changed, 153 insertions(+), 4 deletions(-) diff --git a/livekit-plugins/livekit-plugins-anthropic/livekit/plugins/anthropic/llm.py b/livekit-plugins/livekit-plugins-anthropic/livekit/plugins/anthropic/llm.py index 916a50d65..96cfe2b56 100644 --- a/livekit-plugins/livekit-plugins-anthropic/livekit/plugins/anthropic/llm.py +++ b/livekit-plugins/livekit-plugins-anthropic/livekit/plugins/anthropic/llm.py @@ -48,6 +48,18 @@ def __init__( user: str | None = None, client: anthropic.AsyncClient | None = None, ) -> None: + """ + Create a new instance of Anthropic LLM. + + ``api_key`` must be set to your Anthropic API key, either using the argument or by setting + the ``ANTHROPIC_API_KEY`` environmental variable. + """ + + # throw an error on our end + api_key = api_key or os.environ.get("ANTHROPIC_API_KEY") + if api_key is None: + raise ValueError("Anthropic API key is required") + self._opts = LLMOptions(model=model, user=user) self._client = client or anthropic.AsyncClient( api_key=api_key, diff --git a/livekit-plugins/livekit-plugins-azure/livekit/plugins/azure/stt.py b/livekit-plugins/livekit-plugins-azure/livekit/plugins/azure/stt.py index 98fa8de2f..b3ae6b9ee 100644 --- a/livekit-plugins/livekit-plugins-azure/livekit/plugins/azure/stt.py +++ b/livekit-plugins/livekit-plugins-azure/livekit/plugins/azure/stt.py @@ -45,6 +45,13 @@ def __init__( num_channels: int = 1, languages: list[str] = [], # when empty, auto-detect the language ): + """ + Create a new instance of Azure STT. + + ``speech_key`` and ``speech_region`` must be set, either using arguments or by setting the + ``AZURE_SPEECH_KEY`` and ``AZURE_SPEECH_REGION`` environmental variables, respectively. + """ + super().__init__( capabilities=stt.STTCapabilities(streaming=True, interim_results=True) ) diff --git a/livekit-plugins/livekit-plugins-azure/livekit/plugins/azure/tts.py b/livekit-plugins/livekit-plugins-azure/livekit/plugins/azure/tts.py index 3efeea38a..83446f823 100644 --- a/livekit-plugins/livekit-plugins-azure/livekit/plugins/azure/tts.py +++ b/livekit-plugins/livekit-plugins-azure/livekit/plugins/azure/tts.py @@ -42,6 +42,13 @@ def __init__( speech_region: str | None = None, voice: str | None = None, ) -> None: + """ + Create a new instance of Azure TTS. + + ``speech_key`` and ``speech_region`` must be set, either using arguments or by setting the + ``AZURE_SPEECH_KEY`` and ``AZURE_SPEECH_REGION`` environmental variables, respectively. + """ + super().__init__( capabilities=tts.TTSCapabilities( streaming=False, diff --git a/livekit-plugins/livekit-plugins-cartesia/livekit/plugins/cartesia/tts.py b/livekit-plugins/livekit-plugins-cartesia/livekit/plugins/cartesia/tts.py index 7a93a2ab6..b40417611 100644 --- a/livekit-plugins/livekit-plugins-cartesia/livekit/plugins/cartesia/tts.py +++ b/livekit-plugins/livekit-plugins-cartesia/livekit/plugins/cartesia/tts.py @@ -57,6 +57,13 @@ def __init__( api_key: str | None = None, http_session: aiohttp.ClientSession | None = None, ) -> None: + """ + Create a new instance of Cartesia TTS. + + ``api_key`` must be set to your Cartesia API key, either using the argument or by setting + the ``CARTESIA_API_KEY`` environmental variable. + """ + super().__init__( capabilities=tts.TTSCapabilities(streaming=True), sample_rate=sample_rate, diff --git a/livekit-plugins/livekit-plugins-clova/livekit/plugins/clova/stt.py b/livekit-plugins/livekit-plugins-clova/livekit/plugins/clova/stt.py index 2f279f6e6..308aa8b15 100644 --- a/livekit-plugins/livekit-plugins-clova/livekit/plugins/clova/stt.py +++ b/livekit-plugins/livekit-plugins-clova/livekit/plugins/clova/stt.py @@ -39,6 +39,13 @@ def __init__( http_session: Optional[aiohttp.ClientSession] = None, threshold: float = 0.5, ): + """ + Create a new instance of Clova STT. + + ``secret`` and ``invoke_url`` must be set, either using arguments or by setting the + ``CLOVA_STT_SECRET_KEY`` and ``CLOVA_STT_INVOKE_URL`` environmental variables, respectively. + """ + super().__init__( capabilities=STTCapabilities(streaming=False, interim_results=True) ) diff --git a/livekit-plugins/livekit-plugins-deepgram/livekit/plugins/deepgram/stt.py b/livekit-plugins/livekit-plugins-deepgram/livekit/plugins/deepgram/stt.py index 0b8e63353..ee87096ef 100644 --- a/livekit-plugins/livekit-plugins-deepgram/livekit/plugins/deepgram/stt.py +++ b/livekit-plugins/livekit-plugins-deepgram/livekit/plugins/deepgram/stt.py @@ -68,6 +68,13 @@ def __init__( api_key: str | None = None, http_session: aiohttp.ClientSession | None = None, ) -> None: + """ + Create a new instance of Deepgram STT. + + ``api_key`` must be set to your Deepgram API key, either using the argument or by setting + the ``DEEPGRAM_API_KEY`` environmental variable. + """ + super().__init__( capabilities=stt.STTCapabilities( streaming=True, interim_results=interim_results diff --git a/livekit-plugins/livekit-plugins-elevenlabs/livekit/plugins/elevenlabs/tts.py b/livekit-plugins/livekit-plugins-elevenlabs/livekit/plugins/elevenlabs/tts.py index 72b2490a0..d1eac2674 100644 --- a/livekit-plugins/livekit-plugins-elevenlabs/livekit/plugins/elevenlabs/tts.py +++ b/livekit-plugins/livekit-plugins-elevenlabs/livekit/plugins/elevenlabs/tts.py @@ -104,6 +104,13 @@ def __init__( chunk_length_schedule: list[int] = [80, 120, 200, 260], # range is [50, 500] http_session: aiohttp.ClientSession | None = None, ) -> None: + """ + Create a new instance of ElevenLabs TTS. + + ``api_key`` must be set to your ElevenLabs API key, either using the argument or by setting + the ``ELEVEN_API_KEY`` environmental variable. + """ + super().__init__( capabilities=tts.TTSCapabilities( streaming=True, diff --git a/livekit-plugins/livekit-plugins-google/livekit/plugins/google/stt.py b/livekit-plugins/livekit-plugins-google/livekit/plugins/google/stt.py index 4946a1de9..2f9a63ba4 100644 --- a/livekit-plugins/livekit-plugins-google/livekit/plugins/google/stt.py +++ b/livekit-plugins/livekit-plugins-google/livekit/plugins/google/stt.py @@ -58,8 +58,11 @@ def __init__( credentials_file: str | None = None, ): """ - if no credentials is provided, it will use the credentials on the environment - GOOGLE_APPLICATION_CREDENTIALS (default behavior of Google SpeechAsyncClient) + Create a new instance of Google STT. + + Credentials must be provided, either by using the ``credentials_info`` dict, or reading + from the file specified in ``credentials_file`` or the ``GOOGLE_APPLICATION_CREDENTIALS`` + environmental variable. """ super().__init__( capabilities=stt.STTCapabilities(streaming=True, interim_results=True) diff --git a/livekit-plugins/livekit-plugins-google/livekit/plugins/google/tts.py b/livekit-plugins/livekit-plugins-google/livekit/plugins/google/tts.py index 433ec84d2..23799480f 100644 --- a/livekit-plugins/livekit-plugins-google/livekit/plugins/google/tts.py +++ b/livekit-plugins/livekit-plugins-google/livekit/plugins/google/tts.py @@ -51,9 +51,13 @@ def __init__( credentials_file: str | None = None, ) -> None: """ - if no credentials is provided, it will use the credentials on the environment - GOOGLE_APPLICATION_CREDENTIALS (default behavior of Google TextToSpeechAsyncClient) + Create a new instance of Google TTS. + + Credentials must be provided, either by using the ``credentials_info`` dict, or reading + from the file specified in ``credentials_file`` or the ``GOOGLE_APPLICATION_CREDENTIALS`` + environmental variable. """ + super().__init__( capabilities=tts.TTSCapabilities( streaming=False, diff --git a/livekit-plugins/livekit-plugins-openai/livekit/plugins/openai/llm.py b/livekit-plugins/livekit-plugins-openai/livekit/plugins/openai/llm.py index f24adfa92..0978842c7 100644 --- a/livekit-plugins/livekit-plugins-openai/livekit/plugins/openai/llm.py +++ b/livekit-plugins/livekit-plugins-openai/livekit/plugins/openai/llm.py @@ -52,6 +52,18 @@ def __init__( user: str | None = None, client: openai.AsyncClient | None = None, ) -> None: + """ + Create a new instance of OpenAI LLM. + + ``api_key`` must be set to your OpenAI API key, either using the argument or by setting the + ``OPENAI_API_KEY`` environmental variable. + """ + + # throw an error on our end + api_key = api_key or os.environ.get("OPENAI_API_KEY") + if api_key is None: + raise ValueError("OpenAI API key is required") + self._opts = LLMOptions(model=model, user=user) self._client = client or openai.AsyncClient( api_key=api_key, @@ -116,6 +128,18 @@ def with_fireworks( client: openai.AsyncClient | None = None, user: str | None = None, ) -> LLM: + """ + Create a new instance of Fireworks LLM. + + ``api_key`` must be set to your Fireworks API key, either using the argument or by setting + the ``FIREWORKS_API_KEY`` environmental variable. + """ + + # shim for not using OPENAI_API_KEY + api_key = api_key or os.environ.get("FIREWORKS_API_KEY") + if api_key is None: + raise ValueError("Fireworks API key is required") + return LLM( model=model, api_key=api_key, base_url=base_url, client=client, user=user ) @@ -129,6 +153,18 @@ def with_groq( client: openai.AsyncClient | None = None, user: str | None = None, ) -> LLM: + """ + Create a new instance of Groq LLM. + + ``api_key`` must be set to your Groq API key, either using the argument or by setting + the ``GROQ_API_KEY`` environmental variable. + """ + + # shim for not using OPENAI_API_KEY + api_key = api_key or os.environ.get("GROQ_API_KEY") + if api_key is None: + raise ValueError("Groq API key is required") + return LLM( model=model, api_key=api_key, base_url=base_url, client=client, user=user ) @@ -142,6 +178,18 @@ def with_octo( client: openai.AsyncClient | None = None, user: str | None = None, ) -> LLM: + """ + Create a new instance of OctoAI LLM. + + ``api_key`` must be set to your OctoAI API key, either using the argument or by setting + the ``OCTO_API_KEY`` environmental variable. + """ + + # shim for not using OPENAI_API_KEY + api_key = api_key or os.environ.get("OCTO_API_KEY") + if api_key is None: + raise ValueError("OctoAI API key is required") + return LLM( model=model, api_key=api_key, base_url=base_url, client=client, user=user ) @@ -153,6 +201,10 @@ def with_ollama( base_url: str | None = "http://localhost:11434/v1", client: openai.AsyncClient | None = None, ) -> LLM: + """ + Create a new instance of Ollama LLM. + """ + return LLM(model=model, api_key="ollama", base_url=base_url, client=client) @staticmethod @@ -177,6 +229,18 @@ def with_together( client: openai.AsyncClient | None = None, user: str | None = None, ) -> LLM: + """ + Create a new instance of TogetherAI LLM. + + ``api_key`` must be set to your TogetherAI API key, either using the argument or by setting + the ``TOGETHER_API_KEY`` environmental variable. + """ + + # shim for not using OPENAI_API_KEY + api_key = api_key or os.environ.get("TOGETHER_API_KEY") + if api_key is None: + raise ValueError("TogetherAI API key is required") + return LLM( model=model, api_key=api_key, base_url=base_url, client=client, user=user ) diff --git a/livekit-plugins/livekit-plugins-openai/livekit/plugins/openai/stt.py b/livekit-plugins/livekit-plugins-openai/livekit/plugins/openai/stt.py index f9356a1cb..2a4bf3c9f 100644 --- a/livekit-plugins/livekit-plugins-openai/livekit/plugins/openai/stt.py +++ b/livekit-plugins/livekit-plugins-openai/livekit/plugins/openai/stt.py @@ -47,6 +47,13 @@ def __init__( api_key: str | None = None, client: openai.AsyncClient | None = None, ): + """ + Create a new instance of OpenAI STT. + + ``api_key`` must be set to your OpenAI API key, either using the argument or by setting the + ``OPENAI_API_KEY`` environmental variable. + """ + super().__init__( capabilities=stt.STTCapabilities(streaming=False, interim_results=False) ) @@ -59,6 +66,11 @@ def __init__( model=model, ) + # throw an error on our end + api_key = api_key or os.environ.get("OPENAI_API_KEY") + if api_key is None: + raise ValueError("OpenAI API key is required") + self._client = client or openai.AsyncClient( api_key=api_key, base_url=base_url, diff --git a/livekit-plugins/livekit-plugins-openai/livekit/plugins/openai/tts.py b/livekit-plugins/livekit-plugins-openai/livekit/plugins/openai/tts.py index 27f62df13..d66130ce5 100644 --- a/livekit-plugins/livekit-plugins-openai/livekit/plugins/openai/tts.py +++ b/livekit-plugins/livekit-plugins-openai/livekit/plugins/openai/tts.py @@ -48,6 +48,13 @@ def __init__( api_key: str | None = None, client: openai.AsyncClient | None = None, ) -> None: + """ + Create a new instance of OpenAI TTS. + + ``api_key`` must be set to your OpenAI API key, either using the argument or by setting the + ``OPENAI_API_KEY`` environmental variable. + """ + super().__init__( capabilities=tts.TTSCapabilities( streaming=False, @@ -56,6 +63,11 @@ def __init__( num_channels=OPENAI_TTS_CHANNELS, ) + # throw an error on our end + api_key = api_key or os.environ.get("OPENAI_API_KEY") + if api_key is None: + raise ValueError("OpenAI API key is required") + self._client = client or openai.AsyncClient( api_key=api_key, base_url=base_url, From 14f55ee3de6e99e29bf63564aa7691a8d407ed27 Mon Sep 17 00:00:00 2001 From: aoife cassidy Date: Sat, 24 Aug 2024 16:14:43 -0700 Subject: [PATCH 2/2] add missing import and fix octo api key --- .../livekit/plugins/anthropic/llm.py | 1 + .../livekit-plugins-openai/livekit/plugins/openai/llm.py | 5 +++-- .../livekit-plugins-openai/livekit/plugins/openai/stt.py | 1 + .../livekit-plugins-openai/livekit/plugins/openai/tts.py | 1 + 4 files changed, 6 insertions(+), 2 deletions(-) diff --git a/livekit-plugins/livekit-plugins-anthropic/livekit/plugins/anthropic/llm.py b/livekit-plugins/livekit-plugins-anthropic/livekit/plugins/anthropic/llm.py index 96cfe2b56..f304fa9c2 100644 --- a/livekit-plugins/livekit-plugins-anthropic/livekit/plugins/anthropic/llm.py +++ b/livekit-plugins/livekit-plugins-anthropic/livekit/plugins/anthropic/llm.py @@ -17,6 +17,7 @@ import base64 import inspect import json +import os from dataclasses import dataclass from typing import Any, Awaitable, List, Tuple, get_args, get_origin diff --git a/livekit-plugins/livekit-plugins-openai/livekit/plugins/openai/llm.py b/livekit-plugins/livekit-plugins-openai/livekit/plugins/openai/llm.py index 0978842c7..e531932db 100644 --- a/livekit-plugins/livekit-plugins-openai/livekit/plugins/openai/llm.py +++ b/livekit-plugins/livekit-plugins-openai/livekit/plugins/openai/llm.py @@ -15,6 +15,7 @@ from __future__ import annotations import asyncio +import os from dataclasses import dataclass from typing import Any, Awaitable, MutableSet @@ -182,11 +183,11 @@ def with_octo( Create a new instance of OctoAI LLM. ``api_key`` must be set to your OctoAI API key, either using the argument or by setting - the ``OCTO_API_KEY`` environmental variable. + the ``OCTOAI_TOKEN`` environmental variable. """ # shim for not using OPENAI_API_KEY - api_key = api_key or os.environ.get("OCTO_API_KEY") + api_key = api_key or os.environ.get("OCTOAI_TOKEN") if api_key is None: raise ValueError("OctoAI API key is required") diff --git a/livekit-plugins/livekit-plugins-openai/livekit/plugins/openai/stt.py b/livekit-plugins/livekit-plugins-openai/livekit/plugins/openai/stt.py index 2a4bf3c9f..6cb949b9d 100644 --- a/livekit-plugins/livekit-plugins-openai/livekit/plugins/openai/stt.py +++ b/livekit-plugins/livekit-plugins-openai/livekit/plugins/openai/stt.py @@ -16,6 +16,7 @@ import dataclasses import io +import os import wave from dataclasses import dataclass diff --git a/livekit-plugins/livekit-plugins-openai/livekit/plugins/openai/tts.py b/livekit-plugins/livekit-plugins-openai/livekit/plugins/openai/tts.py index d66130ce5..7ab38e156 100644 --- a/livekit-plugins/livekit-plugins-openai/livekit/plugins/openai/tts.py +++ b/livekit-plugins/livekit-plugins-openai/livekit/plugins/openai/tts.py @@ -14,6 +14,7 @@ from __future__ import annotations +import os from dataclasses import dataclass from typing import AsyncContextManager