quickserve 1.2.0
A lightweight Python web server library with zero external dependencies
License: MIT
Requires Python: >=3.7
Keywords: web, server, framework, http, lightweight, no-dependencies

# QuickServe

Une librairie Python légère pour créer un serveur web simple **sans dépendances externes**.

## Améliorations v1.1.0

✨ **Cookies** - Support natif de lecture/écriture de cookies  
✨ **CORS** - Activation facile de CORS  
✨ **Logging** - Logging structuré en mode debug  
✨ **Réponses HTML** - Classe `HtmlResponse` pour HTML  
✨ **Redirections** - Classe `RedirectResponse` pour redirects  
✨ **Middleware** - Système extensible de middleware  
✨ **Fichiers statiques** - Classe `StaticFileServer`  
✨ **OPTIONS** - Support de la méthode OPTIONS  

## Caractéristiques

✅ **Serveur HTTP** - Lance sur n'importe quel port et host  
✅ **Routes simples** - Utilisez des décorateurs pour définir les routes  
✅ **Réponses flexibles** - Texte, JSON, HTML ou réponses personnalisées  
✅ **Zéro dépendances** - Utilise uniquement la stdlib Python  
✅ **Paramètres de route** - Support des chemins dynamiques (ex: `/users/{id}`)  
✅ **Méthodes HTTP** - GET, POST, PUT, DELETE, PATCH, OPTIONS  
✅ **Requêtes complètes** - Accès aux paramètres, body, headers, cookies  
✅ **Cookies** - Lecture et écriture facile de cookies  
✅ **CORS** - Support natif de CORS  
✅ **Logging** - Logging configurable  
✅ **Middleware** - Système de middleware extensible  
✅ **Fichiers statiques** - Support pour servir des fichiers statiques  

## Installation

```bash
cd quickserve
python example.py
```

## Utilisation rapide

```python
from quickserve import QuickServer, JsonResponse, TextResponse, HtmlResponse

app = QuickServer(port=5000, host='localhost', cors=True, debug=True)

# Route simple
@app.get('/')
def hello(request):
    return 'Hello, World!'

# Réponse JSON
@app.get('/api/data')
def get_data(request):
    return JsonResponse({'key': 'value'})

# Paramètres de route
@app.get('/users/{user_id}')
def get_user(request, user_id):
    return JsonResponse({'id': user_id, 'name': f'User {user_id}'})

# POST avec body
@app.post('/api/users')
def create_user(request):
    data = request['body']  # JSON body
    return JsonResponse({'created': True, 'id': 1}, status_code=201)

# Requête GET avec paramètres
@app.get('/search')
def search(request):
    query = request['query'].get('q', '')  # ?q=terme
    return JsonResponse({'query': query, 'results': []})

# Gestion des cookies
@app.get('/login')
def login(request):
    response = JsonResponse({'logged_in': True})
    response.set_cookie('session', 'abc123', max_age=3600)
    return response

if __name__ == '__main__':
    app.run(debug=True)
```

## API

### QuickServer

```python
app = QuickServer(
    port=8000,          # Port du serveur
    host='localhost',   # Host (127.0.0.1, 0.0.0.0, etc)
    cors=True,          # Activer CORS
    cors_origin='*',    # Origine CORS
    debug=True          # Mode debug
)

app.run(debug=True)        # Lance le serveur
app.enable_cors('*')       # Active CORS
app.stop()                 # Arrête le serveur
```

#### Décorateurs

```python
@app.get(path)
@app.post(path)
@app.put(path)
@app.delete(path)
@app.patch(path)
def handler(request, **params):
    return response
```

### Objet Request

```python
{
    'method': 'GET',           # Méthode HTTP
    'path': '/api/users',      # Chemin
    'query': {'page': '1'},    # Paramètres URL
    'body': {...},             # Données JSON ou texte
    'headers': {...},          # Headers HTTP
    'cookies': {...}           # Cookies
}
```

### Réponses

```python
# Réponse texte
TextResponse(content, status_code=200, headers={})

# Réponse JSON
JsonResponse(data, status_code=200, headers={})

# Réponse HTML
HtmlResponse(content, status_code=200, headers={})

# Redirection
RedirectResponse(location, status_code=302, headers={})

# Ou retournez simplement une chaîne ou un dictionnaire
def handler(request):
    return 'Simple text'       # → TextResponse
    return {'key': 'value'}    # → JsonResponse
```

### Gestion des Cookies

```python
@app.get('/set-cookie')
def set_cookie(request):
    response = JsonResponse({'message': 'Cookie set'})
    response.set_cookie(
        name='user_id',
        value='12345',
        max_age=3600,      # Secondes
        path='/',
        domain=None,
        secure=False,
        http_only=True
    )
    return response

@app.get('/read-cookie')
def read_cookie(request):
    cookies = request['cookies']
    user_id = cookies.get('user_id')
    return JsonResponse({'user_id': user_id})
```

## Exemples avancés

### API REST complète

```python
from quickserve import QuickServer, JsonResponse

app = QuickServer(port=5000, debug=True)

users = {
    1: {'id': 1, 'name': 'Alice'},
    2: {'id': 2, 'name': 'Bob'}
}

@app.get('/users')
def list_users(request):
    return JsonResponse(list(users.values()))

@app.get('/users/{user_id}')
def get_user(request, user_id):
    user = users.get(int(user_id))
    if not user:
        return JsonResponse({'error': 'Not found'}, status_code=404)
    return JsonResponse(user)

@app.post('/users')
def create_user(request):
    data = request['body']
    new_id = max(users.keys()) + 1
    users[new_id] = {'id': new_id, **data}
    return JsonResponse(users[new_id], status_code=201)

@app.put('/users/{user_id}')
def update_user(request, user_id):
    uid = int(user_id)
    if uid not in users:
        return JsonResponse({'error': 'Not found'}, status_code=404)
    users[uid].update(request['body'])
    return JsonResponse(users[uid])

@app.delete('/users/{user_id}')
def delete_user(request, user_id):
    uid = int(user_id)
    if uid in users:
        del users[uid]
    return JsonResponse({'deleted': True})

if __name__ == '__main__':
    app.run(debug=True)
```

### Serveur avec HTML

```python
from quickserve import QuickServer, HtmlResponse

app = QuickServer(port=8000, debug=True)

@app.get('/')
def home(request):
    html = '''
    <html>
        <head><title>Accueil</title></head>
        <body>
            <h1>Bienvenue</h1>
            <p>Serveur QuickServe actif !</p>
        </body>
    </html>
    '''
    return HtmlResponse(html)

if __name__ == '__main__':
    app.run(debug=True)
```

### Validation de données

```python
from quickserve import QuickServer, JsonResponse

app = QuickServer(port=5000, debug=True)

@app.post('/api/validate')
def validate_data(request):
    data = request['body']
    
    errors = []
    if not data.get('name'):
        errors.append('Name is required')
    if not data.get('email'):
        errors.append('Email is required')
    
    if errors:
        return JsonResponse({'errors': errors}, status_code=422)
    
    return JsonResponse({'valid': True, 'data': data})

if __name__ == '__main__':
    app.run(debug=True)
```

### Gestion des erreurs

```python
from quickserve import QuickServer, JsonResponse

app = QuickServer(port=5000, debug=True)

@app.get('/api/divide/{a}/{b}')
def divide(request, a, b):
    try:
        result = int(a) / int(b)
        return JsonResponse({'result': result})
    except ValueError:
        return JsonResponse({'error': 'Invalid numbers'}, status_code=400)
    except ZeroDivisionError:
        return JsonResponse({'error': 'Division by zero'}, status_code=400)
    except Exception as e:
        return JsonResponse({'error': str(e)}, status_code=500)

if __name__ == '__main__':
    app.run(debug=True)
```

## Middleware

QuickServe propose un système de middleware extensible :

```python
from quickserve import QuickServer, AuthenticationMiddleware

app = QuickServer(port=5000)

# Utiliser middleware d'authentification
auth = AuthenticationMiddleware(required_token='secret123')

@app.get('/api/protected')
def protected(request):
    return {'message': 'Accès accordé'}
```

Middlewares disponibles :
- `AuthenticationMiddleware` - Vérification de token Bearer
- `CORSMiddleware` - Gestion CORS
- `JsonErrorMiddleware` - Erreurs au format JSON
- `CompressionMiddleware` - Compression gzip

## Fichiers statiques

```python
from quickserve import QuickServer, StaticFileServer

app = QuickServer(port=8000)
static = StaticFileServer('public', url_prefix='/static')

@app.get('/static/{file}')
def serve_static(request, file):
    content, mime_type = static.read_file(request['path'])
    if content is None:
        return JsonResponse({'error': 'Not found'}, status_code=404)
    
    return Response(content, headers={'Content-Type': mime_type})
```

## Structure du projet

```
quickserve/
├── quickserve/
│   ├── __init__.py      # Exports principales
│   ├── server.py        # Classe QuickServer + RequestHandler
│   ├── routes.py        # Gestion des routes
│   ├── response.py      # Classes de réponse
│   ├── middleware.py    # Système de middleware
│   └── static.py        # Serveur de fichiers statiques
├── example.py           # Exemples complets
└── README.md            # Cette documentation
```

## Notes

- Le serveur utilise `http.server.HTTPServer` de la stdlib Python
- Aucune dépendance externe requise
- Idéal pour des prototypes, tests et petits projets
- Non recommandé pour la production (utiliser Flask, Django, FastAPI pour cela)
- Support natif CORS pour développement frontend
- Logging intégré en mode debug
- Gestion complète des cookies
- Compression gzip optionnelle (middleware)

## Licence

Libre d'utilisation