This release is a pre-release and may not be stable for production use.
axion - Lightweight & Fast Python Web Framework
Overview
axion is a lightweight, modular, and fast web framework implemented in Python using native sockets. Designed for both simplicity and performance, axion provides a modern approach to building web applications, supporting both Server-Side Rendering (SSR) with Jinja2 and Asynchronous API development with Pydantic.
Whether you're building a simple static site or a complex data-driven API, axion gives you the tools you need without the bloat of larger frameworks.
Features
🚀 Core Capabilities
- Native Socket Implementation: Built from the ground up using Python's
socketmodule for maximum control and minimal overhead. - High Concurrency: Multi-threaded request handling over a high-backlog TCP server (64 worker threads, backlog 128).
- Advanced Routing: Regex-based path matching with type-safe parameter extraction (e.g.,
/user/<int:id>). - Async Route Handlers: FastAPI-style
async defhandlers with a dedicated event loop per request. - Static File Serving: Built-in support for serving CSS, JS, images, and other assets with security-first path resolution.
🛡️ Security & Modern Web
- CSRF Protection: Built-in Cross-Site Request Forgery protection for all non-idempotent methods (POST, PUT, DELETE, PATCH).
- CORS Support: Configurable Cross-Origin Resource Sharing for API security.
- Pydantic Integration: Seamless data validation and serialization. Simply type-hint a Pydantic model in your handler, and axion handles the rest.
- Graceful Termination: Full support for system signals (
SIGINT,SIGTERM) to ensure no connections or resources are leaked on shutdown.
🛠️ Developer Experience
- Scaffold CLI: Generate a complete project structure in seconds with
axion startproject. - Hot Reloading: Automatic server restarts during development when code changes are detected.
- Modular Architecture: Decoupled App, Router, and Server components allow for highly portable and testable code.
- UI Component System: A hierarchical Python UI system (similar to Flutter or JSX) for building frontend structures directly in Python code.
Installation
You can install axion using pip:
pip install axion-framework
Database/ORM support is an optional extra; install it when you plan to use
app.use_database():
pip install "axion-framework[db]"
For development, clone the repository and install dependencies:
git clone https://github.com/sachin-acharya-projects/axion.git
cd axion
make dev-install
Documentation
The full user guide lives in docs/. It starts with an
overview and a table of contents, then covers each topic in its own page:
| Topic | What you'll learn |
|---|---|
| Getting Started | Install, scaffold, first routes |
| Routing | Path parameters, methods, error handlers, routers |
| Request & Response | The request/response API, JSON, headers, cookies |
| Middleware | Callable and hook-object middleware, scoping |
| Database & ORM | Models, sessions, transactions, injection |
| Serializers | DRF-style input/output serialization |
| Templates & Static Files | Jinja2 rendering, static assets |
| Security | CSRF and CORS |
| Configuration | Every setting and how to override it |
| Command-Line Interface | startproject, run, hot reload |
A complete worked example is in example/.
Quick Start
1. Create a Project
Use the CLI to generate a new project:
axion startproject my_app
cd my_app
2. Define Your Application
Edit main.py:
from axion import WebServer
from axion.http import Response
from pydantic import BaseModel
app = WebServer(debug=True)
class User(BaseModel):
name: str
age: int
# SSR Route
@app.route("/")
def index(response: Response):
response.render("index.html", title="Welcome to axion")
# API Route with Pydantic validation
@app.route("/api/user", methods=["POST"])
def create_user(user: User, response: Response):
return response.json({"message": f"Hello {user.name}", "received": user.model_dump()})
if __name__ == "__main__":
app.run()
3. Run with Hot Reload
axion run main.py --reload
Middleware
Middleware runs in registration order around your routes. Two styles are supported and can be mixed freely.
Callable middleware
A plain function taking (request, response, call_next). Do work before and
after call_next():
@app.use()
def timing(request, response, call_next):
start = time.monotonic()
call_next()
print(f"{request.path} took {time.monotonic() - start:.3f}s")
Hook middleware
Subclass BaseMiddleware and override before_request / after_request.
Returning early with a response from before_request short-circuits the
request:
from axion.middleware import BaseMiddleware
class AuthMiddleware(BaseMiddleware):
def before_request(self, request, response):
if not request.headers.get("authorization"):
response.send("Unauthorized", 401) # skips the route
app.use(AuthMiddleware())
Scoping
- Global —
app.use(mw)runs for every request. - Path-scoped —
app.use("/api", mw)runs for/apiand/api/...(prefix matching, so/apixis excluded). - Per-route —
@app.route("/users", middleware=[mw])runs only for that route. - Methods —
app.use(mw, methods=["POST"])restricts a middleware to specific HTTP methods. Hook objects may declaremethodson the class.
app.use("/api", auth_middleware, methods=["POST", "PUT", "DELETE"])
Database & ORM
axion ships out-of-the-box SQLAlchemy support through the axion[db] extra.
You never touch the engine or session factory; a request-scoped session is
managed for you and committed (or rolled back) automatically.
Define models
from sqlalchemy import String
from sqlalchemy.orm import Mapped, mapped_column
from axion.db.models import Model
class User(Model):
__tablename__ = "users"
id: Mapped[int] = mapped_column(primary_key=True)
name: Mapped[str] = mapped_column(String(100))
Enable the database
from axion import WebServer
app = WebServer(debug=True)
app.use_database() # uses DATABASE_URL (default: sqlite:///db.sqlite3)
Tables are created automatically (AUTO_CREATE_TABLES). Set DATABASE_URL
in config/settings.py to use another database, e.g.
DATABASE_URL = "postgresql+psycopg://user:pass@localhost/db".
Use the session
Handlers can request a Session directly — it is injected from the
request-scoped session and committed/rolled back at the end of the request:
from sqlalchemy.orm import Session
@app.route("/users", methods=["POST"])
def create_user(user: UserCreate, session: Session, response: Response):
session.add(User(**user.model_dump()))
response.json({"ok": True}, 201)
Configuration
axion uses a settings.py file (typically in a config/ directory) for centralized configuration:
import os
from pathlib import Path
BASE_DIR = Path(__file__).resolve().parent.parent
# Server
HOST = "127.0.0.1"
PORT = 5500
DEBUG = True
# Security
CORS_ALLOWED_ORIGINS = ["*"]
CSRF_COOKIE_NAME = "axion_csrf"
# Directories
TEMPLATE_DIRS = "views"
STATIC_DIRS = ["static"]
Project Structure
A typical axion project looks like this:
.
├── config/
│ └── settings.py
├── static/
│ ├── css/
│ ├── js/
│ └── imgs/
├── views/
│ └── index.html
├── main.py
└── .env
Development
Use the included Makefile for common development tasks:
make install: Install the package.make dev-install: Install with development dependencies.make lint: Run Ruff for linting.make format: Run Ruff for formatting.make build: Build the distribution packages.make publish: Build and publish to PyPI.
License
This project is licensed under the MIT License. See the LICENSE file for details.
Contact
For inquiries or support:
- Email: sachin.acharya@axion.com
- GitHub: sachin-acharya-projects
Metadata
Release files for axion-framework 0.1.0a3
For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.
Source distribution (sdist)
| File | Size | Uploaded | |
|---|---|---|---|
| axion_framework-0.1.0a3.tar.gz | 65.1 kB | Details |
Built distribution (wheel)
| File | Interpreter | ABI | Platform | Reset |
|---|---|---|---|---|
| axion_framework-0.1.0a3-py3-none-any.whl | Python 3 | none | any | Details |
Total release size: 131.1 kB
Release files / axion_framework-0.1.0a3.tar.gz
| Download URL | axion_framework-0.1.0a3.tar.gz |
|---|---|
| Size | 65.1 kB |
| Tags | Source |
|
SHA-256 checksum How to use checksums |
d78f0c86bf553f0b2daa52fc2b3f78e3357b86a31029c216476873ef526da8e7
|
|
BLAKE2b-256 checksum How to use checksums |
00d8c8abff19c81b58b1a57f306241c10aaee1c860cd2d7afb63146999197471
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
Yes |
| Uploaded via |
twine/7.0.0 CPython/3.13.14
|
Provenance
Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.
PyPI Publish Attestation
PyPI verified that this artifact, at this checksum, originated from the publisher listed below.
Signed by GitHub Actions, verified by PyPI on Aug 20, 2026.
Transparency logRelease files / axion_framework-0.1.0a3-py3-none-any.whl
| Download URL | axion_framework-0.1.0a3-py3-none-any.whl |
|---|---|
| Size | 66.0 kB |
| Tags | Python 3 |
|
SHA-256 checksum How to use checksums |
1388c3862c30bb3b18df1d9cdfda9437959f78a760cbbdfd38d8c5d781bea6a9
|
|
BLAKE2b-256 checksum How to use checksums |
87cc19d7dfce48bacf41303abde8a4478f1bdf3ab2932abe4613e2b999d0bc0e
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
Yes |
| Uploaded via |
twine/7.0.0 CPython/3.13.14
|
Provenance
Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.
PyPI Publish Attestation
PyPI verified that this artifact, at this checksum, originated from the publisher listed below.
Signed by GitHub Actions, verified by PyPI on Aug 20, 2026.
Transparency log