Skip to content

Write a handler

Every handler deployment uses the handler preset and must contain a top-level handler.py file with a callable named handle.

handler.py
def handle(input: dict):
return {"received": input}

The handler receives the run’s input object. If a run omits input, the runtime passes an empty dictionary. Return a value accepted by Python’s json.dumps, such as a dictionary, list, string, number, boolean, or None.

def handle(input: dict) -> dict:
numbers = input.get("numbers", [])
return {"sum": sum(numbers), "count": len(numbers)}

An uncaught exception fails the run. Magmell captures its type and message for the run record while protecting secrets from gateway logs.

Add a conventional requirements file beside the handler:

requirements.txt
httpx==0.28.1
pydantic==2.11.7

Then deploy the directory normally:

Terminal window
magmell deploy ./summarizer \
--name summarizer \
--version 1 \
--wait

Pin exact versions for repeatable production builds. Standard-library-only handlers do not need requirements.txt. For system packages and other build commands, see setup and dependencies.

The runtime imports handler.py once when it starts. Put reusable client initialization at module scope and invocation-specific work inside handle.

import httpx
client = httpx.Client(timeout=20)
def handle(input: dict) -> dict:
response = client.get(input["url"])
return {"status": response.status_code}

Do not keep invocation-specific secrets or mutable request state in module globals.

import siloga_agent
def handle(input: dict) -> dict:
siloga_agent.log("starting analysis", document_id=input.get("id"))
with siloga_agent.span("analyze"):
result = analyze(input["text"])
siloga_agent.metric("input.characters", len(input["text"]))
siloga_agent.event("analysis.complete", confidence=result["confidence"])
return result

Events emitted before an exception are retained, which makes them useful for diagnosing failed runs. See events and logs.

import siloga_agent
def handle(input: dict) -> dict:
api_key = siloga_agent.secret("MODEL_API_KEY")
if not api_key:
raise RuntimeError("MODEL_API_KEY is not configured")
return call_model(api_key, input)

Secrets are scoped to the current invocation. They are not environment variables and should never be returned or included in emitted event data.