| Name | dbbasic-web JSON |
| Version |
0.1.7
JSON |
| download |
| home_page | None |
| Summary | Unixy micro-framework: file routing, SSE/WS, jobs, bus, flat files. |
| upload_time | 2025-10-13 11:11:18 |
| maintainer | None |
| docs_url | None |
| author | None |
| requires_python | >=3.10 |
| license | MIT |
| keywords |
web
framework
cgi
unix
tsv
async
asgi
|
| VCS |
 |
| bugtrack_url |
|
| requirements |
No requirements were recorded.
|
| Travis-CI |
No Travis.
|
| coveralls test coverage |
No coveralls.
|
# dbbasic-web
A Unix-philosophy micro-framework that restores the simplicity of CGI while delivering modern performance (~4000 req/s vs 100 req/s for traditional CGI).
## Philosophy
Modern web frameworks moved away from Unix principles and lost key capabilities:
- ❌ Message passing → bolted-on queue systems
- ❌ Cron jobs → separate background job libraries
- ❌ Filesystem routing → giant route tables
- ❌ Flat files → everything forced into SQL
- ❌ Streams → poor SSE/WebSocket support
**dbbasic-web restores these capabilities** using:
- ✅ Filesystem routing (like CGI, but async)
- ✅ TSV-based storage, queues, and streams (no Redis/SQL required)
- ✅ First-class WebSockets and Server-Sent Events
- ✅ Background jobs with dbbasic-queue
- ✅ Message bus with dbbasic-pipe
- ✅ Flat files alongside databases
## Features
### 1. Filesystem Routing
No route tables. No decorators. Just files:
```
api/hello.py → handles /hello
api/user.py → handles /user, /user/123, /user/123/posts
templates/about.html → renders /about
public/css/app.css → serves /css/app.css
```
### 2. Hierarchical API Handlers
Each handler can manage its own sub-routes:
```python
# api/user.py
def handle(request):
path_parts = request['path_parts'] # ['user', '123', 'edit']
if len(path_parts) == 1:
return list_users()
elif len(path_parts) == 2:
return get_user(path_parts[1])
elif len(path_parts) == 3:
return edit_user(path_parts[1], path_parts[2])
```
### 3. TSV-Based Storage (No SQL Required)
```python
from dbbasic_web.storage import write_text, read_text
# Flat files with automatic directory creation
write_text("notes/2024-01-15.txt", "Meeting notes...")
content = read_text("notes/2024-01-15.txt")
```
### 4. Background Jobs (No Celery/Redis)
```python
from dbbasic_web.jobs import enqueue
# Jobs stored in TSV files
enqueue("write_flatfile", relpath="exports/data.csv", content=csv_data)
```
Run worker:
```bash
python manage.py worker
```
### 5. Message Bus (No Kafka/Redis)
```python
from dbbasic_web.bus import EventBus
bus = EventBus()
await bus.publish("notifications", {"user_id": 123, "event": "login"})
async for message in bus.consume("notifications", group="processors", consumer="worker-1"):
print(message['data'])
```
### 6. WebSockets & Server-Sent Events
Built-in, no configuration needed:
**WebSocket:**
```javascript
const ws = new WebSocket('ws://localhost:8000/ws/room-name');
ws.send(JSON.stringify({message: 'Hello!'}));
```
**SSE:**
```javascript
const events = new EventSource('/sse/counter');
events.addEventListener('tick', (e) => console.log(e.data));
```
## Quick Start
### Installation
```bash
pip install dbbasic-web
```
Or install from source:
```bash
git clone https://github.com/askrobots/dbbasic-web.git
cd dbbasic-web
pip install -e .
```
### Run the Server
```bash
python manage.py serve
```
Visit: http://localhost:8000
### Project Structure
```
dbbasic-web/
├── dbbasic_web/
│ ├── api/ # API handlers (filesystem routing)
│ │ ├── hello.py # /hello
│ │ └── user.py # /user, /user/*, /user/*/posts
│ ├── templates/ # Jinja2 templates
│ │ ├── base.html
│ │ └── index.html
│ ├── public/ # Static files
│ │ ├── css/app.css
│ │ └── js/app.js
│ ├── asgi.py # ASGI application
│ ├── router.py # Filesystem router
│ ├── jobs.py # Background jobs
│ ├── bus.py # Message bus
│ ├── storage.py # Flat-file storage
│ ├── websocket.py # WebSocket hub
│ └── sse.py # Server-Sent Events
├── _data/ # Auto-created data directory
│ ├── jobs.tsv # Job queue
│ └── streams/ # Message bus streams
├── manage.py # CLI
└── pyproject.toml
```
## Creating API Endpoints
### Simple Endpoint
```python
# api/status.py
import json
from dbbasic_web.responses import json as json_response
def handle(request):
return json_response(json.dumps({"status": "ok"}))
```
Access: `GET /status`
### REST Resource with Sub-Routes
```python
# api/posts.py
def handle(request):
parts = request['path_parts']
method = request['method']
# /posts
if len(parts) == 1:
if method == 'GET':
return list_posts()
elif method == 'POST':
return create_post(request)
# /posts/123
elif len(parts) == 2:
post_id = parts[1]
if method == 'GET':
return get_post(post_id)
elif method == 'PUT':
return update_post(post_id, request)
# /posts/123/comments
elif len(parts) == 3 and parts[2] == 'comments':
return get_comments(parts[1])
```
## Performance
| Implementation | Requests/sec |
|---------------|--------------|
| Traditional CGI | ~100 |
| dbbasic-web | ~4000 |
Achieved by combining:
- Async I/O (ASGI/uvicorn)
- Filesystem routing (no regex matching)
- Direct module imports (no middleware chains)
- TSV files instead of database round-trips
## Dependencies
Minimal and purposeful:
- `uvicorn` - ASGI server
- `jinja2` - Templates
- `dbbasic-tsv` - TSV database
- `dbbasic-queue` - Job queue
- `dbbasic-pipe` - Message streams
- `dbbasic-sessions` - Authentication
- `websockets` - WebSocket support
**No Redis. No Celery. No PostgreSQL required.**
## Commands
```bash
# Run development server
python manage.py serve
# Run background job worker
python manage.py worker
# Interactive shell
python manage.py shell
```
## Philosophy in Action
This framework proves that:
1. **Simplicity scales** - Filesystem routing is faster than route tables
2. **Flat files work** - TSV beats Redis for many use cases
3. **Unix was right** - Pipes, files, and processes are enough
4. **Less is more** - 8000 lines total vs 200k+ for Django
## License
MIT
## Contributing
Built for clarity and hackability. Every module is under 500 lines. Read the source.
Raw data
{
"_id": null,
"home_page": null,
"name": "dbbasic-web",
"maintainer": null,
"docs_url": null,
"requires_python": ">=3.10",
"maintainer_email": null,
"keywords": "web, framework, cgi, unix, tsv, async, asgi",
"author": null,
"author_email": "DBBasic Team <hello@dbbasic.com>",
"download_url": "https://files.pythonhosted.org/packages/57/39/02d1c523db68b77a6b4ef0cbe3c0b681283d861f659488424b4877ee9da3/dbbasic_web-0.1.7.tar.gz",
"platform": null,
"description": "# dbbasic-web\n\nA Unix-philosophy micro-framework that restores the simplicity of CGI while delivering modern performance (~4000 req/s vs 100 req/s for traditional CGI).\n\n## Philosophy\n\nModern web frameworks moved away from Unix principles and lost key capabilities:\n- \u274c Message passing \u2192 bolted-on queue systems\n- \u274c Cron jobs \u2192 separate background job libraries\n- \u274c Filesystem routing \u2192 giant route tables\n- \u274c Flat files \u2192 everything forced into SQL\n- \u274c Streams \u2192 poor SSE/WebSocket support\n\n**dbbasic-web restores these capabilities** using:\n- \u2705 Filesystem routing (like CGI, but async)\n- \u2705 TSV-based storage, queues, and streams (no Redis/SQL required)\n- \u2705 First-class WebSockets and Server-Sent Events\n- \u2705 Background jobs with dbbasic-queue\n- \u2705 Message bus with dbbasic-pipe\n- \u2705 Flat files alongside databases\n\n## Features\n\n### 1. Filesystem Routing\nNo route tables. No decorators. Just files:\n\n```\napi/hello.py \u2192 handles /hello\napi/user.py \u2192 handles /user, /user/123, /user/123/posts\ntemplates/about.html \u2192 renders /about\npublic/css/app.css \u2192 serves /css/app.css\n```\n\n### 2. Hierarchical API Handlers\nEach handler can manage its own sub-routes:\n\n```python\n# api/user.py\ndef handle(request):\n path_parts = request['path_parts'] # ['user', '123', 'edit']\n\n if len(path_parts) == 1:\n return list_users()\n elif len(path_parts) == 2:\n return get_user(path_parts[1])\n elif len(path_parts) == 3:\n return edit_user(path_parts[1], path_parts[2])\n```\n\n### 3. TSV-Based Storage (No SQL Required)\n```python\nfrom dbbasic_web.storage import write_text, read_text\n\n# Flat files with automatic directory creation\nwrite_text(\"notes/2024-01-15.txt\", \"Meeting notes...\")\ncontent = read_text(\"notes/2024-01-15.txt\")\n```\n\n### 4. Background Jobs (No Celery/Redis)\n```python\nfrom dbbasic_web.jobs import enqueue\n\n# Jobs stored in TSV files\nenqueue(\"write_flatfile\", relpath=\"exports/data.csv\", content=csv_data)\n```\n\nRun worker:\n```bash\npython manage.py worker\n```\n\n### 5. Message Bus (No Kafka/Redis)\n```python\nfrom dbbasic_web.bus import EventBus\n\nbus = EventBus()\nawait bus.publish(\"notifications\", {\"user_id\": 123, \"event\": \"login\"})\n\nasync for message in bus.consume(\"notifications\", group=\"processors\", consumer=\"worker-1\"):\n print(message['data'])\n```\n\n### 6. WebSockets & Server-Sent Events\nBuilt-in, no configuration needed:\n\n**WebSocket:**\n```javascript\nconst ws = new WebSocket('ws://localhost:8000/ws/room-name');\nws.send(JSON.stringify({message: 'Hello!'}));\n```\n\n**SSE:**\n```javascript\nconst events = new EventSource('/sse/counter');\nevents.addEventListener('tick', (e) => console.log(e.data));\n```\n\n## Quick Start\n\n### Installation\n\n```bash\npip install dbbasic-web\n```\n\nOr install from source:\n```bash\ngit clone https://github.com/askrobots/dbbasic-web.git\ncd dbbasic-web\npip install -e .\n```\n\n### Run the Server\n\n```bash\npython manage.py serve\n```\n\nVisit: http://localhost:8000\n\n### Project Structure\n\n```\ndbbasic-web/\n\u251c\u2500\u2500 dbbasic_web/\n\u2502 \u251c\u2500\u2500 api/ # API handlers (filesystem routing)\n\u2502 \u2502 \u251c\u2500\u2500 hello.py # /hello\n\u2502 \u2502 \u2514\u2500\u2500 user.py # /user, /user/*, /user/*/posts\n\u2502 \u251c\u2500\u2500 templates/ # Jinja2 templates\n\u2502 \u2502 \u251c\u2500\u2500 base.html\n\u2502 \u2502 \u2514\u2500\u2500 index.html\n\u2502 \u251c\u2500\u2500 public/ # Static files\n\u2502 \u2502 \u251c\u2500\u2500 css/app.css\n\u2502 \u2502 \u2514\u2500\u2500 js/app.js\n\u2502 \u251c\u2500\u2500 asgi.py # ASGI application\n\u2502 \u251c\u2500\u2500 router.py # Filesystem router\n\u2502 \u251c\u2500\u2500 jobs.py # Background jobs\n\u2502 \u251c\u2500\u2500 bus.py # Message bus\n\u2502 \u251c\u2500\u2500 storage.py # Flat-file storage\n\u2502 \u251c\u2500\u2500 websocket.py # WebSocket hub\n\u2502 \u2514\u2500\u2500 sse.py # Server-Sent Events\n\u251c\u2500\u2500 _data/ # Auto-created data directory\n\u2502 \u251c\u2500\u2500 jobs.tsv # Job queue\n\u2502 \u2514\u2500\u2500 streams/ # Message bus streams\n\u251c\u2500\u2500 manage.py # CLI\n\u2514\u2500\u2500 pyproject.toml\n```\n\n## Creating API Endpoints\n\n### Simple Endpoint\n\n```python\n# api/status.py\nimport json\nfrom dbbasic_web.responses import json as json_response\n\ndef handle(request):\n return json_response(json.dumps({\"status\": \"ok\"}))\n```\n\nAccess: `GET /status`\n\n### REST Resource with Sub-Routes\n\n```python\n# api/posts.py\ndef handle(request):\n parts = request['path_parts']\n method = request['method']\n\n # /posts\n if len(parts) == 1:\n if method == 'GET':\n return list_posts()\n elif method == 'POST':\n return create_post(request)\n\n # /posts/123\n elif len(parts) == 2:\n post_id = parts[1]\n if method == 'GET':\n return get_post(post_id)\n elif method == 'PUT':\n return update_post(post_id, request)\n\n # /posts/123/comments\n elif len(parts) == 3 and parts[2] == 'comments':\n return get_comments(parts[1])\n```\n\n## Performance\n\n| Implementation | Requests/sec |\n|---------------|--------------|\n| Traditional CGI | ~100 |\n| dbbasic-web | ~4000 |\n\nAchieved by combining:\n- Async I/O (ASGI/uvicorn)\n- Filesystem routing (no regex matching)\n- Direct module imports (no middleware chains)\n- TSV files instead of database round-trips\n\n## Dependencies\n\nMinimal and purposeful:\n- `uvicorn` - ASGI server\n- `jinja2` - Templates\n- `dbbasic-tsv` - TSV database\n- `dbbasic-queue` - Job queue\n- `dbbasic-pipe` - Message streams\n- `dbbasic-sessions` - Authentication\n- `websockets` - WebSocket support\n\n**No Redis. No Celery. No PostgreSQL required.**\n\n## Commands\n\n```bash\n# Run development server\npython manage.py serve\n\n# Run background job worker\npython manage.py worker\n\n# Interactive shell\npython manage.py shell\n```\n\n## Philosophy in Action\n\nThis framework proves that:\n1. **Simplicity scales** - Filesystem routing is faster than route tables\n2. **Flat files work** - TSV beats Redis for many use cases\n3. **Unix was right** - Pipes, files, and processes are enough\n4. **Less is more** - 8000 lines total vs 200k+ for Django\n\n## License\n\nMIT\n\n## Contributing\n\nBuilt for clarity and hackability. Every module is under 500 lines. Read the source.\n",
"bugtrack_url": null,
"license": "MIT",
"summary": "Unixy micro-framework: file routing, SSE/WS, jobs, bus, flat files.",
"version": "0.1.7",
"project_urls": {
"Documentation": "https://github.com/dbbasic/dbbasic-web",
"Homepage": "https://dbbasic.com",
"Issues": "https://github.com/dbbasic/dbbasic-web/issues",
"Repository": "https://github.com/dbbasic/dbbasic-web"
},
"split_keywords": [
"web",
" framework",
" cgi",
" unix",
" tsv",
" async",
" asgi"
],
"urls": [
{
"comment_text": null,
"digests": {
"blake2b_256": "d1c8d3ed939bb83f50cf5b82ad0215d4fe0133f54097c1c22bbb2761c71e27cd",
"md5": "a20e32a46257ace4600218168e4f2836",
"sha256": "bebee7f8725587429cfbdaed2c9c0e0a6472c2ad40d80c1115005f67410fa46e"
},
"downloads": -1,
"filename": "dbbasic_web-0.1.7-py3-none-any.whl",
"has_sig": false,
"md5_digest": "a20e32a46257ace4600218168e4f2836",
"packagetype": "bdist_wheel",
"python_version": "py3",
"requires_python": ">=3.10",
"size": 21267,
"upload_time": "2025-10-13T11:11:16",
"upload_time_iso_8601": "2025-10-13T11:11:16.861474Z",
"url": "https://files.pythonhosted.org/packages/d1/c8/d3ed939bb83f50cf5b82ad0215d4fe0133f54097c1c22bbb2761c71e27cd/dbbasic_web-0.1.7-py3-none-any.whl",
"yanked": false,
"yanked_reason": null
},
{
"comment_text": null,
"digests": {
"blake2b_256": "573902d1c523db68b77a6b4ef0cbe3c0b681283d861f659488424b4877ee9da3",
"md5": "86e81da7e5398d0a90dbcf4e700f01bf",
"sha256": "89def6a0beee4c29990502b5c7aa967897d224ada47fe4551a3869e570cde797"
},
"downloads": -1,
"filename": "dbbasic_web-0.1.7.tar.gz",
"has_sig": false,
"md5_digest": "86e81da7e5398d0a90dbcf4e700f01bf",
"packagetype": "sdist",
"python_version": "source",
"requires_python": ">=3.10",
"size": 20496,
"upload_time": "2025-10-13T11:11:18",
"upload_time_iso_8601": "2025-10-13T11:11:18.017878Z",
"url": "https://files.pythonhosted.org/packages/57/39/02d1c523db68b77a6b4ef0cbe3c0b681283d861f659488424b4877ee9da3/dbbasic_web-0.1.7.tar.gz",
"yanked": false,
"yanked_reason": null
}
],
"upload_time": "2025-10-13 11:11:18",
"github": true,
"gitlab": false,
"bitbucket": false,
"codeberg": false,
"github_user": "dbbasic",
"github_project": "dbbasic-web",
"github_not_found": true,
"lcname": "dbbasic-web"
}