# Pure Framework
A lightweight, modern Python web framework built with type safety, dependency injection, and clean architecture principles. Pure Framework provides everything you need to build robust web APIs with minimal overhead and maximum developer experience.
[](https://python.org)
[](LICENSE)
[](pyproject.toml)
## โจ Features
### Core Framework
- **๐ Full Type Safety**: Built with Python protocols and generics for comprehensive type checking
- **๐ Advanced Dependency Injection**: Automatic parameter resolution with singleton, transient, and scoped lifecycles
- **๐ Pipeline-based Middleware**: Chain of responsibility pattern with error handling
- **๐ก๏ธ Guard-based Authorization**: Flexible authorization system with clean interfaces
- **๐ High-Performance Routing**: Regex-compiled routes with parameter extraction
- **๐ Auto-Generated Documentation**: Built-in OpenAPI/Swagger documentation
- **๐ฏ Decorator-based Routing**: Clean, intuitive route definitions
- **๐๏ธ SOLID Principles**: Clean separation of concerns and maintainable architecture
- **๐ Pure Python**: No external dependencies, works with standard library only
### New in v0.0.4
- **โก Async/Await Support**: Full async support with AsyncPureFramework for modern Python applications
- **โ
Request/Response Validation**: Pydantic-style validation with detailed error messages
- **๏ฟฝ๏ธ Enhanced Error Handling**: Structured error responses with proper HTTP status codes
- **๐งช Test Client**: Comprehensive testing utilities for easy unit and integration testing
- **โ๏ธ CLI Tool**: Command-line interface for project scaffolding and development
- **๐ Advanced Middleware**: Support for both sync and async middleware pipelines
- **๐ก๏ธ Enhanced Guards**: Async guards with rate limiting and authorization patterns
## ๏ฟฝ๐ Quick Start
### Installation
```bash
pip install pure-framework
```
### Basic Example
```python
from pure_framework import PureFramework, get, post
from pure_framework.framework_types import IRequest, IResponse
app = PureFramework()
@get('/hello')
def hello_world(req: IRequest, res: IResponse) -> None:
res.json({'message': 'Hello, World!'})
@get('/users/:id')
def get_user(req: IRequest, res: IResponse, id: int) -> None:
# Automatic parameter injection and type conversion
res.json({'user_id': id, 'name': f'User {id}'})
@post('/users')
def create_user(req: IRequest, res: IResponse) -> None:
user_data = req.json
res.json({'created': user_data}, status_code=201)
if __name__ == "__main__":
app.run()
```
### Async Example
```python
from pure_framework import AsyncPureFramework, async_get, async_post
from pure_framework.framework_types import IRequest, IResponse
import asyncio
app = AsyncPureFramework()
@async_get('/hello')
async def hello_world(req: IRequest, res: IResponse) -> None:
# Simulate async work
await asyncio.sleep(0.01)
res.json({'message': 'Hello from async!', 'type': 'async'})
@async_post('/process')
async def process_data(req: IRequest, res: IResponse) -> None:
# Async data processing
data = req.json
await asyncio.sleep(0.1) # Simulate async processing
res.json({'processed': data, 'status': 'completed'})
if __name__ == "__main__":
app.run_async()
```
### CLI Usage
Create a new project:
```bash
pure new my-api # Basic API project
pure new my-async-api --template async-api # Async API project
```
Run your project:
```bash
pure run # Run the current project
pure run --reload # Run with auto-reload
```
Run tests:
```bash
pure test # Run all tests
pure test --verbose # Verbose output
```
if __name__ == '__main__':
app.run() # Starts server at http://127.0.0.1:8000
```
Visit `http://127.0.0.1:8000/docs` to see the auto-generated API documentation!
## ๐๏ธ Architecture Overview
Pure Framework is built around several core concepts:
### 1. **Application (`PureFramework`)**
The main application class that orchestrates all components:
```python
from pure_framework import PureFramework
from pure_framework.framework_types import ApplicationConfig
# Basic setup
app = PureFramework()
# Advanced configuration
config = ApplicationConfig(
host="0.0.0.0",
port=8080,
enable_docs=True,
docs_path="/api-docs"
)
app = PureFramework(config=config)
```
### 2. **Routing System**
High-performance routing with parameter extraction:
```python
from pure_framework import get, post, put, delete, route
from pure_framework.framework_types import HTTPMethod
# Simple routes
@get('/health')
def health_check(req, res):
res.json({'status': 'healthy'})
# Multiple methods
@route('/api/data', methods=[HTTPMethod.GET, HTTPMethod.POST])
def handle_data(req, res):
if req.method == HTTPMethod.GET:
res.json({'data': 'value'})
else:
res.json({'created': req.json})
# Parameter routes with type conversion
@get('/posts/:id/comments/:comment_id')
def get_comment(req, res, id: int, comment_id: int):
res.json({'post_id': id, 'comment_id': comment_id})
```
### 3. **Controller Classes**
Organize related routes into controller classes:
```python
from pure_framework import controller, get, post
from pure_framework.framework_types import IRequest, IResponse
@controller('/api/users')
class UserController:
@get('/')
def list_users(self, req: IRequest, res: IResponse):
res.json({'users': []})
@get('/:id')
def get_user(self, req: IRequest, res: IResponse, id: int):
res.json({'user_id': id})
@post('/')
def create_user(self, req: IRequest, res: IResponse):
user_data = req.json
res.json({'created': user_data})
```
### 4. **Dependency Injection**
Type-safe dependency injection with automatic resolution:
```python
from pure_framework import PureFramework, get, inject
from pure_framework.dependency_injection import DependencyContainer, LifecycleType
# Define services
class DatabaseService:
def get_user(self, user_id: int):
return {'id': user_id, 'name': f'User {user_id}'}
class UserService:
def __init__(self, db: DatabaseService):
self.db = db
def find_user(self, user_id: int):
return self.db.get_user(user_id)
# Configure container
app = PureFramework()
app.configure_container(lambda container: (
container.register_type(DatabaseService, DatabaseService, LifecycleType.SINGLETON)
.register_type(UserService, UserService, LifecycleType.SINGLETON)
))
# Use in routes with automatic injection
@get('/users/:id')
def get_user(req, res, id: int, user_service: UserService = inject()):
user = user_service.find_user(id)
res.json(user)
```
### 5. **Middleware System**
Pipeline-based middleware with error handling:
```python
from pure_framework import PureFramework
from pure_framework.middleware import BaseMiddleware
from pure_framework.framework_types import IRequest, IResponse
class LoggingMiddleware(BaseMiddleware):
def process(self, request: IRequest, response: IResponse) -> None:
print(f"{request.method} {request.path}")
class AuthMiddleware(BaseMiddleware):
def process(self, request: IRequest, response: IResponse) -> None:
auth_header = request.get_header('authorization')
if not auth_header:
response.status_code = 401
response.json({'error': 'Unauthorized'})
return
# Global middleware
app = PureFramework()
app.add_middleware(LoggingMiddleware())
# Route-specific middleware
@get('/protected', middlewares=[AuthMiddleware()])
def protected_route(req, res):
res.json({'message': 'Access granted'})
```
### 6. **Guards for Authorization**
Clean authorization with guard classes:
```python
from pure_framework.middleware import BaseGuard
from pure_framework.framework_types import IRequest
class AdminGuard(BaseGuard):
def can_activate(self, request: IRequest) -> bool:
user_role = request.get_header('user-role')
return user_role == 'admin'
@get('/admin/users', guards=[AdminGuard()])
def admin_users(req, res):
res.json({'admin_data': 'sensitive'})
```
## ๐ API Reference
### Request Object (`IRequest`)
```python
from pure_framework.framework_types import IRequest
def my_handler(req: IRequest, res):
# Path and method
path = req.path # "/api/users/123"
method = req.method # HTTPMethod.GET
# Headers (case-insensitive)
auth = req.get_header('authorization')
content_type = req.headers.get('content-type')
# Query parameters
page = req.get_query('page', '1') # Single value
tags = req.query.get('tags', []) # List of values
# Path parameters (from route pattern)
user_id = req.params.get('id') # From /users/:id
# Request body
raw_body = req.body # Raw string
json_data = req.json # Parsed JSON
```
### Response Object (`IResponse`)
```python
from pure_framework.framework_types import IResponse
def my_handler(req, res: IResponse):
# Set status code
res.status_code = 201
# Set headers
res.set_header('X-Custom', 'value')
# Send responses
res.json({'key': 'value'}) # JSON response
res.html('<h1>Hello</h1>') # HTML response
res.text('Plain text') # Text response
res.send(b'Binary data') # Raw bytes
# With custom status
res.json({'error': 'Not found'}, status_code=404)
```
### Route Decorators
```python
from pure_framework import route, get, post, put, delete, patch
from pure_framework.framework_types import HTTPMethod
# Basic decorators
@get('/path') # GET only
@post('/path') # POST only
@put('/path') # PUT only
@delete('/path') # DELETE only
@patch('/path') # PATCH only
# Multiple methods
@route('/path', methods=[HTTPMethod.GET, HTTPMethod.POST])
# With middleware and guards
@get('/path',
middlewares=[LoggingMiddleware()],
guards=[AuthGuard()],
name='custom_name',
description='Route description')
```
### Dependency Injection
```python
from pure_framework.dependency_injection import (
DependencyContainer, LifecycleType, inject
)
# Container setup
container = DependencyContainer()
# Register types
container.register_type(IService, ServiceImpl, LifecycleType.SINGLETON)
container.register_type(IRepo, RepoImpl, LifecycleType.TRANSIENT)
# Register instances
container.register_instance(IConfig, config_instance)
# Register factories
container.register_factory(IService, lambda: create_service())
# Use in route handlers
@get('/users')
def get_users(req, res, service: IService = inject()):
users = service.get_all_users()
res.json(users)
```
## ๐ง Configuration
### Application Configuration
```python
from pure_framework import PureFramework
from pure_framework.framework_types import ApplicationConfig
config = ApplicationConfig(
host="0.0.0.0", # Bind host
port=8080, # Bind port
enable_docs=True, # Enable Swagger docs
docs_path="/docs", # Docs endpoint path
log_level="INFO" # Logging level
)
app = PureFramework(config=config)
```
### Error Handling
```python
from pure_framework import PureFramework
app = PureFramework()
# Global error handler
def handle_validation_error(error: ValueError, req, res):
res.json({'error': str(error)}, status_code=400)
return True # Mark as handled
app.add_error_handler(ValueError, handle_validation_error)
```
## ๐ Examples
### Complete REST API
```python
from pure_framework import PureFramework, controller, get, post, put, delete
from pure_framework.framework_types import IRequest, IResponse
from pure_framework.dependency_injection import inject, LifecycleType
# Data models
class User:
def __init__(self, id: int, name: str, email: str):
self.id = id
self.name = name
self.email = email
def to_dict(self):
return {'id': self.id, 'name': self.name, 'email': self.email}
# Services
class UserService:
def __init__(self):
self.users = {}
self.next_id = 1
def create_user(self, name: str, email: str) -> User:
user = User(self.next_id, name, email)
self.users[self.next_id] = user
self.next_id += 1
return user
def get_user(self, user_id: int) -> User:
return self.users.get(user_id)
def get_all_users(self) -> list[User]:
return list(self.users.values())
def update_user(self, user_id: int, name: str = None, email: str = None) -> User:
user = self.users.get(user_id)
if user:
if name: user.name = name
if email: user.email = email
return user
def delete_user(self, user_id: int) -> bool:
return self.users.pop(user_id, None) is not None
# Controllers
@controller('/api/users')
class UserController:
@get('/')
def list_users(self, req: IRequest, res: IResponse,
user_service: UserService = inject()):
users = user_service.get_all_users()
res.json([user.to_dict() for user in users])
@get('/:id')
def get_user(self, req: IRequest, res: IResponse, id: int,
user_service: UserService = inject()):
user = user_service.get_user(id)
if user:
res.json(user.to_dict())
else:
res.json({'error': 'User not found'}, status_code=404)
@post('/')
def create_user(self, req: IRequest, res: IResponse,
user_service: UserService = inject()):
data = req.json
user = user_service.create_user(data['name'], data['email'])
res.json(user.to_dict(), status_code=201)
@put('/:id')
def update_user(self, req: IRequest, res: IResponse, id: int,
user_service: UserService = inject()):
data = req.json
user = user_service.update_user(id, data.get('name'), data.get('email'))
if user:
res.json(user.to_dict())
else:
res.json({'error': 'User not found'}, status_code=404)
@delete('/:id')
def delete_user(self, req: IRequest, res: IResponse, id: int,
user_service: UserService = inject()):
if user_service.delete_user(id):
res.json({'message': 'User deleted'})
else:
res.json({'error': 'User not found'}, status_code=404)
# Application setup
app = PureFramework()
# Configure dependencies
app.configure_container(lambda container:
container.register_type(UserService, UserService, LifecycleType.SINGLETON)
)
if __name__ == '__main__':
app.run()
```
## ๐งช Testing
Pure Framework is designed to be easily testable:
```python
import unittest
from pure_framework import PureFramework, get
from pure_framework.framework_types import IRequest, IResponse
class TestAPI(unittest.TestCase):
def setUp(self):
self.app = PureFramework()
@get('/test')
def test_endpoint(req: IRequest, res: IResponse):
res.json({'test': True})
def test_endpoint_response(self):
# Test your endpoints using the application instance
# Note: Full testing utilities coming in future versions
pass
```
## ๐ค Contributing
Contributions are welcome! Please feel free to submit a Pull Request. For major changes, please open an issue first to discuss what you would like to change.
### Development Setup
```bash
# Clone the repository
git clone https://github.com/hasanragab/pure_framework.git
cd pure_framework
# Create virtual environment
python -m venv .venv
source .venv/bin/activate # On Windows: .venv\Scripts\activate
# Install in development mode
pip install -e .
# Run tests
python -m pytest tests/
# Build package
python -m build
```
## ๐ License
This project is licensed under the MIT License - see the [LICENSE](LICENSE) file for details.
## ๐ฎ Roadmap
- [ ] Async/await support
- [ ] WebSocket support
- [ ] Database ORM integration
- [ ] Template engine integration
- [ ] Built-in testing utilities
- [ ] CLI tools for project scaffolding
- [ ] Performance optimizations
- [ ] Plugin system
## ๐ Support
- ๐ง Email: hr145310@gmail.com
- ๐ Issues: [GitHub Issues](https://github.com/hasanragab/pure_framework/issues)
---
Made with โค๏ธ by [Hasan Ragab](mailto:hr145310@gmail.com)
Raw data
{
"_id": null,
"home_page": null,
"name": "pure-framework",
"maintainer": null,
"docs_url": null,
"requires_python": ">=3.9",
"maintainer_email": "Hasan Ragab <hr145310@gmail.com>",
"keywords": "web-framework, rest-api, microservice, http-server, dependency-injection, middleware, type-safety, swagger, openapi, pure-python, lightweight, modern, async, asyncio, validation, error-handling, testing, cli-tool",
"author": null,
"author_email": "Hasan Ragab <hr145310@gmail.com>",
"download_url": "https://files.pythonhosted.org/packages/6b/7f/c87aa916e6d65b9ec8becb22d1eec561b2905e7512c13b5bbaa2b08b7c96/pure_framework-0.0.4.tar.gz",
"platform": null,
"description": "# Pure Framework\n\nA lightweight, modern Python web framework built with type safety, dependency injection, and clean architecture principles. Pure Framework provides everything you need to build robust web APIs with minimal overhead and maximum developer experience.\n\n[](https://python.org)\n[](LICENSE)\n[](pyproject.toml)\n\n## \u2728 Features\n\n### Core Framework\n- **\ud83d\udd12 Full Type Safety**: Built with Python protocols and generics for comprehensive type checking\n- **\ud83d\udc89 Advanced Dependency Injection**: Automatic parameter resolution with singleton, transient, and scoped lifecycles\n- **\ud83d\udd04 Pipeline-based Middleware**: Chain of responsibility pattern with error handling\n- **\ud83d\udee1\ufe0f Guard-based Authorization**: Flexible authorization system with clean interfaces\n- **\ud83d\ude80 High-Performance Routing**: Regex-compiled routes with parameter extraction\n- **\ud83d\udcda Auto-Generated Documentation**: Built-in OpenAPI/Swagger documentation\n- **\ud83c\udfaf Decorator-based Routing**: Clean, intuitive route definitions\n- **\ud83c\udfd7\ufe0f SOLID Principles**: Clean separation of concerns and maintainable architecture\n- **\ud83d\udc0d Pure Python**: No external dependencies, works with standard library only\n\n### New in v0.0.4\n- **\u26a1 Async/Await Support**: Full async support with AsyncPureFramework for modern Python applications\n- **\u2705 Request/Response Validation**: Pydantic-style validation with detailed error messages\n- **\ufffd\ufe0f Enhanced Error Handling**: Structured error responses with proper HTTP status codes\n- **\ud83e\uddea Test Client**: Comprehensive testing utilities for easy unit and integration testing\n- **\u2699\ufe0f CLI Tool**: Command-line interface for project scaffolding and development\n- **\ud83d\udd17 Advanced Middleware**: Support for both sync and async middleware pipelines\n- **\ud83d\udee1\ufe0f Enhanced Guards**: Async guards with rate limiting and authorization patterns\n\n## \ufffd\ud83d\ude80 Quick Start\n\n### Installation\n\n```bash\npip install pure-framework\n```\n\n### Basic Example\n\n```python\nfrom pure_framework import PureFramework, get, post\nfrom pure_framework.framework_types import IRequest, IResponse\n\napp = PureFramework()\n\n@get('/hello')\ndef hello_world(req: IRequest, res: IResponse) -> None:\n res.json({'message': 'Hello, World!'})\n\n@get('/users/:id')\ndef get_user(req: IRequest, res: IResponse, id: int) -> None:\n # Automatic parameter injection and type conversion\n res.json({'user_id': id, 'name': f'User {id}'})\n\n@post('/users')\ndef create_user(req: IRequest, res: IResponse) -> None:\n user_data = req.json\n res.json({'created': user_data}, status_code=201)\n\nif __name__ == \"__main__\":\n app.run()\n```\n\n### Async Example\n\n```python\nfrom pure_framework import AsyncPureFramework, async_get, async_post\nfrom pure_framework.framework_types import IRequest, IResponse\nimport asyncio\n\napp = AsyncPureFramework()\n\n@async_get('/hello')\nasync def hello_world(req: IRequest, res: IResponse) -> None:\n # Simulate async work\n await asyncio.sleep(0.01)\n res.json({'message': 'Hello from async!', 'type': 'async'})\n\n@async_post('/process')\nasync def process_data(req: IRequest, res: IResponse) -> None:\n # Async data processing\n data = req.json\n await asyncio.sleep(0.1) # Simulate async processing\n res.json({'processed': data, 'status': 'completed'})\n\nif __name__ == \"__main__\":\n app.run_async()\n```\n\n### CLI Usage\n\nCreate a new project:\n```bash\npure new my-api # Basic API project\npure new my-async-api --template async-api # Async API project\n```\n\nRun your project:\n```bash\npure run # Run the current project\npure run --reload # Run with auto-reload\n```\n\nRun tests:\n```bash\npure test # Run all tests\npure test --verbose # Verbose output\n```\n\nif __name__ == '__main__':\n app.run() # Starts server at http://127.0.0.1:8000\n```\n\nVisit `http://127.0.0.1:8000/docs` to see the auto-generated API documentation!\n\n## \ud83c\udfdb\ufe0f Architecture Overview\n\nPure Framework is built around several core concepts:\n\n### 1. **Application (`PureFramework`)**\nThe main application class that orchestrates all components:\n\n```python\nfrom pure_framework import PureFramework\nfrom pure_framework.framework_types import ApplicationConfig\n\n# Basic setup\napp = PureFramework()\n\n# Advanced configuration\nconfig = ApplicationConfig(\n host=\"0.0.0.0\",\n port=8080,\n enable_docs=True,\n docs_path=\"/api-docs\"\n)\napp = PureFramework(config=config)\n```\n\n### 2. **Routing System**\nHigh-performance routing with parameter extraction:\n\n```python\nfrom pure_framework import get, post, put, delete, route\nfrom pure_framework.framework_types import HTTPMethod\n\n# Simple routes\n@get('/health')\ndef health_check(req, res):\n res.json({'status': 'healthy'})\n\n# Multiple methods\n@route('/api/data', methods=[HTTPMethod.GET, HTTPMethod.POST])\ndef handle_data(req, res):\n if req.method == HTTPMethod.GET:\n res.json({'data': 'value'})\n else:\n res.json({'created': req.json})\n\n# Parameter routes with type conversion\n@get('/posts/:id/comments/:comment_id')\ndef get_comment(req, res, id: int, comment_id: int):\n res.json({'post_id': id, 'comment_id': comment_id})\n```\n\n### 3. **Controller Classes**\nOrganize related routes into controller classes:\n\n```python\nfrom pure_framework import controller, get, post\nfrom pure_framework.framework_types import IRequest, IResponse\n\n@controller('/api/users')\nclass UserController:\n \n @get('/')\n def list_users(self, req: IRequest, res: IResponse):\n res.json({'users': []})\n \n @get('/:id')\n def get_user(self, req: IRequest, res: IResponse, id: int):\n res.json({'user_id': id})\n \n @post('/')\n def create_user(self, req: IRequest, res: IResponse):\n user_data = req.json\n res.json({'created': user_data})\n```\n\n### 4. **Dependency Injection**\nType-safe dependency injection with automatic resolution:\n\n```python\nfrom pure_framework import PureFramework, get, inject\nfrom pure_framework.dependency_injection import DependencyContainer, LifecycleType\n\n# Define services\nclass DatabaseService:\n def get_user(self, user_id: int):\n return {'id': user_id, 'name': f'User {user_id}'}\n\nclass UserService:\n def __init__(self, db: DatabaseService):\n self.db = db\n \n def find_user(self, user_id: int):\n return self.db.get_user(user_id)\n\n# Configure container\napp = PureFramework()\napp.configure_container(lambda container: (\n container.register_type(DatabaseService, DatabaseService, LifecycleType.SINGLETON)\n .register_type(UserService, UserService, LifecycleType.SINGLETON)\n))\n\n# Use in routes with automatic injection\n@get('/users/:id')\ndef get_user(req, res, id: int, user_service: UserService = inject()):\n user = user_service.find_user(id)\n res.json(user)\n```\n\n### 5. **Middleware System**\nPipeline-based middleware with error handling:\n\n```python\nfrom pure_framework import PureFramework\nfrom pure_framework.middleware import BaseMiddleware\nfrom pure_framework.framework_types import IRequest, IResponse\n\nclass LoggingMiddleware(BaseMiddleware):\n def process(self, request: IRequest, response: IResponse) -> None:\n print(f\"{request.method} {request.path}\")\n\nclass AuthMiddleware(BaseMiddleware):\n def process(self, request: IRequest, response: IResponse) -> None:\n auth_header = request.get_header('authorization')\n if not auth_header:\n response.status_code = 401\n response.json({'error': 'Unauthorized'})\n return\n\n# Global middleware\napp = PureFramework()\napp.add_middleware(LoggingMiddleware())\n\n# Route-specific middleware\n@get('/protected', middlewares=[AuthMiddleware()])\ndef protected_route(req, res):\n res.json({'message': 'Access granted'})\n```\n\n### 6. **Guards for Authorization**\nClean authorization with guard classes:\n\n```python\nfrom pure_framework.middleware import BaseGuard\nfrom pure_framework.framework_types import IRequest\n\nclass AdminGuard(BaseGuard):\n def can_activate(self, request: IRequest) -> bool:\n user_role = request.get_header('user-role')\n return user_role == 'admin'\n\n@get('/admin/users', guards=[AdminGuard()])\ndef admin_users(req, res):\n res.json({'admin_data': 'sensitive'})\n```\n\n## \ud83d\udcd6 API Reference\n\n### Request Object (`IRequest`)\n\n```python\nfrom pure_framework.framework_types import IRequest\n\ndef my_handler(req: IRequest, res):\n # Path and method\n path = req.path # \"/api/users/123\"\n method = req.method # HTTPMethod.GET\n \n # Headers (case-insensitive)\n auth = req.get_header('authorization')\n content_type = req.headers.get('content-type')\n \n # Query parameters\n page = req.get_query('page', '1') # Single value\n tags = req.query.get('tags', []) # List of values\n \n # Path parameters (from route pattern)\n user_id = req.params.get('id') # From /users/:id\n \n # Request body\n raw_body = req.body # Raw string\n json_data = req.json # Parsed JSON\n```\n\n### Response Object (`IResponse`)\n\n```python\nfrom pure_framework.framework_types import IResponse\n\ndef my_handler(req, res: IResponse):\n # Set status code\n res.status_code = 201\n \n # Set headers\n res.set_header('X-Custom', 'value')\n \n # Send responses\n res.json({'key': 'value'}) # JSON response\n res.html('<h1>Hello</h1>') # HTML response\n res.text('Plain text') # Text response\n res.send(b'Binary data') # Raw bytes\n \n # With custom status\n res.json({'error': 'Not found'}, status_code=404)\n```\n\n### Route Decorators\n\n```python\nfrom pure_framework import route, get, post, put, delete, patch\nfrom pure_framework.framework_types import HTTPMethod\n\n# Basic decorators\n@get('/path') # GET only\n@post('/path') # POST only\n@put('/path') # PUT only\n@delete('/path') # DELETE only\n@patch('/path') # PATCH only\n\n# Multiple methods\n@route('/path', methods=[HTTPMethod.GET, HTTPMethod.POST])\n\n# With middleware and guards\n@get('/path', \n middlewares=[LoggingMiddleware()],\n guards=[AuthGuard()],\n name='custom_name',\n description='Route description')\n```\n\n### Dependency Injection\n\n```python\nfrom pure_framework.dependency_injection import (\n DependencyContainer, LifecycleType, inject\n)\n\n# Container setup\ncontainer = DependencyContainer()\n\n# Register types\ncontainer.register_type(IService, ServiceImpl, LifecycleType.SINGLETON)\ncontainer.register_type(IRepo, RepoImpl, LifecycleType.TRANSIENT)\n\n# Register instances\ncontainer.register_instance(IConfig, config_instance)\n\n# Register factories\ncontainer.register_factory(IService, lambda: create_service())\n\n# Use in route handlers\n@get('/users')\ndef get_users(req, res, service: IService = inject()):\n users = service.get_all_users()\n res.json(users)\n```\n\n## \ud83d\udd27 Configuration\n\n### Application Configuration\n\n```python\nfrom pure_framework import PureFramework\nfrom pure_framework.framework_types import ApplicationConfig\n\nconfig = ApplicationConfig(\n host=\"0.0.0.0\", # Bind host\n port=8080, # Bind port \n enable_docs=True, # Enable Swagger docs\n docs_path=\"/docs\", # Docs endpoint path\n log_level=\"INFO\" # Logging level\n)\n\napp = PureFramework(config=config)\n```\n\n### Error Handling\n\n```python\nfrom pure_framework import PureFramework\n\napp = PureFramework()\n\n# Global error handler\ndef handle_validation_error(error: ValueError, req, res):\n res.json({'error': str(error)}, status_code=400)\n return True # Mark as handled\n\napp.add_error_handler(ValueError, handle_validation_error)\n```\n\n## \ud83d\udcca Examples\n\n### Complete REST API\n\n```python\nfrom pure_framework import PureFramework, controller, get, post, put, delete\nfrom pure_framework.framework_types import IRequest, IResponse\nfrom pure_framework.dependency_injection import inject, LifecycleType\n\n# Data models\nclass User:\n def __init__(self, id: int, name: str, email: str):\n self.id = id\n self.name = name\n self.email = email\n \n def to_dict(self):\n return {'id': self.id, 'name': self.name, 'email': self.email}\n\n# Services\nclass UserService:\n def __init__(self):\n self.users = {}\n self.next_id = 1\n \n def create_user(self, name: str, email: str) -> User:\n user = User(self.next_id, name, email)\n self.users[self.next_id] = user\n self.next_id += 1\n return user\n \n def get_user(self, user_id: int) -> User:\n return self.users.get(user_id)\n \n def get_all_users(self) -> list[User]:\n return list(self.users.values())\n \n def update_user(self, user_id: int, name: str = None, email: str = None) -> User:\n user = self.users.get(user_id)\n if user:\n if name: user.name = name\n if email: user.email = email\n return user\n \n def delete_user(self, user_id: int) -> bool:\n return self.users.pop(user_id, None) is not None\n\n# Controllers\n@controller('/api/users')\nclass UserController:\n \n @get('/')\n def list_users(self, req: IRequest, res: IResponse, \n user_service: UserService = inject()):\n users = user_service.get_all_users()\n res.json([user.to_dict() for user in users])\n \n @get('/:id')\n def get_user(self, req: IRequest, res: IResponse, id: int,\n user_service: UserService = inject()):\n user = user_service.get_user(id)\n if user:\n res.json(user.to_dict())\n else:\n res.json({'error': 'User not found'}, status_code=404)\n \n @post('/')\n def create_user(self, req: IRequest, res: IResponse,\n user_service: UserService = inject()):\n data = req.json\n user = user_service.create_user(data['name'], data['email'])\n res.json(user.to_dict(), status_code=201)\n \n @put('/:id')\n def update_user(self, req: IRequest, res: IResponse, id: int,\n user_service: UserService = inject()):\n data = req.json\n user = user_service.update_user(id, data.get('name'), data.get('email'))\n if user:\n res.json(user.to_dict())\n else:\n res.json({'error': 'User not found'}, status_code=404)\n \n @delete('/:id')\n def delete_user(self, req: IRequest, res: IResponse, id: int,\n user_service: UserService = inject()):\n if user_service.delete_user(id):\n res.json({'message': 'User deleted'})\n else:\n res.json({'error': 'User not found'}, status_code=404)\n\n# Application setup\napp = PureFramework()\n\n# Configure dependencies\napp.configure_container(lambda container:\n container.register_type(UserService, UserService, LifecycleType.SINGLETON)\n)\n\nif __name__ == '__main__':\n app.run()\n```\n\n## \ud83e\uddea Testing\n\nPure Framework is designed to be easily testable:\n\n```python\nimport unittest\nfrom pure_framework import PureFramework, get\nfrom pure_framework.framework_types import IRequest, IResponse\n\nclass TestAPI(unittest.TestCase):\n def setUp(self):\n self.app = PureFramework()\n \n @get('/test')\n def test_endpoint(req: IRequest, res: IResponse):\n res.json({'test': True})\n \n def test_endpoint_response(self):\n # Test your endpoints using the application instance\n # Note: Full testing utilities coming in future versions\n pass\n```\n\n## \ud83e\udd1d Contributing\n\nContributions are welcome! Please feel free to submit a Pull Request. For major changes, please open an issue first to discuss what you would like to change.\n\n### Development Setup\n\n```bash\n# Clone the repository\ngit clone https://github.com/hasanragab/pure_framework.git\ncd pure_framework\n\n# Create virtual environment\npython -m venv .venv\nsource .venv/bin/activate # On Windows: .venv\\Scripts\\activate\n\n# Install in development mode\npip install -e .\n\n# Run tests\npython -m pytest tests/\n\n# Build package\npython -m build\n```\n\n## \ud83d\udcc4 License\n\nThis project is licensed under the MIT License - see the [LICENSE](LICENSE) file for details.\n\n## \ud83d\udd2e Roadmap\n\n- [ ] Async/await support\n- [ ] WebSocket support \n- [ ] Database ORM integration\n- [ ] Template engine integration\n- [ ] Built-in testing utilities\n- [ ] CLI tools for project scaffolding\n- [ ] Performance optimizations\n- [ ] Plugin system\n\n## \ud83d\udcde Support\n\n- \ud83d\udce7 Email: hr145310@gmail.com\n- \ud83d\udc1b Issues: [GitHub Issues](https://github.com/hasanragab/pure_framework/issues)\n---\n\nMade with \u2764\ufe0f by [Hasan Ragab](mailto:hr145310@gmail.com)\n",
"bugtrack_url": null,
"license": "MIT",
"summary": "A modern, lightweight Python web framework with type safety, dependency injection, middleware pipelines, async support, request validation, enhanced error handling, and auto-generated API documentation.",
"version": "0.0.4",
"project_urls": {
"Changelog": "https://github.com/HasanRagab/pure_framework/blob/main/CHANGELOG.md",
"Documentation": "https://github.com/HasanRagab/pure_framework#readme",
"Homepage": "https://github.com/HasanRagab/pure_framework",
"Issues": "https://github.com/HasanRagab/pure_framework/issues",
"Repository": "https://github.com/HasanRagab/pure_framework.git"
},
"split_keywords": [
"web-framework",
" rest-api",
" microservice",
" http-server",
" dependency-injection",
" middleware",
" type-safety",
" swagger",
" openapi",
" pure-python",
" lightweight",
" modern",
" async",
" asyncio",
" validation",
" error-handling",
" testing",
" cli-tool"
],
"urls": [
{
"comment_text": null,
"digests": {
"blake2b_256": "8511cca7eaf14f8864e9c8cbe3b22b18c72aef7138647049b7cff854aa6c892f",
"md5": "5bd0866ec274d92cc908dacd45e1a842",
"sha256": "5d4da8317c8c3f4b5a4adb6b55a1bd3f01d446383f2646efdba29f064deea3b4"
},
"downloads": -1,
"filename": "pure_framework-0.0.4-py3-none-any.whl",
"has_sig": false,
"md5_digest": "5bd0866ec274d92cc908dacd45e1a842",
"packagetype": "bdist_wheel",
"python_version": "py3",
"requires_python": ">=3.9",
"size": 54680,
"upload_time": "2025-09-19T22:02:11",
"upload_time_iso_8601": "2025-09-19T22:02:11.959020Z",
"url": "https://files.pythonhosted.org/packages/85/11/cca7eaf14f8864e9c8cbe3b22b18c72aef7138647049b7cff854aa6c892f/pure_framework-0.0.4-py3-none-any.whl",
"yanked": false,
"yanked_reason": null
},
{
"comment_text": null,
"digests": {
"blake2b_256": "6b7fc87aa916e6d65b9ec8becb22d1eec561b2905e7512c13b5bbaa2b08b7c96",
"md5": "79ce3b14fd4df957252e1b5ad6c90eb2",
"sha256": "a5faa89e040c17424cd2edc5356360bf547bb30c45d78106cf82113abc668c35"
},
"downloads": -1,
"filename": "pure_framework-0.0.4.tar.gz",
"has_sig": false,
"md5_digest": "79ce3b14fd4df957252e1b5ad6c90eb2",
"packagetype": "sdist",
"python_version": "source",
"requires_python": ">=3.9",
"size": 51248,
"upload_time": "2025-09-19T22:02:13",
"upload_time_iso_8601": "2025-09-19T22:02:13.941445Z",
"url": "https://files.pythonhosted.org/packages/6b/7f/c87aa916e6d65b9ec8becb22d1eec561b2905e7512c13b5bbaa2b08b7c96/pure_framework-0.0.4.tar.gz",
"yanked": false,
"yanked_reason": null
}
],
"upload_time": "2025-09-19 22:02:13",
"github": true,
"gitlab": false,
"bitbucket": false,
"codeberg": false,
"github_user": "HasanRagab",
"github_project": "pure_framework",
"travis_ci": false,
"coveralls": false,
"github_actions": false,
"lcname": "pure-framework"
}