Lihil
2X faster ASGI web framework for python, offering high-level development, low-level performance.
Install / Use
/learn @raceychan/LihilQuality Score
Category
Development & EngineeringSupported Platforms
README

Lihil
Lihil /ˈliːhaɪl/ — a performant, productive, and professional web framework with a vision:
Making Python the mainstream programming language for web development.
lihil is 100% test covered and strictly typed.
Lihil
📚 Docs: https://lihil.cc
Lihil is
- Performant: Blazing fast across tasks and conditions—Lihil ranks among the fastest Python web frameworks, outperforming other webframeworks by 50%–100%, see reproducible, automated tests lihil benchmarks, independent benchmarks

- Designed to be tested: Built with testability in mind, making it easy for users to write unit, integration, and e2e tests. Lihil supports Starlette's TestClient and provides LocalClient that allows testing at different levels: endpoint, route, middleware, and application.
- Built for large scale applications: Architected to handle enterprise-level applications with robust dependency injection and modular design
- AI Agent Friendly: Designed to work seamlessly with AI coding assistants - see LIHIL_COPILOT.md for comprehensive guidance on using Lihil with AI agents
- Productive: Provides extensive typing information for superior developer experience, complemented by detailed error messages and docstrings for effortless debugging
What’s New: Managed WebSocket Hub
- SocketHub: High-level WebSocket route with class-based channels. Subclass
ChannelBase, declaretopic = Topic("room:{room_id}"), and implementon_join,on_message,on_leave. - Bus fanout: Call
await self.publish(payload, event="chat")inside channels to broadcast to all subscribers of the resolved topic. Bus instances are resolved per connection viabus_factory(supports DI, nested factories). - Registration: Register channels with
hub.channel(MyChannel)and mount the hub like any other route:app = Lihil(hub). - Demo:
demo/ws.pyanddemo/chat.htmlnow show room join/leave and broadcast chat across rooms using the new hub API. - DI in channels: Channels receive the hub’s
Graph; useself.graph.aresolve(...)to pull dependencies (e.g., custom bus backends, services) insideon_join/on_message/on_leave.
Lihil is not
- Not a microframework: Lihil has an ever-growing and prosperous ecosystem that provides industrial, enterprise-ready features such as throttler, timeout, auth, and more
- Not a one-man project: Lihil is open-minded and contributions are always welcome.you can safely assume that your PR will be carefully reviewed
- Not experimental: Lihil optimizes based on real-world use cases rather than benchmarks
Install
lihil requires python>=3.10
pip
pip install "lihil[standard]"
The standard version comes with uvicorn
Qucik Start
from lihil import Lihil, Route, EventStream, SSE
from openai import OpenAI
from openai.types.chat import ChatCompletionChunk as Chunk
from openai.types.chat import ChatCompletionUserMessageParam as MessageIn
gpt = Route("/gpt", deps=[OpenAI])
def chunk_to_str(chunk: Chunk) -> str:
if not chunk.choices:
return ""
return chunk.choices[0].delta.content or ""
@gpt.sub("/messages").post
async def add_new_message(
client: OpenAPI, question: MessageIn, model: str
) -> Stream[Chunk]:
yield SSE(event="open")
chat_iter = client.responses.create(messages=[question], model=model, stream=True)
async for chunk in chat_iter:
yield SSE(event="token", data={"text": chunk_to_str(chunk)})
yield SSE(event="close")
what frontend would receive
event: open
event: token
data: {"text":"Hello"}
event: token
data: {"text":" world"}
event: token
data: {"text":"!"}
event: close
Deprecation notice (routing API)
- Prefer
Route.merge(...)(wasinclude_subroutes) andLihil.include(...)(wasinclude_routes). The legacy names are deprecated and will be removed in0.3.0.
HTTP vs WebSocket routing (do not mix)
- Keep HTTP
Routetrees andWebSocketRoutetrees separate; merge only like with like, then pass both top-level routes toLihil.
api = Route("api")
v1 = api.sub("v1")
users = v1.sub("users")
ws = WebSocketRoute("ws")
ws_v1 = ws.sub("v1")
ws_notify = ws_v1.sub("notification")
app = Lihil(api, ws) # do NOT merge Route into WebSocketRoute or vice versa
Features
-
Param Parsing & Validation
Lihil provides a high level abstraction for parsing request, validating rquest data against endpoint type hints. various model is supported including
msgspec.Struct,pydantic.BaseModel,dataclasses.dataclass,typing.TypedDict
By default, lihil uses
msgspecto serialize/deserialize json data, which is extremly fast, we maintain first-class support forpydantic.BaseModelas well, no plugin required. see benchmarks,- Param Parsing: Automatically parse parameters from query strings, path parameters, headers, cookies, and request bodies
- Validation: Parameters are automatically converted to & validated against their annotated types and constraints.
- Custom Decoders: Apply custom decoders to have the maximum control of how your param should be parsed & validated.
-
Dependency injection: Inject factories, functions, sync/async, scoped/singletons based on type hints, blazingly fast.
-
WebSocket lihil supports the usage of websocket, you might use
WebSocketRoute.ws_handlerto register a function that handles websockets. -
OpenAPI docs & Error Response Generator Lihil creates smart & accurate openapi schemas based on your routes/endpoints, union types,
oneOfresponses, all supported. -
Powerful Plugin System: Lihil features a sophisticated plugin architecture that allows seamless integration of external libraries as if they were built-in components. Create custom plugins to extend functionality or integrate third-party services effortlessly.
-
Strong support for AI featuers: lihil takes AI as a main usecase, AI related features such as SSE, MCP, remote handler will be implemented in the next few patches
There will also be tutorials on how to develop your own AI agent/chatbot using lihil.
- ASGI-compatibility & Vendor types from starlette
- Lihil is ASGI copatible and works well with uvicorn and other ASGI servers.
- ASGI middlewares that works for any ASGIApp should also work with lihil, including those from Starlette.
Plugin System
Lihil's plugin system enables you to integrate external libraries seamlessly into your application as if they were built-in features. Any plugin that implements the IPlugin protocol can access endpoint information and wrap functionality around your endpoints.
Plugin Execution Flow
When you apply multiple plugins like @app.sub("/api/data").get(plugins=[plugin1.dec, plugin2.dec]), here's how they execute:
Plugin Application (Setup Time - Left to Right)
┌─────────────────────────────────────────────────────────────┐
│ original_func → plugin1(ep_info) → plugin2(ep_info) │
│ │
│ Result: plugin2(plugin1(original_func)) │
└─────────────────────────────────────────────────────────────┘
Request Execution (Runtime - Nested/Onion Pattern)
┌────────────────────────────────────────────────────────────┐
│ │
│ Request │
│ │ │
│ ▼ │
│ ┌─────────────────────────────────────────────────────┐ │
│ │ Plugin2 (Outermost) │ │
│ │ ┌─────────────────────────────────────────────────┐ │ │
│ │ │ Plugin1 (Middle) │ │ │
│ │ │ ┌─────────────────────────────────────────────┐ │ │ │
│ │ │ │ Original Function (Core) │ │ │ │
│ │ │ │ │ │ │ │
│ │ │ │ async def get_data(): │ │ │ │
│ │ │ │ return {"data": "value"} │ │ │ │
│ │ │ │ │ │ │ │
│ │ │ └─────────────────────────────────────────────┘ │ │ │
│ │ └─────────────────────────────────────────────────┘ │ │
│ └─────────────────────────────────────────────────────┘ │
│ │ │
│ ▼ │
│ Response │
│ │
└────────────────────────────────────────────────────────────┘
Execution Order:
Request → Plugin2 → Plugin1 → get_data() → Plugin1 → Plugin2 → Response
Real Example with Premier Plugins:
@app.sub("/api").get(plugins=[
plugin.timeout(5), # Applied 1st → Executes Outermost
plugin.retry(max_attempts=3), # Applied 2nd → Executes Middle
plugin.cache(expire_s=60), # Applied 3rd → Executes Innermost
])
Flow: Request → timeout → retry → cache → endpoint → cache → retry → timeout → Response
Creating a Custom Plugin
A plugin is anything that implements the
Related Skills
gh-issues
343.3kFetch GitHub issues, spawn sub-agents to implement fixes and open PRs, then monitor and address PR review comments. Usage: /gh-issues [owner/repo] [--label bug] [--limit 5] [--milestone v1.0] [--assignee @me] [--fork user/repo] [--watch] [--interval 5] [--reviews-only] [--cron] [--dry-run] [--model glm-5] [--notify-channel -1002381931352]
node-connect
343.3kDiagnose OpenClaw node connection and pairing failures for Android, iOS, and macOS companion apps
oracle
343.3kBest practices for using the oracle CLI (prompt + file bundling, engines, sessions, and file attachment patterns).
tmux
343.3kRemote-control tmux sessions for interactive CLIs by sending keystrokes and scraping pane output.
