System Overview
Snek follows a layered architecture pattern with clear separation of concerns. The system is built on Python's aiohttp framework for asynchronous HTTP and WebSocket handling.
Backend Architecture
aiohttp Framework
The backend is built on aiohttp, a high-performance asynchronous HTTP client/server framework. Key features:
- Fully asynchronous request handling with async/await
- Native WebSocket support for real-time communication
- Session management via aiohttp-session
- Static file serving and template rendering
Service Layer Pattern
Services encapsulate business logic and are accessed via a singleton registry:
user = await app.services.user.get(uid=user_uid) channel = await app.services.channel.create(label="#general")
Available services include: user, channel, channel_member, channel_message, chat, socket, container, db, and more.
Mapper Pattern
Mappers provide data access abstraction with consistent CRUD operations:
await mapper.get(uid=uid) await mapper.find(field=value) await mapper.save(model) async for record in mapper.query(sql, params): ...
All mappers support soft delete via the deleted_at field.
Caching Strategy
The service layer implements UID-based caching for frequently accessed data. Cache invalidation occurs on model updates.
Frontend Architecture
Vanilla JavaScript Philosophy
The frontend uses pure ES6 JavaScript modules without any frameworks. This ensures:
- Minimal bundle size and fast load times
- No framework upgrade cycles or breaking changes
- Direct DOM manipulation for maximum performance
- Easy debugging without transpilation
Module Structure
src/snek/static/ app.js # Main Application class (singleton) socket.js # WebSocket RPC client chat-window.js # Chat interface component message-list.js # Message rendering chat-input.js # Input handling ...
Custom Elements
UI components are implemented as Custom Elements:
<chat-window></chat-window> <message-list></message-list> <channel-menu></channel-menu> <nav-menu></nav-menu>
Each component has its own CSS file (no Shadow DOM per project guidelines).
Database Design
Dataset ORM
Snek uses Dataset, a simple database abstraction layer built on SQLAlchemy. It provides:
- Automatic table creation and schema inference
- Dictionary-based record access
- Transaction support
- Raw SQL query execution when needed
Core Tables
user # User accounts channel # Chat channels channel_member # Channel membership channel_message# Chat messages session # User sessions ...
Soft Delete Pattern
Records are never physically deleted. Instead, the deleted_at timestamp is set. All queries filter by deleted_at IS NULL by default.
Real-time Communication
WebSocket RPC System
Real-time features use a JSON-RPC style protocol over WebSocket:
{
"callId": "1",
"method": "send_message",
"args": ["channel_uid", "Hello world", true]
}
The server responds with:
{
"callId": "1",
"success": true,
"data": "message_uid"
}
Event Broadcasting
Server-initiated events are broadcast to channel subscribers:
{
"channel_uid": "...",
"event": "new_message",
"data": { ... }
}
Channel Subscription Model
Users automatically subscribe to all their channels on WebSocket connection. The socket service manages subscriptions and delivers messages to the appropriate clients.
Directory Structure
src/snek/
__main__.py # CLI entry point
app.py # Application setup and routing
view/ # HTTP/WebSocket handlers
index.py # Landing page
rpc.py # WebSocket RPC
settings/ # Settings views
service/ # Business logic layer
mapper/ # Data persistence
model/ # Data models
form/ # Form definitions
system/ # Core infrastructure
view.py # BaseView class
service.py # BaseService class
mapper.py # BaseMapper class
model.py # BaseModel class
static/ # Frontend JavaScript and CSS
templates/ # Jinja2 templates