pillar-framework 0.1.0__tar.gz
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- pillar_framework-0.1.0/PKG-INFO +296 -0
- pillar_framework-0.1.0/Readme.md +241 -0
- pillar_framework-0.1.0/pillar/__init__.py +112 -0
- pillar_framework-0.1.0/pillar/admin.py +455 -0
- pillar_framework-0.1.0/pillar/ai.py +271 -0
- pillar_framework-0.1.0/pillar/ai_tools.py +250 -0
- pillar_framework-0.1.0/pillar/app.py +514 -0
- pillar_framework-0.1.0/pillar/architecture/__init__.py +3 -0
- pillar_framework-0.1.0/pillar/architecture/enforcer.py +102 -0
- pillar_framework-0.1.0/pillar/auth.py +143 -0
- pillar_framework-0.1.0/pillar/cli/__init__.py +3 -0
- pillar_framework-0.1.0/pillar/cli/main.py +671 -0
- pillar_framework-0.1.0/pillar/config.py +183 -0
- pillar_framework-0.1.0/pillar/controller.py +278 -0
- pillar_framework-0.1.0/pillar/dashboard.py +471 -0
- pillar_framework-0.1.0/pillar/db/__init__.py +3 -0
- pillar_framework-0.1.0/pillar/db/async_db.py +200 -0
- pillar_framework-0.1.0/pillar/db/database.py +113 -0
- pillar_framework-0.1.0/pillar/db/rls.py +272 -0
- pillar_framework-0.1.0/pillar/db/sync.py +255 -0
- pillar_framework-0.1.0/pillar/di.py +95 -0
- pillar_framework-0.1.0/pillar/exceptions.py +51 -0
- pillar_framework-0.1.0/pillar/metrics.py +118 -0
- pillar_framework-0.1.0/pillar/middleware.py +187 -0
- pillar_framework-0.1.0/pillar/openapi.py +740 -0
- pillar_framework-0.1.0/pillar/py.typed +0 -0
- pillar_framework-0.1.0/pillar/queue/__init__.py +5 -0
- pillar_framework-0.1.0/pillar/queue/decorators.py +68 -0
- pillar_framework-0.1.0/pillar/queue/storage.py +239 -0
- pillar_framework-0.1.0/pillar/queue/worker.py +200 -0
- pillar_framework-0.1.0/pillar/realtime.py +281 -0
- pillar_framework-0.1.0/pillar/responses.py +138 -0
- pillar_framework-0.1.0/pillar/router.py +342 -0
- pillar_framework-0.1.0/pillar/security.py +252 -0
- pillar_framework-0.1.0/pillar/telemetry.py +293 -0
- pillar_framework-0.1.0/pillar/tracer.py +380 -0
- pillar_framework-0.1.0/pillar/vector.py +328 -0
- pillar_framework-0.1.0/pillar_framework.egg-info/PKG-INFO +296 -0
- pillar_framework-0.1.0/pillar_framework.egg-info/SOURCES.txt +47 -0
- pillar_framework-0.1.0/pillar_framework.egg-info/dependency_links.txt +1 -0
- pillar_framework-0.1.0/pillar_framework.egg-info/entry_points.txt +2 -0
- pillar_framework-0.1.0/pillar_framework.egg-info/requires.txt +44 -0
- pillar_framework-0.1.0/pillar_framework.egg-info/top_level.txt +1 -0
- pillar_framework-0.1.0/pyproject.toml +103 -0
- pillar_framework-0.1.0/setup.cfg +4 -0
- pillar_framework-0.1.0/tests/test_architecture.py +95 -0
- pillar_framework-0.1.0/tests/test_di.py +106 -0
- pillar_framework-0.1.0/tests/test_queue.py +152 -0
- pillar_framework-0.1.0/tests/test_router.py +181 -0
|
@@ -0,0 +1,296 @@
|
|
|
1
|
+
Metadata-Version: 2.4
|
|
2
|
+
Name: pillar-framework
|
|
3
|
+
Version: 0.1.0
|
|
4
|
+
Summary: Production-Grade Python Backend Framework with an optional Rust engine
|
|
5
|
+
License: MIT
|
|
6
|
+
Project-URL: Homepage, https://github.com/Zecrari/pillar
|
|
7
|
+
Project-URL: Repository, https://github.com/Zecrari/pillar
|
|
8
|
+
Project-URL: Issues, https://github.com/Zecrari/pillar/issues
|
|
9
|
+
Keywords: web,framework,async,rest,api,rust,pillar
|
|
10
|
+
Classifier: Development Status :: 3 - Alpha
|
|
11
|
+
Classifier: Framework :: AsyncIO
|
|
12
|
+
Classifier: Intended Audience :: Developers
|
|
13
|
+
Classifier: License :: OSI Approved :: MIT License
|
|
14
|
+
Classifier: Programming Language :: Python :: 3.10
|
|
15
|
+
Classifier: Programming Language :: Python :: 3.11
|
|
16
|
+
Classifier: Programming Language :: Python :: 3.12
|
|
17
|
+
Classifier: Programming Language :: Python :: 3.13
|
|
18
|
+
Classifier: Topic :: Internet :: WWW/HTTP
|
|
19
|
+
Classifier: Topic :: Internet :: WWW/HTTP :: HTTP Servers
|
|
20
|
+
Requires-Python: >=3.10
|
|
21
|
+
Description-Content-Type: text/markdown
|
|
22
|
+
Requires-Dist: starlette>=0.37.0
|
|
23
|
+
Requires-Dist: uvicorn[standard]>=0.29.0
|
|
24
|
+
Requires-Dist: pydantic>=2.0
|
|
25
|
+
Requires-Dist: click>=8.1.0
|
|
26
|
+
Requires-Dist: anyio>=4.0
|
|
27
|
+
Provides-Extra: dev
|
|
28
|
+
Requires-Dist: pytest>=8.0; extra == "dev"
|
|
29
|
+
Requires-Dist: pytest-asyncio>=0.23; extra == "dev"
|
|
30
|
+
Requires-Dist: httpx>=0.27; extra == "dev"
|
|
31
|
+
Requires-Dist: maturin>=1.0; extra == "dev"
|
|
32
|
+
Provides-Extra: async
|
|
33
|
+
Requires-Dist: aiosqlite>=0.19; extra == "async"
|
|
34
|
+
Provides-Extra: realtime
|
|
35
|
+
Requires-Dist: redis>=5.0; extra == "realtime"
|
|
36
|
+
Provides-Extra: otel
|
|
37
|
+
Requires-Dist: opentelemetry-sdk>=1.20; extra == "otel"
|
|
38
|
+
Requires-Dist: opentelemetry-exporter-otlp>=1.20; extra == "otel"
|
|
39
|
+
Provides-Extra: otel-http
|
|
40
|
+
Requires-Dist: opentelemetry-sdk>=1.20; extra == "otel-http"
|
|
41
|
+
Requires-Dist: opentelemetry-exporter-otlp-proto-http>=1.20; extra == "otel-http"
|
|
42
|
+
Provides-Extra: ai
|
|
43
|
+
Requires-Dist: httpx>=0.27; extra == "ai"
|
|
44
|
+
Provides-Extra: jwt
|
|
45
|
+
Requires-Dist: python-jose[cryptography]>=3.3; extra == "jwt"
|
|
46
|
+
Provides-Extra: qdrant
|
|
47
|
+
Requires-Dist: qdrant-client>=1.7; extra == "qdrant"
|
|
48
|
+
Provides-Extra: postgres
|
|
49
|
+
Requires-Dist: asyncpg>=0.29; extra == "postgres"
|
|
50
|
+
Provides-Extra: redis
|
|
51
|
+
Requires-Dist: redis>=5.0; extra == "redis"
|
|
52
|
+
Provides-Extra: all
|
|
53
|
+
Requires-Dist: pillar-framework[ai,async,jwt,otel,qdrant,realtime]; extra == "all"
|
|
54
|
+
Requires-Dist: httpx>=0.27; extra == "all"
|
|
55
|
+
|
|
56
|
+
# 🏛️ Pillar: The Production-Grade, Rust-Powered Python Backend Framework
|
|
57
|
+
|
|
58
|
+
**Pillar** is an opinionated, high-performance backend framework for Python, powered by a Rust engine. It is designed to solve the "Day 100" architecture problem, eliminate the need for external task queues like Celery, and provide a native, secure runtime for AI agents.
|
|
59
|
+
|
|
60
|
+
## 📖 Table of Contents
|
|
61
|
+
1. [Core Philosophy](#1-core-philosophy)
|
|
62
|
+
2. [Architecture Overview](#2-architecture-overview)
|
|
63
|
+
3. [The "Game Changer" Features](#3-the-game-changer-features)
|
|
64
|
+
4. [Project Structure (The Opinionated Standard)](#4-project-structure)
|
|
65
|
+
5. [Quickstart & Code Examples](#5-quickstart--code-examples)
|
|
66
|
+
6. [Production & Deployment](#6-production--deployment)
|
|
67
|
+
7. [Development Setup](#7-development-setup)
|
|
68
|
+
|
|
69
|
+
---
|
|
70
|
+
|
|
71
|
+
## 1. Core Philosophy
|
|
72
|
+
|
|
73
|
+
FastAPI is incredible for Day 1. But on Day 100, when your app has 150 endpoints, FastAPI gives you zero guidance on how to organize your code. Developers end up with massive `main.py` files, circular imports, and spaghetti code.
|
|
74
|
+
|
|
75
|
+
**Pillar's Philosophy:**
|
|
76
|
+
* **Opinionated by Design:** We enforce Clean Architecture (Routers → Services → Repositories). If you break the rules, Pillar stops you before you deploy.
|
|
77
|
+
* **Rust for the Heavy Lifting:** Python is for business logic. Rust handles routing, dependency injection, JSON serialization, and background tasks at C-speeds.
|
|
78
|
+
* **Batteries-Included for Modern Apps:** No more duct-taping Celery for background tasks or LangChain for AI. Pillar has them built into the core.
|
|
79
|
+
|
|
80
|
+
---
|
|
81
|
+
|
|
82
|
+
## 2. Architecture Overview
|
|
83
|
+
|
|
84
|
+
Pillar uses a hybrid **Python/Rust architecture** via `PyO3` and `Maturin`.
|
|
85
|
+
|
|
86
|
+
```text
|
|
87
|
+
[ Client Request ]
|
|
88
|
+
│
|
|
89
|
+
▼
|
|
90
|
+
┌─────────────────────────────────────────────┐
|
|
91
|
+
│ 🦀 The Rust Engine (The Core) │
|
|
92
|
+
│ • HTTP Parsing & Routing (Radix Tree) │
|
|
93
|
+
│ • Dependency Injection Resolution │
|
|
94
|
+
│ • Async/Sync "Smart Bridge" │
|
|
95
|
+
│ • Pillar Queue (Background Tasks) │
|
|
96
|
+
└──────────────────────┬──────────────────────┘
|
|
97
|
+
│ (Zero-cost FFI boundary)
|
|
98
|
+
▼
|
|
99
|
+
┌─────────────────────────────────────────────┐
|
|
100
|
+
│ 🐍 The Python Layer (Business Logic) │
|
|
101
|
+
│ • Domain Routers (HTTP definitions) │
|
|
102
|
+
│ • Domain Services (Business rules) │
|
|
103
|
+
│ • Domain Repositories (Database queries) │
|
|
104
|
+
└─────────────────────────────────────────────┘
|
|
105
|
+
```
|
|
106
|
+
|
|
107
|
+
---
|
|
108
|
+
|
|
109
|
+
## 3. The "Game Changer" Features
|
|
110
|
+
|
|
111
|
+
### 🚀 Pillar Queue (The Celery Killer)
|
|
112
|
+
Stop setting up Redis, RabbitMQ, and separate worker processes just to send an email.
|
|
113
|
+
* **Zero-Dependency:** Uses a highly optimized, embedded Rust database (SQLite in WAL mode) out-of-the-box. Tasks survive server restarts.
|
|
114
|
+
* **Scale on Demand:** Need massive scale? Flip a config switch in `pillar.toml` to use Redis or Postgres.
|
|
115
|
+
* **Built-in Cron:** Schedule recurring tasks natively without external tools.
|
|
116
|
+
|
|
117
|
+
### 🤖 Pillar Agent Runtime (AI-Native)
|
|
118
|
+
Build AI agents without memory leaks or crashing your main server.
|
|
119
|
+
* **Native Streaming:** First-class support for LLM token streaming over WebSockets and HTTP.
|
|
120
|
+
* **Tool Sandboxing:** If an AI agent calls a Python function to execute code or query a DB, Pillar runs it in an isolated, memory-safe Rust sandbox.
|
|
121
|
+
|
|
122
|
+
### 🛡️ Compile-Time Contract Validation
|
|
123
|
+
Catch database errors before you even start the server.
|
|
124
|
+
* The Rust engine reads your Python type hints and Pydantic models at startup.
|
|
125
|
+
* If your DB returns a `String` but your API expects an `Integer`, Pillar throws a `PillarContractError` and refuses to boot.
|
|
126
|
+
|
|
127
|
+
### 🌉 The "Smart Bridge" (Async/Sync Harmony)
|
|
128
|
+
Never worry about blocking the event loop.
|
|
129
|
+
* Write synchronous database queries? The Rust engine automatically routes them to a dedicated, highly optimized thread pool.
|
|
130
|
+
* Write async LLM calls? They go straight to the event loop. You just write Python; Pillar handles the execution context.
|
|
131
|
+
|
|
132
|
+
---
|
|
133
|
+
|
|
134
|
+
## 4. Project Structure
|
|
135
|
+
|
|
136
|
+
Pillar enforces a strict Domain-Driven Design (DDD) folder structure. If a `router.py` tries to import directly from a `repository.py`, Pillar will throw an `ArchitectureViolationError` on startup.
|
|
137
|
+
|
|
138
|
+
```text
|
|
139
|
+
my_pillar_app/
|
|
140
|
+
├── domains/ # Your business logic, separated by domain
|
|
141
|
+
│ ├── users/
|
|
142
|
+
│ │ ├── router.py # ONLY HTTP logic and Pydantic schemas
|
|
143
|
+
│ │ ├── service.py # ONLY business rules and orchestration
|
|
144
|
+
│ │ ├── repository.py # ONLY database queries
|
|
145
|
+
│ │ └── schemas.py # Pydantic models for this domain
|
|
146
|
+
│ └── billing/
|
|
147
|
+
│ ├── router.py
|
|
148
|
+
│ ├── service.py
|
|
149
|
+
│ └── repository.py
|
|
150
|
+
├── core/ # Framework and infrastructure setup
|
|
151
|
+
│ ├── config.py # Environment variables & settings
|
|
152
|
+
│ ├── database.py # DB connection pooling
|
|
153
|
+
│ └── security.py # Auth & JWT logic
|
|
154
|
+
├── main.py # The entry point (Usually just 3 lines of code)
|
|
155
|
+
└── pillar.toml # Framework configuration (Queue, AI, DB settings)
|
|
156
|
+
```
|
|
157
|
+
|
|
158
|
+
---
|
|
159
|
+
|
|
160
|
+
## 5. Quickstart & Code Examples
|
|
161
|
+
|
|
162
|
+
### Step 1: Define the Repository (Database)
|
|
163
|
+
```python
|
|
164
|
+
# domains/users/repository.py
|
|
165
|
+
from pillar.db import Database
|
|
166
|
+
|
|
167
|
+
class UserRepository:
|
|
168
|
+
def __init__(self, db: Database):
|
|
169
|
+
self.db = db
|
|
170
|
+
|
|
171
|
+
# Notice: No 'async' needed. The Smart Bridge handles it!
|
|
172
|
+
def get_by_id(self, user_id: int) -> dict | None:
|
|
173
|
+
return self.db.query("SELECT * FROM users WHERE id = ?", (user_id,))
|
|
174
|
+
```
|
|
175
|
+
|
|
176
|
+
### Step 2: Define the Service (Business Logic)
|
|
177
|
+
```python
|
|
178
|
+
# domains/users/service.py
|
|
179
|
+
from .repository import UserRepository
|
|
180
|
+
from pillar.exceptions import NotFoundError
|
|
181
|
+
|
|
182
|
+
class UserService:
|
|
183
|
+
def __init__(self, repo: UserRepository):
|
|
184
|
+
self.repo = repo # Auto-injected by Pillar!
|
|
185
|
+
|
|
186
|
+
def get_user_profile(self, user_id: int):
|
|
187
|
+
user = self.repo.get_by_id(user_id)
|
|
188
|
+
if not user:
|
|
189
|
+
raise NotFoundError("User not found")
|
|
190
|
+
|
|
191
|
+
# Business logic here (e.g., calculate subscription status)
|
|
192
|
+
return {**user, "status": "active"}
|
|
193
|
+
```
|
|
194
|
+
|
|
195
|
+
### Step 3: Define the Router (HTTP)
|
|
196
|
+
```python
|
|
197
|
+
# domains/users/router.py
|
|
198
|
+
from pillar import Router
|
|
199
|
+
from .service import UserService
|
|
200
|
+
|
|
201
|
+
router = Router(prefix="/users", tags=["Users"])
|
|
202
|
+
|
|
203
|
+
# Notice: No ugly Depends()! Pillar auto-injects the UserService.
|
|
204
|
+
@router.get("/{user_id}")
|
|
205
|
+
async def get_user(user_id: int, service: UserService):
|
|
206
|
+
return service.get_user_profile(user_id)
|
|
207
|
+
```
|
|
208
|
+
|
|
209
|
+
### Step 4: Add a Background Task (No Celery!)
|
|
210
|
+
```python
|
|
211
|
+
# domains/users/service.py
|
|
212
|
+
from pillar import background_task
|
|
213
|
+
|
|
214
|
+
class UserService:
|
|
215
|
+
# ... previous code ...
|
|
216
|
+
|
|
217
|
+
@background_task(retries=3)
|
|
218
|
+
def send_welcome_email(self, user_email: str):
|
|
219
|
+
# This runs in the embedded Rust task queue!
|
|
220
|
+
# No Redis required.
|
|
221
|
+
email_client.send(user_email, "Welcome to Pillar!")
|
|
222
|
+
```
|
|
223
|
+
|
|
224
|
+
### Step 5: Start the App
|
|
225
|
+
```python
|
|
226
|
+
# main.py
|
|
227
|
+
from pillar import Pillar
|
|
228
|
+
from domains.users.router import router as users_router
|
|
229
|
+
|
|
230
|
+
app = Pillar(title="My Awesome App")
|
|
231
|
+
app.include_router(users_router)
|
|
232
|
+
|
|
233
|
+
# Run with: pillar run main:app
|
|
234
|
+
```
|
|
235
|
+
|
|
236
|
+
---
|
|
237
|
+
|
|
238
|
+
## 6. Production & Deployment
|
|
239
|
+
|
|
240
|
+
Pillar is built for the enterprise.
|
|
241
|
+
|
|
242
|
+
### Observability (Zero-Config)
|
|
243
|
+
Pillar automatically instruments your app with **OpenTelemetry**.
|
|
244
|
+
* Every HTTP request, DB query, and background task is traced.
|
|
245
|
+
* Export directly to Datadog, Jaeger, or Grafana by adding your endpoint to `pillar.toml`.
|
|
246
|
+
|
|
247
|
+
### Graceful Shutdown
|
|
248
|
+
When you deploy a new version, Pillar intercepts the `SIGTERM` signal. It stops accepting new requests, waits for all active background tasks (Pillar Queue) to finish, and shuts down cleanly. **Zero dropped connections.**
|
|
249
|
+
|
|
250
|
+
### Docker Deployment
|
|
251
|
+
Pillar includes a highly optimized, multi-stage `Dockerfile` generator.
|
|
252
|
+
```bash
|
|
253
|
+
pillar generate dockerfile
|
|
254
|
+
docker build -t my-pillar-app .
|
|
255
|
+
docker run -p 8000:8000 my-pillar-app
|
|
256
|
+
```
|
|
257
|
+
|
|
258
|
+
---
|
|
259
|
+
|
|
260
|
+
## 7. Development Setup
|
|
261
|
+
|
|
262
|
+
*Note: End-users installing via `pip` do NOT need Rust. This is only for developing the Pillar framework itself.*
|
|
263
|
+
|
|
264
|
+
### Prerequisites
|
|
265
|
+
1. **Python 3.10+**
|
|
266
|
+
2. **Rust** (Install via [rustup.rs](https://rustup.rs/))
|
|
267
|
+
3. **Maturin** (`pip install maturin`)
|
|
268
|
+
|
|
269
|
+
### Initialize the Project
|
|
270
|
+
```bash
|
|
271
|
+
# Create the project using Maturin
|
|
272
|
+
maturin new pillar --bindings pyo3
|
|
273
|
+
cd pillar
|
|
274
|
+
|
|
275
|
+
# Install in development mode
|
|
276
|
+
pip install -e .
|
|
277
|
+
```
|
|
278
|
+
|
|
279
|
+
### Run the Test Suite
|
|
280
|
+
```bash
|
|
281
|
+
# Run Python tests
|
|
282
|
+
pytest tests/
|
|
283
|
+
|
|
284
|
+
# Run Rust unit tests
|
|
285
|
+
cargo test
|
|
286
|
+
```
|
|
287
|
+
|
|
288
|
+
---
|
|
289
|
+
|
|
290
|
+
## 🗺️ The Roadmap
|
|
291
|
+
|
|
292
|
+
* **Phase 1: The Rust Foundation** - HTTP Router, PyO3 bindings, basic Python decorators.
|
|
293
|
+
* **Phase 2: Architecture & DI** - Dependency Injection container, Smart Bridge (Async/Sync), Folder Enforcer.
|
|
294
|
+
* **Phase 3: The Game Changers** - Pillar Queue (Embedded task queue), Compile-time validation.
|
|
295
|
+
* **Phase 4: AI & Production** - Pillar Agent Runtime, OpenTelemetry integration, CLI tooling.
|
|
296
|
+
* **Phase 5: Public Beta** - Launch on Reddit, HackerNews, and PyPI.
|
|
@@ -0,0 +1,241 @@
|
|
|
1
|
+
# 🏛️ Pillar: The Production-Grade, Rust-Powered Python Backend Framework
|
|
2
|
+
|
|
3
|
+
**Pillar** is an opinionated, high-performance backend framework for Python, powered by a Rust engine. It is designed to solve the "Day 100" architecture problem, eliminate the need for external task queues like Celery, and provide a native, secure runtime for AI agents.
|
|
4
|
+
|
|
5
|
+
## 📖 Table of Contents
|
|
6
|
+
1. [Core Philosophy](#1-core-philosophy)
|
|
7
|
+
2. [Architecture Overview](#2-architecture-overview)
|
|
8
|
+
3. [The "Game Changer" Features](#3-the-game-changer-features)
|
|
9
|
+
4. [Project Structure (The Opinionated Standard)](#4-project-structure)
|
|
10
|
+
5. [Quickstart & Code Examples](#5-quickstart--code-examples)
|
|
11
|
+
6. [Production & Deployment](#6-production--deployment)
|
|
12
|
+
7. [Development Setup](#7-development-setup)
|
|
13
|
+
|
|
14
|
+
---
|
|
15
|
+
|
|
16
|
+
## 1. Core Philosophy
|
|
17
|
+
|
|
18
|
+
FastAPI is incredible for Day 1. But on Day 100, when your app has 150 endpoints, FastAPI gives you zero guidance on how to organize your code. Developers end up with massive `main.py` files, circular imports, and spaghetti code.
|
|
19
|
+
|
|
20
|
+
**Pillar's Philosophy:**
|
|
21
|
+
* **Opinionated by Design:** We enforce Clean Architecture (Routers → Services → Repositories). If you break the rules, Pillar stops you before you deploy.
|
|
22
|
+
* **Rust for the Heavy Lifting:** Python is for business logic. Rust handles routing, dependency injection, JSON serialization, and background tasks at C-speeds.
|
|
23
|
+
* **Batteries-Included for Modern Apps:** No more duct-taping Celery for background tasks or LangChain for AI. Pillar has them built into the core.
|
|
24
|
+
|
|
25
|
+
---
|
|
26
|
+
|
|
27
|
+
## 2. Architecture Overview
|
|
28
|
+
|
|
29
|
+
Pillar uses a hybrid **Python/Rust architecture** via `PyO3` and `Maturin`.
|
|
30
|
+
|
|
31
|
+
```text
|
|
32
|
+
[ Client Request ]
|
|
33
|
+
│
|
|
34
|
+
▼
|
|
35
|
+
┌─────────────────────────────────────────────┐
|
|
36
|
+
│ 🦀 The Rust Engine (The Core) │
|
|
37
|
+
│ • HTTP Parsing & Routing (Radix Tree) │
|
|
38
|
+
│ • Dependency Injection Resolution │
|
|
39
|
+
│ • Async/Sync "Smart Bridge" │
|
|
40
|
+
│ • Pillar Queue (Background Tasks) │
|
|
41
|
+
└──────────────────────┬──────────────────────┘
|
|
42
|
+
│ (Zero-cost FFI boundary)
|
|
43
|
+
▼
|
|
44
|
+
┌─────────────────────────────────────────────┐
|
|
45
|
+
│ 🐍 The Python Layer (Business Logic) │
|
|
46
|
+
│ • Domain Routers (HTTP definitions) │
|
|
47
|
+
│ • Domain Services (Business rules) │
|
|
48
|
+
│ • Domain Repositories (Database queries) │
|
|
49
|
+
└─────────────────────────────────────────────┘
|
|
50
|
+
```
|
|
51
|
+
|
|
52
|
+
---
|
|
53
|
+
|
|
54
|
+
## 3. The "Game Changer" Features
|
|
55
|
+
|
|
56
|
+
### 🚀 Pillar Queue (The Celery Killer)
|
|
57
|
+
Stop setting up Redis, RabbitMQ, and separate worker processes just to send an email.
|
|
58
|
+
* **Zero-Dependency:** Uses a highly optimized, embedded Rust database (SQLite in WAL mode) out-of-the-box. Tasks survive server restarts.
|
|
59
|
+
* **Scale on Demand:** Need massive scale? Flip a config switch in `pillar.toml` to use Redis or Postgres.
|
|
60
|
+
* **Built-in Cron:** Schedule recurring tasks natively without external tools.
|
|
61
|
+
|
|
62
|
+
### 🤖 Pillar Agent Runtime (AI-Native)
|
|
63
|
+
Build AI agents without memory leaks or crashing your main server.
|
|
64
|
+
* **Native Streaming:** First-class support for LLM token streaming over WebSockets and HTTP.
|
|
65
|
+
* **Tool Sandboxing:** If an AI agent calls a Python function to execute code or query a DB, Pillar runs it in an isolated, memory-safe Rust sandbox.
|
|
66
|
+
|
|
67
|
+
### 🛡️ Compile-Time Contract Validation
|
|
68
|
+
Catch database errors before you even start the server.
|
|
69
|
+
* The Rust engine reads your Python type hints and Pydantic models at startup.
|
|
70
|
+
* If your DB returns a `String` but your API expects an `Integer`, Pillar throws a `PillarContractError` and refuses to boot.
|
|
71
|
+
|
|
72
|
+
### 🌉 The "Smart Bridge" (Async/Sync Harmony)
|
|
73
|
+
Never worry about blocking the event loop.
|
|
74
|
+
* Write synchronous database queries? The Rust engine automatically routes them to a dedicated, highly optimized thread pool.
|
|
75
|
+
* Write async LLM calls? They go straight to the event loop. You just write Python; Pillar handles the execution context.
|
|
76
|
+
|
|
77
|
+
---
|
|
78
|
+
|
|
79
|
+
## 4. Project Structure
|
|
80
|
+
|
|
81
|
+
Pillar enforces a strict Domain-Driven Design (DDD) folder structure. If a `router.py` tries to import directly from a `repository.py`, Pillar will throw an `ArchitectureViolationError` on startup.
|
|
82
|
+
|
|
83
|
+
```text
|
|
84
|
+
my_pillar_app/
|
|
85
|
+
├── domains/ # Your business logic, separated by domain
|
|
86
|
+
│ ├── users/
|
|
87
|
+
│ │ ├── router.py # ONLY HTTP logic and Pydantic schemas
|
|
88
|
+
│ │ ├── service.py # ONLY business rules and orchestration
|
|
89
|
+
│ │ ├── repository.py # ONLY database queries
|
|
90
|
+
│ │ └── schemas.py # Pydantic models for this domain
|
|
91
|
+
│ └── billing/
|
|
92
|
+
│ ├── router.py
|
|
93
|
+
│ ├── service.py
|
|
94
|
+
│ └── repository.py
|
|
95
|
+
├── core/ # Framework and infrastructure setup
|
|
96
|
+
│ ├── config.py # Environment variables & settings
|
|
97
|
+
│ ├── database.py # DB connection pooling
|
|
98
|
+
│ └── security.py # Auth & JWT logic
|
|
99
|
+
├── main.py # The entry point (Usually just 3 lines of code)
|
|
100
|
+
└── pillar.toml # Framework configuration (Queue, AI, DB settings)
|
|
101
|
+
```
|
|
102
|
+
|
|
103
|
+
---
|
|
104
|
+
|
|
105
|
+
## 5. Quickstart & Code Examples
|
|
106
|
+
|
|
107
|
+
### Step 1: Define the Repository (Database)
|
|
108
|
+
```python
|
|
109
|
+
# domains/users/repository.py
|
|
110
|
+
from pillar.db import Database
|
|
111
|
+
|
|
112
|
+
class UserRepository:
|
|
113
|
+
def __init__(self, db: Database):
|
|
114
|
+
self.db = db
|
|
115
|
+
|
|
116
|
+
# Notice: No 'async' needed. The Smart Bridge handles it!
|
|
117
|
+
def get_by_id(self, user_id: int) -> dict | None:
|
|
118
|
+
return self.db.query("SELECT * FROM users WHERE id = ?", (user_id,))
|
|
119
|
+
```
|
|
120
|
+
|
|
121
|
+
### Step 2: Define the Service (Business Logic)
|
|
122
|
+
```python
|
|
123
|
+
# domains/users/service.py
|
|
124
|
+
from .repository import UserRepository
|
|
125
|
+
from pillar.exceptions import NotFoundError
|
|
126
|
+
|
|
127
|
+
class UserService:
|
|
128
|
+
def __init__(self, repo: UserRepository):
|
|
129
|
+
self.repo = repo # Auto-injected by Pillar!
|
|
130
|
+
|
|
131
|
+
def get_user_profile(self, user_id: int):
|
|
132
|
+
user = self.repo.get_by_id(user_id)
|
|
133
|
+
if not user:
|
|
134
|
+
raise NotFoundError("User not found")
|
|
135
|
+
|
|
136
|
+
# Business logic here (e.g., calculate subscription status)
|
|
137
|
+
return {**user, "status": "active"}
|
|
138
|
+
```
|
|
139
|
+
|
|
140
|
+
### Step 3: Define the Router (HTTP)
|
|
141
|
+
```python
|
|
142
|
+
# domains/users/router.py
|
|
143
|
+
from pillar import Router
|
|
144
|
+
from .service import UserService
|
|
145
|
+
|
|
146
|
+
router = Router(prefix="/users", tags=["Users"])
|
|
147
|
+
|
|
148
|
+
# Notice: No ugly Depends()! Pillar auto-injects the UserService.
|
|
149
|
+
@router.get("/{user_id}")
|
|
150
|
+
async def get_user(user_id: int, service: UserService):
|
|
151
|
+
return service.get_user_profile(user_id)
|
|
152
|
+
```
|
|
153
|
+
|
|
154
|
+
### Step 4: Add a Background Task (No Celery!)
|
|
155
|
+
```python
|
|
156
|
+
# domains/users/service.py
|
|
157
|
+
from pillar import background_task
|
|
158
|
+
|
|
159
|
+
class UserService:
|
|
160
|
+
# ... previous code ...
|
|
161
|
+
|
|
162
|
+
@background_task(retries=3)
|
|
163
|
+
def send_welcome_email(self, user_email: str):
|
|
164
|
+
# This runs in the embedded Rust task queue!
|
|
165
|
+
# No Redis required.
|
|
166
|
+
email_client.send(user_email, "Welcome to Pillar!")
|
|
167
|
+
```
|
|
168
|
+
|
|
169
|
+
### Step 5: Start the App
|
|
170
|
+
```python
|
|
171
|
+
# main.py
|
|
172
|
+
from pillar import Pillar
|
|
173
|
+
from domains.users.router import router as users_router
|
|
174
|
+
|
|
175
|
+
app = Pillar(title="My Awesome App")
|
|
176
|
+
app.include_router(users_router)
|
|
177
|
+
|
|
178
|
+
# Run with: pillar run main:app
|
|
179
|
+
```
|
|
180
|
+
|
|
181
|
+
---
|
|
182
|
+
|
|
183
|
+
## 6. Production & Deployment
|
|
184
|
+
|
|
185
|
+
Pillar is built for the enterprise.
|
|
186
|
+
|
|
187
|
+
### Observability (Zero-Config)
|
|
188
|
+
Pillar automatically instruments your app with **OpenTelemetry**.
|
|
189
|
+
* Every HTTP request, DB query, and background task is traced.
|
|
190
|
+
* Export directly to Datadog, Jaeger, or Grafana by adding your endpoint to `pillar.toml`.
|
|
191
|
+
|
|
192
|
+
### Graceful Shutdown
|
|
193
|
+
When you deploy a new version, Pillar intercepts the `SIGTERM` signal. It stops accepting new requests, waits for all active background tasks (Pillar Queue) to finish, and shuts down cleanly. **Zero dropped connections.**
|
|
194
|
+
|
|
195
|
+
### Docker Deployment
|
|
196
|
+
Pillar includes a highly optimized, multi-stage `Dockerfile` generator.
|
|
197
|
+
```bash
|
|
198
|
+
pillar generate dockerfile
|
|
199
|
+
docker build -t my-pillar-app .
|
|
200
|
+
docker run -p 8000:8000 my-pillar-app
|
|
201
|
+
```
|
|
202
|
+
|
|
203
|
+
---
|
|
204
|
+
|
|
205
|
+
## 7. Development Setup
|
|
206
|
+
|
|
207
|
+
*Note: End-users installing via `pip` do NOT need Rust. This is only for developing the Pillar framework itself.*
|
|
208
|
+
|
|
209
|
+
### Prerequisites
|
|
210
|
+
1. **Python 3.10+**
|
|
211
|
+
2. **Rust** (Install via [rustup.rs](https://rustup.rs/))
|
|
212
|
+
3. **Maturin** (`pip install maturin`)
|
|
213
|
+
|
|
214
|
+
### Initialize the Project
|
|
215
|
+
```bash
|
|
216
|
+
# Create the project using Maturin
|
|
217
|
+
maturin new pillar --bindings pyo3
|
|
218
|
+
cd pillar
|
|
219
|
+
|
|
220
|
+
# Install in development mode
|
|
221
|
+
pip install -e .
|
|
222
|
+
```
|
|
223
|
+
|
|
224
|
+
### Run the Test Suite
|
|
225
|
+
```bash
|
|
226
|
+
# Run Python tests
|
|
227
|
+
pytest tests/
|
|
228
|
+
|
|
229
|
+
# Run Rust unit tests
|
|
230
|
+
cargo test
|
|
231
|
+
```
|
|
232
|
+
|
|
233
|
+
---
|
|
234
|
+
|
|
235
|
+
## 🗺️ The Roadmap
|
|
236
|
+
|
|
237
|
+
* **Phase 1: The Rust Foundation** - HTTP Router, PyO3 bindings, basic Python decorators.
|
|
238
|
+
* **Phase 2: Architecture & DI** - Dependency Injection container, Smart Bridge (Async/Sync), Folder Enforcer.
|
|
239
|
+
* **Phase 3: The Game Changers** - Pillar Queue (Embedded task queue), Compile-time validation.
|
|
240
|
+
* **Phase 4: AI & Production** - Pillar Agent Runtime, OpenTelemetry integration, CLI tooling.
|
|
241
|
+
* **Phase 5: Public Beta** - Launch on Reddit, HackerNews, and PyPI.
|
|
@@ -0,0 +1,112 @@
|
|
|
1
|
+
"""
|
|
2
|
+
Pillar — Production-Grade Python Backend Framework
|
|
3
|
+
|
|
4
|
+
Public API surface:
|
|
5
|
+
|
|
6
|
+
from pillar import Pillar, Router, background_task
|
|
7
|
+
from pillar import ok, created, paginate, problem, no_content
|
|
8
|
+
from pillar.db import Database
|
|
9
|
+
from pillar.exceptions import NotFoundError, UnauthorizedError, ...
|
|
10
|
+
from pillar.di import container
|
|
11
|
+
from pillar.metrics import metrics
|
|
12
|
+
"""
|
|
13
|
+
|
|
14
|
+
from .app import Pillar
|
|
15
|
+
from .router import Router
|
|
16
|
+
from .controller import Controller, action
|
|
17
|
+
from .queue.decorators import background_task
|
|
18
|
+
from .exceptions import (
|
|
19
|
+
PillarError,
|
|
20
|
+
NotFoundError,
|
|
21
|
+
UnauthorizedError,
|
|
22
|
+
ForbiddenError,
|
|
23
|
+
ValidationError,
|
|
24
|
+
ConflictError,
|
|
25
|
+
PillarContractError,
|
|
26
|
+
ArchitectureViolationError,
|
|
27
|
+
)
|
|
28
|
+
from .di import container, DIContainer
|
|
29
|
+
from .config import PillarConfig
|
|
30
|
+
from .responses import ok, created, no_content, paginate, problem, PaginatedResponse
|
|
31
|
+
from .metrics import metrics
|
|
32
|
+
from .ai import PillarAI
|
|
33
|
+
from .security import JWTMiddleware, encode_jwt, decode_jwt, RequireAuth
|
|
34
|
+
from .telemetry import setup_telemetry, trace_span, TelemetryMiddleware
|
|
35
|
+
from .tracer import span_context, current_trace_id, record_span
|
|
36
|
+
from .db.rls import RLSDatabase, set_tenant, get_tenant
|
|
37
|
+
from .db.async_db import AsyncDatabase
|
|
38
|
+
from .auth import require_role, require_permission, require_all_roles
|
|
39
|
+
from .ai_tools import ai_tool, manifest as ai_manifest
|
|
40
|
+
from .realtime import hub, PillarHub
|
|
41
|
+
from .admin import admin, PillarAdmin
|
|
42
|
+
|
|
43
|
+
__version__ = "0.1.0"
|
|
44
|
+
|
|
45
|
+
__all__ = [
|
|
46
|
+
# Core
|
|
47
|
+
"Pillar",
|
|
48
|
+
"Router",
|
|
49
|
+
"background_task",
|
|
50
|
+
# Exceptions
|
|
51
|
+
"PillarError",
|
|
52
|
+
"NotFoundError",
|
|
53
|
+
"UnauthorizedError",
|
|
54
|
+
"ForbiddenError",
|
|
55
|
+
"ValidationError",
|
|
56
|
+
"ConflictError",
|
|
57
|
+
"PillarContractError",
|
|
58
|
+
"ArchitectureViolationError",
|
|
59
|
+
# DI
|
|
60
|
+
"container",
|
|
61
|
+
"DIContainer",
|
|
62
|
+
# Config
|
|
63
|
+
"PillarConfig",
|
|
64
|
+
# Response helpers
|
|
65
|
+
"ok",
|
|
66
|
+
"created",
|
|
67
|
+
"no_content",
|
|
68
|
+
"paginate",
|
|
69
|
+
"problem",
|
|
70
|
+
"PaginatedResponse",
|
|
71
|
+
# Metrics
|
|
72
|
+
"metrics",
|
|
73
|
+
# Controller-based routing
|
|
74
|
+
"Controller",
|
|
75
|
+
"action",
|
|
76
|
+
# AI-native extraction
|
|
77
|
+
"PillarAI",
|
|
78
|
+
# Security
|
|
79
|
+
"JWTMiddleware",
|
|
80
|
+
"encode_jwt",
|
|
81
|
+
"decode_jwt",
|
|
82
|
+
"RequireAuth",
|
|
83
|
+
# Telemetry (OTel)
|
|
84
|
+
"setup_telemetry",
|
|
85
|
+
"trace_span",
|
|
86
|
+
"TelemetryMiddleware",
|
|
87
|
+
# Time-travel tracer (built-in)
|
|
88
|
+
"span_context",
|
|
89
|
+
"current_trace_id",
|
|
90
|
+
"record_span",
|
|
91
|
+
# Auto RLS
|
|
92
|
+
"RLSDatabase",
|
|
93
|
+
"set_tenant",
|
|
94
|
+
"get_tenant",
|
|
95
|
+
# Async DB
|
|
96
|
+
"AsyncDatabase",
|
|
97
|
+
# RBAC
|
|
98
|
+
"require_role",
|
|
99
|
+
"require_permission",
|
|
100
|
+
"require_all_roles",
|
|
101
|
+
# AI tool registry
|
|
102
|
+
"ai_tool",
|
|
103
|
+
"ai_manifest",
|
|
104
|
+
# Real-time hub
|
|
105
|
+
"hub",
|
|
106
|
+
"PillarHub",
|
|
107
|
+
# Admin
|
|
108
|
+
"admin",
|
|
109
|
+
"PillarAdmin",
|
|
110
|
+
# Version
|
|
111
|
+
"__version__",
|
|
112
|
+
]
|