Backend Architecture for Browser-based Experiments
Switch branches/tags
Nothing to show
Clone or download
Fetching latest commit…
Cannot retrieve the latest commit at this time.
Permalink
Failed to load latest commit information.
.idea
config
lib
priv
test
web
.formatter.exs
.gitignore
Dockerfile
LICENSE
Procfile
README.md
brunch-config.js
docker-compose.yml
elixir_buildpack.config
mix.exs
mix.lock
package.json

README.md

Table of Contents

This is a server backend to run simple psychological experiments in the browser and online. It helps receive, store and retrieve data.

A live demo of the app is available. Note that this demo doesn't require user authentication.

If you encounter any bugs during your experiments please submit an issue.

For the most up-to-date documentation, please refer to the _babe project site and its section on the server app.

Work on this project was funded via the project Pro^3, which is part of the XPRAG.de funded by the German Research Foundation (DFG Schwerpunktprogramm 1727).

Server Documentation

This section documents the server program.

Username and password for authentication

The app now comes with Basic access Authentication. The username and password are set under config :babe, :authentication.

For local deployment (:dev environment), the default username is default and the default password is password. You may change it in dev.exs.

If you're deploying on Heroku, be sure to set environment variables AUTH_USERNAME and AUTH_PASSWORD, either via Heroku command line tool or in the Heroku user interface, under Settings tab.

Experiments

Experiment creation

One can create a new experiment with the New button from the user interface. The experiment name and author are mandatory fields. You can create multiple experiments with the same name + author combination. The unique identifier generated by the database itself will differentiate them.

After an experiment is created, you can see its ID in the main user interface. Use this ID for results submission and retrieval.

Edit/Deactivate an experiment

Once you don't want to receive any new submissions for a particular experiment, you can disable it via the edit interface by clicking on the Edit button. You can also edit any other aspect of the experiment as you want, except for its unique ID.

Experiment Result submission

The server expects to receive a JSON array as the set of experiment results, via HTTP POST, at the address {SERVER_ADDRESS}/api/submit_experiment/:id, where :id is the unique experiment ID shown in the main user interface.

All objects of the array should contain a set of identical keys. Each object normally stands for one trial in the experiment, together with any additional information that is not associated with a particular trial, for example, the native language spoken by the participant.

Here you can find a minimal working example. The Minimal Template contains a full example experiment.

Note that to POST a JSON object correctly, one needs to specify the Content-Type header as application/json, and use JSON.stringify to encode the data first.

Note that crossDomain: true is needed since the server domain will likely be different to the domain where the experiment is presented to the participant.

Retrieval of experiment results as CSV

Just press the button to the right of each row in the user interface.

Dynamic experiment result retrieval as JSON

For some experiments, it might helpful to fetch and use data collected from previous experiment submissions in order to dynamically generate future trials. The _babe backend now provides this functionality.

For each experiment, you can specify the keys that should be fetched in the "Edit Experiment" user interface on the server app. Then, with a HTTP GET call to the retrieve_experiment endpoint, specifying the experiment ID, you will be able to get a JSON object that contains the results of that experiment so far.

{SERVER_ADDRESS}/api/retrieve_experiment/:id

A minimal example of frontend code using jQuery:

  $.ajax({
    type: 'GET',
    url: "https://babe-demo.herokuapp.com/api/retrieve_experiment/1",
    crossDomain: true,
    success: function (responseData, textStatus, jqXHR) {
    	console.table(responseData);
    }
  });

Custom Data Records

Sometimes, it might be desirable to store custom data records on the server and later retrieve them for experiments, similar to the dynamic retrieval of previous experiment results. Now there is also an interface for it.

The type of each record is also JSON array of objects.

Uploading a data record

The data record can be either:

  • A CSV file containing the data to be stored in this record. The first row will be treated as the headers (keys). The file must have .csv extension.
  • A JSON array of objects. The file must have .json extension.

The file can be chosen in the browser via the upload button.

If a data record is edited and a new file is uploaded, the old record will be overwritten.

Retrieval of data records

Similar to experiment results, the data records can also be retrieved either as a CSV file via the browser or a JSON file via the API.

The JSON retrieval address is

{SERVER_ADDRESS}/api/retrieve_custom_record/:id

Deploying the Server

This section documents some methods one can use to deploy the server, for both online and offline usages.

Deployment with Heroku

Heroku makes it easy to deploy an web app without having to manually manage the infrastructure. It has a free starter tier, which should be sufficient for the purpose of running experiments.

There is an official guide from Phoenix framework on deploying on Heroku. The deployment procedure is based on this guide, but differs in some places.

  1. Ensure that you have the Phoenix Framework installed and working. However, if you just want to deploy this server and do no development work/change on it at all, you may skip this step.

  2. Ensure that you have a Heroku account already, and have the Heroku CLI installed and working on your computer.

  3. Ensure you have Git installed. Clone this git repo with git clone https://github.com/babe-project/BABE or git clone git@github.com:babe-project/BABE.git.

  4. cd into the project directory just cloned from your Terminal (or cmd.exe on Windows).

  5. Run heroku create --buildpack "https://github.com/HashNuke/heroku-buildpack-elixir.git"

  6. Run heroku buildpacks:add https://github.com/gjaldon/heroku-buildpack-phoenix-static.git

(N.B.: Although the command line output tells you to run git push heroku master, don't do it yet.)

  1. You may want to change the application name instead of using the default name. In that case, run heroku apps:rename newname.

  2. Edit line 17 of the file config/prod.exs. Replace the part babe-backend.herokuapp.com after host with the app name (shown when you first ran heroku create, e.g. mysterious-meadow-6277.herokuapp.com, or the app name that you set at step 6, e.g. newname.herokuapp.com). You shouldn't need to modify anything else.

  3. Ensure that you're at the top-level project directory. Run

heroku addons:create heroku-postgresql:hobby-dev
heroku config:set POOL_SIZE=18
  1. Run mix deps.get then mix phx.gen.secret. Then run heroku config:set SECRET_KEY_BASE="OUTPUT", where OUTPUT should be the output of the mix phx.gen.secret step.

Note: If you don't have Phoenix framework installed on your computer, you may choose to use some other random generator for this task, which essentially asks for a random 64-character secret. On Mac and Linux, you may run openssl rand -base64 64. Or you may use an online password generator such as the one offered by LastPass.

  1. Run git add config/prod.exs, then git commit -m "Set app URL".

  2. Don't forget to set the environment variables AUTH_USERNAME and AUTH_PASSWORD, either in the Heroku web interface or via the command line, i.e.

heroku config:set AUTH_USERNAME="your_username"
heroku config:set AUTH_PASSWORD="your_password"
  1. Run git push heroku master. This will push the repo to the git remote at Heroku (instead of the original remote at Github), and deploy the app.

  2. Run heroku run "POOL_SIZE=2 mix ecto.migrate"

  3. Now, heroku open should open the frontpage of the app.

Local (Offline) Deployment

Normally, running the server in a local development environment would involve installing and configuring Elixir and PostgreSQL. To simplify the development flow, Docker is used instead.

First-time installation (requires internet connection)

The following steps require an internet connection. After they are finished, the server can be launched offline.

  1. Install Docker from https://docs.docker.com/install/. You may have to launch the application once in order to let it install its command line tools. Ensure that it's running by typing docker version in a terminal (e.g., the Terminal app on MacOS or cmd.exe on Windows).

Note:

  • Although the Docker app on Windows and Mac asks for login credentials to Docker Hub, they are not needed for local deployment . You can proceed without creating any Docker account/logging in.
  • Linux users would need to install docker-compose separately. See relevant instructions at https://docs.docker.com/compose/install/.
  1. Ensure you have Git installed. Clone the server repo with git clone https://github.com/babe-project/BABE.git or git clone git@github.com:babe-project/BABE.git.

  2. Open a terminal (e.g., the Terminal app on MacOS or cmd.exe on Windows), cd into the project directory just cloned via git.

  3. For the first-time setup, run in the terminal

docker volume create --name babe-app-volume -d local
docker volume create --name babe-db-volume -d local
docker-compose run --rm web bash -c "mix deps.get && npm install && node node_modules/brunch/bin/brunch build && mix ecto.migrate"

Deployment

After first-time installation, you can launch a local server instance which sets up the experiment in your browser and stores the results.

  1. Run docker-compose up to launch the application every time you want to run the server. Wait until the line web_1 | [info] Running BABE.Endpoint with Cowboy using http://0.0.0.0:4000 appears in the terminal.

  2. Visit localhost:4000 in your browser. You should see the server up and running.

Note: Windows 7 users who installed Docker Machine might need to find out the IP address used by docker-machine instead of localhost. See Docker documentation for details.

  1. Use Ctrl + C to shut down the server.

Note that the database for storing experiment results is stored at /var/lib/docker/volumes/babe-db-volume/_data folder by default. As long as this folder is preserved, experiment results should persist as well.

Upgrading a deployed instance of the server

  1. git pull to pull in the newest changes.
  2. git push heroku master to pull the changes to the deployed instance hosted on Heroku.
  3. You may need to run heroku run "POOL_SIZE=2" mix ecto.migrate if there are new changes on the database.

Experiments (Frontend)

This program is intended to serve as the backend which stores and returns experiment results. An experiment frontend is normally written as a set of static webpages to be hosted on a hosting provider (e.g. Github Pages) and loaded in the participant's browser.

For detailed documentation on the structure and deployment of experiments, please refer to the minimal template and the _babe documentation.

Additional Notes

  • Using JSON object as the value type in the experiment results object to be submitted is currently not allowed. The reason is that it would be hard for the CSV writer to correctly format and produce a CSV file based on such a format. JSON array is supported though not recommended. It's best to split experiment results into different keys containing simple values, e.g. response1, response2, response3.

  • There is limited guarantee on database reliability on Heroku's Hobby grade. The experiment authors are expected to take responsibility of the results. They should retrieve them and perform backups as soon as possible.

  • This app is based on Phoenix Framework and written in Elixir. If you wish to modify the app, please look at the resources available at: