Skip to content

Learn what Sillo is, the core concepts behind it, what you can build, who it is for, and why teams choose it for serious Python software.

Sillo is a Python framework for building serious backend software: web applications, APIs, real-time systems, background workloads, internal tools, and business platforms.

It starts as a productive async web framework, but the goal is larger than routing requests. Sillo gives teams one coherent application model across HTTP, validation, dependency injection, records, authentication, sessions, background jobs, scheduling, caching, WebSockets, testing, and production operations.

The core idea is simple: teams should not have to assemble a fragile collection of unrelated tools before they can build reliable software.

Sillo Core is the open framework foundation of the Sillo platform. It is designed to help a project start small and grow without replacing its architecture every time the product becomes more real.

A Sillo application can begin with one route:

from sillo import silloApp
app = silloApp()
@app.get("/")
async def home(request, response):
return response.json({"message": "Hello from Sillo"})

From there, the same application model can grow into validated endpoints, authenticated routes, database-backed records, queues, scheduled work, WebSocket channels, and operational tooling.

Sillo is built around a small set of concepts that appear consistently across the framework.

ConceptWhat it means
silloAppThe application object. It owns routes, middleware, lifecycle hooks, state, and framework configuration.
RequestThe incoming HTTP boundary: headers, query params, path params, body data, cookies, user state, and request-scoped data.
ResponseA fluent response builder for JSON, text, HTML, files, streams, redirects, cookies, headers, and status codes.
RoutesDecorated functions or router definitions that bind HTTP methods and paths to handlers.
MiddlewareRequest/response pipeline units for cross-cutting concerns such as CORS, auth, sessions, rate limits, ETags, and content negotiation.
Validationrequest_model turns untrusted request bodies into validated Pydantic models at the route boundary.
Dependency InjectionDepend wires services, shared state, request-aware providers, and reusable business logic into handlers.
RecordSillo’s database layer on top of Tortoise ORM for models, setup, serialization, casting, scopes, pagination, and persistence helpers.
WorkloadsJobs, queues, events, scheduler managers, and background work that run outside the request cycle.
WebSocketsReal-time connections, consumers, channels, and broadcast patterns for interactive systems.
TestingTest clients and framework patterns for exercising routes, validation, dependencies, auth, jobs, and application behaviour.

These concepts are meant to form one product language. A developer should not feel like every feature belongs to a different framework.

This example shows a validated endpoint, path parameter, and response object working together.

from pydantic import BaseModel
from sillo import silloApp
from sillo.core.http import Request, Response
app = silloApp()
class CreateProject(BaseModel):
name: str
private: bool = False
@app.post("/teams/{team_id}/projects", request_model=CreateProject)
async def create_project(
request: Request,
response: Response,
team_id: str,
project: CreateProject,
):
return response.json(
{
"team_id": team_id,
"project": project.model_dump(),
"status": "created",
},
status_code=201,
)

What is happening:

  • team_id comes from the path and is passed into the handler.
  • request_model=CreateProject validates the request body.
  • The validated Pydantic object can be injected into the handler.
  • The response object builds a JSON response with a status code.

Sillo includes the common backend pieces teams repeatedly need:

  • async ASGI application foundation
  • routing, route groups, routers, and sub-apps
  • request and response helpers
  • request validation with Pydantic
  • dependency injection
  • middleware pipeline
  • CORS, CSRF, cookies, sessions, and security helpers
  • authentication, permissions, API keys, JWT, and session auth
  • Record ORM layer with database setup, models, casts, scopes, pagination, factories, and upserts
  • background jobs, queues, workers, events, and scheduling
  • caching with memory and Redis-compatible backends
  • WebSockets, consumers, channels, and real-time patterns
  • OpenAPI generation
  • static files, templating, file uploads, and streaming responses
  • test clients and testing utilities
  • HTTP client utilities
  • content negotiation, ETags, request lifecycle helpers, and protocol status constants under sillo.http

Sillo is useful for many backend-heavy products:

  • JSON APIs for web and mobile applications
  • SaaS backends with teams, users, roles, billing, jobs, and dashboards
  • internal tools and admin systems
  • real-time applications using WebSockets and channels
  • workflow systems with queues, retries, and scheduled jobs
  • data-backed business platforms with records, pagination, permissions, and audit-friendly patterns
  • API gateways and integration services
  • background processing systems
  • customer portals and product backends
  • applications that need to move from prototype to production without changing frameworks

Sillo is designed for developers and organisations building serious software with Python.

It is especially useful for:

  • independent developers who want a productive framework that can grow with a project
  • startups that need speed without accumulating avoidable operational debt
  • product teams building APIs, SaaS products, internal systems, and real-time applications
  • agencies that want repeatable backend foundations for client work
  • mid-market engineering teams that need standardisation, visibility, and governance
  • enterprise teams that care about security, lifecycle, compatibility, deployment choice, and operational clarity
  • educators and communities teaching modern Python backend development

Sillo is less suitable if you only need a tiny script, a one-off HTTP handler, or a framework that intentionally avoids owning anything beyond routing.

Software teams rarely fail because they cannot write a route or database query. They struggle because the surrounding system becomes fragmented.

Sillo exists to make that surrounding system coherent.

The framework is guided by these principles:

  • Strong defaults, open boundaries.
  • Developer experience is part of the product.
  • Enterprise readiness should be real, not theatrical.
  • Operations belong in the product story.
  • Documentation is part of the interface.
  • Compatibility and upgrade paths matter.
  • Open source earns trust.

Sillo is opinionated where teams benefit from a clear default, but it should remain transparent and replaceable at the boundaries. Convenience should not mean mystery. Enterprise readiness should not mean unnecessary ceremony.

Sillo is not a drop-in clone of another Python framework. It combines ideas from productive web frameworks, async API frameworks, and full-stack application platforms.

FrameworkGood atSillo difference
FlaskMinimal apps, simple routing, extension-based composition.Sillo provides a broader first-party application model for validation, DI, auth, records, jobs, scheduling, caching, WebSockets, and testing.
FastAPITyped APIs, Pydantic validation, async endpoints.Sillo focuses on the complete backend lifecycle, explicit dependency patterns, first-party workload primitives, and a path toward operations.
DjangoBatteries-included web apps, ORM, admin, mature ecosystem.Sillo is async-first and designed around modern Python APIs, explicit handlers, background workloads, real-time systems, and deployment/operations coherence.
StarletteLow-level ASGI toolkit and primitives.Sillo builds a higher-level product framework on top of ASGI ideas so teams do not assemble every application concern manually.

The goal is not to win by having every feature. The goal is to make the repeated work of serious backend development feel like one designed system.

Sillo Core is the foundation. The broader platform direction includes first-party products for visual administration, managed deployment, server operations, identity, observability, templates, and integrations.

That long-term direction matters because backend software does not stop at code. Teams also need to deploy it, operate it, secure it, observe it, govern access, and help non-engineering teams use it safely.

Sillo’s promise is to help developers move from an idea to dependable enterprise software with fewer disconnected decisions, clearer systems, and tools that grow with their ambition.

Continue with Installation to install Sillo with uv and build your first application.

sillo is an ASGI framework, which means it speaks the same protocol as uvicorn, granian, hypercorn, and every ASGI middleware in the ecosystem. Everything below builds on that one interface.

A request arrives at the server, which hands sillo a scope, a receive, and a send. sillo builds a Request, runs it through the middleware stack, matches it against the router, resolves dependencies and validates inputs, calls your handler, and serializes what comes back.

Around that core sit optional subsystems, each independent: an ORM layer, background work, WebSockets, templating, caching, mail, and an HTTP client. None of them are required. An application that only serves JSON needs none of them.

The path through the documentation depends on what you are building.

A JSON API. RoutingHandlersValidationError Handling. That is enough to build something real. Add Record when you need a database and Authentication when you need users.

A server-rendered application. RoutingTemplatingSessionsCSRF. The last is not optional if your forms authenticate with cookies.

Something real-time. WebSockets first, and read its scaling section before you design anything, because the answer changes what you build.

Anything going to production. Security, Startup & Shutdown, and Concurrency — in that order. The third one is where most performance surprises come from.

These guides document what the framework does, including where it does something surprising or wrong. Where a function has a defect, the page covering it says so, shows the failure, and gives a working alternative.

That is deliberate. A guide that describes intended behaviour is a guide that costs you an afternoon the first time reality differs. Every :::danger and :::caution block in these pages marks something verified by running it.

A few things recur in every guide and are worth knowing once.

Handlers take request, response. Everything after those two is injected — validated parameters, dependencies, the request body.

app.state is process-wide, request.state is per-request. The first is written by lifespan hooks; the second by middleware.

setup_* functions are idempotent. setup_record, setup_work, and setup_mail each store an object in app.state and register lifecycle hooks, and calling one twice returns the existing object rather than reconfiguring.

Async by default. The framework, the ORM, and the HTTP client are all async. Synchronous handlers work and run in a thread; synchronous calls inside an async handler block everything.

Every page ends with “What not to do”. Those lists are the compressed version of the page, and they are the part worth re-reading before shipping.

The guides are organised by subsystem, and the sidebar mirrors the package layout, so sillo.record is under Record and sillo.work under Work. If you know the module, you can find the page.

For questions the guides do not answer, the source is small enough to read. Most modules are a few hundred lines, the abstractions are shallow, and the answer to “what does this actually do” is usually one file away — which is how several of the warnings in these pages were found.

These guides assume working Python and a rough familiarity with HTTP — methods, status codes, headers, and what a request body is. They do not assume prior experience with an async framework; where async/await matters, the page explains what it changes.

Python 3.10 or newer is required. Several guides use match, X | None syntax, and asyncio.timeout, which is 3.11+.

The smallest thing that runs, to anchor everything above:

main.py
from sillo import silloApp
app = silloApp()
@app.get("/")
async def index(request, response):
return response.json({"status": "ok"})
Terminal window
sillo run --app main:app --reload

That is a complete ASGI application. Everything else in these guides — validation, the ORM, background work, WebSockets — is something you add to this when you need it, and nothing is required to get here.