use conditional imports and show help errors if modules not found

This commit is contained in:
Aleix Conchillo Flaqué
2024-04-03 15:09:12 -07:00
parent 23735cb3a3
commit 3528f5d735
19 changed files with 137 additions and 67 deletions

View File

@@ -19,12 +19,12 @@ from dailyai.services.open_ai_services import OpenAILLMService
# from dailyai.services.deepgram_ai_services import DeepgramTTSService # from dailyai.services.deepgram_ai_services import DeepgramTTSService
from dailyai.services.elevenlabs_ai_service import ElevenLabsTTSService from dailyai.services.elevenlabs_ai_service import ElevenLabsTTSService
from dailyai.pipeline.frames import ( from dailyai.pipeline.frames import (
OpenAILLMContextFrame,
Frame, Frame,
LLMFunctionCallFrame, LLMFunctionCallFrame,
LLMFunctionStartFrame, LLMFunctionStartFrame,
AudioFrame, AudioFrame,
) )
from dailyai.pipeline.openai_frames import OpenAILLMContextFrame
from dailyai.services.ai_services import FrameLogger, AIService from dailyai.services.ai_services import FrameLogger, AIService
from openai._types import NotGiven, NOT_GIVEN from openai._types import NotGiven, NOT_GIVEN

View File

@@ -1,9 +1,6 @@
from dataclasses import dataclass from dataclasses import dataclass
from typing import Any, List from typing import Any, List
from dailyai.services.openai_llm_context import OpenAILLMContext
import dailyai.pipeline.protobufs.frames_pb2 as frame_protos
class Frame: class Frame:
def __str__(self): def __str__(self):
@@ -135,14 +132,6 @@ class LLMMessagesFrame(Frame):
messages: List[dict] messages: List[dict]
@dataclass()
class OpenAILLMContextFrame(Frame):
"""Like an LLMMessagesFrame, but with extra context specific to the
OpenAI API. The context in this message is also mutable, and will be
changed by the OpenAIContextAggregator frame processor."""
context: OpenAILLMContext
@dataclass() @dataclass()
class ReceivedAppMessageFrame(Frame): class ReceivedAppMessageFrame(Frame):
message: Any message: Any

View File

@@ -4,15 +4,21 @@ from dailyai.pipeline.frames import (
Frame, Frame,
LLMResponseEndFrame, LLMResponseEndFrame,
LLMResponseStartFrame, LLMResponseStartFrame,
OpenAILLMContextFrame,
TextFrame, TextFrame,
TranscriptionFrame, TranscriptionFrame,
UserStartedSpeakingFrame, UserStartedSpeakingFrame,
UserStoppedSpeakingFrame, UserStoppedSpeakingFrame,
) )
from dailyai.pipeline.openai_frames import OpenAILLMContextFrame
from dailyai.services.openai_llm_context import OpenAILLMContext from dailyai.services.openai_llm_context import OpenAILLMContext
from openai.types.chat import ChatCompletionRole try:
from openai.types.chat import ChatCompletionRole
except ModuleNotFoundError as e:
print(f"Exception: {e}")
print(
"In order to use OpenAI, you need to `pip install dailyai[openai]`. Also, set `OPENAI_API_KEY` environment variable.")
raise Exception(f"Missing module: {e}")
class OpenAIContextAggregator(FrameProcessor): class OpenAIContextAggregator(FrameProcessor):

View File

@@ -0,0 +1,12 @@
from dataclasses import dataclass
from dailyai.pipeline.frames import Frame
from dailyai.services.openai_llm_context import OpenAILLMContext
@dataclass()
class OpenAILLMContextFrame(Frame):
"""Like an LLMMessagesFrame, but with extra context specific to the
OpenAI API. The context in this message is also mutable, and will be
changed by the OpenAIContextAggregator frame processor."""
context: OpenAILLMContext

View File

@@ -1,9 +1,16 @@
from typing import AsyncGenerator from typing import AsyncGenerator
from anthropic import AsyncAnthropic
from dailyai.pipeline.frames import Frame, LLMMessagesFrame, TextFrame from dailyai.pipeline.frames import Frame, LLMMessagesFrame, TextFrame
from dailyai.services.ai_services import LLMService from dailyai.services.ai_services import LLMService
try:
from anthropic import AsyncAnthropic
except ModuleNotFoundError as e:
print(f"Exception: {e}")
print(
"In order to use Anthropic, you need to `pip install dailyai[anthropic]`. Also, set `ANTHROPIC_API_KEY` environment variable.")
raise Exception(f"Missing module: {e}")
class AnthropicLLMService(LLMService): class AnthropicLLMService(LLMService):

View File

@@ -9,12 +9,18 @@ from dailyai.services.ai_services import TTSService, ImageGenService
from PIL import Image from PIL import Image
# See .env.example for Azure configuration needed # See .env.example for Azure configuration needed
from azure.cognitiveservices.speech import ( try:
SpeechSynthesizer, from azure.cognitiveservices.speech import (
SpeechConfig, SpeechSynthesizer,
ResultReason, SpeechConfig,
CancellationReason, ResultReason,
) CancellationReason,
)
except ModuleNotFoundError as e:
print(f"Exception: {e}")
print(
"In order to use Azure TTS, you need to `pip install dailyai[azure]`. Also, set `SPEECH_KEY` and `SPEECH_REGION` environment variables.")
raise Exception(f"Missing module: {e}")
from dailyai.services.openai_api_llm_service import BaseOpenAILLMService from dailyai.services.openai_api_llm_service import BaseOpenAILLMService

View File

@@ -1,4 +1,3 @@
import fal
import aiohttp import aiohttp
import asyncio import asyncio
import io import io
@@ -10,7 +9,13 @@ from dailyai.services.ai_services import ImageGenService
from dailyai.services.ai_services import ImageGenService from dailyai.services.ai_services import ImageGenService
# Fal expects FAL_KEY_ID and FAL_KEY_SECRET to be set in the env try:
import fal
except ModuleNotFoundError as e:
print(f"Exception: {e}")
print(
"In order to use Fal, you need to `pip install dailyai[fal]`. Also, set `FAL_KEY_ID` and `FAL_KEY_SECRET` environment variables.")
raise Exception(f"Missing module: {e}")
class FalImageGenService(ImageGenService): class FalImageGenService(ImageGenService):

View File

@@ -1,12 +1,20 @@
import aiohttp import aiohttp
from PIL import Image from PIL import Image
import io import io
from openai import AsyncOpenAI
from dailyai.services.ai_services import ImageGenService from dailyai.services.ai_services import ImageGenService
from dailyai.services.openai_api_llm_service import BaseOpenAILLMService from dailyai.services.openai_api_llm_service import BaseOpenAILLMService
try:
from openai import AsyncOpenAI
except ModuleNotFoundError as e:
print(f"Exception: {e}")
print(
"In order to use OpenAI, you need to `pip install dailyai[openai]`. Also, set `OPENAI_API_KEY` environment variable.")
raise Exception(f"Missing module: {e}")
class OpenAILLMService(BaseOpenAILLMService): class OpenAILLMService(BaseOpenAILLMService):
def __init__(self, model="gpt-4", * args, **kwargs): def __init__(self, model="gpt-4", * args, **kwargs):

View File

@@ -1,7 +1,6 @@
import json import json
import time import time
from typing import AsyncGenerator, List from typing import AsyncGenerator, List
from openai import AsyncOpenAI, AsyncStream
from dailyai.pipeline.frames import ( from dailyai.pipeline.frames import (
Frame, Frame,
LLMFunctionCallFrame, LLMFunctionCallFrame,
@@ -9,17 +8,25 @@ from dailyai.pipeline.frames import (
LLMMessagesFrame, LLMMessagesFrame,
LLMResponseEndFrame, LLMResponseEndFrame,
LLMResponseStartFrame, LLMResponseStartFrame,
OpenAILLMContextFrame,
TextFrame, TextFrame,
) )
from dailyai.services.ai_services import LLMService from dailyai.services.ai_services import LLMService
from dailyai.pipeline.openai_frames import OpenAILLMContextFrame
from dailyai.services.openai_llm_context import OpenAILLMContext from dailyai.services.openai_llm_context import OpenAILLMContext
from openai.types.chat import ( try:
ChatCompletion, from openai import AsyncOpenAI, AsyncStream
ChatCompletionChunk,
ChatCompletionMessageParam, from openai.types.chat import (
) ChatCompletion,
ChatCompletionChunk,
ChatCompletionMessageParam,
)
except ModuleNotFoundError as e:
print(f"Exception: {e}")
print(
"In order to use OpenAI, you need to `pip install dailyai[openai]`. Also, set `OPENAI_API_KEY` environment variable.")
raise Exception(f"Missing module: {e}")
class BaseOpenAILLMService(LLMService): class BaseOpenAILLMService(LLMService):

View File

@@ -1,11 +1,18 @@
from typing import List from typing import List
from openai._types import NOT_GIVEN, NotGiven
from openai.types.chat import ( try:
ChatCompletionToolParam, from openai._types import NOT_GIVEN, NotGiven
ChatCompletionToolChoiceOptionParam,
ChatCompletionMessageParam, from openai.types.chat import (
) ChatCompletionToolParam,
ChatCompletionToolChoiceOptionParam,
ChatCompletionMessageParam,
)
except ModuleNotFoundError as e:
print(f"Exception: {e}")
print(
"In order to use OpenAI, you need to `pip install dailyai[openai]`. Also, set `OPENAI_API_KEY` environment variable.")
raise Exception(f"Missing module: {e}")
class OpenAILLMContext: class OpenAILLMContext:

View File

@@ -1,11 +1,18 @@
import io import io
import struct import struct
from pyht import Client
from pyht.client import TTSOptions
from pyht.protos.api_pb2 import Format
from dailyai.services.ai_services import TTSService from dailyai.services.ai_services import TTSService
try:
from pyht import Client
from pyht.client import TTSOptions
from pyht.protos.api_pb2 import Format
except ModuleNotFoundError as e:
print(f"Exception: {e}")
print(
"In order to use PlayHT, you need to `pip install dailyai[playht]`. Also, set `PLAY_HT_USER_ID` and `PLAY_HT_API_KEY` environment variables.")
raise Exception(f"Missing module: {e}")
class PlayHTAIService(TTSService): class PlayHTAIService(TTSService):

View File

@@ -3,10 +3,18 @@ import asyncio
from enum import Enum from enum import Enum
import logging import logging
from typing import BinaryIO from typing import BinaryIO
from faster_whisper import WhisperModel
from dailyai.services.local_stt_service import LocalSTTService from dailyai.services.local_stt_service import LocalSTTService
try:
from faster_whisper import WhisperModel
except ModuleNotFoundError as e:
print(f"Exception: {e}")
print(
"In order to use Whisper, you need to `pip install dailyai[whisper]`.")
raise Exception(f"Missing module: {e}")
class Model(Enum): class Model(Enum):
"""Class of basic Whisper model selection options""" """Class of basic Whisper model selection options"""
TINY = "tiny" TINY = "tiny"

View File

@@ -15,14 +15,21 @@ from dailyai.pipeline.frames import (
from threading import Event from threading import Event
from daily import ( try:
EventHandler, from daily import (
CallClient, EventHandler,
Daily, CallClient,
VirtualCameraDevice, Daily,
VirtualMicrophoneDevice, VirtualCameraDevice,
VirtualSpeakerDevice, VirtualMicrophoneDevice,
) VirtualSpeakerDevice,
)
except ModuleNotFoundError as e:
print(f"Exception: {e}")
print(
"In order to use the Daily transport, you need to `pip install dailyai[daily]`.")
raise Exception(f"Missing module: {e}")
from dailyai.transports.threaded_transport import ThreadedTransport from dailyai.transports.threaded_transport import ThreadedTransport

View File

@@ -4,17 +4,18 @@ import tkinter as tk
from dailyai.transports.threaded_transport import ThreadedTransport from dailyai.transports.threaded_transport import ThreadedTransport
try:
import pyaudio
except ModuleNotFoundError as e:
print(f"Exception: {e}")
print(
"In order to use the local transport, you need to `pip install dailyai[local]`. On MacOS, you also need to `brew install portaudio`.")
raise Exception(f"Missing module: {e}")
class LocalTransport(ThreadedTransport): class LocalTransport(ThreadedTransport):
def __init__(self, **kwargs): def __init__(self, **kwargs):
super().__init__(**kwargs) super().__init__(**kwargs)
try:
global pyaudio
import pyaudio
except ModuleNotFoundError as e:
print(f"Exception: {e}")
print("In order to use the local transport, you'll need to `pip install pyaudio`. On MacOS, you'll also need to `brew install portaudio`.")
raise Exception(f"Missing module: {e}")
self._sample_width = kwargs.get("sample_width") or 2 self._sample_width = kwargs.get("sample_width") or 2
self._n_channels = kwargs.get("n_channels") or 1 self._n_channels = kwargs.get("n_channels") or 1
self._tk_root = kwargs.get("tk_root") or None self._tk_root = kwargs.get("tk_root") or None

View File

@@ -1,7 +1,6 @@
from abc import abstractmethod from abc import abstractmethod
import asyncio import asyncio
import itertools import itertools
import logging
import numpy as np import numpy as np
import queue import queue

View File

@@ -1,7 +1,6 @@
import asyncio import asyncio
import time import time
from typing import AsyncGenerator, List from typing import AsyncGenerator, List
import websockets
from dailyai.pipeline.frame_processor import FrameProcessor from dailyai.pipeline.frame_processor import FrameProcessor
from dailyai.pipeline.frames import AudioFrame, ControlFrame, EndFrame, Frame, TTSEndFrame, TTSStartFrame, TextFrame from dailyai.pipeline.frames import AudioFrame, ControlFrame, EndFrame, Frame, TTSEndFrame, TTSStartFrame, TextFrame
@@ -10,6 +9,14 @@ from dailyai.serializers.protobuf_serializer import ProtobufFrameSerializer
from dailyai.transports.abstract_transport import AbstractTransport from dailyai.transports.abstract_transport import AbstractTransport
from dailyai.transports.threaded_transport import ThreadedTransport from dailyai.transports.threaded_transport import ThreadedTransport
try:
import websockets
except ModuleNotFoundError as e:
print(f"Exception: {e}")
print(
"In order to use the websocket transport, you need to `pip install dailyai[websocket]`.")
raise Exception(f"Missing module: {e}")
class WebSocketFrameProcessor(FrameProcessor): class WebSocketFrameProcessor(FrameProcessor):
"""This FrameProcessor filters and mutates frames before they're sent over the websocket. """This FrameProcessor filters and mutates frames before they're sent over the websocket.

View File

@@ -1,8 +1,6 @@
import asyncio import asyncio
import os import os
from dailyai.pipeline.frames import ( from dailyai.pipeline.openai_frames import OpenAILLMContextFrame
OpenAILLMContextFrame,
)
from dailyai.services.azure_ai_services import AzureLLMService from dailyai.services.azure_ai_services import AzureLLMService
from dailyai.services.openai_llm_context import OpenAILLMContext from dailyai.services.openai_llm_context import OpenAILLMContext

View File

@@ -1,7 +1,5 @@
import asyncio import asyncio
from dailyai.pipeline.frames import ( from dailyai.pipeline.openai_frames import OpenAILLMContextFrame
OpenAILLMContextFrame,
)
from dailyai.services.openai_llm_context import OpenAILLMContext from dailyai.services.openai_llm_context import OpenAILLMContext
from openai.types.chat import ( from openai.types.chat import (

View File

@@ -1,8 +1,6 @@
import asyncio import asyncio
import os import os
from dailyai.pipeline.frames import ( from dailyai.pipeline.openai_frames import OpenAILLMContextFrame
OpenAILLMContextFrame,
)
from dailyai.services.openai_llm_context import OpenAILLMContext from dailyai.services.openai_llm_context import OpenAILLMContext
from openai.types.chat import ( from openai.types.chat import (