Hello there! Thanks for checking out the error_classification_server
and error_classification_database
documentation. This particular document is a user's guide. If you are more interested in what the Error Classification System is designed for, and the architecture, please take a look at the introduction document here!
This project adheres to the Contributor Covenant code of conduct. By participating, you are expected to uphold this code. Please report unacceptable behavior to [email protected]. If you are interested in contributing, please refer to the guidelines here.
This article explains how to run the error_classification_server
.
This article shows how to start the error_classification_server
. By the end of this, you will be able to start the API server and run a few sample GET requests to query the error_classification_database
.
Some knowledge of REST APIs and python
is necessary.
You can get access to the API server by cloning this repo. After this, there are a couple of choices as to how you want to build and run the server. Either natively, or using Docker. Steps are as follows:
-
Open a terminal window.
-
Change to a folder of your choice. For example, the home folder:
$ cd ~
-
Clone the repo:
$ git clone https://github.com/cognicept-admin/error_classification_server.git
You can use this approach if you are planning on running this on a system where installing python packages natively is not an issue. These have been tested on Ubuntu OS. Steps are as follows:
-
The server runs on python3. To check if
python3
is available on your system, execute the following command on the terminal.3.6.9
is the minimum version required:$ python3 --version Python 3.6.9
If
python3
is unavailable, the command above will error out. Please installpython3
using one of the recommended methods here. -
Install package dependencies using
pip3
and the provided requirements filerequirements.txt
:$ cd ~/error_classification_server $ pip3 install -r requirements.txt Collecting sanic Downloading sanic-20.6.3-py3-none-any.whl (74 kB) |████████████████████████████████| 74 kB 2.1 MB/s Collecting databases[sqlite] Downloading databases-0.3.2-py3-none-any.whl (18 kB) Collecting httptools>=0.0.10 Downloading httptools-0.1.1-cp36-cp36m-manylinux1_x86_64.whl (216 kB) |████████████████████████████████| 216 kB 7.4 MB/s Collecting httpx==0.11.1 Downloading httpx-0.11.1-py2.py3-none-any.whl (77 kB) |████████████████████████████████| 77 kB 3.2 MB/s Collecting multidict<5.0,>=4.0 Downloading multidict-4.7.6-cp36-cp36m-manylinux1_x86_64.whl (148 kB) |████████████████████████████████| 148 kB 7.6 MB/s Collecting websockets<9.0,>=8.1 Downloading websockets-8.1-cp36-cp36m-manylinux2010_x86_64.whl (78 kB) |████████████████████████████████| 78 kB 5.1 MB/s Collecting uvloop>=0.5.3; sys_platform != "win32" and implementation_name == "cpython" Downloading uvloop-0.14.0-cp36-cp36m-manylinux2010_x86_64.whl (3.9 MB) |████████████████████████████████| 3.9 MB 7.6 MB/s Collecting aiofiles>=0.3.0 Downloading aiofiles-0.5.0-py3-none-any.whl (11 kB) Collecting ujson>=1.35; sys_platform != "win32" and implementation_name == "cpython" Downloading ujson-3.1.0-cp36-cp36m-manylinux1_x86_64.whl (175 kB) |████████████████████████████████| 175 kB 6.0 MB/s Collecting sqlalchemy Downloading SQLAlchemy-1.3.19-cp36-cp36m-manylinux2010_x86_64.whl (1.3 MB) |████████████████████████████████| 1.3 MB 9.3 MB/s Collecting aiocontextvars; python_version < "3.7" Downloading aiocontextvars-0.2.2-py2.py3-none-any.whl (4.9 kB) Collecting aiosqlite; extra == "sqlite" Downloading aiosqlite-0.15.0-py3-none-any.whl (13 kB) Collecting sniffio==1.* Downloading sniffio-1.1.0-py3-none-any.whl (4.5 kB) Collecting certifi Downloading certifi-2020.6.20-py2.py3-none-any.whl (156 kB) |████████████████████████████████| 156 kB 3.5 MB/s Collecting hstspreload Downloading hstspreload-2020.8.18-py3-none-any.whl (938 kB) |████████████████████████████████| 938 kB 11.0 MB/s Collecting idna==2.* Downloading idna-2.10-py2.py3-none-any.whl (58 kB) |████████████████████████████████| 58 kB 7.6 MB/s Collecting h11<0.10,>=0.8 Downloading h11-0.9.0-py2.py3-none-any.whl (53 kB) |████████████████████████████████| 53 kB 2.7 MB/s Collecting h2==3.* Downloading h2-3.2.0-py2.py3-none-any.whl (65 kB) |████████████████████████████████| 65 kB 4.3 MB/s Collecting rfc3986<2,>=1.3 Downloading rfc3986-1.4.0-py2.py3-none-any.whl (31 kB) Collecting urllib3==1.* Downloading urllib3-1.25.10-py2.py3-none-any.whl (127 kB) |████████████████████████████████| 127 kB 22.2 MB/s Collecting chardet==3.* Downloading chardet-3.0.4-py2.py3-none-any.whl (133 kB) |████████████████████████████████| 133 kB 28.5 MB/s Collecting contextvars==2.4; python_version < "3.7" Downloading contextvars-2.4.tar.gz (9.6 kB) Collecting typing_extensions Downloading typing_extensions-3.7.4.2-py3-none-any.whl (22 kB) Collecting hpack<4,>=3.0 Downloading hpack-3.0.0-py2.py3-none-any.whl (38 kB) Collecting hyperframe<6,>=5.2.0 Downloading hyperframe-5.2.0-py2.py3-none-any.whl (12 kB) Collecting immutables>=0.9 Downloading immutables-0.14-cp36-cp36m-manylinux1_x86_64.whl (98 kB) |████████████████████████████████| 98 kB 9.9 MB/s Building wheels for collected packages: contextvars Building wheel for contextvars (setup.py) ... done Created wheel for contextvars: filename=contextvars-2.4-py3-none-any.whl size=7664 sha256=f233b1ff06e760fbfbfdef900ee552cb4eecde5db4877b2be24ddcad4106eabf Stored in directory: /root/.cache/pip/wheels/41/11/53/911724983aa48deb94792432e14e518447212dd6c5477d49d3 Successfully built contextvars Installing collected packages: httptools, immutables, contextvars, sniffio, certifi, hstspreload, idna, h11, hpack, hyperframe, h2, rfc3986, urllib3, chardet, httpx, multidict, websockets, uvloop, aiofiles, ujson, sanic, sqlalchemy, aiocontextvars, typing-extensions, aiosqlite, databases Successfully installed aiocontextvars-0.2.2 aiofiles-0.5.0 aiosqlite-0.15.0 certifi-2020.6.20 chardet-3.0.4 contextvars-2.4 databases-0.3.2 h11-0.9.0 h2-3.2.0 hpack-3.0.0 hstspreload-2020.8.18 httptools-0.1.1 httpx-0.11.1 hyperframe-5.2.0 idna-2.10 immutables-0.14 multidict-4.7.6 rfc3986-1.4.0 sanic-20.6.3 sniffio-1.1.0 sqlalchemy-1.3.19 typing-extensions-3.7.4.2 ujson-3.1.0 urllib3-1.25.10 uvloop-0.14.0 websockets-8.1
That is it for the native installation! You can now jump to Syntax.
You can use this approach if you are planning on running the server on a system where you may not want to install packages natively.
-
First, make sure you have a working Docker installation.
-
You can then build the
docker
image usingdocker build
and the providedDockerfile
:$ cd ~/error_classification_server $ docker build -t error_classification_server .
That is it for the Docker installation! You can now jump to Syntax.
The repo has the latest error_classification_database
file available as ecs.db
. This is a file database using SQLite. So it can be interacted with graphically using things like sqlitebrowser
and programmatically using python packages like sqlite3
, aiosqlite
, databases
etc. The server uses Sanic
with the databases
package. Screenshot below shows how one of the tables look in sqlitebrowser
:
NOTE: If you are planning on doing updates to this local file database (either graphically or programmatically), please be aware that any update function will overwrite your changes! Either rename the local file database and use that OR help the community by posting the local changes to Error Reporting Tool (ERT), so we can classify the logs! Take a look at the ERT introduction here.
The server can be configured using the following environment variables:
Variable | Type | Default | Description |
---|---|---|---|
ECS_DB_LOC |
String | NA | ECS Database File location. If this location is incorrect the server will error out. |
ECS_API |
String | http://0.0.0.0:8000 |
REST API Endpoint to be served. Use this to serve the endpoint at a desired port. If not specified, 8000 will be used. |
Based on the type of installation, you can configure these variables by different methods as follows.
In case of a native installation, you can create them using the export
command at the terminal. For e.g. here is an example set of parameters:
$ export ECS_DB_LOC=~/error_classification_server/ecs.db
$ export ECS_API=http://0.0.0.0:8000
Note: These values are available only in the current terminal and need to be recreated every time before running the server. One way to get around this is to place these statements in the bashrc
file
Now, you can run the server using python3
:
$ python3 src/ecs_endpoint.py
[2020-08-18 17:32:53 +0800] [10601] [INFO] Goin' Fast @ http://127.0.0.1:8000
[2020-08-18 17:32:53 +0800] [10601] [INFO] Starting worker [10601]
That is it for the native configure and run! If you wish, you can press Ctrl+C
to terminate the native server. You can now jump to Examples.
In case of a Docker installation, you can simply use the runtime.env
file in this repository as an example template and pass it to the docker container with the --env-file
argument when using the docker run
command. Simply edit the runtime.env
like a text file, or comment the unnecessary variables and then rerun the container. Example below:
$ docker run -it \
--env-file runtime.env \
-p 8000:8000 \
--name=ec_server \
--volume="${HOME}/error_classification_server/ecs.db:/root/.cognicept/ecs.db" \
error_classification_server:latest \
src/ecs_endpoint.py
[2020-08-18 09:43:01 +0000] [1] [INFO] Goin' Fast @ http://127.0.0.1:8000
[2020-08-18 09:43:01 +0000] [1] [INFO] Starting worker [1]
Note: When using the dockerized API, we need to remember 2 things:
- Expose the correct port to make sure the
ECS_API
port matches here using the-p
option - Mount the database file in the correct location using the
--volume
option
That is it for the Docker configure and run! If you wish, you can press Ctrl+C
to terminate the native server. You can now jump to Examples.
In this example, we will explore the built-in API endpoints to query the Error Reporting Table and the Error Classification Database. The following API endpoints are available:
API Endpoint | Type | Parameters | Description |
---|---|---|---|
/ping |
GET | NA |
Test API that can be used to quickly see if API is live or not. |
/ert/error-data |
GET | RobotModel , ErrorText |
Primary API that can be used to retrieve ERT row corresponding to a robot model/error text combo ERT should be primarily used only in development environment, not production. |
/ecs/error-data |
GET | RobotModel , ErrorText |
Primary API that can be used to retrieve ECS row corresponding to a robot model/error text combo ECS should be the primary choice in a production environment. |
Let's try these endpoints as follows. These should work for default cases. In case you changed the configuration, make sure the URL is appropriately changed:
-
Run the server in one of two ways as explained in the Syntax section.
-
Open a terminal window and and use
curl
to test the/ping
route:$ curl 'http://localhost:8000/ping' {"data":"ECS API is Live!"}
-
Open a terminal window and and use
curl
to test the/ert/error-data
route:$ curl 'http://localhost:8000/ert/error-data/?RobotModel=Turtlebot3&ErrorText=Aborting+because+the+robot+appears+to+be+oscillating+over+and+over.+Even+after+executing+all+recovery+behaviors' {"data":[{"error_code":"Null","error_level":8,"compounding_flag":false,"error_module":"Navigation","error_source":"move_base","error_text":"Aborting because the robot appears to be oscillating over and over. Even after executing all recovery behaviors","error_description":"The robot is unable to find a path. This usually means the robot is mislocalized.","error_resolution":"Relocalize the robot using intervention, assign a sample goal as test, and if successful, assign to its previous goal. If not, escalate to property."}]}
-
Open a terminal window and and use
curl
to test the/ecs/error-data
route:$ curl 'http://localhost:8000/ecs/error-data/?RobotModel=Turtlebot3&ErrorText=Aborting+because+the+robot+appears+to+be+oscillating+over+and+over.+Even+after+executing+all+recovery+behaviors' {"data":[{"cognicept_error_code":"Null","severity":"16","compounding_flag":false,"error_module":"Navigation","error_source":"move_base","error_text":"Aborting because the robot appears to be oscillating over and over. Even after executing all recovery behaviors"}]}
These are the kind of API calls the agent makes to perform error suppression and classification!
The local file based database was chosen for the ECS architecture, intentionally to keep it light, fast and flexible. However, this necessitates a manual sync of the local error_classification_database
with the centralized version that is maintained by the moderators. This is done by running a simple python
script as follows:
Note: The update operation simply pulls JSON data from the centralized ECS and recreates it on the client side. This means the operation will overwrite any local changes. Please be wary and backup/rename existing db files if you want to access those local changes!
$ cd ~/error_classification_server
$ python3 src/ecs_basic_update.py
ECS db already exists here:
/home/swaroophs/error_classification_server/ecs.db
Are you sure you want to overwrite the existing db? You will lose any local changes: (Y/N) y
ECS basic update successful.
For more related information, refer to:
- ECS Intro Document
- Docker Installation
- SQLite
- sqlitebrowser
- sqlite3
- aiosqlite
- databases
- Sanic
- Error Reporting Tool - ERT
We would like to acknowledge the Singapore government for their vision and support to start this ambitious research and development project, "Accelerating Open Source Technologies for Cross Domain Adoption through the Robot Operating System". The project is supported by Singapore National Robotics Programme (NRP).
Any opinions, findings and conclusions or recommendations expressed in this material are those of the author(s) and do not reflect the views of the NR2PO.