Run locally

Reading List is based on top of the cliquet project, and as such, please refer to cliquet’s documentation for more details.

For development

By default, Reading List persists the records and internal cache in a PostgreSQL database.

The default configuration will connect to the postgres database on localhost:5432, with user/password postgres/postgres. See more details below about installation and setup of PostgreSQL.

make serve

Using Docker

Reading List uses Docker Compose, which takes care of running and connecting PostgreSQL:

docker-compose up


By default, Reading List relies on Firefox Account OAuth2 Bearer tokens to authenticate users.

See cliquet documentation to configure authentication options.

Install and setup PostgreSQL

(requires PostgreSQL 9.3 or higher).

Using Docker

docker run -e POSTGRES_PASSWORD=postgres -p 5434:5432 postgres


On debian / ubuntu based systems:

apt-get install postgresql postgresql-contrib

By default, the postgres user has no password and can hence only connect if ran by the postgres system user. The following command will assign it:

sudo -u postgres psql -c "ALTER USER postgres PASSWORD 'postgres';"


Assuming brew is installed:

brew update
brew install postgresql

Create the initial database:

initdb /usr/local/var/postgres

Cryptography libraries


On Debian / Ubuntu based systems:

apt-get install libffi-dev libssl-dev

On RHEL-derivatives:

apt-get install libffi-devel openssl-devel


Assuming brew is installed:

brew install libffi openssl pkg-config

Running in production


# Heka
cliquet.logging_renderer = cliquet.logs.MozillaHekaRenderer

# StatsD
cliquet.statsd_url = udp://carbon.server:8125

Application output should go to stdout, and message format should have no prefix string:

class = StreamHandler
args = (sys.stdout,)
level = INFO
formater = heka

format = %(message)s

Adapt the logging configuration in order to plug Sentry:

keys = root, sentry

keys = console, sentry

keys = generic

level = INFO
handlers = console, sentry

level = WARN
handlers = console
qualname = sentry.errors
propagate = 0

class = StreamHandler
args = (sys.stdout,)
level = INFO
formater = heka

format = %(message)s

class = raven.handlers.logging.SentryHandler
args = ('',)
level = WARNING
formatter = generic

format = %(asctime)s,%(msecs)03d %(levelname)-5.5s [%(name)s] %(message)s
datefmt = %H:%M:%S

PostgreSQL setup

In production, it is wise to run the application with a dedicated database and user.

postgres=# CREATE USER produser;
postgres=# CREATE DATABASE proddb OWNER produser;

The tables needs to be created with the cliquet tool.

$ cliquet --ini config/readinglist.ini migrate
note:Alternatively the SQL initialization files can be found in the cliquet source code (cliquet/cache/postgresql/schemal.sql and cliquet/storage/postgresql/schemal.sql).

Running with uWsgi

To run the application using uWsgi, an app.wsgi file is provided. This command can be used to run it:

uwsgi --ini config/readinglist.ini

uWsgi configuration can be tweaked in the ini file in the dedicated [uwsgi] section.

Here’s an example:

wsgi-file = app.wsgi
enable-threads = true
http-socket =
processes =  3
master = true
module = readinglist
harakiri = 30
uid = readinglist
gid = readinglist
virtualenv = .
lazy = true
lazy-apps = true

To use a different ini file, the READINGLIST_INI environment variable should be present with a path to it.

Running with gevent

It is possible to use gevent, by adding this in the configuration:

readinglist.gevent_enabled = true

Gevent and psycogreen should be installed in the virtualenv for it to work properly:

.venv/bin/pip install gevent psycogreen
note:Gevent support is known to have issues with Python 3, and as such, it is discouraged to use it in this environment.