Giter Club home page Giter Club logo

pyns's Introduction

neuroscout

Build Status codecov DOI

This is the repository for the neuroscout server.

Requirements: Docker and docker-compose.

Configuration

First, set up the main environment variables in .env (see: .env.example). Set DATASET_DIR, KEY_DIR, and FILE_DATA to folders on the host machine.

Optionally, set up pliers API keys for feature extraction in .pliersenv (see: .pliersenv.example). More information on pliers API keys

Next, set up the Flask server's environment variables by modifying neuroscout/config/example_app.py and saving as neuroscout/config/app.py.

Finally, set up the frontend's env variables by modifying neuroscout/frontend/src/config.ts.example and saving as neuroscout/frontend/src/config.ts.

For single sign on using Google, a sign-in project is needed.

Initalizing backend

Build the containers and start services using the development configuration:

docker-compose -f docker-compose.yml -f docker-compose.dev.yml build
docker-compose -f docker-compose.yml -f docker-compose.dev.yml up -d

The server should now be running at http://localhost/

Next, initialize, migrate and upgrade the database migrations. If you have a database file, load it using pg_restore. Otherwise, delete the migrations folder, initalize the database and add a test user.

docker-compose exec neuroscout bash
rm -rf /migrations/migrations
python manage.py db init
python manage.py db migrate
python manage.py db upgrade
python manage.py add_user useremail password

Staging & production server

For the staging server, you can trigger a manual build as follows:

docker-compose -f docker-compose.yml -f docker-compose.build.yml build
docker-compose -f docker-compose.yml -f docker-compose.build.yml up -d

For the staging or production server, you can trigger pull a pre-built image from GHCR: First set the variable IMAGE_TAG to the apprioriate image tag

docker-compose -f docker-compose.yml -f docker-compose.image.yml build
docker-compose -f docker-compose.yml -f docker-compose.image.yml up -d

Setting up front end

The frontend dependencies are managed using yarn

Enter the neuroscout image, and install all the necessary libraries like so:

docker-compose exec neuroscout bash
cd frontend
yarn

You can then start a development server:

yarn start

Or make a production build:

yarn build

Ingesting datasets and extracting features

You can use manage.py commands to ingest data into the database. Run the following commands inside docker: docker-compose exec neuroscout bash

To add BIDS datasets

python manage.py add_task bids_directory_path task_name

For example for dataset ds009

python manage.py add_task /datasets/ds009 emotionalregulation

Finally, once having added a dataset to the database, you can extract features using pliers into the database as follows:

python manage.py extract_features bids_directory_path task_name graph_json

For example:

python manage.py extract_features /datasets/ds009 emotionalregulation graph.json

Even easier, is to use a preconfigured dataset config file, such as:

docker-compose exec neuroscout python manage.py ingest_from_json /neuroscout/config/ds009.json

Maintaining docker image and db

If you make a change to /neuroscout, you should be able to simply restart the server.

docker-compose restart neuroscout

If you need to upgrade the db after changing any models:

docker-compose exec neuroscout python manage.py db migrate
docker-compose exec neuroscout python manage.py db upgrade

To inspect the database using psql:

docker-compose run postgres psql -U postgres -h postgres

API

Once the server is up and running, you can access the API however you'd like.

The API is document using Swagger UI at:

http://localhost/swagger-ui

Authorization

To authorize API requests, we use JSON Web Tokens using Flask-JWT. Simply navigate to localhost:5000/auth and post the following

{
    "username": "[email protected]",
    "password": "string"
}

You will receive an authorization token in return, such as:

{
    "access_token": "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJpZGVudGl0eSI6MSwiaWF0IjoxNDQ0OTE3NjQwLCJuYmYiOjE0NDQ5MTc2NDAsImV4cCI6MTQ0NDkxNzk0MH0.KPmI6WSjRjlpzecPvs3q_T3cJQvAgJvaQAPtk1abC_E"
}

You can then insert this token into the header to authorize API requests:

GET /protected HTTP/1.1
Authorization: JWT eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJpZGVudGl0eSI6MSwiaWF0IjoxNDQ0OTE3NjQwLCJuYmYiOjE0NDQ5MTc2NDAsImV4cCI6MTQ0NDkxNzk0MH0.KPmI6WSjRjlpzecPvs3q_T3cJQvAgJvaQAPtk1abC_E

Note that in order to use any protected routes, you must confirm the email on your account. Confusingly, you can get a valid token without confirming your account, but protected routes will not function until confirmation.

Running backend tests

To run tests, after starting services, create a test database:

docker-compose exec postgres psql -h postgres -U postgres -c "create database scout_test"

and execute:

docker-compose run -e "APP_SETTINGS=neuroscout.config.app.DockerTestConfig" --rm -w /neuroscout neuroscout python -m pytest neuroscout/tests

or run them interactively: docker.compose exec neuroscout bash APP_SETTINGS=neuroscout.config.app.DockerTestConfig python -m pytest neuroscout/tests/ --pdb

To run frontend tests run:

docker-compose run --rm -w /neuroscout/neuroscout/frontend neuroscout npm test

Running frontened tests

To run frontend tests, have Cypress 6.0 or greater installed locally. First, ensure neurscout is running:

docker-compose -f docker-compose.yml -f docker-compose.dev.yml up -d

Next, set up the test environment:

docker-compose exec neuroscout bash
export APP_SETTINGS=neuroscout.config.app.DockerTestConfig
bash setup_frontend_tests.sh

In a separate window, you can run cypress:

cd neuroscout/frontend cypress open

Once done, kill the first command, and run the following to tear down the test db

docker-compose exec -e APP_SETTINGS=neuroscout.config.app.DockerTestConfig neuroscout python manage.py teardown_test_db

pyns's People

Contributors

adelavega avatar jsmentch avatar rbroc avatar

Stargazers

 avatar  avatar  avatar

Watchers

 avatar  avatar  avatar

Forkers

kan-k jsmentch rbroc

pyns's Issues

inconsistent name for RMS predictor

RMS is coded with name field = 'rms' for a bunch of datasets (SchematicNarrative, Sherlock, SherlockMerlin) and as 'rmse' for all others, which yields issues with pyNS-based queries.

pin altair/vegalite version

Analysis reports are generated for the following versions:
altair 4.0.0
vega-lite 2.6.0

Note that when upgrading to these versions, there's no need to call notebook renderer.

Use consistent method names that match API routes

Currently, we have ns.analyses.full() and ns.analyses.get_report(). Methods should probably all follow the same naming conventions, and ideally match the API (so, e.g., the first above should be ns.analyses.get_full().

Add convenience function to fill/clear/push/pull

Currently it's a bit cumbersome:

paranoia = life.clone()
paranoia.dataset_id = 19
paranoia.runs = []
paranoia.predictors = []
paranoia.push()
paranoia.fill()

That could all be made into a little helper function in which you provide a dataset_id

Add _repr_ to objects

Currently, they are not terribly useful:
<pyns.models.analysis.Analysis at 0x7f163c718c50>

Automatically re-authorize

Currently, once your api token is stale, protected calls will just fail, and you have to manually re-authorize.

It'd be nice if the API checks that the token is expired, and automatically re-authorizes when possible (i.e. the keys are in the os environment)

Add exception handling for requests

Requests usually will just return an error code, instead of throw exception.

Instead, lets throw exceptions, and have the calls return the content.

Cache requests

We should consider caching requests in the client, as some routes can take a long time to retrieve. Since you're already using requests (which btw should be added to requirements), a super simple solution I see no downside to would be to add requests-cache.

Add single sign on

The frontend supports SSO, but pyNS currenly only supports users created through our db.

Adding SSO directly from pyNS would be useful.

Add Travis-CI

It would be good to add Travis-CI support for CI testing.

Decide if/how to handle flask/requests Client differences

One idea with this library is that it could also be used internally in neuroscout to test the API itself.
In fact, this library is so far based on the internal flask client wrapper I use in the neuroscout tests.

However, one difficulty is that the flask client (which is used to test in flask without testing the live URL), is slightly different from requests.

We need to decide if its worthwhile to design the library to deal with both clients. There may be a way to subclass the client over in the main neuroscout repo to deal with this, but push off the responsibility over there so that this library stays cleaner.

In depth tutorials/notebooks

Let's add some jupyter notebooks or tutorials covering some use cases of pyNS.

One example is how to deal with categorical variables.

Add betamax support

Add betamax to cache requests in the tests. Also, think about whether the current "test user" is a good idea, or might be insecure.

Add OO Interface for Analysis creation

To make pyNS more user friendly, it would be useful if the library returns python objects that mirror the JSON response. These objects could have methods associated with them to save to the API directly.

For example

analysis = api.Analysis(name='new_analysis')
analysis.create()
print(analysis.hash_id)
    5xdj45
analysis.predictors = [124, 421, 246]
analysis.save()
analysis.compile()
print(analysis.status())
   PENDING
print(analysis.status())
   FINISHED

requests slowing things down?

At least some routes in pyns are extremely slow compared to directly hitting the API (e.g., via the browser). It looks like the bottleneck is in requests, because just doing something like requests.get(https://neuroscout.org/api/analyses/Mzq74/full) is very slow on my machine (several seconds). Probably worth looking into.

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    ๐Ÿ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. ๐Ÿ“Š๐Ÿ“ˆ๐ŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google โค๏ธ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.