Metadata-Version: 2.4
Name: orbit-web-framework
Version: 1.0.2
Summary: Lightweight Python web framework built with pure standard library
Home-page: https://github.com/Zureu/Orbit-Web-Framework
Author: Orbit Framework Team
Author-email: ZureuRexzz@proton.me
License: MIT
Project-URL: Homepage, https://github.com/Zureu/Orbit-Web-Framework
Project-URL: Documentation, https://github.com/Zureu/Orbit-Web-Framework#readme
Project-URL: Repository, https://github.com/Zureu/Orbit-Web-Framework
Project-URL: Changelog, https://github.com/Zureu/Orbit-Web-Framework/blob/main/CHANGELOG_v1.0.2.md
Keywords: web,framework,http,server,socket,lightweight,pure-python,standard-library
Classifier: Development Status :: 4 - Beta
Classifier: Intended Audience :: Developers
Classifier: Topic :: Internet :: WWW/HTTP :: HTTP Servers
Classifier: Topic :: Internet :: WWW/HTTP :: WSGI :: Application
Classifier: License :: OSI Approved :: MIT License
Classifier: Programming Language :: Python :: 3
Classifier: Programming Language :: Python :: 3.8
Classifier: Programming Language :: Python :: 3.9
Classifier: Programming Language :: Python :: 3.10
Classifier: Programming Language :: Python :: 3.11
Classifier: Programming Language :: Python :: 3.12
Classifier: Operating System :: OS Independent
Requires-Python: >=3.8
Description-Content-Type: text/markdown
License-File: LICENSE
Dynamic: author-email
Dynamic: home-page
Dynamic: license-file
Dynamic: requires-python

![Orbit Icon](icon.jpg)

# Orbit Framework

**Lightweight Advanced Python Web Framework** built entirely with Python's standard library.

![Python Version](https://img.shields.io/badge/python-3.8%2B-blue)
![License](https://img.shields.io/badge/license-MIT-green)
![Dependencies](https://img.shields.io/badge/dependencies-none-brightgreen)
![Version](https://img.shields.io/badge/version-1.0.2-orange)

**Latest Release:** v1.0.2 (Access Logging) - [See CHANGELOG](CHANGELOG_v1.0.2.md)

## 🌟 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:

```bash
git clone https://github.com/yourusername/orbit.git
cd orbit
python example_app.py
```

Or include it in your project:

```python
from orbit import Orbit, Request, Response
```

## 🚀 Quick Start

### Basic Application

```python
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

```python
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

```python
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

```python
# 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`):

```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

```python
# Enable static file serving
app.static('static', url_prefix='/static')
```

Now files in `static/` are accessible at `/static/filename.css`

### Middleware

```python
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

```python
# 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

```python
@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)

```python
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

```python
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

```python
# 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

```python
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

1. **Request Validation**
   - Maximum request size
   - Header count limits
   - Path traversal protection
   - Header injection prevention

2. **Security Headers** (via middleware)
   - X-Content-Type-Options
   - X-Frame-Options
   - X-XSS-Protection

3. **Rate Limiting** (via middleware)
   - IP-based tracking
   - Configurable limits
   - Automatic cleanup

4. **CSRF Protection** (via middleware)
   - Token generation
   - Token validation
   - Session-based

5. **Secure Cookies**
   - HttpOnly flag
   - Secure flag
   - SameSite attribute

### Security Best Practices

```python
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

1. **Use Threading** for I/O-bound applications
   ```python
   app.run(use_threading=True, max_connections=100)
   ```

2. **Enable Static File Caching**
   ```python
   app.static('static', enable_cache=True, cache_max_age=3600)
   ```

3. **Optimize Route Ordering**
   - Register static routes before dynamic ones
   - Use route groups for organization

4. **Lazy Body Parsing**
   - Body only parsed when accessed
   - Use `request.get_json()` only when needed

## 🧪 Testing

```python
# 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. 🚀
