Skip to content

Commit

Permalink
Add Gradio web UI with Docker Container (#24)
Browse files Browse the repository at this point in the history
* Initial Gradio web UI implementation with Dockerfile

* Initial outline of settings with UI

* Annotate web_client
Move hard-coded params to configuration
Update README to include configuration example
Update Docker default configuration
Add Docker automation

* wip tts/stt and styling

* add stt/tts, rearrange interface

* Address feedback from #25
Update documentation
Add missing system deps to Dockerfile

* Patch audioread missing license (MIT) https://github.com/beetbox/audioread/blob/main/LICENSE

* Refactor `docker` dependencies to `gradio`
Cleanup logging
Refactor to resolve warnings
Resolve missing directory exception in audio input handling

* Fix STT language handling

---------

Co-authored-by: Daniel McKnight <[email protected]>
Co-authored-by: mikejgray <[email protected]>
  • Loading branch information
3 people authored Nov 7, 2023
1 parent f00d6c9 commit 65eaf62
Show file tree
Hide file tree
Showing 11 changed files with 372 additions and 18 deletions.
2 changes: 2 additions & 0 deletions .github/workflows/license_tests.yml
Original file line number Diff line number Diff line change
Expand Up @@ -6,3 +6,5 @@ on:
jobs:
license_tests:
uses: neongeckocom/.github/.github/workflows/license_tests.yml@master
with:
packages-exclude: '^(precise-runner|fann2|tqdm|bs4|ovos-phal-plugin|ovos-skill|neon-core|nvidia|neon-phal-plugin|bitstruct|audioread).*'
4 changes: 4 additions & 0 deletions .github/workflows/publish_release.yml
Original file line number Diff line number Diff line change
Expand Up @@ -10,3 +10,7 @@ jobs:
build_and_publish_pypi_and_release:
uses: neongeckocom/.github/.github/workflows/publish_stable_release.yml@master
secrets: inherit
build_and_publish_docker:
needs: build_and_publish_pypi_and_release
uses: neongeckocom/.github/.github/workflows/publish_docker.yml@master
secrets: inherit
6 changes: 5 additions & 1 deletion .github/workflows/publish_test_build.yml
Original file line number Diff line number Diff line change
Expand Up @@ -9,9 +9,13 @@ on:
- 'neon_iris/version.py'

jobs:
build_and_publish_pypi:
publish_alpha_release:
uses: neongeckocom/.github/.github/workflows/publish_alpha_release.yml@master
secrets: inherit
with:
version_file: "neon_iris/version.py"
setup_py: "setup.py"
build_and_publish_docker:
needs: publish_alpha_release
uses: neongeckocom/.github/.github/workflows/publish_docker.yml@master
secrets: inherit
21 changes: 21 additions & 0 deletions Dockerfile
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
FROM python:3.8-slim

LABEL vendor=neon.ai \
ai.neon.name="neon-iris"

ENV OVOS_CONFIG_BASE_FOLDER neon
ENV OVOS_CONFIG_FILENAME neon.yaml
ENV XDG_CONFIG_HOME /config

RUN apt update && \
apt install -y ffmpeg

ADD . /neon_iris
WORKDIR /neon_iris

RUN pip install wheel && \
pip install .[gradio]

COPY docker_overlay/ /

CMD ["iris", "start-gradio"]
42 changes: 26 additions & 16 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -5,24 +5,34 @@ interacting with Neon systems remotely, via [MQ](https://github.com/NeonGeckoCom
Install the Iris Python package with: `pip install neon-iris`
The `iris` entrypoint is available to interact with a bus via CLI. Help is available via `iris --help`.

## Configuration
Configuration files can be specified via environment variables. By default,
`Iris` will read configuration from `~/.config/neon/diana.yaml` where
`XDG_CONFIG_HOME` is set to the default `~/.config`.
More information about configuration handling can be found
[in the docs](https://neongeckocom.github.io/neon-docs/quick_reference/configuration/).

## Debugging a Diana installation
A default configuration might look like:
```yaml
MQ:
server: neonaialpha.com
port: 25672
users:
mq_handler:
user: neon_api_utils
password: Klatchat2021
iris:
default_lang: en-us
languages:
- en-us
- uk-ua
webui_chatbot_label: "Neon AI"
webui_mic_label: "Speak with Neon"
webui_input_placeholder: "Chat with Neon"
```
## Interfacing with a Diana installation
The `iris` CLI includes utilities for interacting with a `Diana` backend.

### Configuration
Configuration files can be specified via environment variables. By default,
`Iris` will set default values:
```
OVOS_CONFIG_BASE_FOLDER=neon
OVOS_CONFIG_FILENAME=diana.yaml
```

The example below would override defaults to read configuration from
`~/.config/mycroft/mycroft.conf`.
```
export OVOS_CONFIG_BASE_FOLDER=mycroft
export OVOS_CONFIG_FILENAME=mycroft.conf
```

More information about configuration handling can be found
[in the docs](https://neongeckocom.github.io/neon-docs/quick_reference/configuration/).
19 changes: 19 additions & 0 deletions docker_overlay/etc/neon/neon.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
MQ:
server: neon-rabbitmq
port: 5672
users:
mq_handler:
user: neon_api_utils
password: Klatchat2021
iris:
webui_title: Neon AI
webui_description: Chat with Neon
webui_input_placeholder: Ask me something
server_address: "0.0.0.0"
server_port: 7860
default_lang: en-us
languages:
- en-us
- fr-fr
- es-es
- uk-ua
7 changes: 7 additions & 0 deletions neon_iris/cli.py
Original file line number Diff line number Diff line change
Expand Up @@ -129,6 +129,13 @@ def start_listener():
client.shutdown()


@neon_iris_cli.command(help="Create a GradIO Client session")
def start_gradio():
from neon_iris.web_client import GradIOClient
chat = GradIOClient()
chat.run()


@neon_iris_cli.command(help="Transcribe an audio file")
@click.option('--lang', '-l', default='en-us',
help="language of input audio")
Expand Down
11 changes: 10 additions & 1 deletion neon_iris/client.py
Original file line number Diff line number Diff line change
Expand Up @@ -74,6 +74,10 @@ def uid(self) -> str:
"""
return self._uid

@property
def default_username(self) -> str:
return self._user_config["user"]["username"]

@property
def user_config(self) -> dict:
"""
Expand Down Expand Up @@ -264,6 +268,8 @@ def _build_message(self, msg_type: str, data: dict,

def _send_utterance(self, utterance: str, lang: str,
username: str, user_profiles: list):
username = username or self.default_username
user_profiles = user_profiles or [self.user_config]
message = self._build_message("recognizer_loop:utterance",
{"utterances": [utterance],
"lang": lang}, username, user_profiles)
Expand All @@ -277,7 +283,9 @@ def _send_audio(self, audio_file: str, lang: str,
audio_data = encode_file_to_base64_string(audio_file)
message = self._build_message("neon.audio_input",
{"lang": lang,
"audio_data": audio_data},
"audio_data": audio_data,
"utterances": []},
# TODO: `utterances` patching mq connector
username, user_profiles)
serialized = {"msg_type": message.msg_type,
"data": message.data,
Expand All @@ -290,6 +298,7 @@ def _send_serialized_message(self, serialized: dict):
self._connection.connection,
queue="neon_chat_api_request",
request_data=serialized)
LOG.debug(f"emitted {serialized.get('msg_type')}")
except Exception as e:
LOG.exception(e)
self.shutdown()
Expand Down
Loading

0 comments on commit 65eaf62

Please sign in to comment.