minicorn - A lightweight, production-grade synchronous WSGI server with auto-reload support
Project description
minicorn 🐣🦄🔥
A lightweight, production-grade Python server that speaks both WSGI and ASGI — with full WebSocket support baked in.
minicorn gives you a Uvicorn/Gunicorn-like CLI experience with zero heavyweight dependencies, serving everything from classic Flask apps to modern async FastAPI services over the same port.
Features
| 🐍 WSGI | Full PEP 3333 compliance — Flask, Django, and any WSGI app |
| ⚡ ASGI | Async support for FastAPI, Starlette, and ASGI 3.0 apps |
| 🔌 WebSockets | RFC 6455 compliant WebSocket handling in ASGI mode |
| 🔄 Auto-reload | File-watching hot reload for development |
| 🛠️ Simple CLI | One command to run any app, WSGI or ASGI |
| 📦 Zero Core Deps | Stdlib only — watchdog needed only for --reload |
| 📋 Structured Logging | Colored, leveled log output |
Installation
pip install minicorn
# With dev/reload support
pip install "minicorn[dev]"
Quick Start
WSGI — Flask / Django
# Run a Flask or Django app
minicorn main:app
# Custom host and port
minicorn main:app --host 0.0.0.0 --port 8080
# Hot reload during development
minicorn main:app --reload
ASGI — FastAPI / Starlette
Add --asgi to switch to async mode:
# Run a FastAPI app
minicorn main:app --asgi
# With hot reload
minicorn main:app --asgi --reload
# Custom port
minicorn main:app --asgi --port 8080
WebSockets
WebSocket support is built into ASGI mode — no extra flags needed.
Any endpoint that upgrades to WebSocket (HTTP 101) is handled automatically.
minicorn main:app --asgi
# ws://127.0.0.1:8000/ws is ready to accept connections
Enable keepalive pings to detect dead connections:
minicorn main:app --asgi --ws-ping-interval 20 --ws-ping-timeout 10
Using with Python -m
python -m minicorn main:app --reload
python -m minicorn main:app --asgi --reload
Example Apps
Flask (WSGI)
# main.py
from flask import Flask
app = Flask(__name__)
@app.route("/")
def hello():
return "Hello from minicorn! 🔥"
minicorn main:app --reload
FastAPI (ASGI)
# main.py
from fastapi import FastAPI
app = FastAPI()
@app.get("/")
async def root():
return {"message": "Hello from FastAPI!", "server": "minicorn-asgi"}
minicorn main:app --asgi --reload
WebSocket with FastAPI
# main.py
from fastapi import FastAPI, WebSocket
app = FastAPI()
@app.websocket("/ws")
async def websocket_endpoint(websocket: WebSocket):
await websocket.accept()
while True:
data = await websocket.receive_text()
await websocket.send_text(f"Echo: {data}")
minicorn main:app --asgi
# Connect to ws://127.0.0.1:8000/ws
Programmatic Usage
# WSGI
from minicorn import serve, run
serve("main:app", host="0.0.0.0", port=8080)
# or pass the app object directly
from myapp import app
run(app, host="127.0.0.1", port=8000)
# ASGI
from minicorn import serve_asgi, run_asgi
serve_asgi("main:app", host="0.0.0.0", port=8080)
from myapp import app
run_asgi(app, host="127.0.0.1", port=8000)
CLI Reference
minicorn --help
Auto-Reload
--reload works for both WSGI and ASGI. minicorn watches .py files in your project and restarts the server on changes.
minicorn main:app --reload # WSGI
minicorn main:app --asgi --reload # ASGI
Automatically ignored: __pycache__, .git, venv, .venv, node_modules, dist, build, .mypy_cache, .pytest_cache
Server Capabilities
| Capability | WSGI | ASGI |
|---|---|---|
| HTTP/1.0 & HTTP/1.1 | ✅ | ✅ |
| Keep-Alive connections | ✅ | ✅ |
| Chunked transfer encoding | ✅ | ✅ |
| Streaming responses | ✅ | ✅ |
| WebSocket (RFC 6455) | — | ✅ |
| WebSocket ping/pong | — | ✅ |
| asyncio-based concurrency | — | ✅ |
| Auto-reload | ✅ | ✅ |
Configuration Defaults
| Setting | Default | Description |
|---|---|---|
| Host | 127.0.0.1 |
Bind address |
| Port | 8000 |
Bind port |
| Max Header Size | 64 KB | Reject oversized headers |
| Max Body Size | 1 MB | Reject oversized bodies |
| Recv Timeout | 10s | Timeout waiting for request data |
| Keep-Alive Timeout | 15s | Idle timeout between requests |
| Max Keep-Alive Requests | 100 | Max requests per connection |
| WS Max Message Size | 16 MB | Maximum WebSocket message size |
| WS Ping Interval | disabled | Ping clients every N seconds |
| WS Ping Timeout | disabled | Close if pong not received in N seconds |
License
MIT License
Contributing
Contributions are welcome! Please feel free to submit a Pull Request.
Project details
Release history Release notifications | RSS feed
Download files
Download the file for your platform. If you're not sure which to choose, learn more about installing packages.
Source Distribution
Built Distribution
Filter files by name, interpreter, ABI, and platform.
If you're not sure about the file name format, learn more about wheel file names.
Copy a direct link to the current filters
File details
Details for the file minicorn-1.2.0.tar.gz.
File metadata
- Download URL: minicorn-1.2.0.tar.gz
- Upload date:
- Size: 30.0 kB
- Tags: Source
- Uploaded using Trusted Publishing? No
- Uploaded via: twine/6.2.0 CPython/3.14.0
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
8ebbb0a3a139adb09525f1108412909f6a1393f00dded378512473523ee737f6
|
|
| MD5 |
e2b6304111e0ad9a15ee43c80427e028
|
|
| BLAKE2b-256 |
b64ad49cad20362cd5023279eb065d82a42e64cc957603098befe3afbb6b7880
|
File details
Details for the file minicorn-1.2.0-py3-none-any.whl.
File metadata
- Download URL: minicorn-1.2.0-py3-none-any.whl
- Upload date:
- Size: 30.3 kB
- Tags: Python 3
- Uploaded using Trusted Publishing? No
- Uploaded via: twine/6.2.0 CPython/3.14.0
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
dda8627b8176e9f923641187ee9d15bad353122a46ba82169ff5c3015fbefd18
|
|
| MD5 |
23754e3e46444bb43974d50d2854675d
|
|
| BLAKE2b-256 |
f25e89a389993213c0efef752fb545dfd3d10cb2b84658be5e442beff82c0a31
|