Reference Runtime for Intent-Oriented Programming
Data declares what, runtime decides how.
What is IOP? • Quick Start • Adapters • Features • Docs • PyPI
Intent-Oriented Programming — your data declares what it needs, the runtime handles how.
from evoid.native import create_service, on
from evoid import Intent, Level
app = create_service("my-api")
GET_USER = Intent(name="get_user", level=Level.STANDARD)
async def get_user(intent: Intent) -> dict:
return {"id": 1, "name": "Alice"}
on(app, GET_USER, get_user)Three intent levels control infrastructure automatically:
| Level | Pipeline | Use Case |
|---|---|---|
ephemeral |
validate |
Cache, sessions, temp data |
standard |
validate, authorize |
User profiles, posts |
critical |
validate, authorize, audit, protect |
Payments, medical, legal |
EVOID is a runtime, not a framework. Adapters bridge the outside world:
External Event (HTTP, CLI, Telegram, WebSocket, ...)
|
Adapter converts event → Intent
|
Runtime executes Intent through Pipeline
|
Pipeline runs Processors (validate, authorize, audit, ...)
|
Result returned to Adapter → converted back to response
Adapters provide route decorators and event conversion. Services are Intent + handler registrations. Pipelines are processor chains chosen by intent level.
See How It Works for the full picture.
uv add evoid
evo init my-api && cd my-api
evo service run gateway # already scaffolded, http://0.0.0.0:8000
evo service new api # add another service (optional)
evo service run api # http://0.0.0.0:8001Or install optional engines:
evo install sqlite # SQLite storage
evo install redis # Redis cache
evo install pydantic # Pydantic schema
evo install full # EverythingAll IOP underneath. Pick your style:
Route decorators come from the adapter. Switch adapters, same code:
from evoid.adapters.asgi import get, post
from evoid.web.route import Service
app = Service("my-api")
@get("/users/{user_id}")
async def get_user(user_id: int) -> dict:
return {"id": user_id, "name": "Alice"}@GET, @POST mark routes. @Controller creates Intents from them:
from evoid.web.controller import Service, Controller, GET, POST
app = Service("my-api")
@Controller("/users")
class UserController:
@GET("/{user_id}")
async def get_user(self, user_id: int) -> dict:
return {"id": user_id}Explicit Intent creation. Adapter-agnostic — works with any transport:
from evoid.native import create_service, on
from evoid import Intent, Level
app = create_service("my-api")
GET_USER = Intent(name="get_user", level=Level.STANDARD)
async def get_user(intent: Intent) -> dict:
return {"id": 1, "name": "Alice"}
on(app, GET_USER, get_user)Each adapter converts its event type to Intents. Route decorators live in adapters because param extraction is adapter-specific:
| Adapter | Decorators | Install |
|---|---|---|
| ASGI (HTTP) | @get(path), @post(path) |
evoid[asgi] |
| Robyn | @get(app, path), @post(app, path) |
evoid[robyn] |
| Telegram | on(bot, event, handler) |
evoid[telegram] |
| CLI | intent_from_args(cmd) |
built-in |
| MCP (AI agents) | create_mcp_server(name) |
built-in |
See Adapters for details and examples.
|
Minimal Core Core has one required package (tomli_w) |
AI Agent Integration Schema export + MCP server |
Plugin System PyPI + git install |
|
Python-Native Config Type-safe, composable |
Pipeline Hooks 6 lifecycle events |
Testing System pytest + WebUI dashboard |
|
Async-Native Full async/await support |
Parallel Execution gather, parallel, IntentQueue |
Multi-Adapter ASGI, CLI, Telegram, WebSocket, MCP |
|
Storage Engines Memory, SQLite, Redis, Postgres |
Cache Engine LRU with TTL, Redis backend |
Extend Pipelines before/after processors, pipeline override |
from evoid import export_schemas
from evoid.adapters.mcp import create_mcp_server
schemas = export_schemas()
server = create_mcp_server("my-api")evo plug install evoid-redis # From PyPI
evo plug install git+https://... # From git
evo plug search cache # Search PyPI
evo plug list # List installedfrom evoid.config import config
app = config(
service={"name": "my-api"},
runtime={"adapter": "asgi", "port": 8000},
engines={"storage": "redis"},
)[service]
name = "my-api"
[engines]
storage = "redis"from evoid.testing import tc
from myapp import GET_USER
def test_get_user():
return tc(GET_USER, expect={"id": 1})pytest tests/ -v # Run tests
pytest tests/ --evoid-webui # With dashboard
pytest tests/ --evoid-inspect # With pipeline tracesmy-api/
evoid.toml # TOML config (or evoid_config.py)
shared/ # Shared code
services/
api/
main.py # Service code
evoid/
core/ Intent, Pipeline, Context, Runtime, Events, MessageBus
native/ IOP mother syntax (create_service, on)
web/ @route and @controller syntax
adapters/ asgi, cli, telegram, websocket, mcp, robyn
engines/ storage, cache, auth, di, logger, metrics, schema, serializer
processors/ Built-in processors (validate, authorize, etc.)
config/ TOML + Python config loading
testing/ pytest plugin + WebUI dashboard
project/ Project scaffolding
Full docs: https://evolvebeyond.github.io/EVOID/
Architecture: https://deepwiki.com/EvolveBeyond/EVOID
See CONTRIBUTING.md.
- Fork → Branch → Commit → PR
- Tests:
pytest tests/ -v - Lint:
ruff check evoid/
