Lightweight Python web framework built with pure standard library
Project description
Orbit Framework
Lightweight Advanced Python Web Framework built entirely with Python's standard library.
Latest Release: v1.0.2 (Access Logging) - See CHANGELOG
๐ Features
Core Features
- โ Pure Standard Library - Zero external dependencies
- โ Socket-based HTTP Server - Direct socket handling for full control
- โ HTTP/1.1 Support - Persistent connections (Keep-Alive)
- โ Path-Tree Router - Efficient route matching without decorators
- โ Middleware System - Pre/post request processing chain
- โ Template Engine - Simple built-in templating
- โ Static File Server - MIME type detection and caching
- โ Request/Response Objects - Clean, intuitive API
- โ Access Logging - Built-in HTTP access logs with IP, timing, and security events
Advanced Features
-
๐ Security-First Design
- Header sanitization
- Path traversal protection
- Request size limits
- CSRF token system
- Secure cookie handling
- Rate limiting (IP-based)
-
๐ Performance Optimized
- Multi-threading or selector-based I/O
- Lazy body parsing
- Connection pooling
- Efficient route matching
-
๐ ๏ธ Developer Friendly
- Clear error messages
- Debug mode
- Comprehensive logging
- Route groups
- Multiple content types (JSON, Form, HTML)
๐ฆ Installation
Since Orbit has no external dependencies, simply clone and use:
git clone https://github.com/yourusername/orbit.git
cd orbit
python example_app.py
Or include it in your project:
from orbit import Orbit, Request, Response
๐ Quick Start
Basic Application
from orbit import Orbit, Request, Response
# Create app
app = Orbit(debug=True)
# Define handler
def hello(request: Request) -> Response:
name = request.get_query('name', 'World')
return Response.json({
'message': f'Hello, {name}!'
})
# Register route
app.route('/hello', ['GET'], hello)
# Run server
if __name__ == '__main__':
app.run(host='0.0.0.0', port=8080)
Visit: http://localhost:8080/hello?name=Orbit
With Path Parameters
def user_detail(request: Request) -> Response:
user_id = request.path_params.get('id')
return Response.json({
'user_id': user_id,
'name': f'User {user_id}'
})
app.route('/user/{id}', ['GET'], user_detail)
JSON Request Handling
def create_item(request: Request) -> Response:
data = request.get_json()
if not data:
return Response.error(400, 'Invalid JSON')
return Response.json({
'created': True,
'item': data
}, status=201)
app.route('/items', ['POST'], create_item)
Using Templates
# Enable templates
app.templates('templates')
def home(request: Request) -> Response:
return app.render('index.html', {
'title': 'Welcome',
'users': ['Alice', 'Bob', 'Charlie']
})
app.route('/', ['GET'], home)
Template (templates/index.html):
<!DOCTYPE html>
<html>
<head>
<title>{{ title }}</title>
</head>
<body>
<h1>{{ title }}</h1>
<ul>
{% for user in users %}
<li>{{ user }}</li>
{% endfor %}
</ul>
</body>
</html>
Static Files
# Enable static file serving
app.static('static', url_prefix='/static')
Now files in static/ are accessible at /static/filename.css
Middleware
from orbit.core.middleware import SecurityHeadersMiddleware, RateLimitMiddleware
# Add security headers
app.middleware(SecurityHeadersMiddleware())
# Add rate limiting (60 requests/minute)
app.middleware(RateLimitMiddleware(requests_per_minute=60))
Route Groups
# Create API group
api = app.group('/api/v1')
def get_users(request: Request) -> Response:
return Response.json({'users': []})
def get_posts(request: Request) -> Response:
return Response.json({'posts': []})
# Routes will be /api/v1/users and /api/v1/posts
api.add_route('/users', ['GET'], get_users)
api.add_route('/posts', ['GET'], get_posts)
Error Handlers
@app.error_handler(404)
def not_found(request: Request) -> Response:
return Response.json({
'error': 'Not Found',
'path': request.path
}, status=404)
@app.error_handler(500)
def server_error(request: Request, exception: Exception) -> Response:
return Response.json({
'error': 'Internal Server Error',
'detail': str(exception)
}, status=500)
๐๏ธ Architecture
Project Structure
orbit/
โโโ orbit/
โ โโโ __init__.py
โ โโโ core/
โ โ โโโ application.py # Main Orbit class
โ โ โโโ request.py # Request object
โ โ โโโ response.py # Response builder
โ โ โโโ router.py # Path-tree router
โ โ โโโ middleware.py # Middleware system
โ โโโ http/
โ โ โโโ parser.py # HTTP request parser
โ โ โโโ server.py # Socket-based server
โ โโโ static/
โ โ โโโ handler.py # Static file handler
โ โโโ template/
โ โโโ engine.py # Template engine
โโโ example_app.py
โโโ templates/
โโโ static/
Request Lifecycle
1. Socket receives raw HTTP data
2. HTTPParser parses into structured data
3. Request object created
4. Pre-request middleware chain
5. Router matches path to handler
6. Handler processes request
7. Response object created
8. Post-response middleware chain
9. Response converted to HTTP bytes
10. Sent back through socket
๐ API Reference
Application (Orbit)
app = Orbit(debug=False)
# Routing
app.route(path, methods, handler, name=None)
app.group(prefix) -> RouterGroup
# Middleware
app.middleware(middleware_instance)
# Static & Templates
app.static(static_dir, url_prefix='/static')
app.templates(template_dir)
app.render(template_name, context) -> Response
# Error Handlers
@app.error_handler(status_code)
# Run
app.run(host='0.0.0.0', port=8080, use_threading=True)
Request
request.method # HTTP method
request.path # Request path
request.headers # Dict of headers
request.query_params # Dict of query params
request.body # Raw body bytes
request.path_params # Path parameters from route
# Helper methods
request.get_header(name, default=None)
request.get_query(name, default=None)
request.get_json() -> dict
request.get_form(name, default=None)
request.is_json() -> bool
request.is_form() -> bool
request.client_ip -> str
Response
# Constructor
Response(body='', status=200, headers=None, content_type='text/html')
# Static methods
Response.json(data, status=200)
Response.html(html, status=200)
Response.text(text, status=200)
Response.redirect(location, status=302)
Response.error(status, message=None)
# Methods
response.set_header(name, value)
response.set_cookie(name, value, max_age=None, secure=False, httponly=True)
Middleware
class CustomMiddleware(Middleware):
def process_request(self, request: Request) -> Optional[Response]:
# Return Response to short-circuit
# Return None to continue
pass
def process_response(self, request: Request, response: Response) -> Response:
# Modify and return response
return response
๐ Security Features
Built-in Security
-
Request Validation
- Maximum request size
- Header count limits
- Path traversal protection
- Header injection prevention
-
Security Headers (via middleware)
- X-Content-Type-Options
- X-Frame-Options
- X-XSS-Protection
-
Rate Limiting (via middleware)
- IP-based tracking
- Configurable limits
- Automatic cleanup
-
CSRF Protection (via middleware)
- Token generation
- Token validation
- Session-based
-
Secure Cookies
- HttpOnly flag
- Secure flag
- SameSite attribute
Security Best Practices
from orbit.core.middleware import (
SecurityHeadersMiddleware,
RateLimitMiddleware,
CSRFProtectionMiddleware
)
# Add all security middleware
app.middleware(SecurityHeadersMiddleware())
app.middleware(RateLimitMiddleware(requests_per_minute=60))
app.middleware(CSRFProtectionMiddleware())
# Use HTTPS in production (with SSL wrapper)
โก Performance Tips
-
Use Threading for I/O-bound applications
app.run(use_threading=True, max_connections=100)
-
Enable Static File Caching
app.static('static', enable_cache=True, cache_max_age=3600)
-
Optimize Route Ordering
- Register static routes before dynamic ones
- Use route groups for organization
-
Lazy Body Parsing
- Body only parsed when accessed
- Use
request.get_json()only when needed
๐งช Testing
# Create test client
client = app.test_client()
# Make requests (implementation in testing module)
response = client.get('/hello')
assert response.status == 200
๐ Examples
See example_app.py for a comprehensive example covering:
- Basic routing
- Path parameters
- JSON handling
- Templates
- Static files
- Middleware
- Error handlers
- Route groups
๐ค Contributing
Contributions are welcome! This is an educational project demonstrating web framework internals.
๐ License
MIT License - Feel free to use in your projects!
๐ฏ Roadmap
- WebSocket support
- Session management
- Database helpers
- Form validation
- File upload handling
- CLI tool (
orbit run,orbit new) - Hot reload in debug mode
- More built-in middleware
- Comprehensive test suite
๐ Acknowledgments
Built to demonstrate that powerful web frameworks can be created with Python's standard library alone. Inspired by the need for educational resources on web framework internals.
Orbit - Where simplicity meets power. ๐
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 orbit_web_framework-1.0.2.tar.gz.
File metadata
- Download URL: orbit_web_framework-1.0.2.tar.gz
- Upload date:
- Size: 30.4 kB
- Tags: Source
- Uploaded using Trusted Publishing? No
- Uploaded via: twine/6.2.0 CPython/3.12.12
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
7fe9e6301e2468ef01c1c2e4a98c610d230f92a9e4505984db841690a9d6df48
|
|
| MD5 |
e35df45f6752dabe691a10fb79eb9979
|
|
| BLAKE2b-256 |
66419561777f61815c95e5715a4d633923731464ed5c91c4be601200692453c0
|
File details
Details for the file orbit_web_framework-1.0.2-py3-none-any.whl.
File metadata
- Download URL: orbit_web_framework-1.0.2-py3-none-any.whl
- Upload date:
- Size: 27.0 kB
- Tags: Python 3
- Uploaded using Trusted Publishing? No
- Uploaded via: twine/6.2.0 CPython/3.12.12
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
a2b9b3c1ebf87fc4171bbbf62a7eb72a45892c5dd8323929475008eb5235952f
|
|
| MD5 |
e61ed166e48cda02a6e6c23f5e74d717
|
|
| BLAKE2b-256 |
51f14633e20713481b53c8768a8ba4846a7969fe8bf236c7a40279709ffd36dd
|