HTTP server
Every request becomes a pipeline item
Pipeline.server(routes) starts a small HTTP server and uses it as a source. Each route is a (method, path, handler) tuple; handler receives the decoded JSON body (None if missing or invalid) and its return value enters the pipeline as (socket, value). A downstream step answers with send_json_response(socket, dict), which sends the JSON response and closes the connection.
Signature
Pipeline.server(route_handlers, port=8000, host="localhost",
debug=False, inactivity_timeout=None) -> Pipeline[tuple[socket, OutPacket]]
send_json_response(connection, response: dict, status=200, reason="OK") -> None
# route_handlers: list of (method, path, handler); handler(json_body) -> valuefrom olympipe import Pipeline
from olympipe.helpers.server import send_json_response
def handle(pair):
connection, body = pair # (socket, value returned by the route handler)
result = {"square": body["x"] ** 2}
send_json_response(connection, result) # answers and closes the connection
return result
results = (
Pipeline.server(
[("POST", "/square", lambda body: body)], # (method, path, handler)
port=8000,
inactivity_timeout=5.0, # stop after 5 s without requests
)
.task(handle, count=2)
.wait_for_result()
)
print("served:", results)$ curl -X POST localhost:8000/square -d '{"x": 3}'
{"square": 9}
$ curl -X POST localhost:8000/square -d '{"x": 4}'
{"square": 16}
$ curl localhost:8000/nope
{"error": "Path not found"}
# server side, after 5 s without requests:
No route handler for GET /nope
Closing server due to inactivity
served: [{'square': 9}, {'square': 16}]How it works
The server listens on host:port (default localhost:8000) as soon as it is called, before later steps are even added. A request with no matching route gets a 404 {"error": "Path not found"}. Without inactivity_timeout, the server runs forever; with it, it stops after that many seconds without a request and the pipeline ends. debug=True prints every handled route.
