Skip to content
Snippets Groups Projects
Commit d2e3ace9 authored by Thomas Schneider's avatar Thomas Schneider
Browse files

WIP: docs

parent 05c69bc1
Branches
No related tags found
No related merge requests found
Checking pipeline status
...@@ -43,4 +43,6 @@ All while heeding the event’s design. ...@@ -43,4 +43,6 @@ All while heeding the event’s design.
``docs/index.rst`` (which includes this file) as well from content that ``docs/index.rst`` (which includes this file) as well from content that
should only appear here. should only appear here.
See ``docs/installation.rst`` for installation instructions. See ``docs/installation.rst`` for installation instructions. To build the
documentation as HTML locally, run ``pdm run docs`` and open
``docs/_build/index.html``.
...@@ -25,7 +25,7 @@ release = version ...@@ -25,7 +25,7 @@ release = version
# -- General configuration --------------------------------------------------- # -- General configuration ---------------------------------------------------
# https://www.sphinx-doc.org/en/master/usage/configuration.html#general-configuration # https://www.sphinx-doc.org/en/master/usage/configuration.html#general-configuration
extensions = [] extensions = ["sphinx.ext.intersphinx"]
templates_path = ["_templates"] templates_path = ["_templates"]
exclude_patterns = ["_build", "Thumbs.db", ".DS_Store"] exclude_patterns = ["_build", "Thumbs.db", ".DS_Store"]
...@@ -35,4 +35,10 @@ exclude_patterns = ["_build", "Thumbs.db", ".DS_Store"] ...@@ -35,4 +35,10 @@ exclude_patterns = ["_build", "Thumbs.db", ".DS_Store"]
# https://www.sphinx-doc.org/en/master/usage/configuration.html#options-for-html-output # https://www.sphinx-doc.org/en/master/usage/configuration.html#options-for-html-output
html_theme = "alabaster" html_theme = "alabaster"
html_static_path = ["_static"]
intersphinx_mapping = dict(
flask=("https://flask.palletsprojects.com/en/3.0.x/", None),
flask_multipass=("https://flask-multipass.readthedocs.io/en/latest/", None),
flask_sqlalchemy=("https://flask-sqlalchemy.palletsprojects.com/en/3.1.x/", None),
gunicorn=("https://docs.gunicorn.org/en/stable/", None),
)
...@@ -16,7 +16,7 @@ server: ...@@ -16,7 +16,7 @@ server:
.. code:: shell-session .. code:: shell-session
% npm install # may update package-lock.json % npm install # may update package-lock.json, or instead:
% npm clean-install # uses package-lock.json exactly % npm clean-install # uses package-lock.json exactly
% npm run start % npm run start
......
Installation Installation
============ ============
It is recommended to use our pre-built `Python package`_ (wheel) or `container To install this software, you can use a container-based setup, or run it
image`_. Building the package yourself is left as an exercise to the reader directly in a Python environment. As there are many ways (and opinions!) how to
(hint: it is a standard Python package, you need Node.js, pass configure a web server and deploy a Python WSGI application, only some details
``--config-setting without-npm`` to ``pyproject-build`` if you do not want it to are outlined here and the reader is expected to be familiar with at least web
build the frontend for you, but then you need to run ``npm run build`` server administration.
beforehand).
See also the :external+flask:std:doc:`Flask documentation on production
The container image ships with all supported features. For the Python package, deployment <deploying/index>`.
some features require optional dependencies: ``auth-ldap``, ``auth-saml``,
Container setup (Podman, Kubernetes, …)
---------------------------------------
Pull the `container image`_ (or build it yourself using the provided
``Containerfile``):
.. code:: shell-session
% podman pull registry.git.fsmpi.rwth-aachen.de/schilder/schilder2000:{{TAG}}
Config and data is expected in ``/usr/local/var/schilder2000-instance/``. For
starters, you can use the ``examples/`` directory in the `source repository`_,
which is also included in the container image. To create a volume based on it:
.. code:: shell-session
% [[ $(id -u) -eq 0 ]] || podman unshare
# pushd $(podman image mount registry.git.fsmpi.rwth-aachen.de/schilder/schilder2000:{{TAG}})
# cd usr/local/var/schilder2000-instance
# tar cf - . | podman volume import schilder2000-instance
# popd
# podman image unmount registry.git.fsmpi.rwth-aachen.de/schilder/schilder2000:{{TAG}}
You can also use a volume just for ``/usr/local/var/schilder2000-instance/data``
and mount ``/usr/local/var/schilder2000-instance/config/config.py`` separately.
Continue with :ref:`configuration`.
Without container
-----------------
You can use our pre-built `Python package`_ (wheel) or build it yourself.
Dependencies
~~~~~~~~~~~~
You need Python 3.9 or later and the dependencies specified in
``pyproject.toml``. It is suggested to use a virtualenv, as distribution
packages are often missing or outdated.
Some optional dependencies need additional native libraries, namely
MySQL/MariaDB Connector/C for MySQL/MariaDB support (both should work with
either database), and OpenLDAP and Cyrus SASL for LDAP authentication. If
binary wheels for those are not available, you need the development versions of
those as well as C compiler and Python development infrastructure.
Additionally, Git is required to get the sources of some dependencies.
.. code:: shell-session
# apt-get install python3-dev pkg-config gcc libmariadb-dev libldap-dev libsasl2-dev git
# dnf install python3-devel gcc 'pkgconfig(libmariadb)' 'pkgconfig(ldap)' git-core
# apk add -t .schilder2000 python3 mariadb-connector-c libldap # Runtime
# apk add -t .schilder2000-build build-base git mariadb-connector-c-dev \
openldap-dev python3-dev # Build only, can be removed later
To use OS packages as much as possible (note that the versions your distribution
provides may be too outdated and you may need to install the development
dependencies from above anyway):
.. code:: shell-session
# apt-get install python3 weasyprint python3-jinja2 python3-flask \
python3-asgiref python3-flask-sqlalchemy python3-flaskext.wtf alembic \
python3-qrcode python3-ldap python3-authlib python3-psycopg \
python3-mysqldb git
# dnf install python3 \
python3dist\({weasyprint,jinja2,flask\\[async\\],flask-sqlalchemy,flask-wtf,alembic,qrcode}\) \
python3dist\({python-ldap,python3-saml,authlib,psycopg,mysqlclient}\)
# apk add -t .schilder2000 python3 weasyprint py3-jinja2 py3-flask \
py3-asgiref py3-flask-sqlalchemy py3-flask-wtf py3-alembic py3-ldap \
py3-python3-saml py3-authlib py3-psycopg py3-mysqlclient git
If you are not using the pre-built `Python package`_ (wheel), you also need
Node.js and npm to build the frontend:
.. code:: shell-session
# apt-get install npm
# dnf install nodejs-npm
# apk add npm
You will also likely want a WSGI server. If in doubt, choose Gunicorn_:
.. code:: shell-session
# apt-get install gunicorn
# dnf install python3-gunicorn
# apk add py3-gunicorn
Pre-built package
~~~~~~~~~~~~~~~~~
In your chosen deployment location (e. g., virtualenv), install the package with
your desired optional extras. These are ``auth-ldap``, ``auth-saml``,
``auth-oauth``, ``all-auth``, ``db-postgres``, ``db-mysql``, ``all-db``, ``auth-oauth``, ``all-auth``, ``db-postgres``, ``db-mysql``, ``all-db``,
``all``. For example, to install the package with support for SAML login and ``all``. For example, to install with support for SAML login and Postgres
Postgres database: database:
.. code:: shell-session
% pip install "schilder2000[auth-saml,db-postgres]" \
--index-url https://git.fsmpi.rwth-aachen.de/api/v4/projects/305/packages/pypi/simple
Continue with :ref:`configuration`.
Building from source
~~~~~~~~~~~~~~~~~~~~
This package follows `PEP 517`_ conventions. You can use `build`_ to generate
SDist and wheel packages, or run ``pip install .`` in your local source tree, …
if you are at this point, you probably know your choices anyway.
The default build process will automatically invoke Node.js/npm to build the
frontend. To disable this behaviour, pass ``without-npm`` as build config
setting. This requires the files to already exist. For example:
.. code:: shell-session .. code:: shell-session
% pip install "schilder2000[auth-saml,db-postgres]" --index-url https://git.fsmpi.rwth-aachen.de/api/v4/projects/305/packages/pypi/simple % npm run build
% python -m build --config-setting without-npm
.. _configuration:
Configuration
-------------
Configuration and runtime data is stored in the instance directory. For Configuration and runtime data is stored in the instance directory. For
container installs, mount a volume to ``/usr/local/var/schilder2000-instance/``. container installs, this is ``/usr/local/var/schilder2000-instance/``.
For package installs, this is ``{{ python prefix }}/var/schilder2000-instance``; For package installs, this is ``{{ python prefix }}/var/schilder2000-instance``;
if in doubt, try to run ``flask -A schilder2000``, the error should tell you if in doubt, try to run ``flask -A schilder2000``, the error should tell you
where it expects the instance directory. Example config and data is located in where it expects the instance directory.
the ``examples`` directory. The templates there get their footer text and logo
from the application config and should also be useful as an example to write
your own templates.
The main application config is located in ``config/config.py``. Customise it as Example config and data is located in the ``examples`` directory. The templates
needed, the example config should provide enough comments. there get their footer text and logo from the application config and should also
be useful as an example to write your own templates.
An example config for Gunicorn_ is provided in ``gunicorn.conf.py``. If you The main application config is located in ``config/config.py``. Available
want to use another WSGI server, configure it to use options:
``schilder2000:create_app()`` as application object. Note that this is a
factory function that returns the application callable, you have to call it! .. py:data:: SQLALCHEMY_DATABASE_URI
:type: str
**Required**. Database connection URI. See
:external:py:data:`Flask-SQLAlchemy documentation
<flask_sqlalchemy.config.SQLALCHEMY_DATABASE_URI>` for details and
additional options. Note that the ``db-postgres`` optional dependency
install the ``psycopg`` driver (i. e., version 3), not ``psycopg2``.
.. py:data:: SECRET_KEY
:type: str | bytes
**Required**. Secret key for signing cookies and other security related
needs. See :external+flask:py:data:`Flask documentation <SECRET_KEY>`
for details.
.. py:data:: SCHILD_FOOTER
:type: str
Footer text used by the templates shipped in ``examples/``.
.. py:data:: SCHILD_LOGO
:type: str
Logo used by the templates shipped in ``examples/``. Expects a file
relative to ``{{ instance path }}/data/static``.
.. py:data:: TEMPLATES_AUTO_RELOAD
:type: bool
Reload templates when they are changed. See
:external+flask:py:data:`Flask documentation <TEMPLATES_AUTO_RELOAD>`
for details.
.. py:data:: PRINTERS
:type: dict[str, str]
**Required**. Available printers. Maps display names to IPP(S) URLs.
.. py:data:: REQUIRE_LOGIN
:type: bool
**Required**. Whether authentication is required to access the service.
If enabled, requires additional configuration for
:external+flask_multipass:std:doc:`index`.
.. py:data:: MULTIPASS_AUTH_PROVIDERS
:type: dict[str, dict]
.. py:data:: MULTIPASS_IDENTITY_PROVIDERS
:type: dict[str, dict]
.. py:data:: MULTIPASS_PROVIDER_MAP
:type: dict[str, str]
See :external+flask_multipass:std:doc:`Flask-Multipass documentation
<index>` for details.
.. py:data:: MULTIPASS_IDENTITY_INFO_KEYS
:type: list
Required by Flask-Multipass, but can be empty, as identity information
is not used.
See also :external+flask:std:doc:`Flask documentation <config>` for additional
options and information.
Database migration
~~~~~~~~~~~~~~~~~~
Unless you use SQLite, create the database in your database server. In all Unless you use SQLite, create the database in your database server. In all
cases, run the migrations: cases, run the migrations:
...@@ -42,10 +227,28 @@ cases, run the migrations: ...@@ -42,10 +227,28 @@ cases, run the migrations:
% flask -A schilder2000 alembic upgrade head % flask -A schilder2000 alembic upgrade head
If you want to use your webserver to directly serve static files, route WSGI and webserver setup
``/static`` to ``{{ python packages directory }}/schilder2000/static`` and ~~~~~~~~~~~~~~~~~~~~~~~~
``/instance/static`` to ``{{ instance path }}/data/static``.
An example config for Gunicorn_ is provided in ``gunicorn.conf.py``. This
will listen on ``[::]:8080`` (port 8080, all interfaces), and write the access
log to stdout.
See :external+flask:std:doc:`Flask documentation on Gunicorn
<deploying/gunicorn>` and :external+gunicorn:std:doc:`Gunicorn documentation
<index>` for further information.
If you want to use another WSGI server, configure it to use
``schilder2000:create_app()`` as application object. Note that this is a
factory function that returns the application callable, you have to call it!
To use your webserver to directly serve static files, route ``/static`` to ``{{
python packages directory }}/schilder2000/static`` and ``/instance/static`` to
``{{ instance path }}/data/static``.
.. _`Python package`: https://git.fsmpi.rwth-aachen.de/schilder/schilder2000/-/packages .. _`Python package`: https://git.fsmpi.rwth-aachen.de/schilder/schilder2000/-/packages
.. _`container image`: https://git.fsmpi.rwth-aachen.de/schilder/schilder2000/container_registry/33 .. _`container image`: https://git.fsmpi.rwth-aachen.de/schilder/schilder2000/container_registry/33
.. _Gunicorn: https://gunicorn.org/ .. _Gunicorn: https://gunicorn.org/
.. _`source repository`: https://git.fsmpi.rwth-aachen.de/schilder/schilder2000
.. _`PEP 517`: https://peps.python.org/pep-0517/
.. _`build`: https://github.com/pypa/build
...@@ -12,7 +12,7 @@ SQLALCHEMY_DATABASE_URI = "postgresql+psycopg:///schilder2000" ...@@ -12,7 +12,7 @@ SQLALCHEMY_DATABASE_URI = "postgresql+psycopg:///schilder2000"
# To generate a secret key: # To generate a secret key:
# % python -c 'import secrets; print(secrets.token_hex())' # % python -c 'import secrets; print(secrets.token_hex())'
SECRET_KEY = "abc123" # Replace me! #SECRET_KEY = ... # Replace me!
TEMPLATES_AUTO_RELOAD = True TEMPLATES_AUTO_RELOAD = True
SCHILD_FOOTER = "Organization Without a Cool Acronym – O.W.C.A." SCHILD_FOOTER = "Organization Without a Cool Acronym – O.W.C.A."
......
...@@ -56,6 +56,7 @@ docs = [ ...@@ -56,6 +56,7 @@ docs = [
[tool.pdm.scripts] [tool.pdm.scripts]
serve = "flask -A schilder2000 run --debug" serve = "flask -A schilder2000 run --debug"
migrate = "flask -A schilder2000 alembic upgrade head" migrate = "flask -A schilder2000 alembic upgrade head"
docs = "sphinx-build docs docs/_build"
[tool.pdm.build] [tool.pdm.build]
includes = [ includes = [
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Please register or to comment