---
title: "clika_runtime.http"
sidebar_label: "clika_runtime.http"
description: "The clika_runtime.http module, introspected from the installed wheel."
---

<!-- Generated by tools/api_reference/generate_api_docs.py. Do not edit. -->

Serve HTTP from Python: routes, middleware, static files, streamed replies.

An :class:`HttpServer` takes handlers for exact paths and for patterns with
captures, runs them on its own threads, and answers with the
:class:`Response` a handler returns::

    from clika_runtime import http

    server = http.HttpServer()

    @server.get("/health")
    def health(request: http.Request) -> dict[str, str]:
        return {"status": "ok"}                 # a dict is sent as JSON

    @server.route("GET", r"/models/(?P<name>[^/]+)", pattern=True)
    def model(request: http.Request) -> str:
        return f"model {request.param('name')}"  # a str is sent as text/plain

    @server.post("/echo")
    def echo(request: http.Request) -> http.Response:
        return http.Response.bytes(request.body, "application/octet-stream")

    with server:
        port = server.bind_to_any_port("127.0.0.1")
        ...                                     # the block ends with server.stop()

A handler returns a :class:`Response` (built with ``Response.text``,
``.json``, ``.html``, ``.bytes``, ``.error``, ``.redirect``, ``.file``,
``.stream`` or ``.sse``), a ``str`` (sent as ``text/plain``) or a ``dict`` /
``list`` (serialized with ``json.dumps`` and sent as ``application/json``).
A streamed body pulls its chunks from a generator::

    @server.get("/events")
    def events(request: http.Request) -> http.Response:
        def frames():
            for i in range(3):
                yield {"event": "tick", "data": str(i)}
        return http.Response.sse(frames())

The :class:`Request` a handler receives is a view over the request the
server is handling: read it during the call; a read after the handler
returned raises ``RuntimeError``.

Middleware wraps every route: ``middleware(request, next)`` inspects the
request, then returns ``next()`` (the downstream response, changed or not)
or its own response without calling ``next``. Register middleware, routes
and mounts before the server listens.

A handler that raises answers an opaque 500; the exception's text reaches
the handler installed with :meth:`HttpServer.set_exception_handler` as
``what`` (do not echo it to clients) and the server keeps serving.

Threading: ``listen`` blocks its thread until ``stop`` is called from
another; ``listen_async`` and ``bind_to_any_port`` serve on the server's
own thread. Every one of them, and ``stop`` and ``wait_until_ready``,
releases the interpreter lock while it waits, so other Python threads keep
running. A handler holds the lock only while it runs Python code, so
several handlers make progress at once whenever they wait on I/O or on the
runtime.

| Name | Kind |
| --- | --- |
| [`FormFile`](./FormFile.md) | class |
| [`FormPart`](./FormPart.md) | class |
| [`HttpServer`](./HttpServer.md) | class |
| [`Method`](./Method.md) | class |
| [`Next`](./Next.md) | class |
| [`Request`](./Request.md) | class |
| [`Response`](./Response.md) | class |
| [`RouteGroup`](./RouteGroup.md) | class |