Full-stack Python. Zero runtime dependencies.
Asok is a batteries-included Python web framework built entirely on the standard library. It gives you routing, ORM, templates, admin interface, REST and GraphQL APIs, WebSockets, background tasks, and SSG/ISR — all from a single pip install, with nothing else required at runtime.
Built for developers who want a complete stack without assembling one.
🌐 Documentation · 💬 Discord · 🎥 Tutorials
| Flask | Django | Asok | |
|---|---|---|---|
| Runtime dependencies | ~6 | ~20+ transitive | 0 |
| ORM built-in | ✗ | ✓ | ✓ |
| Admin interface | ✗ | ✓ | ✓ |
| File-based routing | ✗ | ✗ | ✓ |
| GraphQL built-in | ✗ | ✗ | ✓ |
| WebSockets built-in | ✗ | ✗ | ✓ |
| Reactive components | ✗ | ✗ | ✓ |
| SSG / ISR | ✗ | ✗ | ✓ |
| Auto OpenAPI docs | ✗ | ✗ | ✓ |
| Background tasks | ✗ | ✗ | ✓ |
Choose Asok when you want a full stack out of the box, dependency auditability matters (security-critical environments, embedded deployments, strict supply chain policies), or you're a solo developer or small team who doesn't want to assemble and maintain a stack of integrations.
# wsgi.py
from asok import Asok, Field, Model, Admin
app = Asok(__name__)
class Post(Model):
title = Field.String(nullable=False)
body = Field.Text()
author = Field.String()
admin = Admin(app)# src/pages/page.py
from asok import Request
from src.models.post import Post
def render(request: Request):
posts = Post.query().order_by("-id").limit(10).get()
return request.render("page.html", posts=posts)That's a working app with database, admin interface, and a paginated index page. Run it:
pip install asok
asok create my-blog && cd my-blog
asok migrate
asok devAsok provides two built-in options for building interactive frontends, both operating on Zero-Eval Security (strict CSP compliance, no 'unsafe-eval' required).
Create reactive, server-side components that synchronize state automatically over WebSockets using the @exposed decorator.
# src/components/counter.py
from asok import Component
from asok.component import exposed
class Counter(Component):
"""Reusable UI component for Counter."""
count = 0
@exposed
def increment(self):
self.count += 1
def render(self):
return self.html("counter.html")<!-- src/components/counter.html -->
<div>
<h3>Count: {{ count }}</h3>
<button ws-click="increment">Add 1</button>
</div><!-- In any page template (e.g., src/pages/page.html) -->
{{ component('Counter', count=10) }}For offline or local state updates, use native lightweight reactive directives directly in your HTML markup (~5KB client runtime, zero build step):
<div asok-state="{ count: 0 }">
<h3>Count: <span asok-text="count"></span></h3>
<button asok-on:click="count++">Add 1</button>
</div>- File-based routing —
src/pages/blog/[slug]/page.pymaps to/blog/hello-world - Dynamic parameters —
[id],[slug:slug], catch-all patterns - Template engine — Jinja-compatible with inheritance, macros, and auto-escaping
- HTML streaming — chunked responses for instant TTFB
- Multi-database — SQLite (default), PostgreSQL, MySQL with connection pooling
- Relations — HasMany, BelongsTo, BelongsToMany, MorphTo, self-referencing
- Migrations — automatic schema diffing, rollback, multi-DB
- Security — parameterized queries, column whitelisting, mass-assignment protection, encrypted fields (Fernet AES-256)
- Password fields — PBKDF2-SHA256 with 600,000 iterations
- REST — decorator-based routes with automatic OpenAPI 3.0 generation and live Swagger UI
- GraphQL — schema auto-generated from ORM models, playground in development, WS subscriptions
- API versioning — URL-based and header-based, deprecation sunset headers
- Bearer token auth — HMAC-signed, configurable expiry
- WebSockets — rooms, presence tracking, typing indicators, direct messages
- Live components — server-driven reactive UI over WebSockets
- Client reactivity —
asok-state,asok-on:click,asok-textdirectives (~3KB, no build step)
- Auto-generated CRUD for every model
- Role-based access control (RBAC)
- Two-factor authentication (TOTP + backup codes)
- Audit logs, inline editing, advanced filters
- Fully customizable templates
- WSGI + ASGI — run on Gunicorn or Uvicorn
- Background tasks — thread pool (local) or Redis queue (
asok worker) with HMAC-signed job envelopes - Caching — in-memory, Redis, fragment caching
- Sessions — HMAC-signed, Redis-backed, HttpOnly + SameSite=Strict
- Static site generation — SSG for static routes, ISR with background cache warming
- Islands architecture — selective hydration for performance-critical pages
- Email — SMTP with templates, async dispatch via Redis
- S3 storage — AWS S3 integration with automatic mime-type detection
- CSRF protection with auto-rotation and HMAC validation
- Content Security Policy with per-request nonces
- HSTS, X-Frame-Options, X-Content-Type-Options, Permissions-Policy
- HTML and SVG sanitizer (two-pass whitelist)
- Path traversal prevention on file uploads
- SQL injection protection (parameterized queries + identifier validation)
- Rate limiting (per-IP, per-user, configurable windows)
- GraphQL mutations blocked by default without
GRAPHQL_AUTHORIZE
- CLI —
asok create,asok dev,asok migrate,asok make model,asok build - Production build — bytecode compilation, JS/CSS minification, WebP conversion
- Testing — built-in test client,
TestClient, fixture helpers - Developer toolbar — request inspector, query analyzer, cache stats in-browser
- i18n —
{{ __('key') }}with JSON locale files, translation management UI - Extensions — community plugin system with secure path sandboxing
- VSCode extension — syntax highlighting, IntelliSense, route navigation
pip install asokAsok has zero runtime dependencies. SQLite works out of the box. Add extras only if you need them:
pip install "asok[postgres]" # PostgreSQL
pip install "asok[mysql]" # MySQL
pip install "asok[redis]" # Redis (caching, sessions, background tasks)
pip install "asok[async]" # ASGI / async support
pip install "asok[postgres,redis]" # Combinedasok create my-project
cd my-project
asok devOpen http://localhost:8000. Edit src/pages/page.html to start.
my-project/
├── src/
│ ├── components/ # Reactive components
│ ├── locales/ # Translations (en.json, fr.json, ...)
│ ├── middlewares/ # Request interceptors
│ ├── models/ # ORM models
│ ├── pages/ # Routes (page.py + page.html)
│ └── partials/ # css, js, images, uploads
└── wsgi.py # Entry point
# WSGI
gunicorn wsgi:app
# ASGI
uvicorn asgi:appRequired environment variables:
DEBUG=false
SECRET_KEY=your-64-character-key # generate: python -c "import secrets; print(secrets.token_hex(32))"
APP_URL=https://yourdomain.com
DATABASE_URL=sqlite:///data/prod.dbGenerate a deployment config:
asok deploy # outputs Gunicorn + Nginx + SystemD configs
asok build # optimized production build (bytecode + minification)| Version | Status | Focus |
|---|---|---|
| v0.4.0 | ✅ Released (June 2026) | GraphQL, extensions, SSG/ISR, advanced WebSockets |
| v0.5.0 | ✅ Released (June 2026) | Security hardening, GraphQL auth, signed Redis jobs, offline GraphiQL |
| v1.0.0 | 📋 Q3 2026 | Stable API, monitoring, multi-tenancy, CDN pipeline |
Full details in ROADMAP.md.
git clone https://github.com/asok-framework/asok.git
cd asok
python -m venv venv && source venv/bin/activate
pip install -e .
python -m pytestMIT — see LICENSE.