The Supreme Information Providing Application
Python JavaScript HTML CSS Nginx Shell
Failed to load latest commit information.
build Upgrade factory_boy to include dependency fix Jan 14, 2017
example Use a `dictConfig` instead of the old-style ini Feb 13, 2016
sipa Fix `__all__` and mute pylint in datasource definitions Jan 14, 2017
tests Make user_from_ip for sample accessible and update test Jan 14, 2017
.dockerignore Fix #97, display version information. Nov 15, 2015
AUTHORS Add newline to authors Jan 14, 2017
Dockerfile Make Dockerfile Relative Apr 15, 2016
babel.cfg Add flask-babel, full translation, Babel messages Aug 1, 2014
error.log Move log file to ./error.log temporarily Apr 24, 2015
requirements.txt Fix `requirements.txt` symlink May 23, 2016
tox.ini Expand line length to 90 Mar 3, 2016
uwsgi.ini Fix config regarding prefixes Jul 1, 2016

Build Status Code Climate

SIPA - Supreme Information Providing Application


Just as SIPA stands for a ball over the net game[1], the lesser known Supreme Information Providing Application does just the same -- sending packets over the internet.

This project is a flask-based webserver developed by members of the student network Dresden.


Please note that SIPA has been built to fit our specific purposes. This means that there will be features you probably won't need, such as the traffic monitoring or splitting the login process into certain divisions.

How can I run Sipa?

As a general note, you should have docker and docker-compose installed. Just using python and e.g. a virtualenv is possible, but discouraged.

The simplest method is to run docker-compose -f build/development.yml up -d.

This should automatically set up an nginx container on port 80 providing /sipa and /sipa_debug, which are two containers of sipa, the first running on uwsgi, and the second directly using

If this does not work for you see “Running on Docker” below for a manual (i.e. not docker-compose-based) container setup.

How can I run the tests?

For testing, there exists the docker-compose file build/testing.yml:

docker-compose -f build/testing.yml up -d
docker-compose -f build/testing.yml run --rm sipa_testing python test

…ore choose any other testing command you wish. For example, you can execute a single test case using nosetests -v tests.integration.test_hss_ldap:HssLdapPasswordTestCase

Running on Docker

To build the image, cd into your instance of sipa (which contains the Dockerfile) and run

docker build -t sipa .

Now, you have basically two possibilities to use sipa:

  • Using uwsgi: This is the standard option. Just run:
docker run --name sipa -d sipa

Note that in order to use above example, you have to use another docker container, i.e. an nginx instance, which is linked to the sipa container. If you don't want to do this, you have to expose port 5000 adding -p 5000:5000 as a parameter.

  • Using http: This is an option you have to envoke manually. To use it, run
docker run --name sipa -p 5000:5000 -d sipa python --exposed

If you want to use sipa for development, adding --debug after and mounting your sipa folder using -v <path>:/home/sipa/sipa is recommended.

Running with a prefix

If you run sipa under something else than /, make sure you specify this during docker run!

Instead of the default uwsgi --ini uwsgi.ini, you will have to use uwsgi --ini uwsgi.ini:prefixed --set-ph prefix=/mountpoint


Environment variables

The default config (sipa.default_config) reads environment variables for the most cases.

Local Python config file

If one prefers to write configuration into a file locally, sipa reads / If the environment variable SIPA_CONFIG_FILE is set, its path is taken instead.


In order to provide an additional logfile, set the app's LOG_CONFIG variable in your local configuration file.

It has to be set to a dict usable by dictConfig(). For further documentation, see the python docs.

Also, you might want to look into sipa.defaults.DEFAULT_CONFIG for the current structure.

Keep in mind you don't need to rewrite the whole default configuration every time, since you can include 'incremental': True in said dict.

Required format for the markdown files

In the folder content/ you can place markdown files to use them as content pages as well as news. The folder structure has to look like this, following the conditions explained below:

├── images
│   ├── image.png
│   └── logo.png
├── legal
│   ├──
│   ├──
│   ├──
│   └──
├── news
│   ├──
│   ├──
│   ├──
│   └──
└── support

The navigation bar is built by scanning every directory for *.md-files. Directories containing the latter are then expected to contain an index file for every language code, e.g. These index files decide whether it will appear in the navigation bar and which title it will be displayed with.

The index files have to contain certain metadata in the form property: value. This metadata section is terminated by an empty line (\n\n)

  • To not include a folder in the menu, set index: false, as you will need for the news/ folder(!).

  • To include a folder, set the title of the navigation bar with name: as well as its position with rank. Do not forget to set index: true explicitly.

If the parameter index does not exist, the corresponding folder will not appear in the navigation bar, although every folder containing a markdown file must contain an file.

The markdown files must have a header in the same fashion as the index files. A complete .md file can look like this:

title: Stuff
author: alice
date: 2015-03-27
glyphicon: glyphicon-user

### Stuff
#### Part 1

To do stuff, you have to do stuff first.

Another possibility is to include hyperlinks, which only have a metadata section:

title: Awesome page
glyphicon: glyphicon-tower
link: http://
rank: 1

Adding dynamic content

Sipa is capable of parsing a json file to provide “dynamic” content, i.e. content which varies according to the dormitory selected.

For each content file, Sipa tries to open a file following the naming scheme <pagename>.<locale>.json. If it does not exist or does not contain valid json, this is ignored and no additional block is displayed on the webpage.

The file has to follow the format below:

    "title": "Financial data",
    "keys": {
        "beneficiary": "Beneficiary",
        "iban": "IBAN",
        "bank": "Bank",
        "bic": "BIC",
        "information": "Information"
    "values": {
        "wu": {
            "beneficiary": "Studentenrat TUD - AG DSN",
            "bank": "Ostsächsische Sparkasse Dresden",
            "iban": "DE61850503003120219540",
            "bic": "OSDD DE 81 XXX",
            "information": "User-ID, Last Name, First Name, Dormitory / Room number"
        "gerok": {
            "beneficiary": "Studentenrat TUD - AG DSN",
            "bank": "Ostsächsische Sparkasse Dresden",
            "iban": "To be investigated",
            "bic": "To be investigated",
            "information": "To be investigated"
        "local": {
            "beneficiary": "Not available",
            "bank": "Not available",
            "iban": "Not available",
            "bic": "Not available",
            "information": "Not available"
    "mappings": {
        "wu": "wu",
        "zw": "wu",
        "borsi": "wu",
        "gerok": "gerok",
        "localhost": "local"

Because information may or may not dependend on a data source, it can be grouped using mappings. Dormitories whose name is not specified in mappings will not appear in the select field on the web page, so be careful to keep the list complete.

The value of a mappings field has to correspond to a dataset in values.