MycroftAI / selene-backend

Microservices and web apps to support Mycroft devices
GNU Affero General Public License v3.0
144 stars 53 forks source link

License CLA Team Status

PRs Welcome Join chat Code style: black

Selene -- Mycroft's Server Backend

Selene provides the services used by Mycroft Core to manage devices, skills and settings. It consists of two repositories. This one contains Python and SQL representing the database definition, data access layer, APIs and scripts. The second repository, Selene UI, contains Angular web applications that use the APIs defined in this repository.

There are four APIs defined in this repository, account management, single sign on, skill marketplace and device. The first three support account.mycroft.ai (aka home.mycroft.ai), sso.mycroft.ai, and market.mycroft.ai, respectively. The device API is how devices running Mycroft Core communicate with the server. Also included in this repository is a package containing batch scripts for maintenance and the definition of the database schema.

Each API is designed to run independently of the others. Code common to each of the APIs, such as the Data Access Layer, can be found in the "shared" directory. The shared code is an independent Python package required by each of the APIs. Each API has its own Pipfile so that it can be run in its own virtual environment.

Installation

The Python code utilizes features introduced in Python 3.7, such as data classes. Pipenv is used for virtual environment and package management. If you prefer to use pip and pyenv (or virtualenv), you can find the required libraries in the files named "Pipfile". These instructions will use pipenv commands.

If the Selene applications will be servicing a large number of devices (enterprise usage, for example), it is recommended that each of the applications run on their own server or virtual machine. This configuration makes it easier to scale and monitor each application independently. However, all applications can be run on a single server. This configuration could be more practical for a household running a handful of devices.

These instructions will assume a multi-server setup for several thousand devices. To run on a single server servicing a small number of devices, the recommended system requirements are 4 CPU, 8GB RAM and 100GB of disk. There are a lot of manual steps in this section that will eventually be replaced with an installation script.

All Selene applications are time zone agnostic. It is recommended that the time zone on any server running Selene be UTC.

It is recommended to create an application specific user. In these instructions this user will be mycroft.

Postgres DB

Redis DB

APIs

The majority of the setup for each API is the same. This section defines the steps common to all APIs. Steps specific to each API will be defined in their respective sections.

Single Sign On API

Recommended server configuration: Ubuntu 18.04 LTS, 1 CPU, 1GB RAM, 5GB disk

Account API

Marketplace API

Device API

Precise API

Single Sign On API

[Service] User=mycroft Group=www-data Restart=always Type=simple WorkingDirectory=/opt/selene/selene-backend/api/sso ExecStart=/usr/local/bin/pipenv run uwsgi --ini uwsgi.ini Environment=DB_HOST= Environment=DB_NAME=mycroft Environment=DB_PASSWORD= Environment=DB_PORT=5432 Environment=DB_USER=selene Environment=GITHUB_CLIENT_ID= Environment=GITHUB_CLIENT_SECRET= Environment=JWT_ACCESS_SECRET= Environment=JWT_REFRESH_SECRET= Environment=JWT_RESET_SECRET= Environment=SALT= Environment=SELENE_ENVIRONMENT=<test/prod> Environment=SENDGRID_API_KEY= Environment=SSO_BASE_URL=

[Install] WantedBy=multi-user.target

* Start the sso_api service and set it to start on boot

sudo systemctl start sso_api.service sudo systemctl enable sso_api.service


#### Account API
* The account API uses the same authentication mechanism as the single sign on API.  The JWT_ACCESS_SECRET,
JWT_REFRESH_SECRET and SALT environment variables must be the same values as those on the single sign on API.
* This application uses the Redis database so the service needs to know where it resides.
* Define a systemd service to run the API.  The service defines environment variables that use the secret and API keys
generated in previous steps.

sudo vim /etc/systemd/system/account_api.service

[Unit] Description=Mycroft Account API After=network.target

[Service] User=mycroft Group=www-data Restart=always Type=simple WorkingDirectory=/opt/selene/selene-backend/api/account ExecStart=/usr/local/bin/pipenv run uwsgi --ini uwsgi.ini Environment=DB_HOST= Environment=DB_NAME=mycroft Environment=DB_PASSWORD= Environment=DB_PORT=5432 Environment=DB_USER=selene Environment=JWT_ACCESS_SECRET= Environment=JWT_REFRESH_SECRET= Environment=OAUTH_BASE_URL= Environment=REDIS_HOST= Environment=REDIS_PORT=6379 Environment=SELENE_ENVIRONMENT=<test/prod> Environment=SALT=

[Install] WantedBy=multi-user.target

* Start the account_api service and set it to start on boot

sudo systemctl start account_api.service sudo systemctl enable account_api.service


#### Marketplace API
* The marketplace API uses the same authentication mechanism as the single sign on API.  The JWT_ACCESS_SECRET,
JWT_REFRESH_SECRET and SALT environment variables must be the same values as those on the single sign on API.
* This application uses the Redis database so the service needs to know where it resides.
* Define a systemd service to run the API.  The service defines environment variables that use the secret and API keys
generated in previous steps.

sudo vim /etc/systemd/system/market_api.service

[Unit] Description=Mycroft Marketplace API After=network.target

[Service] User=mycroft Group=www-data Restart=always Type=simple WorkingDirectory=/opt/selene/selene-backend/api/market ExecStart=/usr/local/bin/pipenv run uwsgi --ini uwsgi.ini Environment=DB_HOST= Environment=DB_NAME=mycroft Environment=DB_PASSWORD= Environment=DB_PORT=5432 Environment=DB_USER=selene Environment=JWT_ACCESS_SECRET= Environment=JWT_REFRESH_SECRET= Environment=OAUTH_BASE_URL= Environment=REDIS_HOST= Environment=REDIS_PORT=6379 Environment=SELENE_ENVIRONMENT=<test/prod> Environment=SALT=

[Install] WantedBy=multi-user.target

* Start the market_api service and set it to start on boot

sudo systemctl start market_api.service sudo systemctl enable market_api.service

* The marketplace API assumes that the skills it supplies to the web application are in the Postgres database. To get
them there, a script needs to be run to download them from Github.  The script requires the GITHUB_USER, GITHUB_PASSWORD,
DB_HOST, DB_NAME, DB_USER and DB_PASSWORD environment variables to run.  Use the same values as those in the service
definition files.

cd /opt/selene/selene-backend/batch pipenv install pipenv run python load_skill_display_data.py --core-version <specify core version, e.g. 19.02>


#### Device API
* The device API uses the same authentication mechanism as the single sign on API.  The JWT_ACCESS_SECRET,
JWT_REFRESH_SECRET and SALT environment variables must be the same values as those on the single sign on API.
* This application uses the Redis database so the service needs to know where it resides.
* The weather skill requires a key to the Open Weather Map API
* The speech to text engine requires a key to Google's STT API.
* The Wolfram Alpha skill requires an API key to the Wolfram Alpha API
* Define a systemd service to run the API.  The service defines environment variables that use the secret and API keys
generated in previous steps.

sudo vim /etc/systemd/system/public_api.service

[Unit] Description=Mycroft Public API After=network.target

[Service] User=mycroft Group=www-data Restart=always Type=simple WorkingDirectory=/opt/selene/selene-backend/api/public ExecStart=/usr/local/bin/pipenv run uwsgi --ini uwsgi.ini Environment=DB_HOST= Environment=DB_NAME=mycroft Environment=DB_PASSWORD= Environment=DB_PORT=5432 Environment=DB_USER=selene Environment=EMAIL_SERVICE_HOST= Environment=EMAIL_SERVICE_PORT= Environment=EMAIL_SERVICE_USER= Environment=EMAIL_SERVICE_PASSWORD= Environment=GOOGLE_STT_KEY= Environment=JWT_ACCESS_SECRET= Environment=JWT_REFRESH_SECRET= Environment=OAUTH_BASE_URL= Environment=OWM_KEY= Environment=OWM_URL=https://api.openweathermap.org/data/2.5 Environment=REDIS_HOST= Environment=REDIS_PORT=6379 Environment=SELENE_ENVIRONMENT=<test/prod> Environment=SALT= Environment=WOLFRAM_ALPHA_KEY=<Wolfram Alpha API Key Environment=WOLFRAM_ALPHA_URL=https://api.wolframalpha.com

[Install] WantedBy=multi-user.target

* Start the public_api service and set it to start on boot

sudo systemctl start public_api.service sudo systemctl enable public_api.service


### Testing the endpoints

Before we continue, let's make sure that your endpoints are operational - for this we'll use the `public_api` endpoint as an example.

1. As we do not yet have a http router configured, we must change the `uwsgi` configuration for the endpoint we want to test. This is contained in: `/opt/selene/selene-backend/api/public/uwsgi.ini`. Here we want to replace
socket = :$PORT
```
with
```
http = :$PORT
```
then restart the service:
```
sudo systemctl restart public_api.service
```
  1. Check the status of the systemd service:

    systemctl status public_api.service

    Should report the service as "active (running)"

  2. Send a GET request from a remote device:

    curl -v http://$IP_ADDRESS:$PORT/code?state=this-is-a-test

    You can also monitor this from the service logs by running:

    journalctl -u public_api.service -f

Other Considerations

DNS

There are multiple ways to setup DNS. This document will not dictate how to do so for Selene. However, here is an example, based on how DNS is setup at Mycroft AI...

Each application runs on its own sub-domain. Assuming a top level domain of "mycroft.ai" the subdomains are:

The APIs that support the web applications are directories within the sub-domain (e.g. account.mycroft.ai/api). Since the device API is externally facing, it is versioned. It's subdirectory must be "v1".

Reverse Proxy

There are multiple tools available for setting up a reverse proxy that will point your DNS entries to your APIs. As such, the decision on how to set this up will be left to the user.

SSL

It is recommended that Selene applications be run using HTTPS. To do this an SSL certificate is necessary.

Let's Encrypt is a great way to easily set up SSL certificates for free.

What About the GUI???

Once the database and API setup is complete, the next step is to setup the GUI, The README file for the Selene UI repository contains the instructions for setting up the web applications.

Getting Involved

This is an open source project and we would love your help. We have prepared a contributing guide to help you get started.

If this is your first PR or you're not sure where to get started, say hi in Mycroft Chat and a team member would be happy to guide you. Join the Mycroft Forum for questions and answers.