Search notes:

Gunicorn

Gunicorn is a Python WSGI HTTP server running on Unix.
$ sudo apt install -y gunicorn

Simple application

appModule.py

def appCallable(environ, start_response):

    start_response(
       '200 OK',
       [('Content-Type', 'text/plain; charset=utf-8')]
    )

    return [
       'Hello world!\n\n'                .encode('utf-8'),
      f'Serving {environ["PATH_INFO"]}\n'.encode('utf-8')
    ]

Starting the app

When starting a WSGI application, the name of the WSGI callable (here: appCallable) and the module (Python script, here: appModule) must be specified:
$ gunicorn appModule:appCallable
After starting it, the webserver listens on port 8000 (if the default is not changed).

Concurrency

app.py

import time
import threading
import os

def application(environ, start_response):

    start_response( '200 OK', [('Content-Type', 'text/plain; charset=utf-8') ])

    yield f'os.get_pid                    : {os.getpid()}\n'              .encode('utf-8')
    yield f'threading.get_native_id native: {threading.get_native_id()}\n'.encode('utf-8')
    yield f'threading.get_ident           : {threading.get_ident()}\n'    .encode('utf-8')
    for i in range(10):
        time.sleep(1)
        yield f'{i}\n'.encode('utf-8')

Starting Gunicorn

Play with option values of --threads and --worker-connections:
$ gunicorn --threads 3 --worker-connections 2 app

Check number of simultaneous requests

Use tmux and the start-tmux.sh shell script below to execute a curl command to check how many requests are executed in parallel:
$ ./start-tmux.sh
Use ctrl-b followed by :kill-session to exit the tmux session.

start-tmux.sh

#!/bin/bash

tmux                                \
set-option -g remain-on-exit on \;  \
new-session                         \
"$CMD"                           \; \
split-window -h                     \
"$CMD"                           \; \
split-window -h                     \
"$CMD"                           \; \
split-window -h                     \
"$CMD"                           \; \
split-window -h                     \
"$CMD"                           \; \
select-layout even-horizontal
This Superuser answer was helpful when I wrote the script.

See also

Running a flask application with Gunicorn.
Configuring nginx as an application gateway for a WSGI server

Index

Fatal error: Uncaught PDOException: SQLSTATE[HY000]: General error: 8 attempt to write a readonly database in /home/httpd/vhosts/renenyffenegger.ch/php/web-request-database.php:78 Stack trace: #0 /home/httpd/vhosts/renenyffenegger.ch/php/web-request-database.php(78): PDOStatement->execute(Array) #1 /home/httpd/vhosts/renenyffenegger.ch/php/web-request-database.php(30): insert_webrequest_('/notes/web/webs...', 1758199563, '216.73.216.150', 'Mozilla/5.0 App...', NULL) #2 /home/httpd/vhosts/renenyffenegger.ch/httpsdocs/notes/web/webserver/Gunicorn/index(124): insert_webrequest() #3 {main} thrown in /home/httpd/vhosts/renenyffenegger.ch/php/web-request-database.php on line 78