API Reference
adafruit_httpserver
Socket based HTTP Server for CircuitPython
Author(s): Dan Halbert, Michał Pokusa
Implementation Notes
Software and Dependencies:
Adafruit CircuitPython firmware for the supported boards: https://github.com/adafruit/circuitpython/releases
adafruit_httpserver.server
Author(s): Dan Halbert, Michał Pokusa
- class adafruit_httpserver.server.Server(socket_source: _ISocketPool, root_path: str = None, *, https: bool = False, certfile: str = None, keyfile: str = None, debug: bool = False)
A basic socket-based HTTP server.
Create a server, and get it ready to run.
- Parameters:
socket – An object that is a source of sockets. This could be a
socketpoolin CircuitPython or thesocketmodule in CPython.root_path (str) – Root directory to serve files from
debug (bool) – Enables debug messages useful during development
https (bool) – If True, the server will use HTTPS
certfile (str) – Path to the certificate file, required if
httpsis Truekeyfile (str) – Path to the private key file, required if
httpsis True
- add_routes(routes: List[Route]) None
Add multiple routes at once.
- Parameters:
routes (List[Route]) – List of routes to add to the server
Example:
from separate_file import external_route1, external_route2 ... server.add_routes([ Route("/example", GET, route_func1, append_slash=True), Route("/example/<my_parameter>", GET, route_func2), Route("/example/..../something", [GET, POST], route_func3), external_route1, external_route2, ]}
- property headers: Headers
Headers to be sent with every response, without the need to specify them in each handler.
If a header is specified in both the handler and the server, the handler’s header will be used.
Example:
server = Server(pool, "/static") server.headers = { "X-Server": "Adafruit CircuitPython HTTP Server", "Access-Control-Allow-Origin": "*", }
- poll() str
Call this method inside your main loop to get the server to check for new incoming client requests. When a request comes in, it will be handled by the handler function.
Returns str representing the result of the poll e.g.
NO_REQUESTorREQUEST_HANDLED_RESPONSE_SENT.
- property request_buffer_size: int
The maximum size of the incoming request buffer. If the default size isn’t adequate to handle your incoming data you can set this after creating the server instance.
Default size is 1024 bytes.
Example:
server = Server(pool, "/static") server.request_buffer_size = 2048 server.serve_forever(str(wifi.radio.ipv4_address))
- require_authentication(auths: List[Basic | Token | Bearer]) None
Requires authentication for all routes and files in
root_path. Any non-authenticated request will be rejected with a 401 status code.Example:
server = Server(pool, "/static") server.require_authentication([Basic("username", "password")])
- route(path: str, methods: str | Iterable[str] = GET, *, append_slash: bool = False) Callable
Decorator used to add a route.
If request matches multiple routes, the first matched one added will be used.
- Parameters:
Example:
# Default method is GET @server.route("/example") def route_func(request): ... # It is necessary to specify other methods like POST, PUT, etc. @server.route("/example", POST) def route_func(request): ... # If you want to access URL with and without trailing slash, use append_slash=True @server.route("/example-with-slash", append_slash=True) # which is equivalent to @server.route("/example-with-slash") @server.route("/example-with-slash/") def route_func(request): ... # Multiple methods can be specified @server.route("/example", [GET, POST]) def route_func(request): ... # URL parameters can be specified @server.route("/example/<my_parameter>", GET) e.g. /example/123 def route_func(request, my_parameter): ... # It is possible to use wildcard that can match any number of path segments @server.route("/example/.../something", GET) # e.g. /example/123/something @server.route("/example/..../something", GET) # e.g. /example/123/456/something def route_func(request): ...
- serve_forever(host: str = '0.0.0.0', port: int = 5000, *, poll_interval: float = 0.1) None
Wait for HTTP requests at the given host and port. Does not return. Ignores any exceptions raised by the handler function and continues to serve. Returns only when the server is stopped by calling
.stop().
- property socket_timeout: int
Timeout after which the socket will stop waiting for more incoming data.
Must be set to positive integer or float. Default is 1 second.
When exceeded, raises
OSErrorwitherrno.ETIMEDOUT.Example:
server = Server(pool, "/static") server.socket_timeout = 3 server.serve_forever(str(wifi.radio.ipv4_address))
adafruit_httpserver.request
Author(s): Dan Halbert, Michał Pokusa
- class adafruit_httpserver.request.File(filename: str, content_type: str, content: str | bytes)
Class representing a file uploaded via POST.
Examples:
file = request.form_data.files.get("uploaded_file") # File(filename="foo.txt", content_type="text/plain", size=14) file.content # "Hello, world!\n"
- class adafruit_httpserver.request.Files
Class for files uploaded via POST.
- property fields
Returns a list of field names.
- items()
Returns a list of (name, value) tuples.
- keys()
Returns a list of header names.
- values()
Returns a list of header values.
- class adafruit_httpserver.request.FormData(data: bytes, headers: Headers, *, debug: bool = False)
Class for parsing and storing form data from POST requests.
Supports
application/x-www-form-urlencoded,multipart/form-dataandtext/plaincontent types.Examples:
form_data = FormData(b"foo=bar&baz=qux&baz=quuz", "application/x-www-form-urlencoded") # or form_data = FormData(b"foo=bar\r\nbaz=qux\r\nbaz=quux", "text/plain") # FormData({"foo": ["bar"], "baz": ["qux", "quux"]}) form_data.get("foo") # "bar" form_data["foo"] # "bar" form_data.get("non-existent-key") # None form_data.get_list("baz") # ["qux", "quux"] "unknown-key" in form_data # False form_data.fields # ["foo", "baz"]
- property fields
Returns a list of field names.
- get(field_name: str, default: str | bytes = None, *, safe=True) str | bytes | None
Get the value of a field.
- items()
Returns a list of (name, value) tuples.
- keys()
Returns a list of header names.
- values()
Returns a list of header values.
- class adafruit_httpserver.request.QueryParams(query_string: str)
Class for parsing and storing GET query parameters requests.
Examples:
query_params = QueryParams("foo=bar&baz=qux&baz=quux") # QueryParams({"foo": ["bar"], "baz": ["qux", "quux"]}) query_params.get("foo") # "bar" query_params["foo"] # "bar" query_params.get("non-existent-key") # None query_params.get_list("baz") # ["qux", "quux"] "unknown-key" in query_params # False query_params.fields # ["foo", "baz"]
- property fields
Returns a list of field names.
- items()
Returns a list of (name, value) tuples.
- keys()
Returns a list of header names.
- values()
Returns a list of header values.
- class adafruit_httpserver.request.Request(server: Server, connection: _ISocket, client_address: Tuple[str, int], raw_request: bytes = None)
Incoming request, constructed from raw incoming bytes. It is passed as first argument to all route handlers.
- client_address: Tuple[str, int]
Address and port bound to the socket on the other end of the connection.
Example:
request.client_address # ('192.168.137.1', 40684)
- connection: _ISocket
Socket object used to send and receive data on the connection.
- property cookies: Dict[str, str]
Cookies sent with the request.
Example:
request.headers["Cookie"] # "foo=bar; baz=qux; foo=quux" request.cookies # {"foo": "quux", "baz": "qux"}
- property form_data: FormData | None
POST data of the request.
Example:
# application/x-www-form-urlencoded request = Request(..., raw_request=b"""... foo=bar&baz=qux""" ) # or # multipart/form-data request = Request(..., raw_request=b"""... --boundary Content-Disposition: form-data; name="foo" bar --boundary Content-Disposition: form-data; name="baz" qux --boundary--""" ) # or # text/plain request = Request(..., raw_request=b"""... foo=bar baz=qux """ ) request.form_data # FormData({'foo': ['bar'], 'baz': ['qux']}) request.form_data["foo"] # "bar" request.form_data.get_list("baz") # ["qux"]
- json() dict | None
Body of the request, as a JSON-decoded dictionary. Only available for POST, PUT, PATCH and DELETE requests.
- query_params: QueryParams
Query/GET parameters in the request.
Example:
request = Request(..., raw_request=b"GET /?foo=bar&baz=qux HTTP/1.1...") request.query_params # QueryParams({"foo": "bar"}) request.query_params["foo"] # "bar" request.query_params.get_list("baz") # ["qux"]
adafruit_httpserver.response
Author(s): Dan Halbert, Michał Pokusa
- class adafruit_httpserver.response.ChunkedResponse(request: Request, body: Generator[str | bytes, Any, Any], *, status: Status | Tuple[int, str] = OK_200, headers: Headers | Dict[str, str] = None, cookies: Dict[str, str] = None, content_type: str = None)
Specialized version of
Responseclass for sending data using chunked transfer encoding.Instead of requiring the whole content to be passed to the constructor, it expects a generator that yields chunks of data.
Example:
@server.route(path, method) def route_func(request: Request): def body(): yield "Some ch" yield "unked co" yield "ntent" return ChunkedResponse(request, body, content_type="text/plain")
- Parameters:
request (Request) – Request object
body (Generator) – Generator that yields chunks of data.
status (Status) – Status object or tuple with code and message.
headers (Headers) – Headers to be sent with the response.
cookies (Dict[str, str]) – Cookies to be sent with the response.
content_type (str) – Content type of the response.
- class adafruit_httpserver.response.FileResponse(request: Request, filename: str = 'index.html', root_path: str = None, *, status: Status | Tuple[int, str] = OK_200, headers: Headers | Dict[str, str] = None, cookies: Dict[str, str] = None, content_type: str = None, as_attachment: bool = False, download_filename: str = None, buffer_size: int = 1024, head_only: bool = False, safe: bool = True)
Specialized version of
Responseclass for sending files.Instead of
bodyit takesfilenameandroot_patharguments. It is also possible to send only headers withhead_onlyargument or modifybuffer_size.If browsers should download the file instead of displaying it, use
as_attachmentanddownload_filenamearguments.Example:
@server.route(path, method) def route_func(request: Request): return FileResponse(request, filename='index.html', root_path='/www')
- Parameters:
request (Request) – Request that this is a response to.
filename (str) – Name of the file to send.
root_path (str) – Path to the root directory from which to serve files. Defaults to server’s
root_path.status (Status) – Status code and text. Defaults to
200 OK.headers (Headers) – Headers to include in response.
cookies (Dict[str, str]) – Cookies to be sent with the response.
content_type (str) – Content type of response.
as_attachment (bool) – If
True, the file will be sent as an attachment.download_filename (str) – Name of the file to send as an attachment.
buffer_size (int) – Size of the buffer used to send the file. Defaults to
1024.head_only (bool) – If
True, only headers will be sent. Defaults toFalse.safe (bool) – If
True, checks iffilenameis valid. Defaults toTrue.
- class adafruit_httpserver.response.JSONResponse(request: Request, data: Dict[Any, Any], *, headers: Headers | Dict[str, str] = None, cookies: Dict[str, str] = None, status: Status | Tuple[int, str] = OK_200)
Specialized version of
Responseclass for sending JSON data.Instead of requiring
bodyto be passed to the constructor, it expectsdatato be passed instead.Example:
@server.route(path, method) def route_func(request: Request): return JSONResponse(request, {"key": "value"})
- class adafruit_httpserver.response.Redirect(request: Request, url: str, *, permanent: bool = False, preserve_method: bool = False, status: Status | Tuple[int, str] | None = None, headers: Headers | Dict[str, str] | None = None, cookies: Dict[str, str] = None)
Specialized version of
Responseclass for redirecting to another URL.Instead of requiring the body to be passed to the constructor, it expects a URL to redirect to.
Example:
@server.route(path, method) def route_func(request: Request): return Redirect(request, "https://www.example.com")
By default uses
permamentandpreserve_methodto determine thestatuscode to use, but if you prefer you can specify it directly.Note that
301 Moved Permanentlyand302 Foundcan change the method toGETwhile307 Temporary Redirectand308 Permanent Redirectpreserve the method.More information: https://developer.mozilla.org/en-US/docs/Web/HTTP/Status#redirection_messages
- Parameters:
request (Request) – Request that this is a response to.
url (str) – URL to redirect to.
permanent (bool) – Whether to use a permanent redirect or a temporary one.
preserve_method (bool) – Whether to preserve the method of the request.
status (Status) – Status object or tuple with code and message.
headers (Headers) – Headers to include in response.
cookies (Dict[str, str]) – Cookies to be sent with the response.
- class adafruit_httpserver.response.Response(request: Request, body: str | bytes = '', *, status: Status | Tuple[int, str] = OK_200, headers: Headers | Dict[str, str] = None, cookies: Dict[str, str] = None, content_type: str = None)
Response to a given
Request. Use inServer.routehandler functions.Base class for all other response classes.
Example:
@server.route(path, method) def route_func(request: Request): return Response(request, body='Some content', content_type="text/plain")
- Parameters:
request (Request) – Request that this is a response to.
body (str) – Body of response. Defaults to empty string.
status (Status) – Status code and text. Defaults to 200 OK.
headers (Headers) – Headers to include in response. Defaults to empty dict.
cookies (Dict[str, str]) – Cookies to be sent with the response.
content_type (str) – Content type of response. Defaults to None.
- class adafruit_httpserver.response.SSEResponse(request: Request, headers: Headers | Dict[str, str] = None, cookies: Dict[str, str] = None)
Specialized version of
Responseclass for sending Server-Sent Events.Allows one way communication with the client using a persistent connection.
Keep in mind, that in order to send events, the socket must be kept open. This means that you have to store the response object somewhere, so you can send events to it and close it later.
It is very important to close the connection manually, it will not be done automatically.
Example:
sse = None @server.route(path, method) def route_func(request: Request): # Store the response object somewhere in global scope global sse sse = SSEResponse(request) return sse ... # Later, when you want to send an event sse.send_event("Simple message") sse.send_event("Message", event="event_name", id=1, retry=5000) # Close the connection sse.close()
- Parameters:
- close()
Close the connection.
Always call this method when you are done sending events.
- class adafruit_httpserver.response.Websocket(request: Request, headers: Headers | Dict[str, str] = None, cookies: Dict[str, str] = None, buffer_size: int = 1024)
Specialized version of
Responseclass for creating a websocket connection.Allows two way communication between the client and the server.
Keep in mind, that in order to send and receive messages, the socket must be kept open. This means that you have to store the response object somewhere, so you can send events to it and close it later.
It is very important to close the connection manually, it will not be done automatically.
Example:
ws = None @server.route(path, method) def route_func(request: Request): # Store the response object somewhere in global scope global ws ws = Websocket(request) return ws ... # Receive message from client message = ws.receive() # Later, when you want to send an event ws.send_message("Simple message") # Close the connection ws.close()
- Parameters:
- close(code: int = None, reason: str = None)
Close the connection.
Always call this method when you are done sending events.
- receive(fail_silently: bool = False) str | bytes | None
Receive a message from the client.
- Parameters:
fail_silently (bool) – If True, no error will be raised if the connection is closed.
adafruit_httpserver.headers
Author(s): Michał Pokusa
- class adafruit_httpserver.headers.Headers(headers: str | Dict[str, str] = None)
A dict-like class for storing HTTP headers.
Allows access to headers using case insensitive names.
Does not implement all dict methods.
Examples:
headers = Headers("Content-Type: text/html\r\nContent-Length: 1024\r\n") # or headers = Headers({"Content-Type": "text/html", "Content-Length": "1024"}) len(headers) # 2 headers.setdefault("Access-Control-Allow-Origin", "*") headers["Access-Control-Allow-Origin"] # '*' headers["Content-Length"] # '1024' headers["content-type"] # 'text/html' headers["User-Agent"] # KeyError: User-Agent "CONTENT-TYPE" in headers # True
- add(field_name: str, value: str)
Adds a header with the given field name and value. Allows adding multiple headers with the same name.
- copy()
Returns a copy of the headers.
- property fields
Returns a list of field names.
- get(field_name: str, default: str = None) str | None
Returns the value for the given header name, or default if not found.
- get_directive(name: str, default: str = None) str | None
Returns the main value (directive) for the given header name, or default if not found.
Example:
headers = Headers({"Content-Type": "text/html; charset=utf-8"}) headers.get_directive("Content-Type") # 'text/html'
- get_parameter(name: str, parameter: str, default: str = None) str | None
Returns the value of the given parameter for the given header name, or default if not found.
Example:
headers = Headers({"Content-Type": "text/html; charset=utf-8"}) headers.get_parameter("Content-Type", "charset") # 'utf-8'
- items()
Returns a list of (name, value) tuples.
- keys()
Returns a list of header names.
- setdefault(name: str, default: str = None)
Sets the value for the given header name if it does not exist.
- values()
Returns a list of header values.
adafruit_httpserver.status
Author(s): Dan Halbert, Michał Pokusa
- class adafruit_httpserver.status.Status(code: int, text: str)
HTTP status code.
Define a status code.
adafruit_httpserver.mime_types
Author(s): Michał Pokusa
- class adafruit_httpserver.mime_types.MIMETypes
Contains MIME types for common file extensions. Allows to set default type for unknown files, unregister unused types and register new ones using the
MIMETypes.configure().- DEFAULT = 'text/plain'
Default MIME type for unknown files. Can be changed using
MIMETypes.configure(default_to=...).
- classmethod configure(default_to: str = None, keep_for: List[str] = None, register: Dict[str, str] = None) None
Allows to globally configure the MIME types.
It is recommended to always call this method before starting the
Server. Unregistering unused MIME types will decrease overall memory usage.- Parameters:
Example:
MIMETypes.configure( default_to="text/plain", keep_for=[".jpg", ".mp4", ".txt"], register={".foo": "text/foo", ".bar": "text/bar", ".baz": "text/baz"}, )
adafruit_httpserver.exceptions
Author(s): Michał Pokusa
- exception adafruit_httpserver.exceptions.AuthenticationError
Raised by
require_authenticationwhen theRequestis not authorized.
- exception adafruit_httpserver.exceptions.BackslashInPathError(path: str)
Backslash
\in path.Creates a new
BackslashInPathErrorfor thepath.
- exception adafruit_httpserver.exceptions.FileNotExistsError(path: str)
Raised when a file does not exist.
Creates a new
FileNotExistsErrorfor the file atpath.
- exception adafruit_httpserver.exceptions.InvalidPathError
Parent class for all path related errors.
- exception adafruit_httpserver.exceptions.ParentDirectoryReferenceError(path: str)
Path contains
.., a reference to the parent directory.Creates a new
ParentDirectoryReferenceErrorfor thepath.
- exception adafruit_httpserver.exceptions.ServerStoppedError
Raised when
.pollis called on a stoppedServer.
- exception adafruit_httpserver.exceptions.ServingFilesDisabledError
Raised when
root_pathis not set and there is no handler forrequest.