Quickstart
This guide deploys a small Python handler and calls it from your laptop. You need Python 3.11 or newer, Docker, a Surfra account, and a cloud account such as RunPod or Salad connected under Credentials → Cloud accounts. The dashboard’s Get started page walks through the same steps and checks each one off as you go.
-
Install the SDK and set your key.
Create an API key in the dashboard under Credentials → API Keys, then:
Terminal window pip install surfraexport SURFRA_API_KEY=sfk_... -
Write a handler.
@surfra.warmupruns once when a worker starts.@surfra.handlerruns once per request.request.inputis the JSON object the caller sent. Return anything JSON can encode.app.py import surfragreeting = None@surfra.warmupdef load():global greetinggreeting = "hello" # load model weights here@surfra.handlerdef predict(request: surfra.Request):name = request.input.get("name", "world")return {"text": f"{greeting} {name}"} -
Build an image.
The image needs the
surfrapackage and your file. Surfra starts the container withsurfra worker, which importsapp.pyand runs the handler.Dockerfile FROM python:3.12-slimRUN pip install surfraWORKDIR /appCOPY app.py .CMD ["surfra", "worker"]Terminal window docker build -t ghcr.io/you/hello:1 .docker push ghcr.io/you/hello:1A private registry needs a saved login. See Secrets and registries.
-
Deploy.
The name identifies the app. Deploying the same name again updates it in place.
deploy.py import surfraapp = surfra.App("hello")app.deploy(image="ghcr.io/you/hello:1",entrypoint="app.py",runtime={"engine": "python"},autoscale={"min_replicas": 0,"max_replicas": 2,"idle_timeout_sec": 300,"providers": [{"provider": "salad", "gpu": "cpu", "priority": 1, "vcpu": 2, "ram_gb": 4},{"provider": "runpod", "gpu": "cpu", "priority": 2, "vcpu": 2, "ram_gb": 4},],},)The dashboard does the same thing. Open Serverless → New App, pick machines, and copy the generated SDK code from the side panel.
-
Call it.
print(app.run({"name": "Surfra"}, timeout=600))# {'text': 'hello Surfra'}The first call starts a replica, so it waits for the image to pull and warmup to finish. Later calls go to the warm replica until it has been idle for
idle_timeout_sec.
Where to go next
Section titled “Where to go next”- Handlers covers warmup, errors, and schemas.
- Batching and concurrency runs several requests through one loaded model.
- HTTP servers deploys an existing server such as vLLM instead of a handler.
- Autoscaling explains minimums, failover, and per-provider limits.
