experimental.http_server

A simple HTTP server for the Raspberry Pi Pico

class experimental.http_server.HttpServer(port=80)

A basic HTTP server for EuroPi.

This class will open a socket on the specified port, allowing for clients to connect to us. Only HTTP is supported, not HTTPS. Basic GET/POST requests should work, but websockets and anything fancy likely won’t.

Port 80 is officially reserved for HTTP traffic, and can be used by default. Port 8080 is also commonly used for HTTP traffic.

If you’re operating in WiFi Client mode you may be subject to the whims of whatever port filter/firewall your IT administrator has implemented, so some ports may not work/ may not be available.

Operating in WiFi AP mode should allow the use of any port you want.

You should define a callback to handle incoming GET and/or POST requests, e.g.:

server = HttpServer(port=8080)

@server.get_handler
def handle_http_get(request:str=None, connection:Socket=None):
    # process the request
    server.send_response(...)

@server.post_handler
def handle_http_post(request:str=None, connection:Socket=None):
    # process the request
    server.send_response(...)

Responses can be an HTTP page, plain text, or JSON/CSV/YAML/XML formatted data. See MimeTypes for supported types. The response should always be a string; if sending a dict as JSON data you’ll need to stringify it before passing it to send_response.

You may send your own error codes as desired:

def handle_http_request(connection=None, request=None):
    srv.send_error_page(
        Exception("We're out of coffee!")
        connection,
        HttpStatus.TEAPOT,  # send error 418 "I'm a teapot"
    )

Inside the program’s main loop you should call srv.check_connections() to process any incoming requests:

def main(self):
    # ...
    while True:
        # ...
        srv.check_requests()
        # ...
Parameters

port – The port to listen on

check_requests()

Poll the socket and process any incoming requests.

This will invoke the request handler function if it has been defined

This function should be called inside the main loop of the program

The client socket is closed after we send our response

default_request_handler(connection=None, request=None)

The default request handler for GET and POST requests the server.

The intent is that whatever program is using the HTTP server will create their own callback to replace this function. So all we do is raise a NotImplementedError that’s handled by self.check_requests() and will serve our HTTP 501 error page accordingly.

Parameters
  • connection – The socket the client connected on

  • request – The client’s request

Raises

NotImplementedError – This results in an HTTP 501 error response

get_handler(func)

Decorator for the function to handle HTTP GET requests

The provided function must accept the following keyword arguments: - request: str The request the client sent - conn: socket A socket connection to the client

Parameters

func – The function to handle the request.

post_handler(func)

Decorator for the function to handle HTTP POST requests

The provided function must accept the following keyword arguments: - request: str The request the client sent - conn: socket A socket connection to the client

Parameters

func – The function to handle the request.

send_error_page(error, connection, status=500, headers=None)

Serve our customized HTTP error page

Parameters
  • error – The exception that caused the error

  • connection – The socket to send the response over

  • status – The error status to respond with

  • headers – Optional additional headers

send_html(connection, html_page, status=200, headers=None)

Send an HTML document to the client

Parameters
  • connection – The socket to send the data over

  • html_page – A string containing the HTML document.

  • status – The HTTP status to send the page with

  • headers – Optional additional HTTP headers

send_json(connection, data, headers=None)

Send a JSON object to the client

Parameters
  • connection – The socket connection to the client

  • data – A dict to be converted to a JSON object

  • headers – Optional additional HTTP headers to include

send_response(connection, response, status=200, content_type='text/html', headers=None)

Send a response to the client

Parameters
  • connection – The socket connection to the client

  • response – The response payload

  • status – The HTTP status to respond with

  • content_type – The MIME type to include in the HTTP header

  • headers – Optional dict of key/value pairs for addtional HTTP headers. Charset is ALWAYS utf-8

class experimental.http_server.HttpStatus

HTTP status codes to include in the header.

This collection is not exhaustive, just what we need to handle this minimal server implementation

class experimental.http_server.MimeTypes

Common MIME types we can support with this HTTP server implementation