Pyjo.Server.Daemon - Non-blocking I/O HTTP and WebSocket server¶
from Pyjo.Server.Daemon import Daemon
daemon = Daemon(listen=['http://*:8080'])
@daemon.unsubscribe('request').on('request')
def request(daemon, tx):
# Request
method = tx.req.method
path = tx.req.url.path
# Response
tx.res.code = 200
tx.res.headers.content_type = 'text/plain'
tx.res.body = f'{method} request for {path}!'.encode()
# Resume transaction
tx.resume()
daemon.run()
# Or import the module, as in Google Python Style Guide
import Pyjo.Server.Daemon
daemon = Pyjo.Server.Daemon.new(listen=['http://*:8080'])
@daemon.unsubscribe('request').on('request')
def request(daemon, tx):
# Request
method = tx.req.method
path = tx.req.url.path
# Response
tx.res.code = 200
tx.res.headers.content_type = 'text/plain'
tx.res.body = f'{method} request for {path}!'.encode()
# Resume transaction
tx.resume()
daemon.run()
Pyjo.Server.Daemon is a full featured, highly portable non-blocking
I/O HTTP and WebSocket server, with IPv6, TLS, SNI, Comet (long polling),
keep-alive and multiple event loop support. It also speaks FastCGI to a web
server in front of it, on the listen locations fcgi:// and
fcgi+unix://, with Pyjo.Server.FastCGI.
TLS support comes from ssl of the standard library, and can be
disabled with the PYJO_NO_TLS environment variable, as name resolution
and SOCKS5 support of Pyjo.IOLoop with PYJO_NO_NNR and
PYJO_NO_SOCKS.
A daemon is also a context manager, which stops listening and closes its connections at its end.
The end of a with block stops the daemon and closes its sockets.
Signals¶
The Pyjo.Server.Daemon process can be controlled at runtime with the
following signals.
INT, TERM¶
Shut down server gracefully: stop accepting new connections and wait for the
accepted ones to be closed. A second INT, as of Ctrl-C pressed twice,
shuts it down immediately, a second TERM does nothing.
QUIT¶
Shut down server immediately. On Windows, which has no QUIT, BREAK
does it, as of Ctrl-Break.
HUP¶
Ignored, as there is nothing to reload. Windows has no HUP.
Events¶
Pyjo.Server.Daemon inherits all events from Pyjo.Server.
Debugging¶
You can set the PYJO_SERVER_DEBUG environment variable to get some
advanced diagnostics information printed to sys.stderr.
PYJO_SERVER_DEBUG=1
See also¶
Pyjoyment, https://mojolicious.org.
Ported from Mojo::Server::Daemon of Mojolicious 9.49.
Classes¶
- class Pyjo.Server.Daemon.Pyjo_Server_Daemon(*, acceptors: list[str] | None = None, backlog: int | None = None, inactivity_timeout: float | None = None, ioloop: Pyjo_IOLoop | None = None, keep_alive_timeout: float | None = None, listen: Sequence[Location] | None = None, max_clients: int | None = None, max_requests: int = 100, silent: bool | None = None, **kwargs: Any)¶
Pyjo.Server.Daemoninherits all methods fromPyjo.Serverand implements the following new ones.- acceptors: list[str]¶
acceptors = daemon.acceptors daemon.acceptors = ['6be0c140ef00a389c5d039536b56d139']
Active acceptor ids.
# Check port port = daemon.ioloop.acceptor(daemon.acceptors[0]).port
- backlog¶
backlog = daemon.backlog daemon.backlog = 128
Listen backlog size, defaults to
socket.SOMAXCONN.
- close() None¶
daemon.close()
Close the listen sockets and the connections of the server, as the end of a
withblock does.
- property inactivity_timeout: float¶
timeout = daemon.inactivity_timeout daemon.inactivity_timeout = 5
Maximum amount of time in seconds a connection with an active request can be inactive before getting closed, defaults to the value of the
PYJO_INACTIVITY_TIMEOUTenvironment variable or30. Setting the value to0will allow connections to be inactive indefinitely.
- ioloop: Pyjo_IOLoop¶
loop = daemon.ioloop daemon.ioloop = Pyjo.IOLoop.new()
Event loop object to use for I/O operations, defaults to the global
Pyjo.IOLoopsingleton.
- property keep_alive_timeout: float¶
timeout = daemon.keep_alive_timeout daemon.keep_alive_timeout = 10
Maximum amount of time in seconds a connection without an active request can be inactive before getting closed, defaults to the value of the
PYJO_KEEP_ALIVE_TIMEOUTenvironment variable or5. Setting the value to0will allow connections to be inactive indefinitely.
- property listen: list[Location]¶
listen = daemon.listen daemon.listen = ['https://127.0.0.1:8080']
List of one or more locations to listen on, as strings or
Pyjo.URLobjects, defaults to the value of thePYJO_LISTENenvironment variable, tohttp://*:with the port of thePORTenvironment variable, which platforms as Knative, Cloud Run and Heroku set, or tohttp://*:3000(shortcut forhttp://0.0.0.0:3000).# Listen on all IPv4 interfaces daemon.listen = ['http://*:3000'] # Listen on all IPv4 and IPv6 interfaces daemon.listen = ['http://[::]:3000'] # Listen on IPv6 interface daemon.listen = ['http://[::1]:4000'] # Listen on IPv4 and IPv6 interfaces daemon.listen = ['http://127.0.0.1:3000', 'http://[::1]:3000'] # Listen on UNIX domain socket "/tmp/myapp.sock" (percent encoded slash) daemon.listen = ['http+unix://%2Ftmp%2Fmyapp.sock'] # FastCGI for a web server in front of the application daemon.listen = ['fcgi://127.0.0.1:9000'] # FastCGI on UNIX domain socket "/tmp/myapp.sock" daemon.listen = ['fcgi+unix://%2Ftmp%2Fmyapp.sock'] # File descriptor, as used by systemd daemon.listen = ['http://127.0.0.1?fd=3'] # Allow multiple servers to use the same port (SO_REUSEPORT) daemon.listen = ['http://*:8080?reuse=1'] # Listen on two ports with HTTP and HTTPS at the same time daemon.listen = ['http://*:3000', 'https://*:4000'] # Location of a URL object daemon.listen = [Pyjo.URL.new().set(scheme='http', host='127.0.0.1', port=3000)] # Use a custom certificate and key daemon.listen = ['https://*:3000?cert=/x/server.crt&key=/y/server.key'] # Domain specific certificates and keys (SNI) daemon.listen = ['https://*:3000?example.com_cert=/x/my.crt&example.com_key=/y/my.key'] # Or even a custom certificate authority daemon.listen = ['https://*:3000?cert=/x/server.crt&key=/y/server.key&ca=/z/ca.crt']
These parameters are currently available:
- ca
ca=/etc/tls/ca.crt
Path to TLS certificate authority file used to verify the peer certificate.
- cert
cert=/etc/tls/server.crt mojolicious.org_cert=/etc/tls/mojo.crt
Path to the TLS cert file, defaults to a built-in test certificate.
- ciphers
ciphers=AES128-GCM-SHA256:RC4:HIGH:!MD5:!aNULL:!EDH
TLS cipher specification string. For more information about the format see https://www.openssl.org/docs/manmaster/man1/ciphers.html#CIPHER-STRINGS.
- fd
fd=3
File descriptor with an already prepared listen socket.
- key
key=/etc/tls/server.key mojolicious.org_key=/etc/tls/mojo.key
Path to the TLS key file, defaults to a built-in test key.
- reuse
reuse=1
Allow multiple servers to use the same port with the
SO_REUSEPORTsocket option.- single_accept
single_accept=1
Only accept one connection at a time.
- verify
verify=0x00
TLS verification mode:
0x00verifies no peer,0x01verifies a peer certificate if there is one, and0x03requires it.- version
version=TLSv1_2
TLS protocol version.
- max_clients¶
max = daemon.max_clients daemon.max_clients = 100
Maximum number of accepted connections this server is allowed to handle concurrently, before stopping to accept new incoming connections, passed along to
Pyjo.IOLoop.Pyjo_IOLoop.max_connections.
- max_requests¶
max = daemon.max_requests daemon.max_requests = 250
Maximum number of keep-alive requests per connection, defaults to
100.
- ports() list[int]¶
ports = daemon.ports()
Get all ports this server is currently listening on.
# All ports for port in daemon.ports(): print(port)
- run() None¶
daemon.run()
Run server and wait for the signals
INT,TERMandQUIT.
- silent¶
boolean = daemon.silent daemon.silent = boolean
Disable console messages.
- start() Self¶
daemon = daemon.start()
Start or resume accepting connections through
ioloop.# Listen on random port daemon.listen = ['http://127.0.0.1'] port = daemon.start().ports()[0] # Run multiple web servers concurrently daemon1 = Pyjo.Server.Daemon.new(listen=['http://*:3000']).start() daemon2 = Pyjo.Server.Daemon.new(listen=['http://*:4000']).start() if not Pyjo.IOLoop.is_running(): Pyjo.IOLoop.start()