Skip to content

Commit b799e49

Browse files
committed
docs: add Reddit post for chanx WebSocket package
1 parent 9a7758d commit b799e49

File tree

1 file changed

+183
-0
lines changed

1 file changed

+183
-0
lines changed

reddit_post.md

Lines changed: 183 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,183 @@
1+
# Chanx: Stop fighting WebSocket boilerplate in FastAPI (and Django)
2+
3+
After years of building WebSocket apps, I got tired of the same pain points: endless if-else chains, manual validation, missing type safety, and zero documentation. So I built **Chanx** - a batteries-included WebSocket framework that makes FastAPI (and Django Channels) WebSocket development actually enjoyable.
4+
5+
## The Problem
6+
7+
**Without Chanx**, your FastAPI WebSocket code probably looks like this:
8+
9+
```python
10+
@app.websocket("/ws")
11+
async def websocket_endpoint(websocket: WebSocket):
12+
await websocket.accept()
13+
while True:
14+
data = await websocket.receive_json()
15+
action = data.get("action")
16+
17+
if action == "chat":
18+
if "message" not in data.get("payload", {}):
19+
await websocket.send_json({"error": "Missing message"})
20+
continue
21+
# No broadcasting, must manually track connections
22+
# No type safety, no validation, no documentation
23+
elif action == "ping":
24+
await websocket.send_json({"action": "pong"})
25+
# ... more manual handling
26+
```
27+
28+
You're stuck with:
29+
- Manual if-else routing hell
30+
- Hand-written validation code
31+
- No type safety (runtime surprises!)
32+
- Zero API documentation
33+
- No broadcasting/groups out of the box
34+
- Painful testing setup
35+
36+
## The Solution
37+
38+
**With Chanx**, the same code becomes:
39+
40+
```python
41+
@channel(name="chat", description="Real-time chat API")
42+
class ChatConsumer(AsyncJsonWebsocketConsumer):
43+
groups = ["chat_room"] # Auto-join on connect
44+
45+
@ws_handler(
46+
summary="Handle chat messages",
47+
output_type=ChatNotificationMessage
48+
)
49+
async def handle_chat(self, message: ChatMessage) -> None:
50+
# Automatically routed, validated, and type-safe
51+
await self.broadcast_message(
52+
ChatNotificationMessage(
53+
payload=ChatPayload(message=f"User: {message.payload.message}")
54+
)
55+
)
56+
57+
@ws_handler
58+
async def handle_ping(self, message: PingMessage) -> PongMessage:
59+
return PongMessage() # Auto-documented in AsyncAPI
60+
```
61+
62+
## What You Get
63+
64+
### **Performance & Structure**
65+
- **Automatic routing** via Pydantic discriminated unions (no if-else chains!)
66+
- **Type-safe broadcasting** with channel layer integration
67+
- **Async/await** throughout for maximum performance
68+
- **Zero overhead** - decorators compile to efficient handlers
69+
70+
### **Offload the Boring Stuff**
71+
- **Auto-validation** with Pydantic models
72+
- **AsyncAPI 3.0 docs** generated automatically (like Swagger for WebSockets!)
73+
- **Type-safe client generator** - generates Python clients from your API
74+
- **Built-in testing utilities** for both FastAPI and Django
75+
76+
### **Consistency & Type Safety**
77+
- **mypy/pyright compatible** - catch errors at dev time, not runtime
78+
- **Single codebase** works with both FastAPI and Django Channels
79+
- **Enforced patterns** via decorators (no more inconsistent implementations)
80+
- **Structured logging** with automatic request/response tracing
81+
82+
### **Developer Experience**
83+
- **Self-documenting code** - AsyncAPI spec is the single source of truth
84+
- **Clean code reviews** - declarative handlers instead of nested logic
85+
- **Fast onboarding** - newcomers read the AsyncAPI docs and they're good to go
86+
- **Framework agnostic** - switch between Django/FastAPI with zero refactoring
87+
88+
## Real-World Impact
89+
90+
What Chanx eliminates in your daily workflow:
91+
92+
**Technical Pain:**
93+
- Writing manual routing logic
94+
- Hand-crafting validation code
95+
- Debugging runtime type errors
96+
- Writing API documentation
97+
- Setting up WebSocket test infrastructure
98+
99+
**Team Collaboration:**
100+
- Inconsistent WebSocket implementations across the team
101+
- Painful code reviews of nested if-else chains
102+
- Slow onboarding (no API contract for frontend teams)
103+
- Debugging hell with unstructured logs
104+
105+
## Quick Example
106+
107+
**1. Define typed messages:**
108+
```python
109+
class ChatMessage(BaseMessage):
110+
action: Literal["chat"] = "chat"
111+
payload: ChatPayload
112+
113+
class ChatNotificationMessage(BaseMessage):
114+
action: Literal["chat_notification"] = "chat_notification"
115+
payload: ChatPayload
116+
```
117+
118+
**2. Create consumer:**
119+
```python
120+
@channel(name="chat")
121+
class ChatConsumer(AsyncJsonWebsocketConsumer):
122+
groups = ["chat_room"]
123+
124+
@ws_handler(output_type=ChatNotificationMessage)
125+
async def handle_chat(self, message: ChatMessage) -> None:
126+
await self.broadcast_message(
127+
ChatNotificationMessage(payload=message.payload)
128+
)
129+
```
130+
131+
**3. Setup routing (FastAPI):**
132+
```python
133+
app = FastAPI()
134+
ws_router = FastAPI()
135+
ws_router.add_websocket_route("/chat", ChatConsumer.as_asgi())
136+
app.mount("/ws", ws_router)
137+
```
138+
139+
**4. Visit `/asyncapi/` for interactive documentation**
140+
141+
## Advanced Features
142+
143+
- **Built-in auth** with DRF permission support (+ extensible for custom flows)
144+
- **Testing utilities** - framework-specific WebSocket communicators
145+
- **Structured logging** with automatic tracing
146+
- **Flexible config** - Django settings or class-level attributes
147+
- **Client generator CLI** - `chanx generate-client --schema http://localhost:8000/asyncapi.json`
148+
149+
## Installation
150+
151+
```bash
152+
# For FastAPI
153+
pip install "chanx[fast_channels]"
154+
155+
# For Django Channels
156+
pip install "chanx[channels]"
157+
158+
# For client generator
159+
pip install "chanx[cli]"
160+
```
161+
162+
## Why I Built This
163+
164+
I spent years building real-time features for production apps, and every project had the same problems:
165+
- Junior devs writing fragile if-else chains
166+
- No one documenting the WebSocket API
167+
- Frontend teams guessing message formats
168+
- Tests breaking on every refactor
169+
170+
Chanx solves all of this by providing **proven patterns** that help teams ship faster, maintain cleaner code, and actually enjoy working with WebSockets.
171+
172+
---
173+
174+
**Links:**
175+
- PyPI: https://pypi.org/project/chanx/
176+
- Docs: https://chanx.readthedocs.io/
177+
- GitHub: https://github.com/huynguyengl99/chanx
178+
179+
Built for the FastAPI and Django communities. Open to feedback and contributions!
180+
181+
---
182+
183+
*Works with Python 3.11+, FastAPI, and Django Channels. Full type safety with mypy/pyright. 100% test coverage.*

0 commit comments

Comments
 (0)