ESC

Type to search...

Configuration

EVOID supports two config formats:

  1. TOML (evoid.toml): traditional, human-readable
  2. Python (evoid_config.py): native, type-safe, IOP-native

Both produce the same config. Change infrastructure by changing config: business logic stays untouched.

# evoid_config.py
from evoid.config import config

app = config(
    service={"name": "my-api", "version": "1.0.0"},
    runtime={"adapter": "asgi", "port": 8000},
    engines={"storage": "memory", "cache": "memory"},
)

TOML Config

# evoid.toml
[service]
name = "my-api"
version = "1.0.0"

[runtime]
adapter = "asgi"
port = 8000

[engines]
storage = "memory"
cache = "memory"

Auto-Detection

EVOID auto-detects the config format:

from evoid.config import load_config

config = load_config()  # Tries evoid.toml, then evoid_config.py

Project Structure

my-api/
  evoid.toml              # Project config (root)
  shared/                 # Shared code between services
  services/
    api/
      evoid.toml          # Service config (optional override)
      main.py
    workers/
      evoid.toml          # Service config for worker
      main.py

Two levels of config:

  • Project (root/evoid.toml): defaults for all services
  • Service (services/*/evoid.toml): overrides for one service

Service config merges into project config. Only specify what you want to override.

Complete Reference

[service] — Service Identity

[service]
name = "my-api"
version = "1.0.0"
FieldTypeDefaultDescription
namestr"evoid-service"Service name. Used in logs, metrics, and inter-service communication.
versionstr"0.1.0"Semantic version. Included in health check responses.

[runtime] — Server Configuration

[runtime]
adapter = "asgi"
host = "0.0.0.0"
port = 8000
FieldTypeDefaultDescription
adapterstr"asgi"How Intents are triggered. See Adapter Reference.
hoststr"0.0.0.0"Bind address. Use 127.0.0.1 for local-only.
portint8000Bind port.

[engines] — Infrastructure Selection

[engines]
schema = "native"
storage = "memory"
cache = "memory"
serializer = "json"
di = "native"
logger = "loguru"
metrics = "simple"
auth = "simple"

Each engine is pluggable. Change the value to swap the implementation.

FieldOptionsDefaultPurpose
schemanative, pydantic, msgspec, attrsnativeData validation
storagememory, sqlite, sqlalchemy, redis, postgres, mongomemoryData persistence
cachememory, redismemoryCaching layer
serializerjson, msgspec, orjsonjsonSerialization
dinativenativeDependency injection
loggerstructlog, loguruloguruStructured logging
metricssimple, prometheussimpleMetrics collection
authsimple, jwtsimpleAuthentication

[pipeline] — Default Processors

[pipeline]
processors = ["validate", "authorize"]
FieldTypeDefaultDescription
processorslist[str]["validate", "authorize"]Default processor chain for all Intents. Override per-Intent in code.

Real-World Examples

Minimal API (Development)

[service]
name = "dev-api"
version = "0.1.0"

[runtime]
adapter = "asgi"
port = 8000

[engines]
schema = "native"
storage = "memory"
cache = "memory"
serializer = "json"
logger = "loguru"

Production API with PostgreSQL

[service]
name = "production-api"
version = "2.1.0"

[runtime]
adapter = "asgi"
host = "0.0.0.0"
port = 8000

[engines]
schema = "pydantic"
storage = "sqlalchemy"
cache = "redis"
serializer = "orjson"
logger = "structlog"
metrics = "prometheus"
auth = "jwt"

[pipeline]
processors = ["validate", "authorize", "audit"]
evo sync
# Installs: pydantic, sqlalchemy, aiosqlite, redis, orjson, structlog, prometheus-client, pyjwt

Telegram Bot

[service]
name = "my-bot"
version = "1.0.0"

[runtime]
adapter = "telegram"

[engines]
schema = "native"
storage = "sqlite"
cache = "memory"
serializer = "json"
logger = "loguru"

Microservices (Multiple Services)

Project root (evoid.toml):

[service]
name = "my-platform"
version = "1.0.0"

[engines]
schema = "pydantic"
storage = "sqlalchemy"
cache = "redis"
serializer = "json"
logger = "structlog"

API service (services/api/evoid.toml):

[service]
name = "api"

[runtime]
adapter = "asgi"
port = 8000

Worker service (services/workers/evoid.toml):

[service]
name = "workers"

[runtime]
adapter = "cli"

[engines]
storage = "sqlite"

The worker inherits schema, cache, serializer, logger from project config but overrides storage and adapter.

Config Precedence

Service config  →  merges into  →  Project config  →  defaults
  1. Start with project config defaults
  2. Service config overrides specific fields
  3. Environment variables override both (if supported)

Example:

# Project: services/ with SQLite
[engines]
storage = "sqlite"

# Service: services/cache-only/evoid.toml
# This service only needs memory — override storage
[engines]
storage = "memory"

Adapter Reference

AdapterUse CasePackage RequiredTrigger Source
asgiHTTP APIsevoid[asgi]HTTP requests
cliCommand-line toolscore onlyTerminal commands
telegramTelegram botsevoid[telegram]Telegram messages
robynRobyn frameworkevoid[robyn]HTTP requests
websocketWebSocket appsevoid[asgi]WebSocket messages

Syncing Dependencies

evo sync reads evoid.toml, maps engine names to packages, and installs them:

evo sync
# Reads: evoid.toml
# Maps: storage="sqlalchemy" → sqlalchemy[asyncio], aiosqlite
# Installs via: uv add

Engine → Package Map

EngineValuePackages InstalledBuilt-in?
schemanativenone
schemapydanticpydantic>=2.0.0extra
schemamsgspecmsgspec>=0.18.0extra
storagememorynone
storagesqliteaiosqlite>=0.20.0extra
storagesqlalchemysqlalchemy[asyncio]>=2.0.0, aiosqliteextra
storageredisredis>=4.0.0plugin
storagepostgresasyncpg>=0.28.0plugin
cachememorynone
cacheredisredis>=4.0.0plugin
serializerjsonnone
serializermsgspecmsgspec>=0.18.0extra
serializerorjsonorjson>=3.9.0extra
loggerstructlogstructlog>=24.0.0extra
loggerloguruloguru>=0.7.0extra
metricssimplenone
metricsprometheusprometheus-client>=0.15.0extra
authsimplenone
authjwtpyjwt>=2.10.0extra
adapterasgistarlette>=0.27.0, uvicorn[standard]>=0.24.0extra
adapterrobynrobyn>=0.30.0extra
adaptertelegramaiogram>=3.0.0extra

Optional Dependencies

Install only what you need. Core EVOID has minimal required dependencies:

# Core extras (built into EVOID)
uv add "evoid[asgi]"           # HTTP APIs
uv add "evoid[pydantic]"       # Pydantic schemas
uv add "evoid[sqlite]"         # SQLite storage
uv add "evoid[loguru]"         # Loguru logging
uv add "evoid[full]"           # All extras

# Plugins (separate packages)
uv add evoid-redis             # Redis cache
uv add evoid-postgresql        # PostgreSQL storage
uv add evoid-di                # Advanced DI
uv add evoid-auth              # Custom auth providers

Environment Variables

Override config values at runtime:

EVOID_HOST=127.0.0.1
EVOID_PORT=3000
EVOID_ADAPTER=cli