Skip to content

Commit

Permalink
requested changes
Browse files Browse the repository at this point in the history
  • Loading branch information
mikejgray committed Dec 21, 2023
1 parent c975dcf commit 9ff5460
Show file tree
Hide file tree
Showing 10 changed files with 179 additions and 48 deletions.
5 changes: 5 additions & 0 deletions .dockerignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
.git/
tests/
*.egg-info
build/
dist/
48 changes: 36 additions & 12 deletions Dockerfile
Original file line number Diff line number Diff line change
@@ -1,21 +1,45 @@
# Stage 1: Use a base image to install ffmpeg
FROM jrottenberg/ffmpeg:4.1 as ffmpeg-base

# Stage 2: Build the final image
FROM python:3.8-slim

LABEL vendor=neon.ai \
ai.neon.name="neon-iris"
# Label for vendor
LABEL vendor=neon.ai

ENV OVOS_CONFIG_BASE_FOLDER neon
ENV OVOS_CONFIG_FILENAME neon.yaml
ENV XDG_CONFIG_HOME /config
# Build argument for specifying extras
ARG EXTRAS

RUN apt update && \
apt install -y ffmpeg
ENV OVOS_CONFIG_BASE_FOLDER=neon \
OVOS_CONFIG_FILENAME=neon.yaml \
XDG_CONFIG_HOME=/config

ADD . /neon_iris
WORKDIR /neon_iris
# Copy ffmpeg binaries from the ffmpeg-base stage
COPY --from=ffmpeg-base /usr/local/bin/ /usr/local/bin/
COPY --from=ffmpeg-base /usr/local/lib/ /usr/local/lib/

RUN pip install wheel && \
pip install .[gradio]
RUN mkdir -p /neon_iris/requirements
COPY ./requirements/* /neon_iris/requirements

RUN pip install wheel && pip install -r /neon_iris/requirements/requirements.txt
RUN if [ "$EXTRAS" = "gradio" ]; then \
pip install -r /neon_iris/requirements/gradio.txt; \
elif [ "$EXTRAS" = "web_sat" ]; then \
pip install -r /neon_iris/requirements/web_sat.txt; \
else \
pip install -r /neon_iris/requirements/requirements.txt; \
fi

WORKDIR /neon_iris
ADD . /neon_iris
RUN pip install .

COPY docker_overlay/ /

CMD ["iris", "start-gradio"]
# Expose port 8000 for websat
EXPOSE 8000

ENTRYPOINT ["iris"]

# Default command
CMD ["-h"]
24 changes: 0 additions & 24 deletions Dockerfile.websat

This file was deleted.

37 changes: 37 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -68,6 +68,43 @@ instance connected via MQ.
This starts a local webserver and serves a web UI for interacting with a Neon
instance connected to MQ.

## Docker

### Building

To build the Docker image, run:

```bash
docker build -t ghcr.io/neongeckocom/neon-iris:latest .
```

To build the Docker image with gradio extras, run:

```bash
docker build --build-arg EXTRAS=gradio -t ghcr.io/neongeckocom/neon-iris:latest .
```

To build the Docker image with websat extras, run:

```bash
docker build --build-arg EXTRAS=websat -t ghcr.io/neongeckocom/neon-iris:latest .
```

### Running

The Docker image that is built for this service runs the `iris` CLI with the
`-h` argument by default. In order to use the container to run different services,
you must override the entrypoint. For example, to run the `start-websat` service,
you would run:

```bash
docker run --rm -p 8000:8000 ghcr.io/neongeckocom/neon-iris:latest start-websat
```

Running the container without any arguments gives you a list of commands that
can be run. You can choose to run any of these commands by replacing `start-websat`
in the above command with the command you want to run.

## websat

### Configuration
Expand Down
26 changes: 26 additions & 0 deletions neon_iris/models/__init__.py
Original file line number Diff line number Diff line change
@@ -1 +1,27 @@
# NEON AI (TM) SOFTWARE, Software Development Kit & Application Development System
# All trademark and other rights reserved by their respective owners
# Copyright 2008-2024 Neongecko.com Inc.
# BSD-3
# Redistribution and use in source and binary forms, with or without
# modification, are permitted provided that the following conditions are met:
# 1. Redistributions of source code must retain the above copyright notice,
# this list of conditions and the following disclaimer.
# 2. Redistributions in binary form must reproduce the above copyright notice,
# this list of conditions and the following disclaimer in the documentation
# and/or other materials provided with the distribution.
# 3. Neither the name of the copyright holder nor the names of its
# contributors may be used to endorse or promote products derived from this
# software without specific prior written permission.
# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
# AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
# THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
# PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR
# CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
# EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
# PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA,
# OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
# LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
# NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
# SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.

from .web_sat import UserInput, UserInputResponse # noqa
26 changes: 26 additions & 0 deletions neon_iris/models/web_sat.py
Original file line number Diff line number Diff line change
@@ -1,4 +1,30 @@
"""API data models for the WebSAT API."""
# NEON AI (TM) SOFTWARE, Software Development Kit & Application Development System
# All trademark and other rights reserved by their respective owners
# Copyright 2008-2021 Neongecko.com Inc.
# BSD-3
# Redistribution and use in source and binary forms, with or without
# modification, are permitted provided that the following conditions are met:
# 1. Redistributions of source code must retain the above copyright notice,
# this list of conditions and the following disclaimer.
# 2. Redistributions in binary form must reproduce the above copyright notice,
# this list of conditions and the following disclaimer in the documentation
# and/or other materials provided with the distribution.
# 3. Neither the name of the copyright holder nor the names of its
# contributors may be used to endorse or promote products derived from this
# software without specific prior written permission.
# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
# AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
# THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
# PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR
# CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
# EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
# PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA,
# OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
# LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
# NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
# SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.

from typing import Optional
from pydantic import BaseModel

Expand Down
3 changes: 2 additions & 1 deletion neon_iris/version.py
Original file line number Diff line number Diff line change
@@ -1,8 +1,9 @@
# NEON AI (TM) SOFTWARE, Software Development Kit & Application Framework
# All trademark and other rights reserved by their respective owners
# Copyright 2008-2022 Neongecko.com Inc.
# Copyright 2008-2024 Neongecko.com Inc.
# Contributors: Daniel McKnight, Guy Daniels, Elon Gasper, Richard Leeds,
# Regina Bloomstine, Casimiro Ferreira, Andrii Pernatii, Kirill Hrymailo
# Mike Gray, David Scripka
# BSD-3 License
# Redistribution and use in source and binary forms, with or without
# modification, are permitted provided that the following conditions are met:
Expand Down
2 changes: 1 addition & 1 deletion neon_iris/web_client.py
Original file line number Diff line number Diff line change
Expand Up @@ -118,7 +118,7 @@ def update_profile(self, stt_lang: str, tts_lang: str, tts_lang_2: str,
def on_user_input(self, utterance: str,
chat_history: List[Tuple[str, str]],
audio_input: str,
client_session: str):
client_session: str):# -> tuple[List[Tuple[str, str]], str, Literal[''], None, Any]:
"""
Callback to handle textual user input
@param utterance: String utterance submitted by the user
Expand Down
50 changes: 41 additions & 9 deletions neon_iris/web_sat_client.py
Original file line number Diff line number Diff line change
@@ -1,10 +1,36 @@
"""Runs a web server that serves the Neon AI Web UI and Voice Satellite."""
# NEON AI (TM) SOFTWARE, Software Development Kit & Application Development System
# All trademark and other rights reserved by their respective owners
# Copyright 2008-2024 Neongecko.com Inc.
# BSD-3
# Redistribution and use in source and binary forms, with or without
# modification, are permitted provided that the following conditions are met:
# 1. Redistributions of source code must retain the above copyright notice,
# this list of conditions and the following disclaimer.
# 2. Redistributions in binary form must reproduce the above copyright notice,
# this list of conditions and the following disclaimer in the documentation
# and/or other materials provided with the distribution.
# 3. Neither the name of the copyright holder nor the names of its
# contributors may be used to endorse or promote products derived from this
# software without specific prior written permission.
# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
# AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
# THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
# PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR
# CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
# EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
# PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA,
# OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
# LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
# NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
# SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.

import json
from os import makedirs
from os.path import isdir, join
from threading import Event
from time import time
from typing import Dict, List, Optional
from typing import Dict, Optional, Sequence
from uuid import uuid4

import numpy as np
Expand All @@ -26,7 +52,7 @@
class WebSatNeonClient(NeonAIClient):
"""Neon AI Web UI and Voice Satellite client."""

def __init__(self, lang: str = None):
def __init__(self, lang: str = ""):
config = Configuration()
self.config = config.get("iris") or dict()
self.mq_config = config.get("MQ")
Expand All @@ -46,7 +72,7 @@ def __init__(self, lang: str = None):
) # TODO: Clear periodically, or have persistent storage
if not isdir(self._audio_path):
makedirs(self._audio_path)
self.default_lang = lang or self.config.get("default_lang")
self.default_lang = lang or self.config.get("default_lang", "")
LOG.name = "iris"
LOG.init(self.config.get("logs"))
# OpenWW
Expand Down Expand Up @@ -122,12 +148,17 @@ def send_audio( # pylint: disable=arguments-renamed
)

@property
def supported_languages(self) -> List[str]:
def supported_languages(self) -> Sequence[str]:
"""
Get a list of supported languages from configuration
@returns: list of BCP-47 language codes
"""
return self.config.get("languages") or [self.default_lang]
languages = self.config.get("languages")
if languages is None:
return [self.default_lang]
if not isinstance(languages, list):
raise TypeError("Expected a list of languages in the configuration")
return languages

def _start_session(self):
sid = uuid4().hex
Expand Down Expand Up @@ -164,6 +195,7 @@ async def websocket_endpoint(websocket: WebSocket):
await websocket.send_text(
json.dumps({"loaded_models": list(self.oww_model.models.keys())})
)
sample_rate = None

while True:
message = await websocket.receive()
Expand All @@ -185,7 +217,7 @@ async def websocket_endpoint(websocket: WebSocket):

# Convert audio to correct format and sample rate
audio_data = np.frombuffer(audio_bytes, dtype=np.int16)
if sample_rate != 16000:
if sample_rate and sample_rate != 16000:
audio_data = resampy.resample(
audio_data, sample_rate, 16000
)
Expand Down Expand Up @@ -234,7 +266,7 @@ async def on_user_input_worker(
LOG.info(f"Sending utterance: {utterance} with lang: {lang}")
self.send_utterance(
utterance,
lang,
lang or "en-us",
username=session_id,
user_profiles=[self._profiles[session_id]],
context={
Expand All @@ -243,10 +275,10 @@ async def on_user_input_worker(
},
)
else:
LOG.info(f"Sending audio: {audio_input} with lang: {lang}")
LOG.info(f"Sending audio with length of {len(audio_input)} with lang: {lang}")
self.send_audio(
audio_input,
lang,
lang or "en-us",
username=session_id,
user_profiles=[self._profiles[session_id]],
context={
Expand Down
6 changes: 5 additions & 1 deletion setup.py
Original file line number Diff line number Diff line change
@@ -1,8 +1,9 @@
# NEON AI (TM) SOFTWARE, Software Development Kit & Application Framework
# All trademark and other rights reserved by their respective owners
# Copyright 2008-2022 Neongecko.com Inc.
# Copyright 2008-2024 Neongecko.com Inc.
# Contributors: Daniel McKnight, Guy Daniels, Elon Gasper, Richard Leeds,
# Regina Bloomstine, Casimiro Ferreira, Andrii Pernatii, Kirill Hrymailo
# Mike Gray, David Scripka
# BSD-3 License
# Redistribution and use in source and binary forms, with or without
# modification, are permitted provided that the following conditions are met:
Expand Down Expand Up @@ -74,5 +75,8 @@ def get_requirements(requirements_filename: str):
extras_require={"gradio": get_requirements("gradio.txt"), "web_sat": get_requirements("web_sat.txt")},
entry_points={
'console_scripts': ['iris=neon_iris.cli:neon_iris_cli']
},
package_data={
"neon_iris": ["static/*", "templates/*", "res/*", "wakeword_models/*"]
}
)

0 comments on commit 9ff5460

Please sign in to comment.