summonpot
An AI-native API framework. Every endpoint is an agent that runs automatically.
summonpot is a full API framework — with routing, validation, middleware, and serving — but built for the era where APIs don't just respond, they reason. Define routes. The framework runs the agents. No agent configuration. No framework ontology. Just endpoints that think.
You define routes with a function signature, a docstring, and tools. The framework owns the agentic runtime — the LLM call loop, tool orchestration, structured output, and streaming. You don't configure an agent. You define an endpoint. The agent is summoned.
from summonpot import Pot
pot = Pot("my-service", tools=[search_web])
@pot.summon("/research")
def research_topic(query: str, depth: str = "standard") -> str:
"""Research this topic thoroughly and return a comprehensive report."""
@pot.summon("/analyze")
def analyze_sentiment(text: str) -> dict:
"""Analyze the text and return a JSON object with sentiment and topics."""
pot.serve()
Call it like any API:
curl -X POST http://localhost:8000/research \
-H "Content-Type: application/json" \
-d '{"query": "quantum computing", "depth": "deep"}'
Behind the scenes, an agent runs — it thinks, uses tools, calls the LLM, enforces structured output, and returns the result. But you never wrote an agent. You wrote a route.
Why another framework?
Every existing approach to building agentic APIs has the same problem: you first learn an agent framework (LangChain, CrewAI, AutoGen), then bolt an HTTP server on top. The mental model is "configure an agent" — which is complex, brittle, and framework-y.
summonpot flips this: the web framework IS the agent framework. The routing is the agentic logic. The decorator is the incantation. The framework owns the smart parts.
| Existing frameworks | summonpot | |
|---|---|---|
| Mental model | "Configure an agent" | "Define an endpoint" |
| Surface area | Large (chains, agents, tools, memory, callbacks...) | Tiny (decorator + types + docstring) |
| API exposure | Bolt-on HTTP wrapper | Native (routing IS the agent) |
| Complexity | User manages the loop | Framework owns the loop, user provides intent |
| Testability | Heavy mocking required | Test like a regular HTTP endpoint |
| Onboarding | Learn the framework's ontology | If you know HTTP, you know this |
Installation
pip install summonpot # core
pip install summonpot[serve] # + HTTP server (FastAPI/uvicorn)
pip install summonpot[cli] # + Typer CLI
pip install summonpot[all] # everything
You also need an OpenAI-compatible API key:
export SUMMONPOT_API_KEY=sk-... # or OPENAI_API_KEY
export SUMMONPOT_MODEL=gpt-4o-mini # optional, default gpt-4o-mini
export SUMMONPOT_BASE_URL=https://api.openai.com/v1 # optional
Quick Start
Create a file app.py:
from summonpot import Pot
# A tool available to every endpoint
def search_web(query: str) -> list[dict]:
"""Search the web for information."""
return [{"query": query, "result": "..."}]
pot = Pot("my-service", tools=[search_web])
@pot.summon("/research")
def research_topic(query: str, depth: str = "standard") -> str:
"""Research this topic thoroughly and return a comprehensive report."""
@pot.summon("/summarize")
def summarize(text: str) -> str:
"""Summarize the given text into key bullet points."""
@pot.summon("/analyze")
def analyze_sentiment(text: str) -> dict:
"""Analyze the text and return a JSON object with sentiment and topics."""
Serve it:
summonpot serve app.py # serves on 0.0.0.0:8000
summonpot serve app.py --port 9000
Or from Python:
pot.serve() # 0.0.0.0:8000
pot.serve(host="127.0.0.1", port=9000)
The Summoning Model
| Concept | As summoning |
|---|---|
| Route definition | "At this path, I summon..." |
| Docstring | The incantation (system prompt) |
| Tools | Ingredients placed in the circle |
| Parameters | What the summoner brings |
| Return type | What appears |
stream=True |
You asked it to speak continuously |
How it works
summonpot inspects your endpoint function:
- Docstring → becomes the system prompt the agent follows
- Parameters → become the JSON request schema (validated by Pydantic)
- Return type → becomes the output contract (structured JSON for non-
strtypes) - Tools → exposed to the agent via function calling, so it can act, not just answer
The framework owns the LLM call loop, tool orchestration, and structured-output enforcement. You provide intent — the endpoint.
Configuration
| Variable | Default | Purpose |
|---|---|---|
SUMMONPOT_API_KEY |
OPENAI_API_KEY |
API key for the LLM provider |
SUMMONPOT_BASE_URL |
OPENAI_BASE_URL or https://api.openai.com/v1 |
OpenAI-compatible endpoint |
SUMMONPOT_MODEL |
gpt-4o-mini |
Default model for all endpoints |
Per-endpoint overrides:
@pot.summon("/research", model="gpt-4o", stream=True)
def research_topic(query: str) -> str:
"""Research this topic."""
Development
Requires uv.
git clone https://github.com/tugrulguner/summonpot.git
cd summonpot
uv sync --all-extras
make check # lint + typecheck + test
make lint # ruff check + format check
make test # pytest
make format # auto-format
See CONTRIBUTING.md for pull-request and single-source release instructions.
License
MIT
Download files
Download the file for your platform. If you're not sure which to choose, learn more about installing packages.
Source Distribution
Built Distribution
Filter files by name, interpreter, ABI, and platform.
If you're not sure about the file name format, learn more about wheel file names.
Copy a direct link to the current filters
File details
Details for the file summonpot-0.1.0.tar.gz.
File metadata
- Download URL: summonpot-0.1.0.tar.gz
- Upload date:
- Size: 2.4 MB
- Tags: Source
- Uploaded using Trusted Publishing? Yes
- Uploaded via: twine/7.0.0 CPython/3.13.14
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
a49933b3df294ee6026a8fdf6a6611cd116dc6bde2d98624e4cabe524c78e90a
|
|
| MD5 |
95f4c7c8fc551fd02b92beca2abd9005
|
|
| BLAKE2b-256 |
a5c2a2e793b9aef6a5018764b320477d96e866e320f5805c5f3847a7600f5cbe
|
Provenance
The following attestation bundles were made for summonpot-0.1.0.tar.gz:
Publisher:
release.yml on tugrulguner/summonpot
-
Statement:
-
Statement type:
https://in-toto.io/Statement/v1 -
Predicate type:
https://docs.pypi.org/attestations/publish/v1 -
Subject name:
summonpot-0.1.0.tar.gz -
Subject digest:
a49933b3df294ee6026a8fdf6a6611cd116dc6bde2d98624e4cabe524c78e90a - Sigstore transparency entry: 2415995628
- Sigstore integration time:
-
Permalink:
tugrulguner/summonpot@5adfe3e06c06025182de0258c77cd6f4c88bbffa -
Branch / Tag:
refs/tags/v0.1.0 - Owner: https://github.com/tugrulguner
-
Access:
public
-
Token Issuer:
https://token.actions.githubusercontent.com -
Runner Environment:
github-hosted -
Publication workflow:
release.yml@5adfe3e06c06025182de0258c77cd6f4c88bbffa -
Trigger Event:
push
-
Statement type:
File details
Details for the file summonpot-0.1.0-py3-none-any.whl.
File metadata
- Download URL: summonpot-0.1.0-py3-none-any.whl
- Upload date:
- Size: 13.9 kB
- Tags: Python 3
- Uploaded using Trusted Publishing? Yes
- Uploaded via: twine/7.0.0 CPython/3.13.14
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
dbb99bcde2d3cb8da688491051f76dd80452bfebebfed77bb4afa6cfb4400de3
|
|
| MD5 |
ac56cf588125a60905f4c400d736c1a6
|
|
| BLAKE2b-256 |
24fd2cf275d2dd8b43396cb4e699df3be1ca07d04a5a60462eb361a85c8289d2
|
Provenance
The following attestation bundles were made for summonpot-0.1.0-py3-none-any.whl:
Publisher:
release.yml on tugrulguner/summonpot
-
Statement:
-
Statement type:
https://in-toto.io/Statement/v1 -
Predicate type:
https://docs.pypi.org/attestations/publish/v1 -
Subject name:
summonpot-0.1.0-py3-none-any.whl -
Subject digest:
dbb99bcde2d3cb8da688491051f76dd80452bfebebfed77bb4afa6cfb4400de3 - Sigstore transparency entry: 2415995664
- Sigstore integration time:
-
Permalink:
tugrulguner/summonpot@5adfe3e06c06025182de0258c77cd6f4c88bbffa -
Branch / Tag:
refs/tags/v0.1.0 - Owner: https://github.com/tugrulguner
-
Access:
public
-
Token Issuer:
https://token.actions.githubusercontent.com -
Runner Environment:
github-hosted -
Publication workflow:
release.yml@5adfe3e06c06025182de0258c77cd6f4c88bbffa -
Trigger Event:
push
-
Statement type: