- Preparation step:
- Make sure you have
python3
,pip
andgit
installed. - Download Howitz from the GitHub repo.
- Make sure you have
- Installation step:
Create and activate venv, from the project root folder run:
$ python3 -m venv howitzvenv $ source howitzvenv/bin/activate
Install dependencies, from the project root folder run:
$ pip install -e .
Read more about installation in the Install safely section.
- Configuration step:
The easiest way to configure Howitz is via a
toml
file.Create an empty
.howitz.toml
file in the project root folder.Copy the values from the preferred example config file
howitz.*.example
to.howitz.toml
. Here using thehowitz.min.toml.example
:$ cp howitz.min.toml.example .howitz.toml
Open
.howitz.toml
and fill out at least the config values:SECRET_KEY
andserver
. Those values are left empty in the example config file.Play around with the config values in
.howitz.toml
, if desired.
Read more about other configuration methods, different configurations options and variables in the Configuration section.
NB!:
When configuring for production, make sure that
.howitz.toml
is appropriately adjusted as described in the Config file for production section.
- User management step:
Check if you have an existing user in the Howitz database, from the project root folder run:
$ flask --app howitz user list
Create a new user if you do not have one already, from the project root folder run:
$ flask --app howitz user create USERNAME PASSWORD TOKEN
Read more about user management and other commands in the User management section.
- Run Howitz:
Start Howitz as a flask app, from the project root folder run:
$ python3 -m howitz
Open Howitz in the browser. By default in dev, Howitz will be accessible at http://127.0.0.1:5000.
Read more about running Howitz in the Play around section.
Create and activate a virtualenv, install dependencies in that virtualenv:
$ python3 -m venv howitzvenv $ source howitzvenv/bin/activate $ pip install -e .
Tip:
Howitz is deeply dependent on the libraryzinolib
. When developing Howitz, it might be prudent to add zinolib manually to the virtualenv by downloading the source, entering the directory and runningpip install -e .
. This will make it very easy to switch between versions and branches of zinolib.
You need to have either a minimal configuration file or set two environment variables, see Configuration. Tip for quickly setting up an extensive config file for dev:
Check out the Example config-file (for development) section.
After both installation (see Install safely) and Configuration are done, you can run Howitz by running either:
$ python3 -m howitz
or:
$ flask --app howitz run
This will get you a web interface running at http://127.0.0.1:5000/. The database (see User management) is by default put in the current directory.
NB!:
If you get an error when attempting to log in for the first time, make sure you have created a user in the Howitz database, see Managing the Howitz user database.
You need to have either a minimal configuration file or set two environment variables, see Configuration.
Tip for quickly setting up an extensive config file:
Check out the Example config-file (for development) section. Make sure the config file is appropriate for production, see Config file for production.
Always use an installed Howitz.
- gunicorn:
gunicorn 'howitz:create_app()'
- waitress:
waitress-serve --call howitz:create_app
See https://flask.palletsprojects.com/en/3.0.x/deploying/ for more options and additional details, and the respective server's docs for server-specific details.
Due to how Zino protocol 1 does logins, the password (here called token) needs to be stored in plain text in every client. For security reasons it is not desirable to ever store this token in a cookie or otherwise in a browser, so instead the token is stored where the browser cannot get to it, in a user database local to the frontend server.
When logging in to Howitz a user uses a normal password (not the token) which is used to safely fetch the token for connecting to the Zino protocol 1 server. This password can be treated like any other password and be put in a vault or a password manager.
The mapping from websafe password to legacy token is done via a user database. The Zino backend server admin creates a token and username. The frontend server admin creates a local user with the backend username and token, and a password preferrably chosen by the users themselves.
We are planning to allow users to change the frontend password eventually but we do not wish for the backend token to ever be seen by a browser in any fashion.
Users are by default stored in the file ./howitz.sqlite
, this can be changed
in the configuration file.
While it is possible to use an sqlite3-client to alter the database, setting the password should be done via the command line, to ensure that the password is hashed correctly.
Get a list of the possible commands by running:
$ flask --app howitz user Usage: flask user [OPTIONS] COMMAND [ARGS]... Options: --help Show this message and exit. Commands: create delete list update
Get help for each sub-command with appending "--help", for instance:
$ flask -A howitz user update --help Usage: flask user update [OPTIONS] USERNAME Options: -p, --password TEXT -t, --token TEXT --help Show this message and exit.
When running commands to Howitz user database, you may need to provide all or some of the options.
USERNAME
- an existing username on your Zino server. You will need to provide it when logging in to Howitz on web.
TOKEN
- token assigned to a given username on your Zino server. In the original Zino protocol this value is referred to as a Secret. Store it in the Howitz database once and forget about it when logging in to Howitz on web.
PASSWORD
- a password of your choice. This one is purely Howitz-specific. You will need to provide it when logging in to Howitz on web.
create
- creates a user, the username needs to be unique
delete
- removes an existing user
list
- shows all known usernames
update
- is used to change the web password or Zino token for an existing user
Howitz can run without a configuration file. Default values will be used for listen-address (127.0.0.1), port (5000) and storage location (./howitz.sqlite3). However, at minimum you also need to pass in a SECRET_KEY for Flask and a Zino server address to fetch events from.
These can be passed via a configuration file, .howitz.toml
(stored in the current directory or user home
directory) or via environment variables.
Via a .howitz.toml
configuration file:
[flask] SECRET_KEY = "long string!" [zino.connections.default] server = "zino.server.domain"
Directly via environment variables:
HOWITZ_SECRET_KEY="long string!" HOWITZ_ZINO1_SERVER="zino.server.domain"
All config options can be overruled by environment variables. Prefix them with "HOWITZ_" for Flask-specific options and "HOWITZ_ZINO1_" for Zino-specific options. It is also possible to override logging by setting "HOWITZ_LOGGING" to a string of a Python dict but we do not recommend it, use a config file instead.
The refresh interval value specifies the frequency with which events are checked for updates, i.e., are synchronized. This value can be modified by adding, for example, refresh_interval = 10
to
the [howitz]
-section, or by setting the environment variable HOWITZ_REFRESH_INTERVAL
to a new value.
Refresh interval values are in seconds and must be integers. The default value is 5
seconds.
Debugging can be turned on either by adding DEBUG = true
to the
[flask]
-section or setting the environment variable HOWITZ_DEBUG
to 1
.
The default timezone for timestamps is UTC
. Timezone information can be changed by adding timezone = "LOCAL"
to
the [howitz]
-section or setting the environment variable HOWITZ_TIMEZONE
to LOCAL
. Timezone values other
than LOCAL
and UTC
provided in config will be ignored and fall back to UTC
.
Howitz uses caching. You can configure preferred caching type under the [flask]
-section.
See Flask-Caching's configuration docs for available configuration options.
Default cache type is SimpleCache.
Howitz will use the configuration in [zino.connections.default]
. There may
be other sections starting with zino.connections
, these are a holdover from
CLI clients being able to choose a specific server with a CLI flag on startup.
See future plans.
In addition to server
, you can also set an explicit port
, as an
integer. The default is port 8001
. In addition to this port there is
a hardcoded usage of port 8002
for the push update service. (You might find
mentions of NTIE, this is an internal name for the update service.)
Sorting method can be changed under the [howitz]
-section by adding:
sort_by = "<valid sorting method>"
Valid sorting methods are:
- raw - The same order in which Zino server sends events (by ID, ascending).
- lasttrans - Newest transaction first, all IGNORED at the bottom. Default sorting in curitz.
- severity - Events with highest priority first, grouped by event type. Priority takes into account both whether event signifies any disturbance, event's administrative phase and event's type, so there might not be continuous blocks of color. Existing method in Ritz TK, but it is called 'default' there.
- down-rev - Shortest/none downtime first. Identical to an existing method in Ritz TK.
- down - Longest downtime first. Identical to an existing method in Ritz TK.
- upd-rev - Events with the most recent update date first. Identical to an existing method in Ritz TK.
- upd - Events with the oldest update date first. Identical to an existing method in Ritz TK.
- age-rev - Oldest events first. Identical to an existing method in Ritz TK.
- age - Newest events first. Identical to an existing method in Ritz TK.
For development, copy the contents of the included file howitz.toml.example
to .howitz.toml
in the same directory.
- Set
[flask] -> SECRET_KEY
to some long string. - Set
[zino.connections.default] -> server
to the address of a Zino 1 server. - Optionally set
[zino.connections.other] -> server
to the address of a fallback Zino 1 server. If the default server stops working you can swap "other" with "default" in the config-file and keep on working. If you don't set it to anything, keep it commented out or remove it.
As for logging, there is a handler debug
that will copy everything DEBUG or higher to a file
debug.log
, you might want to use this handler for your code.
The handler error
will likewise put everything WARNING or higher in the
error.log
file.
It is better to control [flask] -> SECRET_KEY
and
[zino.connections.default] -> server
via environment variables than
hardcoding them in the config file. It's best to delete them from the config
file.
[flask] -> DEBUG
must be false
. Keeping it as true
may lead to
surprising bugs.
[howitz] -> devmode
must be false
. Due to devmode
being false
it becomes necessary to explicitly write in the [howitz]
section which
IP-address and port to listen on:
[howitz] devmode = false listen = "127.0.0.1" port = 5000
(127.0.0.1 and 5000 are the Flask defaults.)
[logging]
will need adjustments. Increase the level of the wsgi
-handler
or only use the error
handler. Change the error-handler to ship its log
somewhere else, via syslog or Sentry or similar.
Linting: tox -e lint
Tests: tox
We hope to be able to automatically failover to other servers in
zino.connections
.