Glad you asked! Sciris (http://sciris.org) is a library of tools that make it faster and more pleasant to write scientific Python code. Built on top of NumPy and Matplotlib, Sciris provides functions covering a wide range of common array and plotting operations. This means you can get more done with less code, and spend less time looking things up on StackOverflow.
ScirisWeb is an extension of Sciris that allows you to build Python webapps without reinventing the wheel – kind of like Shiny for Python. In contrast to Plotly Dash and Streamlit, which have limited options for customization, ScirisWeb is completely modular, so you have control over which tools to use for which aspects of the project. Out of the box, ScirisWeb provides a "just works" solution using Vuejs for the frontend, Flask as the web framework, Redis for the (optional) database, and Matplotlib/mpld3 for plotting. But if you want a React frontend linked to an SQL database with Plotly figures, ScirisWeb can serve as the glue holding all of that together.
Sciris is available on PyPi (pip install sciris
) and GitHub. Full documentation is available at http://docs.sciris.org. If you have questions, feature suggestions, or would like some help getting started, please reach out to us at info@sciris.org.
Some highlights of Sciris (import sciris as sc
):
- Powerful containers – The
sc.odict
class is whatOrderedDict
(almost) could have been, allowing reference by position or key, casting to a NumPy array, sorting and enumeration functions, etc. - Array operations – Want to find the indices of an array that match a certain value or condition?
sc.findinds()
will do that. How about just the nearest value, regardless of exact match?sc.findnearest()
. What about the last matching value?sc.findlast()
. Yes, you could donp.nonzero()[0][-1]
instead, butsc.findlast()
is easier to read, type, and remember, and handles edge cases more elegantly. - File I/O – One-liner functions for saving and loading text, JSON, spreadsheets, or even arbitrary Python objects.
- Plotting recipes – Simple functions for mapping sequential or qualitative data onto colors, manipulating color data, and updating axis limits and tick labels, plus several new colormaps.
Some highlights of ScirisWeb (import scirisweb as sw
):
- ScirisApp – An extension of a Flask App that can be created as simply as
app = sw.ScirisApp(config)
and run withapp.run()
. - RPCs – Simple "remote procedure calls" that define how the frontend (web interface) interacts with the backend (Python server).
- Datastore – For more fully-featured webapps, user and data management are available based on Redis (with additional options for SQL or file-based databases).
That's OK. Perhaps you'd be interested in seeing what a script that performs tasks like parallelization, saving and loading files, and 3D plotting looks like when written in "vanilla Python" (left) compared to using Sciris (right):
Both of these do the same thing, but the plain Python version requires 50% more lines of code to produce the same graph:
Development of Sciris began in 2014 to support development of the Optima suite of models. We kept encounting the same issues and inconveniences over and over while building scientific webapps, and began collecting the tools we used to overcome these issues into a shared library. This library evolved into Sciris. (Note: while "Sciris" doesn't mean anything, "iris" means "rainbow" in Greek, and the name was loosely inspired by the wide spectrum of scientific computing features included in Sciris.)
To give a based-on-a-true-story example, let's say you have a dictionary of results for multiple runs of your model, called results
. The output of each model run is itself a dictionary, with keys such as name
and data
. Now let's say you want to access the data from the first model run. Using plain Python dictionaries, this would be results[list(results.keys())[0]]['data']
. Using a Sciris objdict
, this is results[0].data
– almost 3x shorter.
Yes. Sciris is currently used by a number of scientific computing libraries, including Atomica and Covasim. ScirisWeb provides the backend for webapps such as the Cascade Analysis Tool, HIPtool, and Covasim. Note that Sciris is still undergoing rapid development, and ScirisWeb, while functional, is still in beta development.
Here are a few more of the most commonly used features.
sc.odict()
: flexible container representing the best-of-all-worlds across lists, dicts, and arrayssc.objdict()
: like an odict, but allows get/set via e.g.foo.bar
instead offoo['bar']
sc.findinds()
: find indices of an array matching a value or conditionsc.findnearest()
: find nearest matching valuesc.smooth()
: simple smoothing of 1D or 2D arrayssc.isnumber()
: checks if something is any number typesc.promotetolist()
: converts any object to a list, for easy iterationsc.promotetoarray()
: tries to convert any object to an array, for easy use with NumPy
sc.saveobj()/sc.loadobj()
: efficiently save/load any Python object (via pickling)sc.savejson()/sc.loadjson()
: likewise, for JSONssc.thisdir()
: get current foldersc.getfilelist()
: easy way to access glob
sc.hex2grb()/sc.rgb2hex()
: convert between different color conventionssc.vectocolor()
: map a list of sequential values onto a list of colorssc.gridcolors()
: map a list of qualitative categories onto a list of colorssc.plot3d()/sc.surf3d()
: easy way to render 3D plotssc.boxoff()
: turn off top and right parts of the axes boxsc.commaticks()
: convert labels from "10000" and "1e6" to "10,000" and "1,000,0000"sc.SIticks()
: convert labels from "10000" and "1e6" to "10k" and "1m"sc.maximize()
: make the figure fill the whole screensc.savemovie()
: save a sequence of figures as an MP4 or other movie
sc.parallelize()
: as-easy-as-possible parallelizationsc.loadbalancer()
: very basic load balancer
sc.readdate()
: convert strings to dates using common formatssc.tic()/sc.toc()
: simple method for timing durationssc.runcommand()
: simple way of executing shell commands (shortcut tosubprocess.Popen()
)sc.dcp()
: simple way of copying objects (shortcut tocopy.deepcopy()
)sc.pr()
: print full representation of an object, including methods and each attributesc.heading()
: print text as a 'large' headingsc.colorize()
: print text in a certain colorsc.sigfigs()
: truncate a number to a certain number of significant figures
- Install Sciris:
pip install sciris
- Use Sciris:
import sciris as sc
- Download ScirisWeb (e.g.
git clone http://github.com/sciris/scirisweb
) - Install ScirisWeb (which will install Sciris as well):
cd scirisweb; python setup.py develop
- Change to the Hello World folder:
cd examples/helloworld
- Run the app:
python app.py
- Go to
localhost:8080
in your browser - Have fun!
Note: if you're a developer, you'll likely already have some/all of these packages installed.
- Install NodeJS (JavaScript manager)
- Install Redis (database)
- Install Anaconda Python (scientific Python environment)
- Clone and install Sciris:
git clone http://github.com/sciris/sciris
- Clone ScirisWeb:
git clone http://github.com/sciris/scirisweb
- Once you've done all that, to install, simply run
python setup.py develop
in the root folders ofsciris
andscirisweb
. This should install Sciris and ScirisWeb as importable Python modules.
To test, open up a new Python window and type import sciris
(and/or import scirisweb
)
If you have problems, please email info@sciris.org, or consult the rest of this guide for more information.
The easiest way to install Sciris is by using pip: pip install scirisweb
(which will also automatically install sciris
). If you want to install from source, follow these steps:
- Install Git:
sudo apt install git
- Install NodeJS:
sudo apt install nodejs
- Install Redis: https://redis.io/topics/quickstart
- (Optional) Install Anaconda Python (as of version 0.15, Sciris is only compatible with Python 3), and make sure it's the default Python, e.g.
your_computer:~> python Python 3.7.4 (default, Aug 13 2019, 20:35:49) [GCC 7.3.0] :: Anaconda, Inc. on linux Type "help", "copyright", "credits" or "license" for more information.
- Clone the Sciris repositories:
git clone http://github.com/sciris/sciris.git
andgit clone http://github.com/sciris/scirisweb.git
. - Run
python setup.py develop
in each of the two Sciris folders. - To test, open up a new Python window and type
import sciris
andimport scirisweb
. You should see something like:
>>> import sciris >>> import scirisweb
First, make sure that you have npm
(included in Node.js installation) and git
installed on your machine.
Install Anaconda Python. In your Python setup, you also need to have the following packages (instructions in parentheses show how to install with Anaconda Python environment already installed). Note, these should all be installed automatically when you type python setup.py develop
in the Sciris and ScirisWeb folders.
If you use Redis as your DataStore mode, you will need to have Redis installed on your computer (as a service). Redis does not directly support Windows, but there is a MicrosoftArchive page on GitHub where you may go for installation directions on your Windows machine. (For example, it can be installed at this site , downloading a .msi file). It ends up being installed as a service which you can navigate to by going the Windows Task Manager and going to the Services tab. Make sure the Redis
service is in the Running state.
Most likely, the directory for your Redis executables will be installed at C:\Program Files\Redis
. In that directory, you can double-click the icon for redis-cli.exe
to start the redis database command line interface at the default Redis database (#0). You can do keys *
to look at all of the store key / value pairs in the database, and exit
exits the interface.
You will probably want to use a non-default (i.e. N
is not 0) database. To investigate what keys are in, for example, database #2, while you are within redis-cli
, you can type select 2
to switch to that database.
Install Git. This can be done by installing Xcode commandline tools.
xcode-select --install
Install NodeJS. Visit https://nodejs.org/en/download/ and download the Mac version and install.
Install Redis: https://redis.io/topics/quickstart or run (Assumming brew is installed)
brew install redis
Install Anaconda Python 3, and make sure it's the default Python, e.g.
your_computer:~> python Python 3.7.4 (default, Aug 13 2019, 20:35:49) [GCC 7.3.0] :: Anaconda, Inc. on linux Type "help", "copyright", "credits" or "license" for more information.
Create a directory that will hold Sciris. For reference purposes we will create and refer to that directory as
pyenv
.Clone the Sciris repository into
pyenv
:git clone http://github.com/sciris/sciris.git
Create a Python virtual environment (venv) inside the directory of your choice. This will be the parent of the Sciris folder.
`virtualenv venv`
More information about python virtual environments can be found here. The project structure should be as follows;
-pyenv -venv -sciris
Get into the virtual environment. While inside the
pyenv
folder, to activate the virtual environment, type:./venv/bin/activate
Change to the Sciris root folder and type:
python setup.py develop
Repeat in the ScirisWeb root folder:
python setup.py develop
- To test if the if everything is working accordingly, open Python window within the virtual environment and type
import sciris
andimport scirisweb
. If no errors occur, then the import worked.
The problem with the simple deployment method described above is that requests are single-threaded. If this is an issue, recommended deployment is using nginx
to serve the static files, and gunicorn
to run the Flask app. Note that it is common for an application to call several RPCs with each page load. This means that the multithreaded deployment can result in improved site performance even for a single user.
You must have nginx (sudo apt install nginx
) and gunicorn
(pip install gunicorn
) installed.
- Copy
examples/gunicorn/example_nginx_config
to e.g./etc/nginx/sites-enabled/my_app
(can change filename if desired) - Edit the copied file to specify
- The hostname/URL for the site e.g.
my_app.com
- The full path to the directory containing
index.html
on the system runningnginx
- Change the port in
proxy_pass
line if desired - it must match the port inlaunch_gunicorn
- The hostname/URL for the site e.g.
- Reload or restart
nginx
e.g.sudo service nginx reload
For example, this will start it running at localhost:8188
:
server {
listen 8188;
server_name localhost;
location / {
root /home/my_username/my_sciris_app;
}
location /api {
proxy_pass http://127.0.0.1:8097/;
}
}
- Copy
examples/gunicorn/example_launch_gunicorn
to the folder with your app (e.g.launch_my_app_gunicorn
), and set the number of workers as desired - usual recommendation is twice the number of CPUs but for applications that are CPU bound (e.g., an RPC call runs a model) then it may be better to reduce it to just the number of CPUs. - The example script references the Flask app using
name_of_your_app:flask_app
. Thename_of_your_app
should be importable in Python (either via running Python in the current directory, or installing as a package viapip
) andflask_app
is the name of a variable containing the Flask application. So for example, you might have a filefoo.py
containing
app = sw.ScirisApp(__name__, name="My App")
the_app = app.flask_app
in which case the launch_my_app_gunicorn
script should contain foo:the_app
instead of name_of_your_app:flask_app
.
- Run
launch_my_app_gunicorn
. This will need to be kept running to support the site (so run vianohup
orscreen
etc.).
For example:
cd my_app
screen -S my_app_session
./launch_my_app_gunicorn
<you can now close the terminal>
...
<coming back later, you can restart it with>
screen -R my_app_session
Note that for local development, you can add the --reload
flag to the gunicorn
command to automatically reload the site. This can be helpful if using the nginx+gunicorn
setup for local development.
In the examples
and vue_proto_webapps
directories are contained a number of working examples of web applications combining Vue, Flask, and Twisted. These are being used as stepping stones for developing the main framework based in user_interface
, session_manager
, model_code
, and bin
.
A very simple test case of Sciris. In the examples/helloworld
folder, type python app.py
. If you go to localhost:8080
in your browser, it should be running a simple Python webapp.
See the directions here on how to install and run this example.