:mod:`!socketserver` --- A framework for network servers
========================================================

.. module:: socketserver
   :synopsis: A framework for network servers.

**Source code:** :source:`Lib/socketserver.py`

--------------

The :mod:`!socketserver` module simplifies the task of writing network servers.

.. include:: ../includes/wasm-notavail.rst

There are four basic concrete server classes:


.. class:: TCPServer(server_address, RequestHandlerClass, bind_and_activate=True)

   This uses the internet TCP protocol, which provides for
   continuous streams of data between the client and server.
   If *bind_and_activate* is true, the constructor automatically attempts to
   invoke :meth:`~BaseServer.server_bind` and
   :meth:`~BaseServer.server_activate`.  The other parameters are passed to
   the :class:`BaseServer` base class.

   .. versionchanged:: 3.15
      The default queue size is now ``socket.SOMAXCONN`` for :class:`socketserver.TCPServer`.

.. class:: UDPServer(server_address, RequestHandlerClass, bind_and_activate=True)

   This uses datagrams, which are discrete packets of information that may
   arrive out of order or be lost while in transit.  The parameters are
   the same as for :class:`TCPServer`.


.. class:: UnixStreamServer(server_address, RequestHandlerClass, bind_and_activate=True)
           UnixDatagramServer(server_address, RequestHandlerClass, bind_and_activate=True)

   These more infrequently used classes are similar to the TCP and
   UDP classes, but use Unix domain sockets; they're not available on
   non-Unix platforms.  The parameters are the same as for
   :class:`TCPServer`.


These four classes process requests :dfn:`synchronously`; each request must be
completed before the next request can be started.  This isn't suitable if each
request takes a long time to complete, because it requires a lot of computation,
or because it returns a lot of data which the client is slow to process.  The
solution is to create a separate process or thread to handle each request; the
:class:`ForkingMixIn` and :class:`ThreadingMixIn` mix-in classes can be used to
support asynchronous behaviour.

Creating a server requires several steps.  First, you must create a request
handler class by subclassing the :class:`BaseRequestHandler` class and
overriding its :meth:`~BaseRequestHandler.handle` method;
this method will process incoming
requests.  Second, you must instantiate one of the server classes, passing it
the server's address and the request handler class. It is recommended to use
the server in a :keyword:`with` statement. Then call the
:meth:`~BaseServer.handle_request` or
:meth:`~BaseServer.serve_forever` method of the server object to
process one or many requests.  Finally, call :meth:`~BaseServer.server_close`
to close the socket (unless you used a :keyword:`!with` statement).

When inheriting from :class:`ThreadingMixIn` for threaded connection behavior,
you should explicitly declare how you want your threads to behave on an abrupt
shutdown.  The :class:`ThreadingMixIn` class defines an attribute
*daemon_threads*, which indicates whether or not the server should wait for
thread termination.  You should set the flag explicitly if you would like
threads to behave autonomously; the default is :const:`False`, meaning that
Python will not exit until all threads created by :class:`ThreadingMixIn` have
exited.

Server classes have the same external methods and attributes, no matter what
network protocol they use.


Server Creation Notes
---------------------

There are five classes in an inheritance diagram, four of which represent
synchronous servers of four types::

   +------------+
   | BaseServer |
   +------------+
         |
         v
   +-----------+        +------------------+
   | TCPServer |------->| UnixStreamServer |
   +-----------+        +------------------+
         |
         v
   +-----------+        +--------------------+
   | UDPServer |------->| UnixDatagramServer |
   +-----------+        +--------------------+

Note that :class:`UnixDatagramServer` derives from :class:`UDPServer`, not from
:class:`UnixStreamServer` --- the only difference between an IP and a Unix
server is the address family.


.. class:: ForkingMixIn
           ThreadingMixIn

   Forking and threading versions of each type of server can be created
   using these mix-in classes.  For instance, :class:`ThreadingUDPServer`
   is created as follows::

      class ThreadingUDPServer(ThreadingMixIn, UDPServer):
          pass

   The mix-in class comes first, since it overrides a method defined in
   :class:`UDPServer`.  Setting the various attributes also changes the
   behavior of the underlying server mechanism.

   :class:`ForkingMixIn` and the Forking classes mentioned below are
   only available on POSIX platforms that support :func:`~os.fork`.

   .. attribute:: block_on_close

      :meth:`ForkingMixIn.server_close <BaseServer.server_close>`
      waits until all child processes complete, except if
      :attr:`block_on_close` attribute is ``False``.

      :meth:`ThreadingMixIn.server_close <BaseServer.server_close>`
      waits until all non-daemon threads complete, except if
      :attr:`block_on_close` attribute is ``False``.

   .. attribute:: max_children

      Specify how many child processes will exist to handle requests at a time
      for :class:`ForkingMixIn`.  If the limit is reached,
      new requests will wait until one child process has finished.

   .. attribute:: daemon_threads

      For :class:`ThreadingMixIn` use daemonic threads by setting
      :data:`ThreadingMixIn.daemon_threads <daemon_threads>`
      to ``True`` to not wait until threads complete.

   .. versionchanged:: 3.7

      :meth:`ForkingMixIn.server_close <BaseServer.server_close>` and
      :meth:`ThreadingMixIn.server_close <BaseServer.server_close>` now waits until all
      child processes and non-daemonic threads complete.
      Add a new :attr:`ForkingMixIn.block_on_close <block_on_close>` class
      attribute to opt-in for the pre-3.7 behaviour.


.. class:: ForkingTCPServer
           ForkingUDPServer
           ThreadingTCPServer
           ThreadingUDPServer
           ForkingUnixStreamServer
           ForkingUnixDatagramServer
           ThreadingUnixStreamServer
           ThreadingUnixDatagramServer

   These classes are pre-defined using the mix-in classes.

.. versionadded:: 3.12
   The ``ForkingUnixStreamServer`` and ``ForkingUnixDatagramServer`` classes
   were added.

To implement a service, you must derive a class from :class:`BaseRequestHandler`
and redefine its :meth:`~BaseRequestHandler.handle` method.
You can then run various versions of
the service by combining one of the server classes with your request handler
class.  The request handler class must be different for datagram or stream
services.  This can be hidden by using the handler subclasses
:class:`StreamRequestHandler` or :class:`DatagramRequestHandler`.

Of course, you still have to use your head!  For instance, it makes no sense to
use a forking server if the service contains state in memory that can be
modified by different requests, since the modifications in the child process
would never reach the initial state kept in the parent process and passed to
each child.  In this case, you can use a threading server, but you will probably
have to use locks to protect the integrity of the shared data.

On the other hand, if you are building an HTTP server where all data is stored
externally (for instance, in the file system), a synchronous class will
essentially render the service "deaf" while one request is being handled --
which may be for a very long time if a client is slow to receive all the data it
has requested.  Here a threading or forking server is appropriate.

In some cases, it may be appropriate to process part of a request synchronously,
but to finish processing in a forked child depending on the request data.  This
can be implemented by using a synchronous server and doing an explicit fork in
the request handler class :meth:`~BaseRequestHandler.handle` method.

Another approach to handling multiple simultaneous requests in an environment
that supports neither threads nor :func:`~os.fork` (or where these are too
expensive or inappropriate for the service) is to maintain an explicit table of
partially finished requests and to use :mod:`selectors` to decide which
request to work on next (or whether to handle a new incoming request).  This is
particularly important for stream services where each client can potentially be
connected for a long time (if threads or subprocesses cannot be used).

.. XXX should data and methods be intermingled, or separate?
   how should the distinction between class and instance variables be drawn?


Server Objects
--------------

.. class:: BaseServer(server_address, RequestHandlerClass)

   This is the superclass of all Server objects in the module.  It defines the
   interface, given below, but does not implement most of the methods, which is
   done in subclasses.  The two parameters are stored in the respective
   :attr:`server_address` and :attr:`RequestHandlerClass` attributes.


   .. method:: fileno()

      Return an integer file descriptor for the socket on which the server is
      listening.  This function is most commonly passed to :mod:`selectors`, to
      allow monitoring multiple servers in the same process.


   .. method:: handle_request()

      Process a single request.  This function calls the following methods in
      order: :meth:`get_request`, :meth:`verify_request`, and
      :meth:`process_request`.  If the user-provided
      :meth:`~BaseRequestHandler.handle` method of the
      handler class raises an exception, the server's :meth:`handle_error` method
      will be called.  If no request is received within :attr:`timeout`
      seconds, :meth:`handle_timeout` will be called and :meth:`handle_request`
      will return.


   .. method:: serve_forever(poll_interval=0.5)

      Handle requests until an explicit :meth:`shutdown` request.  Poll for
      shutdown every *poll_interval* seconds.
      Ignores the :attr:`timeout` attribute.  It
      also calls :meth:`service_actions`, which may be used by a subclass or mixin
      to provide actions specific to a given service.  For example, the
      :class:`ForkingMixIn` class uses :meth:`service_actions` to clean up zombie
      child processes.

      .. versionchanged:: 3.3
         Added ``service_actions`` call to the ``serve_forever`` method.


   .. method:: service_actions()

      This is called in the :meth:`serve_forever` loop. This method can be
      overridden by subclasses or mixin classes to perform actions specific to
      a given service, such as cleanup actions.

      .. versionadded:: 3.3

   .. method:: shutdown()

      Tell the :meth:`serve_forever` loop to stop and wait until it does.
      :meth:`shutdown` must be called while :meth:`serve_forever` is running in a
      different thread otherwise it will deadlock.


   .. method:: server_close()

      Clean up the server. May be overridden.


   .. attribute:: address_family

      The family of protocols to which the server's socket belongs.  Common
      examples are :const:`socket.AF_INET`, :const:`socket.AF_INET6`, and
      :const:`socket.AF_UNIX`.  Subclass the TCP or UDP server classes in this
      module with class attribute ``address_family = AF_INET6`` set if you
      want IPv6 server classes.


   .. attribute:: RequestHandlerClass

      The user-provided request handler class; an instance of this class is created
      for each request.


   .. attribute:: server_address

      The address on which the server is listening.  The format of addresses varies
      depending on the protocol family;
      see the documentation for the :mod:`socket` module
      for details.  For internet protocols, this is a tuple containing a string giving
      the address, and an integer port number: ``('127.0.0.1', 80)``, for example.


   .. attribute:: socket

      The socket object on which the server will listen for incoming requests.


   The server classes support the following class variables:

   .. XXX should class variables be covered before instance variables, or vice versa?

   .. attribute:: allow_reuse_address

      Whether the server will allow the reuse of an address.  This defaults to
      :const:`False`, and can be set in subclasses to change the policy.


   .. attribute:: request_queue_size

      The size of the request queue.  If it takes a long time to process a single
      request, any requests that arrive while the server is busy are placed into a
      queue, up to :attr:`request_queue_size` requests.  Once the queue is full,
      further requests from clients will get a "Connection denied" error.  The default
      value is usually 5, but this can be overridden by subclasses.


   .. attribute:: socket_type

      The type of socket used by the server; :const:`socket.SOCK_STREAM` and
      :const:`socket.SOCK_DGRAM` are two common values.


   .. attribute:: timeout

      Timeout duration, measured in seconds, or :const:`None` if no timeout is
      desired.  If :meth:`handle_request` receives no incoming requests within the
      timeout period, the :meth:`handle_timeout` method is called.


   There are various server methods that can be overridden by subclasses of base
   server classes like :class:`TCPServer`; these methods aren't useful to external
   users of the server object.

   .. XXX should the default implementations of these be documented, or should
      it be assumed that the user will look at socketserver.py?

   .. method:: finish_request(request, client_address)

      Actually processes the request by instantiating :attr:`RequestHandlerClass` and
      calling its :meth:`~BaseRequestHandler.handle` method.


   .. method:: get_request()

      Must accept a request from the socket, and return a 2-tuple containing the *new*
      socket object to be used to communicate with the client, and the client's
      address.


   .. method:: handle_error(request, client_address)

      This function is called if the :meth:`~BaseRequestHandler.handle`
      method of a :attr:`RequestHandlerClass` instance raises
      an exception.  The default action is to print the traceback to
      standard error and continue handling further requests.

      .. versionchanged:: 3.6
         Now only called for exceptions derived from the :exc:`Exception`
         class.


   .. method:: handle_timeout()

      This function is called when the :attr:`timeout` attribute has been set to a
      value other than :const:`None` and the timeout period has passed with no
      requests being received.  The default action for forking servers is
      to collect the status of any child processes that have exited, while
      in threading servers this method does nothing.


   .. method:: process_request(request, client_address)

      Calls :meth:`finish_request` to create an instance of the
      :attr:`RequestHandlerClass`.  If desired, this function can create a new process
      or thread to handle the request; the :class:`ForkingMixIn` and
      :class:`ThreadingMixIn` classes do this.


   .. Is there any point in documenting the following two functions?
      What would the purpose of overriding them be: initializing server
      instance variables, adding new network families?

   .. method:: server_activate()

      Called by the server's constructor to activate the server.  The default behavior
      for a TCP server just invokes :meth:`~socket.socket.listen`
      on the server's socket.  May be overridden.


   .. method:: server_bind()

      Called by the server's constructor to bind the socket to the desired address.
      May be overridden.


   .. method:: verify_request(request, client_address)

      Must return a Boolean value; if the value is :const:`True`, the request will
      be processed, and if it's :const:`False`, the request will be denied.  This
      function can be overridden to implement access controls for a server. The
      default implementation always returns :const:`True`.


   .. versionchanged:: 3.6
      Support for the :term:`context manager` protocol was added.  Exiting the
      context manager is equivalent to calling :meth:`server_close`.


Request Handler Objects
-----------------------

.. class:: BaseRequestHandler

   This is the superclass of all request handler objects.  It defines
   the interface, given below.  A concrete request handler subclass must
   define a new :meth:`handle` method, and can override any of
   the other methods.  A new instance of the subclass is created for each
   request.


   .. method:: setup()

      Called before the :meth:`handle` method to perform any initialization actions
      required.  The default implementation does nothing.


   .. method:: handle()

      This function must do all the work required to service a request.  The
      default implementation does nothing.  Several instance attributes are
      available to it; the request is available as :attr:`request`; the client
      address as :attr:`client_address`; and the server instance as
      :attr:`server`, in case it needs access to per-server information.

      The type of :attr:`request` is different for datagram or stream
      services.  For stream services, :attr:`request` is a socket object; for
      datagram services, :attr:`request` is a pair of string and socket.


   .. method:: finish()

      Called after the :meth:`handle` method to perform any clean-up actions
      required.  The default implementation does nothing.  If :meth:`setup`
      raises an exception, this function will not be called.


   .. attribute:: request

      The *new* :class:`socket.socket` object
      to be used to communicate with the client.


   .. attribute:: client_address

      Client address returned by :meth:`BaseServer.get_request`.


   .. attribute:: server

      :class:`BaseServer` object used for handling the request.


.. class:: StreamRequestHandler
           DatagramRequestHandler

   These :class:`BaseRequestHandler` subclasses override the
   :meth:`~BaseRequestHandler.setup` and :meth:`~BaseRequestHandler.finish`
   methods, and provide :attr:`rfile` and :attr:`wfile` attributes.

   .. attribute:: rfile

      A file object from which receives the request is read.
      Support the :class:`io.BufferedIOBase` readable interface.

   .. attribute:: wfile

      A file object to which the reply is written.
      Support the :class:`io.BufferedIOBase` writable interface


   .. versionchanged:: 3.6
      :attr:`wfile` also supports the
      :class:`io.BufferedIOBase` writable interface.


Examples
--------

:class:`socketserver.TCPServer` Example
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

This is the server side::

   import socketserver

   class MyTCPHandler(socketserver.BaseRequestHandler):
       """
       The request handler class for our server.

       It is instantiated once per connection to the server, and must
       override the handle() method to implement communication to the
       client.
       """

       def handle(self):
           # self.request is the TCP socket connected to the client
           pieces = [b'']
           total = 0
           while b'\n' not in pieces[-1] and total < 10_000:
               pieces.append(self.request.recv(2000))
               total += len(pieces[-1])
           self.data = b''.join(pieces)
           print(f"Received from {self.client_address[0]}:")
           print(self.data.decode("utf-8"))
           # just send back the same data, but upper-cased
           self.request.sendall(self.data.upper())
           # after we return, the socket will be closed.

   if __name__ == "__main__":
       HOST, PORT = "localhost", 9999

       # Create the server, binding to localhost on port 9999
       with socketserver.TCPServer((HOST, PORT), MyTCPHandler) as server:
           # Activate the server; this will keep running until you
           # interrupt the program with Ctrl-C
           server.serve_forever()

An alternative request handler class that makes use of streams (file-like
objects that simplify communication by providing the standard file interface)::

   class MyTCPHandler(socketserver.StreamRequestHandler):

       def handle(self):
           # self.rfile is a file-like object created by the handler.
           # We can now use e.g. readline() instead of raw recv() calls.
           # We limit ourselves to 10000 bytes to avoid abuse by the sender.
           self.data = self.rfile.readline(10000).rstrip()
           print(f"{self.client_address[0]} wrote:")
           print(self.data.decode("utf-8"))
           # Likewise, self.wfile is a file-like object used to write back
           # to the client
           self.wfile.write(self.data.upper())

The difference is that the ``readline()`` call in the second handler will call
``recv()`` multiple times until it encounters a newline character, while the
first handler had to use a ``recv()`` loop to accumulate data until a
newline itself.  If it had just used a single ``recv()`` without the loop it
would just have returned what has been received so far from the client.
TCP is stream based: data arrives in the order it was sent, but there is no
correlation between client ``send()`` or ``sendall()`` calls and the number
of ``recv()`` calls on the server required to receive it.


This is the client side::

   import socket
   import sys

   HOST, PORT = "localhost", 9999
   data = " ".join(sys.argv[1:])

   # Create a socket (SOCK_STREAM means a TCP socket)
   with socket.socket(socket.AF_INET, socket.SOCK_STREAM) as sock:
       # Connect to server and send data
       sock.connect((HOST, PORT))
       sock.sendall(bytes(data, "utf-8"))
       sock.sendall(b"\n")

       # Receive data from the server and shut down
       received = str(sock.recv(1024), "utf-8")

   print("Sent:    ", data)
   print("Received:", received)


The output of the example should look something like this:

Server:

.. code-block:: shell-session

   $ python TCPServer.py
   127.0.0.1 wrote:
   b'hello world with TCP'
   127.0.0.1 wrote:
   b'python is nice'

Client:

.. code-block:: shell-session

   $ python TCPClient.py hello world with TCP
   Sent:     hello world with TCP
   Received: HELLO WORLD WITH TCP
   $ python TCPClient.py python is nice
   Sent:     python is nice
   Received: PYTHON IS NICE


:class:`socketserver.UDPServer` Example
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

This is the server side::

   import socketserver

   class MyUDPHandler(socketserver.BaseRequestHandler):
       """
       This class works similar to the TCP handler class, except that
       self.request consists of a pair of data and client socket, and since
       there is no connection the client address must be given explicitly
       when sending data back via sendto().
       """

       def handle(self):
           data = self.request[0].strip()
           socket = self.request[1]
           print(f"{self.client_address[0]} wrote:")
           print(data)
           socket.sendto(data.upper(), self.client_address)

   if __name__ == "__main__":
       HOST, PORT = "localhost", 9999
       with socketserver.UDPServer((HOST, PORT), MyUDPHandler) as server:
           server.serve_forever()

This is the client side::

   import socket
   import sys

   HOST, PORT = "localhost", 9999
   data = " ".join(sys.argv[1:])

   # SOCK_DGRAM is the socket type to use for UDP sockets
   sock = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)

   # As you can see, there is no connect() call; UDP has no connections.
   # Instead, data is directly sent to the recipient via sendto().
   sock.sendto(bytes(data + "\n", "utf-8"), (HOST, PORT))
   received = str(sock.recv(1024), "utf-8")

   print("Sent:    ", data)
   print("Received:", received)

The output of the example should look exactly like for the TCP server example.


Asynchronous Mixins
~~~~~~~~~~~~~~~~~~~

To build asynchronous handlers, use the :class:`ThreadingMixIn` and
:class:`ForkingMixIn` classes.

An example for the :class:`ThreadingMixIn` class::

   import socket
   import threading
   import socketserver

   class ThreadedTCPRequestHandler(socketserver.BaseRequestHandler):

       def handle(self):
           data = str(self.request.recv(1024), 'ascii')
           cur_thread = threading.current_thread()
           response = bytes("{}: {}".format(cur_thread.name, data), 'ascii')
           self.request.sendall(response)

   class ThreadedTCPServer(socketserver.ThreadingMixIn, socketserver.TCPServer):
       pass

   def client(ip, port, message):
       with socket.socket(socket.AF_INET, socket.SOCK_STREAM) as sock:
           sock.connect((ip, port))
           sock.sendall(bytes(message, 'ascii'))
           response = str(sock.recv(1024), 'ascii')
           print("Received: {}".format(response))

   if __name__ == "__main__":
       # Port 0 means to select an arbitrary unused port
       HOST, PORT = "localhost", 0

       server = ThreadedTCPServer((HOST, PORT), ThreadedTCPRequestHandler)
       with server:
           ip, port = server.server_address

           # Start a thread with the server -- that thread will then start one
           # more thread for each request
           server_thread = threading.Thread(target=server.serve_forever)
           # Exit the server thread when the main thread terminates
           server_thread.daemon = True
           server_thread.start()
           print("Server loop running in thread:", server_thread.name)

           client(ip, port, "Hello World 1")
           client(ip, port, "Hello World 2")
           client(ip, port, "Hello World 3")

           server.shutdown()


The output of the example should look something like this:

.. code-block:: shell-session

   $ python ThreadedTCPServer.py
   Server loop running in thread: Thread-1
   Received: Thread-2: Hello World 1
   Received: Thread-3: Hello World 2
   Received: Thread-4: Hello World 3


The :class:`ForkingMixIn` class is used in the same way, except that the server
will spawn a new process for each request.
Available only on POSIX platforms that support :func:`~os.fork`.

