Project for Advanced System Design Course at Tel Aviv University. See full documentation.
- Clone the repository and enter it:
$ git clone git@github.com:kerenso/brainz.git ... $ cd brainz/
- Run the installation script and activate the virtual environment:
$ ./scripts/install.sh ... $ source .env/bin/activate [brainz] $ # you're good to go!
- To check that everything is working as expected, run the tests:
$ pytest tests/ ...
Make sure you have docker
and docker-compose
installed, then run the scripts/run-pipeline.sh
script.
It uses docker-compose to build and run all the system containers. Once all the containers are up, you can use the
brainz.client
and brainz.cli
CLIs as described below. You can also browse the brainz gui at http://localhost:8080/.
The client reads the sample and uploads it to the server. It is available as brainz.client
and exposes the following API:
from brainz.client import upload_sample
upload_sample(host='127.0.0.1', port=8000, path='sample.mind.gz', protobuf=True)
# upload path to host:port
And the following CLI:
python -m brainz.client upload-sample \
-h/--host '127.0.0.1' \
-p/--port 8000 \
'snapshot.mind.gz'
The server accepts a connection, receives the uploaded samples and publishes them to its message queue.
It is available as brainz.server
and exposes the following API:
from brainz.server import run_server
def print_message(message):
print(message)
run_server(host='127.0.0.1', port=8000, publish=print_message)
# listen on host:port and pass received messages to publish
And the following CLI:
python -m brainz.server run-server \
-h/--host '127.0.0.1' \
-p/--port 8000 \
'rabbitmq://127.0.0.1:5672/'
The URL is of the form mq-scheme://host:port
.
The parsers are simple functions or classes, that are easily deployable as microservices consuming raw data from the
queue, and producing parsed results to it. They are located in brainz.parsers
, and expose the following API:
from brainz.parsers import parse
data = '...'
result = parse('pose', data)
Which accepts a parser name and some raw data, as consumed from the message queue, and returns the result, as published to the message queue. They also provide the following CLI:
python -m brainz.parsers parse 'pose' 'snapshot.raw' > 'pose.result'
Which accepts a parser name and a path to some raw data, as consumed from the message queue, and prints the result, as published to the message queue (optionally redirecting it to a file). This way of invocation runs the parser exactly once. The CLI also supports running the parser as a service, which works with a message queue indefinitely.
python -m brainz.parsers run-parser 'pose' 'rabbitmq://127.0.0.1:5672/'
The implemented parsers are:
Pose
- Collects the translation and the rotation of the user's head at a given timestamp, and publishes the result to a dedicated topic.Color Image
- Collects the color image of what the user was seeing at a given timestamp, and publishes the result to a dedicated topic. Note: the data itself is stored to disk, and only the metadata published.Depth Image
- Collects the depth image of what the user was seeing at a given timestamp, and publishes the result to a dedicated topic. Note: the data itself is stored to disk, and only the metadata published.Feelings
- Collects the feelings the user was experiencing at any timestamp, and publishes the result to a dedicated topic.
To add a new parser, use the add_parser.py
script from the scripts
directory.
Usage: python scripts/add_parser.py [OPTIONS] PARSER_NAME
Add a parser named PARSER_NAME. Add class if class-parser flag is on,
otherwise add method.
Options:
-c, --class-parser Add class parser.
--help Show this message and exit.
The saver is available as brainz.saver
and exposes the following API:
from brainz.saver import Saver
saver = Saver('mongodb://127.0.0.1:27017')
data = '...'
saver.save('pose', data)
Which connects to a database, accepts a topic name and some data, as consumed from the message queue, and saves it to the database. It also provides the following CLI:
python -m brainz.saver save \
-d/--database 'mongodb://127.0.0.1:27017' \
'pose' \
'pose.result'
Which accepts a topic name and a path to some raw data, as consumed from the message queue, and saves it to a database. This way of invocation runs the saver exactly once.The CLI also supports running the saver as a service, which works with a message queue indefinitely.
python -m brainz.saver run-saver \
'mongodb://127.0.0.1:27017' \
'rabbitmq://127.0.0.1:5672'
The URL is of the form db-scheme://host:port
.
The API is available as brainz.api
and exposes the following API:
from brainz.api import run_api_server
run_api_server(host='127.0.0.1', port=5000,database_url='mongodb://127.0.0.1:27017')
# listen on host:port and serve data from database_url
And the following CLI:
python -m brainz.api run-server \
-h/--host '127.0.0.1' \
-p/--port 5000 \
-d/--database 'mongodb://127.0.0.1:27017'
The API server supports the following RESTful API endpoints:
GET /users
returns the list of all the supported users, including their IDs and names only.GET /users/user-id
returns the specified user's details: ID, name, birthday and gender.GET /users/user-id/snapshots
returns the list of the specified user's snapshot IDs and datetimes only.GET /users/user-id/snapshots/snapshot-id
returns the specified snapshot's details: ID, datetime, and the available results' names only (e.g. pose).GET /users/user-id/snapshots/snapshot-id/result-name
returns the specified snapshot's result (supports pose, color-image, depth-image and feelings).GET /users/user-id/snapshots/snapshot-id/result-name/data
returns the data of results with large binary data (color-image, depth-image).
The CLI consumes the API, and reflects it. It is available as brainz.cli
.
python -m brainz.cli get-users
python -m brainz.cli get-user 1
python -m brainz.cli get-snapshots 1
python -m brainz.cli get-snapshot 1 2
python -m brainz.cli get-result 1 2 'pose'
All commands accept the -h/--host and -p/--port flags to configure the host and port of the api. The get-result command also accepts the -s/--save flag that, if specified, receives a path, and saves the result's data to that path.
The GUI consumes the API and reflects it (using React), it provides the following API/CLI:
from brainz.gui import run_server
run_server(host='127.0.0.1', port=8080, api_host='127.0.0.1', api_port=5000)
python -m brainz.gui run-server \
-h/--host '127.0.0.1' \
-p/--port 8080 \
-H/--api-host '127.0.0.1' \
-P/--api-port 5000