From 128d350abcc7efe7b95187e3bdbc6d2e731d9eba Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Aleix=20Conchillo=20Flaqu=C3=A9?= Date: Wed, 3 Apr 2024 15:06:16 -0700 Subject: [PATCH 01/11] pyproject.toml: use project optional dependencies and pin them --- README.md | 38 +++-- pyproject.toml | 33 ++--- requirements-dev.txt | 4 + requirements.txt | 323 ++++++++++++++++++++++++++++++++++++++++++- 4 files changed, 363 insertions(+), 35 deletions(-) create mode 100644 requirements-dev.txt diff --git a/README.md b/README.md index 21e38a31d..fa00ac1a5 100644 --- a/README.md +++ b/README.md @@ -4,12 +4,8 @@ Build things like this: [![AI-powered voice patient intake for healthcare](https://img.youtube.com/vi/lDevgsp9vn0/0.jpg)](https://www.youtube.com/watch?v=lDevgsp9vn0) - - - **`dailyai` started as a toolkit for implementing generative AI voice bots.** Things like personal coaches, meeting assistants, story-telling toys for kids, customer support bots, and snarky social companions. - In 2023 a *lot* of us got excited about the possibility of having open-ended conversations with LLMs. It became clear pretty quickly that we were all solving the same [low-level problems](https://www.daily.co/blog/how-to-talk-to-an-llm-with-your-voice/): - low-latency, reliable audio transport - echo cancellation @@ -48,7 +44,7 @@ If you'd like to [implement a service]((https://github.com/daily-co/daily-ai-sdk ## Getting started -Today, the easiest way to get started with `dailyai` is to use [Daily](https://www.daily.co/) as your transport service. This toolkit started life as an internal SDK at Daily and millions of minutes of AI conversation have been served using it and its earlier prototype incarnations. (The [transport base class](https://github.com/daily-co/daily-ai-sdk/blob/main/src/dailyai/services/base_transport_service.py) is easy to extend, though, so feel free to submit PRs if you'd like to implement another transport service.) +Today, the easiest way to get started with `dailyai` is to use [Daily](https://www.daily.co/) as your transport service. This toolkit started life as an internal SDK at Daily and millions of minutes of AI conversation have been served using it and its earlier prototype incarnations. (The [transport base class](https://github.com/daily-co/daily-ai-sdk/blob/main/src/dailyai/transports/abstract_transport.py) is easy to extend, though, so feel free to submit PRs if you'd like to implement another transport service.) ``` # install the module @@ -58,6 +54,18 @@ pip install dailyai cp dot-env.template .env ``` +By default, in order to minimize dependencies, only the basic framework functionality is available. Some third-party AI services require additional +dependencies that you can install with: + +``` +pip install dailyai[option,...] +``` + +Your project may or may not need these, so they're made available as optional requirements. Here is a list: + +- **AI services**: `anthropic`, `azure`, `fal`, `openai`, `playht`, `silero`, `whisper` +- **Transports**: `daily`, `local`, `websocket` + ## Code examples There are two directories of examples: @@ -65,6 +73,12 @@ There are two directories of examples: - [foundational](https://github.com/daily-co/daily-ai-sdk/tree/main/examples/foundational) — demos that build on each other, introducing one or two concepts at a time - [starter apps](https://github.com/daily-co/daily-ai-sdk/tree/main/examples/starter-apps) — complete applications that you can use as starting points for development +Before running the examples you need to install the dependencies (which will install all the dependencies to run all of the examples): + +``` +pip install -r requirements.txt +``` + To run the example below you need to sign up for a [free Daily account](https://dashboard.daily.co/u/signup) and create a Daily room (so you can hear the LLM talking). After that, join the room's URL directly from a browser tab and run: ``` @@ -76,14 +90,14 @@ python examples/foundational/02-llm-say-one-thing.py _Note that you may need to set up a virtual environment before following the instructions below. For instance, you might need to run the following from the root of the repo:_ ``` -python3 -m venv env -source env/bin/activate +python3 -m venv venv +source venv/bin/activate ``` From the root of this repo, run the following: ``` -pip install -r requirements.txt +pip install -r requirements.txt -r requirements-dev.txt python -m build ``` @@ -101,13 +115,7 @@ pip install path_to_this_repo ### Running tests -To run tests you need to install `pytest`: - -``` -pip install pytest -``` - -Then, from the root directory, run: +From the root directory, run: ``` pytest --doctest-modules --ignore-glob="*to_be_updated*" src tests diff --git a/pyproject.toml b/pyproject.toml index 18ca2e56b..6888759c7 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -20,28 +20,29 @@ classifiers = [ "Topic :: Scientific/Engineering :: Artificial Intelligence" ] dependencies = [ - "aiohttp", - "anthropic", - "azure-cognitiveservices-speech", - "daily-python", - "fal", - "faster_whisper", - "flask", - "flask_cors", - "google-cloud-texttospeech", - "numpy", - "openai", - "Pillow", - "pyht", - "python-dotenv", - "typing-extensions", - "websockets" + "aiohttp==3.9.3", + "numpy==1.26.4", + "Pillow==10.2.0", + "typing-extensions==4.10.0", ] [project.urls] Source = "https://github.com/daily-co/daily-ai-sdk" Website = "https://daily.co" +[project.optional-dependencies] +anthropic = [ "anthropic==0.20.0" ] +azure = [ "azure-cognitiveservices-speech==1.36.0" ] +daily = [ "daily-python==0.7.2" ] +examples = [ "python-dotenv==1.0.1", "flask==3.0.2", "flask_cors==4.0.0" ] +fal = [ "fal==0.12.3" ] +local = [ "pyaudio==0.2.14" ] +openai = [ "openai==1.14.2" ] +playht = [ "pyht==0.0.26" ] +silero = [ "torch==2.2.1", "torchaudio==2.2.1" ] +websocket = [ "websockets==12.0" ] +whisper = [ "faster_whisper==1.0.1" ] + [tool.setuptools.packages.find] # All the following settings are optional: where = ["src"] diff --git a/requirements-dev.txt b/requirements-dev.txt new file mode 100644 index 000000000..39c6d0b2e --- /dev/null +++ b/requirements-dev.txt @@ -0,0 +1,4 @@ +autopep8==2.0.4 +build==1.0.3 +pip-tools==7.4.1 +pytest==8.1.1 diff --git a/requirements.txt b/requirements.txt index 6f4b399f1..ae6faf9e0 100644 --- a/requirements.txt +++ b/requirements.txt @@ -1,4 +1,319 @@ -autopep8==2.0.4 -build==1.0.3 -packaging==23.2 -pyproject_hooks==1.0.0 +# +# This file is autogenerated by pip-compile with Python 3.10 +# by the following command: +# +# pip-compile --all-extras pyproject.toml +# +aiohttp==3.9.3 + # via dailyai (pyproject.toml) +aiosignal==1.3.1 + # via aiohttp +anthropic==0.20.0 + # via dailyai (pyproject.toml) +anyio==4.3.0 + # via + # anthropic + # httpx + # openai + # starlette +async-timeout==4.0.3 + # via aiohttp +attrs==23.2.0 + # via + # aiohttp + # fal +av==11.0.0 + # via faster-whisper +azure-cognitiveservices-speech==1.36.0 + # via dailyai (pyproject.toml) +blinker==1.7.0 + # via flask +certifi==2024.2.2 + # via + # httpcore + # httpx + # requests +charset-normalizer==3.3.2 + # via requests +click==8.1.7 + # via + # fal + # flask +colorama==0.4.6 + # via fal +coloredlogs==15.0.1 + # via onnxruntime +ctranslate2==4.1.0 + # via faster-whisper +daily-python==0.7.2 + # via dailyai (pyproject.toml) +deprecated==1.2.14 + # via opentelemetry-api +dill==0.3.7 + # via fal +distlib==0.3.8 + # via virtualenv +distro==1.9.0 + # via + # anthropic + # openai +exceptiongroup==1.2.0 + # via anyio +fal==0.12.3 + # via dailyai (pyproject.toml) +fastapi==0.99.1 + # via fal +faster-whisper==1.0.1 + # via dailyai (pyproject.toml) +filelock==3.13.3 + # via + # huggingface-hub + # pyht + # torch + # triton + # virtualenv +flask==3.0.2 + # via + # dailyai (pyproject.toml) + # flask-cors +flask-cors==4.0.0 + # via dailyai (pyproject.toml) +flatbuffers==24.3.25 + # via onnxruntime +frozenlist==1.4.1 + # via + # aiohttp + # aiosignal +fsspec==2024.3.1 + # via + # huggingface-hub + # torch +grpc-interceptor==0.15.4 + # via fal +grpcio==1.62.1 + # via + # fal + # grpc-interceptor + # isolate + # isolate-proto + # pyht +h11==0.14.0 + # via httpcore +httpcore==1.0.5 + # via httpx +httpx==0.27.0 + # via + # anthropic + # fal + # openai +huggingface-hub==0.22.2 + # via + # faster-whisper + # tokenizers +humanfriendly==10.0 + # via coloredlogs +idna==3.6 + # via + # anyio + # httpx + # requests + # yarl +importlib-metadata==7.0.0 + # via opentelemetry-api +isolate[build]==0.12.7 + # via + # fal + # isolate-proto +isolate-proto==0.3.3 + # via fal +itsdangerous==2.1.2 + # via flask +jinja2==3.1.3 + # via + # flask + # torch +markdown-it-py==3.0.0 + # via rich +markupsafe==2.1.5 + # via + # jinja2 + # werkzeug +mdurl==0.1.2 + # via markdown-it-py +mpmath==1.3.0 + # via sympy +msgpack==1.0.8 + # via fal +multidict==6.0.5 + # via + # aiohttp + # yarl +networkx==3.2.1 + # via torch +numpy==1.26.4 + # via + # ctranslate2 + # dailyai (pyproject.toml) + # onnxruntime +nvidia-cublas-cu12==12.1.3.1 + # via + # nvidia-cudnn-cu12 + # nvidia-cusolver-cu12 + # torch +nvidia-cuda-cupti-cu12==12.1.105 + # via torch +nvidia-cuda-nvrtc-cu12==12.1.105 + # via torch +nvidia-cuda-runtime-cu12==12.1.105 + # via torch +nvidia-cudnn-cu12==8.9.2.26 + # via torch +nvidia-cufft-cu12==11.0.2.54 + # via torch +nvidia-curand-cu12==10.3.2.106 + # via torch +nvidia-cusolver-cu12==11.4.5.107 + # via torch +nvidia-cusparse-cu12==12.1.0.106 + # via + # nvidia-cusolver-cu12 + # torch +nvidia-nccl-cu12==2.19.3 + # via torch +nvidia-nvjitlink-cu12==12.4.127 + # via + # nvidia-cusolver-cu12 + # nvidia-cusparse-cu12 +nvidia-nvtx-cu12==12.1.105 + # via torch +onnxruntime==1.17.1 + # via faster-whisper +openai==1.14.2 + # via dailyai (pyproject.toml) +opentelemetry-api==1.24.0 + # via + # fal + # opentelemetry-sdk +opentelemetry-sdk==1.24.0 + # via fal +opentelemetry-semantic-conventions==0.45b0 + # via opentelemetry-sdk +packaging==24.0 + # via + # fal + # huggingface-hub + # onnxruntime +pathspec==0.11.2 + # via fal +pillow==10.2.0 + # via + # dailyai (pyproject.toml) + # fal +platformdirs==4.2.0 + # via + # isolate + # virtualenv +portalocker==2.8.2 + # via fal +protobuf==4.25.3 + # via + # isolate + # isolate-proto + # onnxruntime + # pyht +pyaudio==0.2.14 + # via dailyai (pyproject.toml) +pydantic==1.10.15 + # via + # anthropic + # fal + # fastapi + # openai +pygments==2.17.2 + # via rich +pyht==0.0.26 + # via dailyai (pyproject.toml) +pyjwt==2.8.0 + # via fal +python-dateutil==2.9.0.post0 + # via fal +python-dotenv==1.0.1 + # via dailyai (pyproject.toml) +pyyaml==6.0.1 + # via + # ctranslate2 + # huggingface-hub + # isolate +requests==2.31.0 + # via + # huggingface-hub + # pyht +rich==13.7.1 + # via fal +six==1.16.0 + # via python-dateutil +sniffio==1.3.1 + # via + # anthropic + # anyio + # httpx + # openai +starlette==0.27.0 + # via fastapi +structlog==22.3.0 + # via fal +sympy==1.12 + # via + # onnxruntime + # torch +tblib==3.0.0 + # via isolate +tokenizers==0.15.2 + # via + # anthropic + # faster-whisper +torch==2.2.1 + # via + # dailyai (pyproject.toml) + # torchaudio +torchaudio==2.2.1 + # via dailyai (pyproject.toml) +tqdm==4.66.2 + # via + # huggingface-hub + # openai +triton==2.2.0 + # via torch +types-python-dateutil==2.9.0.20240316 + # via fal +typing-extensions==4.10.0 + # via + # anthropic + # anyio + # dailyai (pyproject.toml) + # fal + # fastapi + # huggingface-hub + # openai + # opentelemetry-sdk + # pydantic + # torch +urllib3==2.2.1 + # via requests +virtualenv==20.25.1 + # via isolate +websockets==12.0 + # via + # dailyai (pyproject.toml) + # fal +werkzeug==3.0.2 + # via flask +wrapt==1.16.0 + # via deprecated +yarl==1.9.4 + # via aiohttp +zipp==3.18.1 + # via importlib-metadata + +# The following packages are considered to be unsafe in a requirements file: +# setuptools From 6918dc69f04a740090b4d69a3261b6e3d3cf5f34 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Aleix=20Conchillo=20Flaqu=C3=A9?= Date: Wed, 3 Apr 2024 15:07:32 -0700 Subject: [PATCH 02/11] github: separate build and test workflows --- .github/workflows/build.yaml | 53 ++++++++++++++++++++++++++++++++++++ .github/workflows/tests.yaml | 17 +++--------- 2 files changed, 57 insertions(+), 13 deletions(-) create mode 100644 .github/workflows/build.yaml diff --git a/.github/workflows/build.yaml b/.github/workflows/build.yaml new file mode 100644 index 000000000..068469986 --- /dev/null +++ b/.github/workflows/build.yaml @@ -0,0 +1,53 @@ +name: build + +on: + workflow_dispatch: + push: + branches: + - main + pull_request: + branches: + - "**" + paths-ignore: + - "docs/**" + +concurrency: + group: build-${{ github.event.pull_request.number || github.ref }} + cancel-in-progress: true + +jobs: + build: + name: "Build and Install" + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v4 + - name: Set up Python + id: setup_python + uses: actions/setup-python@v4 + with: + python-version: '3.10' + - name: Cache virtual environment + uses: actions/cache@v3 + with: + # We are hashing requirements-dev.txt and requirements-extra.txt which + # contain all dependencies needed to run the tests and examples. + key: venv-${{ runner.os }}-${{ steps.setup_python.outputs.python-version}}-${{ hashFiles('requirements.txt') }}-${{ hashFiles('requirements-dev.txt') }} + path: .venv + - name: Install system packages + run: sudo apt-get install -y portaudio19-dev + - name: Setup virtual environment + run: | + python -m venv .venv + - name: Install basic Python dependencies + run: | + source .venv/bin/activate + python -m pip install --upgrade pip + pip install -r requirements.txt -r requirements-dev.txt + - name: Build project + run: | + source .venv/bin/activate + python -m build + - name: Install project and other Python dependencies + run: | + source .venv/bin/activate + pip install --editable . diff --git a/.github/workflows/tests.yaml b/.github/workflows/tests.yaml index 4222e1e8f..fc90bfaaf 100644 --- a/.github/workflows/tests.yaml +++ b/.github/workflows/tests.yaml @@ -29,9 +29,9 @@ jobs: - name: Cache virtual environment uses: actions/cache@v3 with: - # TODO: we are hashing requirements.txt but that doesn't contain all - # our dependencies pinned. - key: venv-${{ runner.os }}-${{ steps.setup_python.outputs.python-version}}-${{ hashFiles('requirements.txt') }} + # We are hashing requirements-dev.txt and requirements-extra.txt which + # contain all dependencies needed to run the tests and examples. + key: venv-${{ runner.os }}-${{ steps.setup_python.outputs.python-version}}-${{ hashFiles('requirements.txt') }}-${{ hashFiles('requirements-dev.txt') }} path: .venv - name: Install system packages run: sudo apt-get install -y portaudio19-dev @@ -42,17 +42,8 @@ jobs: run: | source .venv/bin/activate python -m pip install --upgrade pip - pip install -r requirements.txt - - name: Build project - run: | - source .venv/bin/activate - python -m build - - name: Install project and other Python dependencies - run: | - source .venv/bin/activate - pip install --editable . + pip install -r requirements.txt -r requirements-dev.txt - name: Test with pytest run: | source .venv/bin/activate - pip install pytest pytest --doctest-modules --ignore-glob="*to_be_updated*" src tests From 23735cb3a396594e65991fbddc91198800025c73 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Aleix=20Conchillo=20Flaqu=C3=A9?= Date: Wed, 3 Apr 2024 15:08:01 -0700 Subject: [PATCH 03/11] dot-env.example: cleanup and add missing environment variables --- dot-env.template | 26 +++++++++++++++++++++++--- 1 file changed, 23 insertions(+), 3 deletions(-) diff --git a/dot-env.template b/dot-env.template index 60e09358a..bbbef51ab 100644 --- a/dot-env.template +++ b/dot-env.template @@ -1,5 +1,25 @@ -OPENAI_API_KEY=... -ELEVENLABS_API_KEY=... -ELEVENLABS_VOICE_ID=... +# Anthropic +ANTHROPIC_API_KEY=... + +# Azure +SPEECH_KEY=... +SPEECH_REGION=... + +# Daily DAILY_API_KEY=... DAILY_SAMPLE_ROOM_URL=https://... + +# ElevenLabs +ELEVENLABS_API_KEY=... +ELEVENLABS_VOICE_ID=... + +# Fal +FAL_KEY_ID=... +FAL_KEY_SECRET=... + +# PlayHT +PLAY_HT_USER_ID=... +PLAY_HT_API_KEY=... + +# OpenAI +OPENAI_API_KEY=... From 3528f5d7356767a138e4b14a26c24f1809ae0b20 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Aleix=20Conchillo=20Flaqu=C3=A9?= Date: Wed, 3 Apr 2024 15:09:12 -0700 Subject: [PATCH 04/11] use conditional imports and show help errors if modules not found --- examples/starter-apps/patient-intake.py | 2 +- src/dailyai/pipeline/frames.py | 11 --------- .../pipeline/opeanai_llm_aggregator.py | 10 ++++++-- src/dailyai/pipeline/openai_frames.py | 12 ++++++++++ src/dailyai/services/anthropic_llm_service.py | 9 +++++++- src/dailyai/services/azure_ai_services.py | 18 ++++++++++----- src/dailyai/services/fal_ai_services.py | 9 ++++++-- src/dailyai/services/open_ai_services.py | 10 +++++++- .../services/openai_api_llm_service.py | 21 +++++++++++------ src/dailyai/services/openai_llm_context.py | 19 ++++++++++----- src/dailyai/services/playht_ai_service.py | 13 ++++++++--- src/dailyai/services/whisper_ai_services.py | 10 +++++++- src/dailyai/transports/daily_transport.py | 23 ++++++++++++------- src/dailyai/transports/local_transport.py | 15 ++++++------ src/dailyai/transports/threaded_transport.py | 1 - src/dailyai/transports/websocket_transport.py | 9 +++++++- tests/integration/integration_azure_llm.py | 4 +--- tests/integration/integration_ollama_llm.py | 4 +--- tests/integration/integration_openai_llm.py | 4 +--- 19 files changed, 137 insertions(+), 67 deletions(-) create mode 100644 src/dailyai/pipeline/openai_frames.py diff --git a/examples/starter-apps/patient-intake.py b/examples/starter-apps/patient-intake.py index 9409d894a..553aacde5 100644 --- a/examples/starter-apps/patient-intake.py +++ b/examples/starter-apps/patient-intake.py @@ -19,12 +19,12 @@ # 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 diff --git a/src/dailyai/pipeline/frames.py b/src/dailyai/pipeline/frames.py index 658f3c357..4942747b8 100644 --- a/src/dailyai/pipeline/frames.py +++ b/src/dailyai/pipeline/frames.py @@ -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 diff --git a/src/dailyai/pipeline/opeanai_llm_aggregator.py b/src/dailyai/pipeline/opeanai_llm_aggregator.py index 38c0f4566..b4b254087 100644 --- a/src/dailyai/pipeline/opeanai_llm_aggregator.py +++ b/src/dailyai/pipeline/opeanai_llm_aggregator.py @@ -4,15 +4,21 @@ 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): diff --git a/src/dailyai/pipeline/openai_frames.py b/src/dailyai/pipeline/openai_frames.py new file mode 100644 index 000000000..2a14c670e --- /dev/null +++ b/src/dailyai/pipeline/openai_frames.py @@ -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 diff --git a/src/dailyai/services/anthropic_llm_service.py b/src/dailyai/services/anthropic_llm_service.py index ea48950e7..44c045992 100644 --- a/src/dailyai/services/anthropic_llm_service.py +++ b/src/dailyai/services/anthropic_llm_service.py @@ -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): diff --git a/src/dailyai/services/azure_ai_services.py b/src/dailyai/services/azure_ai_services.py index b6ca1e4fd..0f0151144 100644 --- a/src/dailyai/services/azure_ai_services.py +++ b/src/dailyai/services/azure_ai_services.py @@ -9,12 +9,18 @@ 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 diff --git a/src/dailyai/services/fal_ai_services.py b/src/dailyai/services/fal_ai_services.py index 10343f97c..9130b062b 100644 --- a/src/dailyai/services/fal_ai_services.py +++ b/src/dailyai/services/fal_ai_services.py @@ -1,4 +1,3 @@ -import fal import aiohttp import asyncio import io @@ -10,7 +9,13 @@ 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): diff --git a/src/dailyai/services/open_ai_services.py b/src/dailyai/services/open_ai_services.py index 61963769a..9d177f8b7 100644 --- a/src/dailyai/services/open_ai_services.py +++ b/src/dailyai/services/open_ai_services.py @@ -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): diff --git a/src/dailyai/services/openai_api_llm_service.py b/src/dailyai/services/openai_api_llm_service.py index d36e878e2..2ddfc7796 100644 --- a/src/dailyai/services/openai_api_llm_service.py +++ b/src/dailyai/services/openai_api_llm_service.py @@ -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 @@ 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): diff --git a/src/dailyai/services/openai_llm_context.py b/src/dailyai/services/openai_llm_context.py index ce705f547..2d16c3cb6 100644 --- a/src/dailyai/services/openai_llm_context.py +++ b/src/dailyai/services/openai_llm_context.py @@ -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: diff --git a/src/dailyai/services/playht_ai_service.py b/src/dailyai/services/playht_ai_service.py index 350e5cb88..291855264 100644 --- a/src/dailyai/services/playht_ai_service.py +++ b/src/dailyai/services/playht_ai_service.py @@ -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): diff --git a/src/dailyai/services/whisper_ai_services.py b/src/dailyai/services/whisper_ai_services.py index cc657e6cf..ddddb4f98 100644 --- a/src/dailyai/services/whisper_ai_services.py +++ b/src/dailyai/services/whisper_ai_services.py @@ -3,10 +3,18 @@ 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" diff --git a/src/dailyai/transports/daily_transport.py b/src/dailyai/transports/daily_transport.py index d510cadbb..66798782f 100644 --- a/src/dailyai/transports/daily_transport.py +++ b/src/dailyai/transports/daily_transport.py @@ -15,14 +15,21 @@ 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 diff --git a/src/dailyai/transports/local_transport.py b/src/dailyai/transports/local_transport.py index 4b24fb535..e79b147a8 100644 --- a/src/dailyai/transports/local_transport.py +++ b/src/dailyai/transports/local_transport.py @@ -4,17 +4,18 @@ 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 diff --git a/src/dailyai/transports/threaded_transport.py b/src/dailyai/transports/threaded_transport.py index 033cb97a2..9adb496d4 100644 --- a/src/dailyai/transports/threaded_transport.py +++ b/src/dailyai/transports/threaded_transport.py @@ -1,7 +1,6 @@ from abc import abstractmethod import asyncio import itertools -import logging import numpy as np import queue diff --git a/src/dailyai/transports/websocket_transport.py b/src/dailyai/transports/websocket_transport.py index 0784eb89f..f5009a02e 100644 --- a/src/dailyai/transports/websocket_transport.py +++ b/src/dailyai/transports/websocket_transport.py @@ -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.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. diff --git a/tests/integration/integration_azure_llm.py b/tests/integration/integration_azure_llm.py index 41cb8ee6c..d4744bd8b 100644 --- a/tests/integration/integration_azure_llm.py +++ b/tests/integration/integration_azure_llm.py @@ -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 diff --git a/tests/integration/integration_ollama_llm.py b/tests/integration/integration_ollama_llm.py index 527a20e98..2ac90ce65 100644 --- a/tests/integration/integration_ollama_llm.py +++ b/tests/integration/integration_ollama_llm.py @@ -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 ( diff --git a/tests/integration/integration_openai_llm.py b/tests/integration/integration_openai_llm.py index baea80d00..fa4a449ec 100644 --- a/tests/integration/integration_openai_llm.py +++ b/tests/integration/integration_openai_llm.py @@ -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 ( From e3ee3f9cc6647129bd73644e3e475f92c9d040a5 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Aleix=20Conchillo=20Flaqu=C3=A9?= Date: Wed, 3 Apr 2024 15:12:46 -0700 Subject: [PATCH 05/11] github(lint): use requirements-dev.txt --- .github/workflows/lint.yaml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/.github/workflows/lint.yaml b/.github/workflows/lint.yaml index da097d237..6dba57d28 100644 --- a/.github/workflows/lint.yaml +++ b/.github/workflows/lint.yaml @@ -29,11 +29,11 @@ jobs: - name: Setup virtual environment run: | python -m venv .venv - - name: Install basic Python dependencies + - name: Install development Python dependencies run: | source .venv/bin/activate python -m pip install --upgrade pip - pip install -r requirements.txt + pip install -r requirements-dev.txt - name: autopep8 id: autopep8 run: | From 48bb3c695531284071b8fb01cedc1fd1431137bd Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Aleix=20Conchillo=20Flaqu=C3=A9?= Date: Wed, 3 Apr 2024 15:57:59 -0700 Subject: [PATCH 06/11] github: add publish to pypi workflows --- .github/workflows/deploy.yaml | 69 +++++++++++++++++++++++++++++ .github/workflows/test_deploy.yaml | 71 ++++++++++++++++++++++++++++++ 2 files changed, 140 insertions(+) create mode 100644 .github/workflows/deploy.yaml create mode 100644 .github/workflows/test_deploy.yaml diff --git a/.github/workflows/deploy.yaml b/.github/workflows/deploy.yaml new file mode 100644 index 000000000..96653bb53 --- /dev/null +++ b/.github/workflows/deploy.yaml @@ -0,0 +1,69 @@ +name: deploy + +on: + workflow_dispatch: + inputs: + gitref: + type: string + description: "what git ref to build" + required: true + +jobs: + build: + name: "Build and upload wheel" + runs-on: ubuntu-latest + steps: + - name: Checkout repo + uses: actions/checkout@v4 + with: + ref: ${{ github.event.inputs.gitref }} + - name: Set up Python + id: setup_python + uses: actions/setup-python@v4 + with: + python-version: '3.10' + - name: Cache virtual environment + uses: actions/cache@v3 + with: + # We are hashing requirements-dev.txt and requirements-extra.txt which + # contain all dependencies needed to run the tests and examples. + key: venv-${{ runner.os }}-${{ steps.setup_python.outputs.python-version}}-${{ hashFiles('requirements.txt') }}-${{ hashFiles('requirements-dev.txt') }} + path: .venv + - name: Install system packages + run: sudo apt-get install -y portaudio19-dev + - name: Setup virtual environment + run: | + python -m venv .venv + - name: Install basic Python dependencies + run: | + source .venv/bin/activate + python -m pip install --upgrade pip + pip install -r requirements.txt -r requirements-dev.txt + - name: Build project + run: | + source .venv/bin/activate + python -m build + - name: Upload wheel + uses: actions/upload-artifact@v4 + with: + path: ./dist + + publish-to-pypi: + name: "Publish to PyPI" + runs-on: ubuntu-latest + needs: [ build ] + environment: + name: pypi + url: https://pypi.org/p/dailyai + permissions: + id-token: write + steps: + - name: Download wheels + uses: actions/download-artifact@v4 + with: + path: ./dist + - name: Publish to PyPI + uses: pypa/gh-action-pypi-publish@release/v1 + with: + verbose: true + print-hash: true diff --git a/.github/workflows/test_deploy.yaml b/.github/workflows/test_deploy.yaml new file mode 100644 index 000000000..b370b0905 --- /dev/null +++ b/.github/workflows/test_deploy.yaml @@ -0,0 +1,71 @@ +name: test-deploy + +on: + workflow_dispatch: + push: + branches: + - main + pull_request: + branches: + - "**" + +jobs: + build: + name: "Build and upload wheel" + runs-on: ubuntu-latest + steps: + - name: Checkout repo + uses: actions/checkout@v4 + with: + ref: ${{ github.event.inputs.gitref }} + - name: Set up Python + id: setup_python + uses: actions/setup-python@v4 + with: + python-version: '3.10' + - name: Cache virtual environment + uses: actions/cache@v3 + with: + # We are hashing requirements-dev.txt and requirements-extra.txt which + # contain all dependencies needed to run the tests and examples. + key: venv-${{ runner.os }}-${{ steps.setup_python.outputs.python-version}}-${{ hashFiles('requirements.txt') }}-${{ hashFiles('requirements-dev.txt') }} + path: .venv + - name: Install system packages + run: sudo apt-get install -y portaudio19-dev + - name: Setup virtual environment + run: | + python -m venv .venv + - name: Install basic Python dependencies + run: | + source .venv/bin/activate + python -m pip install --upgrade pip + pip install -r requirements.txt -r requirements-dev.txt + - name: Build project + run: | + source .venv/bin/activate + python -m build + - name: Upload wheels + uses: actions/upload-artifact@v4 + with: + path: ./dist + + publish-to-pypi: + name: "Test publish to PyPI" + runs-on: ubuntu-latest + needs: [ build ] + environment: + name: pypi + url: https://pypi.org/p/dailyai + permissions: + id-token: write + steps: + - name: Download wheels + uses: actions/download-artifact@v4 + with: + path: ./dist + - name: Publish to PyPI + uses: pypa/gh-action-pypi-publish@release/v1 + with: + verbose: true + print-hash: true + repository-url: https://test.pypi.org/legacy/ From d57d473c13ce50c430b684ff3f385e763c2c8beb Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Aleix=20Conchillo=20Flaqu=C3=A9?= Date: Wed, 3 Apr 2024 16:13:07 -0700 Subject: [PATCH 07/11] pyproject.toml: use setuptools_scm to auto manage versions --- pyproject.toml | 7 +++++-- requirements-dev.txt | 2 ++ 2 files changed, 7 insertions(+), 2 deletions(-) diff --git a/pyproject.toml b/pyproject.toml index 6888759c7..ebffca741 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -1,10 +1,10 @@ [build-system] -requires = ["setuptools"] +requires = ["setuptools>=64", "setuptools_scm>=8"] build-backend = "setuptools.build_meta" [project] name = "dailyai" -version = "0.0.3.1" +dynamic = ["version"] description = "An open source framework for real-time, multi-modal, conversational AI applications" license = { text = "BSD 2-Clause License" } readme = "README.md" @@ -49,3 +49,6 @@ where = ["src"] [tool.pytest.ini_options] pythonpath = ["src"] + +[tool.setuptools_scm] +# Empty diff --git a/requirements-dev.txt b/requirements-dev.txt index 39c6d0b2e..bbd666cf6 100644 --- a/requirements-dev.txt +++ b/requirements-dev.txt @@ -2,3 +2,5 @@ autopep8==2.0.4 build==1.0.3 pip-tools==7.4.1 pytest==8.1.1 +setuptools==69.2.0 +setuptools_scm==8.0.4 From 18c4bccc13fc9574adcbf0e6feccb72dc38ae4c3 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Aleix=20Conchillo=20Flaqu=C3=A9?= Date: Wed, 3 Apr 2024 16:21:04 -0700 Subject: [PATCH 08/11] github: rename deploy to publish --- .github/workflows/{deploy.yaml => publish.yaml} | 6 +++--- .github/workflows/{test_deploy.yaml => publish_test.yaml} | 4 ++-- 2 files changed, 5 insertions(+), 5 deletions(-) rename .github/workflows/{deploy.yaml => publish.yaml} (96%) rename .github/workflows/{test_deploy.yaml => publish_test.yaml} (97%) diff --git a/.github/workflows/deploy.yaml b/.github/workflows/publish.yaml similarity index 96% rename from .github/workflows/deploy.yaml rename to .github/workflows/publish.yaml index 96653bb53..b4aa635dd 100644 --- a/.github/workflows/deploy.yaml +++ b/.github/workflows/publish.yaml @@ -1,4 +1,4 @@ -name: deploy +name: publish on: workflow_dispatch: @@ -10,7 +10,7 @@ on: jobs: build: - name: "Build and upload wheel" + name: "Build and upload wheels" runs-on: ubuntu-latest steps: - name: Checkout repo @@ -43,7 +43,7 @@ jobs: run: | source .venv/bin/activate python -m build - - name: Upload wheel + - name: Upload wheels uses: actions/upload-artifact@v4 with: path: ./dist diff --git a/.github/workflows/test_deploy.yaml b/.github/workflows/publish_test.yaml similarity index 97% rename from .github/workflows/test_deploy.yaml rename to .github/workflows/publish_test.yaml index b370b0905..ab3dc1448 100644 --- a/.github/workflows/test_deploy.yaml +++ b/.github/workflows/publish_test.yaml @@ -1,4 +1,4 @@ -name: test-deploy +name: test-publish on: workflow_dispatch: @@ -11,7 +11,7 @@ on: jobs: build: - name: "Build and upload wheel" + name: "Build and upload wheels" runs-on: ubuntu-latest steps: - name: Checkout repo From 1fc800754b022cc6efadcf7c0d6e2f690c9e3a48 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Aleix=20Conchillo=20Flaqu=C3=A9?= Date: Wed, 3 Apr 2024 16:26:58 -0700 Subject: [PATCH 09/11] github: no need to install dependencies when building/deploying --- .github/workflows/build.yaml | 11 +---------- .github/workflows/publish_test.yaml | 11 +---------- 2 files changed, 2 insertions(+), 20 deletions(-) diff --git a/.github/workflows/build.yaml b/.github/workflows/build.yaml index 068469986..d5f36687c 100644 --- a/.github/workflows/build.yaml +++ b/.github/workflows/build.yaml @@ -26,15 +26,6 @@ jobs: uses: actions/setup-python@v4 with: python-version: '3.10' - - name: Cache virtual environment - uses: actions/cache@v3 - with: - # We are hashing requirements-dev.txt and requirements-extra.txt which - # contain all dependencies needed to run the tests and examples. - key: venv-${{ runner.os }}-${{ steps.setup_python.outputs.python-version}}-${{ hashFiles('requirements.txt') }}-${{ hashFiles('requirements-dev.txt') }} - path: .venv - - name: Install system packages - run: sudo apt-get install -y portaudio19-dev - name: Setup virtual environment run: | python -m venv .venv @@ -42,7 +33,7 @@ jobs: run: | source .venv/bin/activate python -m pip install --upgrade pip - pip install -r requirements.txt -r requirements-dev.txt + pip install -r requirements-dev.txt - name: Build project run: | source .venv/bin/activate diff --git a/.github/workflows/publish_test.yaml b/.github/workflows/publish_test.yaml index ab3dc1448..06019fdbc 100644 --- a/.github/workflows/publish_test.yaml +++ b/.github/workflows/publish_test.yaml @@ -23,15 +23,6 @@ jobs: uses: actions/setup-python@v4 with: python-version: '3.10' - - name: Cache virtual environment - uses: actions/cache@v3 - with: - # We are hashing requirements-dev.txt and requirements-extra.txt which - # contain all dependencies needed to run the tests and examples. - key: venv-${{ runner.os }}-${{ steps.setup_python.outputs.python-version}}-${{ hashFiles('requirements.txt') }}-${{ hashFiles('requirements-dev.txt') }} - path: .venv - - name: Install system packages - run: sudo apt-get install -y portaudio19-dev - name: Setup virtual environment run: | python -m venv .venv @@ -39,7 +30,7 @@ jobs: run: | source .venv/bin/activate python -m pip install --upgrade pip - pip install -r requirements.txt -r requirements-dev.txt + pip install -r requirements-dev.txt - name: Build project run: | source .venv/bin/activate From 8bc3c03a695e9b7d2d50dc7fc688923e63d924d0 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Aleix=20Conchillo=20Flaqu=C3=A9?= Date: Wed, 3 Apr 2024 18:10:47 -0700 Subject: [PATCH 10/11] add a requirements.txt per platform --- .github/workflows/build.yaml | 2 +- .github/workflows/lint.yaml | 2 +- .github/workflows/publish.yaml | 2 +- .github/workflows/publish_test.yaml | 2 +- .github/workflows/tests.yaml | 2 +- README.md | 4 +- requirements-dev.txt => dev-requirements.txt | 0 ...ments.txt => linux-py3.10-requirements.txt | 0 macos-py3.10-requirements.txt | 285 ++++++++++++++++++ 9 files changed, 292 insertions(+), 7 deletions(-) rename requirements-dev.txt => dev-requirements.txt (100%) rename requirements.txt => linux-py3.10-requirements.txt (100%) create mode 100644 macos-py3.10-requirements.txt diff --git a/.github/workflows/build.yaml b/.github/workflows/build.yaml index d5f36687c..0759bcb69 100644 --- a/.github/workflows/build.yaml +++ b/.github/workflows/build.yaml @@ -33,7 +33,7 @@ jobs: run: | source .venv/bin/activate python -m pip install --upgrade pip - pip install -r requirements-dev.txt + pip install -r dev-requirements.txt - name: Build project run: | source .venv/bin/activate diff --git a/.github/workflows/lint.yaml b/.github/workflows/lint.yaml index 6dba57d28..ad5b160f1 100644 --- a/.github/workflows/lint.yaml +++ b/.github/workflows/lint.yaml @@ -33,7 +33,7 @@ jobs: run: | source .venv/bin/activate python -m pip install --upgrade pip - pip install -r requirements-dev.txt + pip install -r dev-requirements.txt - name: autopep8 id: autopep8 run: | diff --git a/.github/workflows/publish.yaml b/.github/workflows/publish.yaml index b4aa635dd..6ceccd56e 100644 --- a/.github/workflows/publish.yaml +++ b/.github/workflows/publish.yaml @@ -38,7 +38,7 @@ jobs: run: | source .venv/bin/activate python -m pip install --upgrade pip - pip install -r requirements.txt -r requirements-dev.txt + pip install -r linux-py3.10-requirements.txt -r dev-requirements.txt - name: Build project run: | source .venv/bin/activate diff --git a/.github/workflows/publish_test.yaml b/.github/workflows/publish_test.yaml index 06019fdbc..774f2b168 100644 --- a/.github/workflows/publish_test.yaml +++ b/.github/workflows/publish_test.yaml @@ -30,7 +30,7 @@ jobs: run: | source .venv/bin/activate python -m pip install --upgrade pip - pip install -r requirements-dev.txt + pip install -r dev-requirements.txt - name: Build project run: | source .venv/bin/activate diff --git a/.github/workflows/tests.yaml b/.github/workflows/tests.yaml index fc90bfaaf..67a77c905 100644 --- a/.github/workflows/tests.yaml +++ b/.github/workflows/tests.yaml @@ -42,7 +42,7 @@ jobs: run: | source .venv/bin/activate python -m pip install --upgrade pip - pip install -r requirements.txt -r requirements-dev.txt + pip install -r linux-py3.10-requirements.txt -r dev-requirements.txt - name: Test with pytest run: | source .venv/bin/activate diff --git a/README.md b/README.md index fa00ac1a5..7f3361446 100644 --- a/README.md +++ b/README.md @@ -76,7 +76,7 @@ There are two directories of examples: Before running the examples you need to install the dependencies (which will install all the dependencies to run all of the examples): ``` -pip install -r requirements.txt +pip install -r {env}-requirements.txt ``` To run the example below you need to sign up for a [free Daily account](https://dashboard.daily.co/u/signup) and create a Daily room (so you can hear the LLM talking). After that, join the room's URL directly from a browser tab and run: @@ -97,7 +97,7 @@ source venv/bin/activate From the root of this repo, run the following: ``` -pip install -r requirements.txt -r requirements-dev.txt +pip install -r {env}-requirements.txt -r dev-requirements.txt python -m build ``` diff --git a/requirements-dev.txt b/dev-requirements.txt similarity index 100% rename from requirements-dev.txt rename to dev-requirements.txt diff --git a/requirements.txt b/linux-py3.10-requirements.txt similarity index 100% rename from requirements.txt rename to linux-py3.10-requirements.txt diff --git a/macos-py3.10-requirements.txt b/macos-py3.10-requirements.txt new file mode 100644 index 000000000..cdbe80270 --- /dev/null +++ b/macos-py3.10-requirements.txt @@ -0,0 +1,285 @@ +# +# This file is autogenerated by pip-compile with Python 3.10 +# by the following command: +# +# pip-compile --all-extras pyproject.toml +# +aiohttp==3.9.3 + # via dailyai (pyproject.toml) +aiosignal==1.3.1 + # via aiohttp +anthropic==0.20.0 + # via dailyai (pyproject.toml) +anyio==4.3.0 + # via + # anthropic + # httpx + # openai + # starlette +async-timeout==4.0.3 + # via aiohttp +attrs==23.2.0 + # via + # aiohttp + # fal +av==11.0.0 + # via faster-whisper +azure-cognitiveservices-speech==1.36.0 + # via dailyai (pyproject.toml) +blinker==1.7.0 + # via flask +certifi==2024.2.2 + # via + # httpcore + # httpx + # requests +charset-normalizer==3.3.2 + # via requests +click==8.1.7 + # via + # fal + # flask +colorama==0.4.6 + # via fal +coloredlogs==15.0.1 + # via onnxruntime +ctranslate2==4.1.0 + # via faster-whisper +daily-python==0.7.2 + # via dailyai (pyproject.toml) +deprecated==1.2.14 + # via opentelemetry-api +dill==0.3.7 + # via fal +distlib==0.3.8 + # via virtualenv +distro==1.9.0 + # via + # anthropic + # openai +exceptiongroup==1.2.0 + # via anyio +fal==0.12.3 + # via dailyai (pyproject.toml) +fastapi==0.99.1 + # via fal +faster-whisper==1.0.1 + # via dailyai (pyproject.toml) +filelock==3.13.3 + # via + # huggingface-hub + # pyht + # torch + # virtualenv +flask==3.0.2 + # via + # dailyai (pyproject.toml) + # flask-cors +flask-cors==4.0.0 + # via dailyai (pyproject.toml) +flatbuffers==24.3.25 + # via onnxruntime +frozenlist==1.4.1 + # via + # aiohttp + # aiosignal +fsspec==2024.3.1 + # via + # huggingface-hub + # torch +grpc-interceptor==0.15.4 + # via fal +grpcio==1.62.1 + # via + # fal + # grpc-interceptor + # isolate + # isolate-proto + # pyht +h11==0.14.0 + # via httpcore +httpcore==1.0.5 + # via httpx +httpx==0.27.0 + # via + # anthropic + # fal + # openai +huggingface-hub==0.22.2 + # via + # faster-whisper + # tokenizers +humanfriendly==10.0 + # via coloredlogs +idna==3.6 + # via + # anyio + # httpx + # requests + # yarl +importlib-metadata==7.0.0 + # via opentelemetry-api +isolate[build]==0.12.7 + # via + # fal + # isolate-proto +isolate-proto==0.3.3 + # via fal +itsdangerous==2.1.2 + # via flask +jinja2==3.1.3 + # via + # flask + # torch +markdown-it-py==3.0.0 + # via rich +markupsafe==2.1.5 + # via + # jinja2 + # werkzeug +mdurl==0.1.2 + # via markdown-it-py +mpmath==1.3.0 + # via sympy +msgpack==1.0.8 + # via fal +multidict==6.0.5 + # via + # aiohttp + # yarl +networkx==3.2.1 + # via torch +numpy==1.26.4 + # via + # ctranslate2 + # dailyai (pyproject.toml) + # onnxruntime +onnxruntime==1.17.1 + # via faster-whisper +openai==1.14.2 + # via dailyai (pyproject.toml) +opentelemetry-api==1.24.0 + # via + # fal + # opentelemetry-sdk +opentelemetry-sdk==1.24.0 + # via fal +opentelemetry-semantic-conventions==0.45b0 + # via opentelemetry-sdk +packaging==24.0 + # via + # fal + # huggingface-hub + # onnxruntime +pathspec==0.11.2 + # via fal +pillow==10.2.0 + # via + # dailyai (pyproject.toml) + # fal +platformdirs==4.2.0 + # via + # isolate + # virtualenv +portalocker==2.8.2 + # via fal +protobuf==4.25.3 + # via + # isolate + # isolate-proto + # onnxruntime + # pyht +pyaudio==0.2.14 + # via dailyai (pyproject.toml) +pydantic==1.10.15 + # via + # anthropic + # fal + # fastapi + # openai +pygments==2.17.2 + # via rich +pyht==0.0.26 + # via dailyai (pyproject.toml) +pyjwt==2.8.0 + # via fal +python-dateutil==2.9.0.post0 + # via fal +python-dotenv==1.0.1 + # via dailyai (pyproject.toml) +pyyaml==6.0.1 + # via + # ctranslate2 + # huggingface-hub + # isolate +requests==2.31.0 + # via + # huggingface-hub + # pyht +rich==13.7.1 + # via fal +six==1.16.0 + # via python-dateutil +sniffio==1.3.1 + # via + # anthropic + # anyio + # httpx + # openai +starlette==0.27.0 + # via fastapi +structlog==22.3.0 + # via fal +sympy==1.12 + # via + # onnxruntime + # torch +tblib==3.0.0 + # via isolate +tokenizers==0.15.2 + # via + # anthropic + # faster-whisper +torch==2.2.1 + # via + # dailyai (pyproject.toml) + # torchaudio +torchaudio==2.2.1 + # via dailyai (pyproject.toml) +tqdm==4.66.2 + # via + # huggingface-hub + # openai +types-python-dateutil==2.9.0.20240316 + # via fal +typing-extensions==4.10.0 + # via + # anthropic + # anyio + # dailyai (pyproject.toml) + # fal + # fastapi + # huggingface-hub + # openai + # opentelemetry-sdk + # pydantic + # torch +urllib3==2.2.1 + # via requests +virtualenv==20.25.1 + # via isolate +websockets==12.0 + # via + # dailyai (pyproject.toml) + # fal +werkzeug==3.0.2 + # via flask +wrapt==1.16.0 + # via deprecated +yarl==1.9.4 + # via aiohttp +zipp==3.18.1 + # via importlib-metadata + +# The following packages are considered to be unsafe in a requirements file: +# setuptools From a37e4fabad1ba819dbc26e8d87683ec3ae388808 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Aleix=20Conchillo=20Flaqu=C3=A9?= Date: Thu, 4 Apr 2024 09:58:42 -0700 Subject: [PATCH 11/11] github: only run publish-test on main --- .github/workflows/publish_test.yaml | 5 +---- 1 file changed, 1 insertion(+), 4 deletions(-) diff --git a/.github/workflows/publish_test.yaml b/.github/workflows/publish_test.yaml index 774f2b168..eba8ba4f9 100644 --- a/.github/workflows/publish_test.yaml +++ b/.github/workflows/publish_test.yaml @@ -1,13 +1,10 @@ -name: test-publish +name: publish-test on: workflow_dispatch: push: branches: - main - pull_request: - branches: - - "**" jobs: build: