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.elevenlabs_ai_service import ElevenLabsTTSService
from dailyai.pipeline.frames import (
OpenAILLMContextFrame,
Frame,
LLMFunctionCallFrame,
LLMFunctionStartFrame,
AudioFrame,
)
from dailyai.pipeline.openai_frames import OpenAILLMContextFrame
from dailyai.services.ai_services import FrameLogger, AIService
from openai._types import NotGiven, NOT_GIVEN

View File

@@ -1,9 +1,6 @@
from dataclasses import dataclass
from typing import Any, List
from dailyai.services.openai_llm_context import OpenAILLMContext
import dailyai.pipeline.protobufs.frames_pb2 as frame_protos
class Frame:
def __str__(self):
@@ -135,14 +132,6 @@ class LLMMessagesFrame(Frame):
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()
class ReceivedAppMessageFrame(Frame):
message: Any

View File

@@ -4,15 +4,21 @@ from dailyai.pipeline.frames import (
Frame,
LLMResponseEndFrame,
LLMResponseStartFrame,
OpenAILLMContextFrame,
TextFrame,
TranscriptionFrame,
UserStartedSpeakingFrame,
UserStoppedSpeakingFrame,
)
from dailyai.pipeline.openai_frames import OpenAILLMContextFrame
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):

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 anthropic import AsyncAnthropic
from dailyai.pipeline.frames import Frame, LLMMessagesFrame, TextFrame
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):

View File

@@ -9,12 +9,18 @@ from dailyai.services.ai_services import TTSService, ImageGenService
from PIL import Image
# See .env.example for Azure configuration needed
from azure.cognitiveservices.speech import (
SpeechSynthesizer,
SpeechConfig,
ResultReason,
CancellationReason,
)
try:
from azure.cognitiveservices.speech import (
SpeechSynthesizer,
SpeechConfig,
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

View File

@@ -1,4 +1,3 @@
import fal
import aiohttp
import asyncio
import io
@@ -10,7 +9,13 @@ 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):

View File

@@ -1,12 +1,20 @@
import aiohttp
from PIL import Image
import io
from openai import AsyncOpenAI
from dailyai.services.ai_services import ImageGenService
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):
def __init__(self, model="gpt-4", * args, **kwargs):

View File

@@ -1,7 +1,6 @@
import json
import time
from typing import AsyncGenerator, List
from openai import AsyncOpenAI, AsyncStream
from dailyai.pipeline.frames import (
Frame,
LLMFunctionCallFrame,
@@ -9,17 +8,25 @@ from dailyai.pipeline.frames import (
LLMMessagesFrame,
LLMResponseEndFrame,
LLMResponseStartFrame,
OpenAILLMContextFrame,
TextFrame,
)
from dailyai.services.ai_services import LLMService
from dailyai.pipeline.openai_frames import OpenAILLMContextFrame
from dailyai.services.openai_llm_context import OpenAILLMContext
from openai.types.chat import (
ChatCompletion,
ChatCompletionChunk,
ChatCompletionMessageParam,
)
try:
from openai import AsyncOpenAI, AsyncStream
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):

View File

@@ -1,11 +1,18 @@
from typing import List
from openai._types import NOT_GIVEN, NotGiven
from openai.types.chat import (
ChatCompletionToolParam,
ChatCompletionToolChoiceOptionParam,
ChatCompletionMessageParam,
)
try:
from openai._types import NOT_GIVEN, NotGiven
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:

View File

@@ -1,11 +1,18 @@
import io
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
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):

View File

@@ -3,10 +3,18 @@ import asyncio
from enum import Enum
import logging
from typing import BinaryIO
from faster_whisper import WhisperModel
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 of basic Whisper model selection options"""
TINY = "tiny"

View File

@@ -15,14 +15,21 @@ from dailyai.pipeline.frames import (
from threading import Event
from daily import (
EventHandler,
CallClient,
Daily,
VirtualCameraDevice,
VirtualMicrophoneDevice,
VirtualSpeakerDevice,
)
try:
from daily import (
EventHandler,
CallClient,
Daily,
VirtualCameraDevice,
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

View File

@@ -4,17 +4,18 @@ import tkinter as tk
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):
def __init__(self, **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._n_channels = kwargs.get("n_channels") or 1
self._tk_root = kwargs.get("tk_root") or None

View File

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

View File

@@ -1,7 +1,6 @@
import asyncio
import time
from typing import AsyncGenerator, List
import websockets
from dailyai.pipeline.frame_processor import FrameProcessor
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.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):
"""This FrameProcessor filters and mutates frames before they're sent over the websocket.

View File

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

View File

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

View File

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