pyrest-framework


Namepyrest-framework JSON
Version 2.0.1 PyPI version JSON
download
home_pagehttps://github.com/mamadusamadev/pyrest-framework
SummaryFramework Python para criação de APIs REST - Estilo Express.js
upload_time2025-07-26 14:32:02
maintainerNone
docs_urlNone
authorMamadu Sama
requires_python>=3.7
licenseMIT
keywords api rest framework web http server express microframework ads education
VCS
bugtrack_url
requirements build certifi charset-normalizer colorama docutils id idna jaraco.classes jaraco.context jaraco.functools keyring markdown-it-py mdurl more-itertools nh3 packaging Pygments pyproject_hooks pywin32-ctypes readme_renderer requests requests-toolbelt rfc3986 rich setuptools twine urllib3 wheel
Travis-CI No Travis.
coveralls test coverage No coveralls.
            # PYREST-FRAMEWORK v2.0.1 - Documentação Técnica

## Visão Geral

O **PYREST-FRAMEWORK** é um framework Python moderno e robusto para criação de APIs REST, inspirado no Express.js do Node.js. Desenvolvido especificamente para projetos acadêmicos de Análise e Desenvolvimento de Sistemas (ADS), oferece uma experiência de desenvolvimento profissional com arquitetura MVC completa.

### Características Principais

- ✅ **Arquitetura MVC Completa**: Controllers, Services, Models e Repositories
- ✅ **Integração com Prisma ORM**: Suporte a PostgreSQL, MySQL e SQLite
- ✅ **Sistema de Validação Robusto**: Validação automática de dados
- ✅ **CLI Avançado**: Criação automática de projetos com estrutura completa
- ✅ **Middlewares Avançados**: CORS, logging, auth, rate limiting
- ✅ **Sintaxe Familiar**: Inspirado no Express.js
- ✅ **Documentação Extensa**: Guias completos e exemplos
- ✅ **Sistema de Testes**: Cobertura abrangente
- ✅ **Exemplos Práticos**: Código real e funcional

## Índice

1. [Instalação](#instalação)
2. [Primeiros Passos](#primeiros-passos)
3. [Conceitos Fundamentais](#conceitos-fundamentais)
4. [Roteamento](#roteamento)
5. [Request e Response](#request-e-response)
6. [Middlewares](#middlewares)
7. [Tratamento de Erros](#tratamento-de-erros)
8. [CLI (Command Line Interface)](#cli-command-line-interface)
9. [Exemplos Avançados](#exemplos-avançados)
10. [Testes](#testes)
11. [Deploy](#deploy)
12. [Referência da API](#referência-da-api)

---

## Instalação

### Requisitos do Sistema

- **Python**: 3.7 ou superior
- **Sistema Operacional**: Windows, macOS, Linux
- **Memória**: Mínimo 128MB RAM
- **Espaço**: Mínimo 50MB de espaço em disco

### Instalação via pip

```bash
pip install pyrest-framework
```

### Instalação em Desenvolvimento

```bash
git clone https://github.com/mamadusamadev/pyrest-framework.git
cd pyrest-framework
pip install -e .
```

### Verificação da Instalação

```bash
# Testa a instalação
python install_and_test.py

# Ou usa o CLI
pyrest info
```

---

## Primeiros Passos

### Hello World

```python
from pyrest import create_app

# Cria a aplicação
app = create_app()

# Define uma rota
@app.get('/')
def hello_world(req, res):
    res.json({
        "message": "Hello, PYREST-FRAMEWORK!",
        "version": "2.0.1"
    })

# Inicia o servidor
if __name__ == '__main__':
    app.listen(port=3000, debug=True)
```

### Usando o CLI

```bash
# Cria um novo projeto
pyrest create minha-api

# Entra no projeto
cd minha-api

# Inicia o servidor
pyrest serve --debug

# Ou inicia um servidor de exemplo
pyrest serve --quick
```

---

## Conceitos Fundamentais

### Arquitetura do Framework

O PYREST-FRAMEWORK segue uma arquitetura modular e extensível:

```
┌─────────────────┐
│   Application   │  ← Classe principal
├─────────────────┤
│    Routes       │  ← Sistema de roteamento
├─────────────────┤
│   Middlewares   │  ← Camada de middlewares
├─────────────────┤
│   Request/Res   │  ← Objetos HTTP
└─────────────────┘
```

### Fluxo de Requisição

1. **Requisição HTTP** chega ao servidor
2. **Middlewares** são executados em sequência
3. **Roteamento** encontra o handler correto
4. **Handler** processa a requisição
5. **Response** é enviada de volta

### Componentes Principais

#### PyRestFramework (App)
- Classe principal do framework
- Gerencia rotas, middlewares e configurações
- Responsável pelo ciclo de vida da aplicação

#### Route
- Representa uma rota HTTP
- Suporte a parâmetros dinâmicos (`:id`)
- Matching baseado em regex

#### Request
- Objeto que representa a requisição HTTP
- Parsing automático de JSON e form data
- Acesso a headers, query params, body

#### Response
- Objeto que representa a resposta HTTP
- Múltiplos formatos de resposta (JSON, HTML, XML)
- Headers de segurança e cache

---

## Roteamento

### Métodos HTTP Suportados

```python
@app.get('/users')           # GET
@app.post('/users')          # POST
@app.put('/users/:id')       # PUT
@app.delete('/users/:id')    # DELETE
@app.patch('/users/:id')     # PATCH
@app.options('/users')       # OPTIONS
```

### Parâmetros de Rota

```python
@app.get('/users/:id')
def get_user(req, res):
    user_id = req.params['id']  # Acessa o parâmetro
    res.json({"id": user_id})

# Requisição: GET /users/123
# Resultado: {"id": "123"}
```

### Query Parameters

```python
@app.get('/users')
def get_users(req, res):
    page = req.get_query('page', '1')
    limit = req.get_query('limit', '10')
    
    res.json({
        "page": page,
        "limit": limit
    })

# Requisição: GET /users?page=2&limit=20
```

### Múltiplas Rotas

```python
@app.get('/')
@app.get('/home')
def home(req, res):
    res.json({"message": "Welcome!"})
```

---

## Request e Response

### Objeto Request

#### Propriedades Principais

```python
req.method        # Método HTTP (GET, POST, etc.)
req.path          # Caminho da requisição
req.headers       # Headers HTTP (dict)
req.body          # Corpo da requisição (string)
req.params        # Parâmetros de rota (dict)
req.query         # Query parameters (dict)
req.json_data     # Dados JSON parseados (dict)
req.form_data     # Dados de formulário (dict)
```

#### Métodos Úteis

```python
# Headers
user_agent = req.get_header('user-agent', 'Unknown')

# Query Parameters
page = req.get_query('page', '1')

# Route Parameters
user_id = req.get_param('id')

# JSON Data
data = req.get_json()
name = req.get_json('name', 'Default')

# Form Data
form_data = req.get_form()
email = req.get_form('email')

# Verificações
if req.is_json():
    data = req.get_json()

if req.is_secure():
    # Requisição HTTPS
```

### Objeto Response

#### Métodos de Resposta

```python
# JSON Response
res.json({"message": "Success"})

# Text Response
res.send("Hello World")

# HTML Response
res.html("<h1>Hello</h1>")

# XML Response
res.xml("<root><message>Hello</message></root>")

# File Response
res.file(content, "file.txt", "text/plain")

# Redirect
res.redirect('/new-page')
```

#### Headers e Status

```python
# Status Code
res.status(201).json(data)

# Headers
res.header('Content-Type', 'application/json')
res.header('Authorization', 'Bearer token')

# Multiple Headers
res.headers_dict({
    'Content-Type': 'application/json',
    'Cache-Control': 'no-cache'
})
```

#### Cookies e CORS

```python
# Cookies
res.cookie('session', 'abc123', max_age=3600, secure=True)
res.clear_cookie('session')

# CORS
res.cors(origin='https://example.com', credentials=True)
```

---

## Middlewares

### Middlewares Incluídos

#### CORS (Cross-Origin Resource Sharing)

```python
from pyrest import Middlewares

app.use(Middlewares.cors())
app.use(Middlewares.cors(
    origin='https://example.com',
    credentials=True
))
```

#### Logger

```python
app.use(Middlewares.logger())        # combined
app.use(Middlewares.logger('dev'))   # desenvolvimento
app.use(Middlewares.logger('common')) # comum
```

#### Body Parser

```python
app.use(Middlewares.body_parser())
app.use(Middlewares.json_parser())
app.use(Middlewares.urlencoded())
```

#### Security Headers

```python
app.use(Middlewares.security_headers())
```

#### Rate Limiting

```python
app.use(Middlewares.rate_limit(
    max_requests=100,
    window_ms=60000
))
```

#### Authentication

```python
app.use(Middlewares.auth_required())
```

#### Static Files

```python
app.use(Middlewares.static_files('public', '/static'))
```

### Middleware Personalizado

```python
def custom_middleware(req, res):
    # Adiciona timestamp à requisição
    req.timestamp = time.time()
    
    # Continua a execução
    return True

app.use(custom_middleware)
```

### Middleware que Para a Execução

```python
def auth_middleware(req, res):
    token = req.get_header('authorization')
    
    if not token:
        res.status(401).json({
            "error": "Unauthorized"
        })
        return False  # Para a execução
    
    return True  # Continua a execução

app.use(auth_middleware)
```

---

## Tratamento de Erros

### Handlers de Erro Personalizados

```python
@app.error_handler(404)
def not_found(req, res):
    res.json({
        "error": "Not Found",
        "message": f"Route '{req.path}' not found"
    })

@app.error_handler(500)
def server_error(req, res):
    res.json({
        "error": "Internal Server Error",
        "message": "Something went wrong"
    })
```

### Tratamento de Exceções

```python
@app.get('/users/:id')
def get_user(req, res):
    try:
        user_id = int(req.params['id'])
        user = find_user(user_id)
        
        if not user:
            res.status(404).json({
                "error": "User not found"
            })
            return
        
        res.json(user)
        
    except ValueError:
        res.status(400).json({
            "error": "Invalid ID format"
        })
    except Exception as e:
        res.status(500).json({
            "error": "Internal server error",
            "message": str(e)
        })
```

### Middleware de Tratamento Global

```python
def error_handler_middleware(req, res):
    try:
        # Continua a execução
        pass
    except Exception as e:
        res.status(500).json({
            "error": "Internal Server Error",
            "message": str(e)
        })
        return False

app.use(error_handler_middleware)
```

---

## CLI (Command Line Interface)

### Comandos Disponíveis

#### `pyrest create <nome>`

Cria um novo projeto com estrutura completa.

```bash
# Criação básica
pyrest create minha-api

# Com diretório específico
pyrest create minha-api -o /path/to/output
```

**Estrutura criada:**
```
minha-api/
├── app.py              # Aplicação principal
├── README.md           # Documentação
├── requirements.txt    # Dependências
├── .gitignore         # Git ignore
├── routes/            # Rotas organizadas
├── middlewares/       # Middlewares customizados
├── models/            # Modelos de dados
├── utils/             # Utilitários
└── tests/             # Testes
```

#### `pyrest serve`

Inicia um servidor PyRest.

```bash
# Carrega app.py (padrão)
pyrest serve

# Carrega arquivo específico
pyrest serve app.py

# Servidor de exemplo
pyrest serve --quick

# Configurações específicas
pyrest serve --port 8080 --host 0.0.0.0 --debug
```

#### `pyrest info`

Mostra informações sobre o framework.

```bash
pyrest info
```

### Opções do Comando Serve

| Opção | Descrição | Padrão |
|-------|-----------|--------|
| `--port` | Porta do servidor | 3000 |
| `--host` | Host do servidor | localhost |
| `--debug` | Modo debug | False |
| `--quick` | Servidor de exemplo | False |

---

## Exemplos Avançados

### API REST Completa

```python
from pyrest import create_app, Middlewares

app = create_app()

# Middlewares
app.use(Middlewares.cors())
app.use(Middlewares.logger('dev'))
app.use(Middlewares.json_parser())

# Simula banco de dados
users = []

# GET /users
@app.get('/users')
def get_users(req, res):
    page = int(req.get_query('page', '1'))
    limit = int(req.get_query('limit', '10'))
    
    start = (page - 1) * limit
    end = start + limit
    
    paginated_users = users[start:end]
    
    res.json({
        "users": paginated_users,
        "pagination": {
            "page": page,
            "limit": limit,
            "total": len(users)
        }
    })

# POST /users
@app.post('/users')
def create_user(req, res):
    data = req.json_data
    
    if not data or 'name' not in data:
        res.status(400).json({
            "error": "Name is required"
        })
        return
    
    new_user = {
        "id": len(users) + 1,
        "name": data['name'],
        "email": data.get('email', '')
    }
    
    users.append(new_user)
    
    res.status(201).json(new_user)

# GET /users/:id
@app.get('/users/:id')
def get_user(req, res):
    try:
        user_id = int(req.params['id'])
        user = next((u for u in users if u['id'] == user_id), None)
        
        if user:
            res.json(user)
        else:
            res.status(404).json({
                "error": "User not found"
            })
    except ValueError:
        res.status(400).json({
            "error": "Invalid ID"
        })

# PUT /users/:id
@app.put('/users/:id')
def update_user(req, res):
    try:
        user_id = int(req.params['id'])
        data = req.json_data
        
        user_index = next((i for i, u in enumerate(users) 
                          if u['id'] == user_id), None)
        
        if user_index is None:
            res.status(404).json({
                "error": "User not found"
            })
            return
        
        users[user_index].update(data)
        users[user_index]['id'] = user_id
        
        res.json(users[user_index])
        
    except ValueError:
        res.status(400).json({
            "error": "Invalid ID"
        })

# DELETE /users/:id
@app.delete('/users/:id')
def delete_user(req, res):
    try:
        user_id = int(req.params['id'])
        
        user_index = next((i for i, u in enumerate(users) 
                          if u['id'] == user_id), None)
        
        if user_index is None:
            res.status(404).json({
                "error": "User not found"
            })
            return
        
        deleted_user = users.pop(user_index)
        
        res.json({
            "message": "User deleted",
            "user": deleted_user
        })
        
    except ValueError:
        res.status(400).json({
            "error": "Invalid ID"
        })

if __name__ == '__main__':
    app.listen(port=3000, debug=True)
```

### Autenticação com JWT

```python
import jwt
import hashlib
from datetime import datetime, timedelta
from pyrest import create_app, Middlewares

app = create_app()

# Configurações
JWT_SECRET = "your-secret-key"
JWT_EXPIRATION = 3600

# Middleware de autenticação
def auth_middleware(req, res):
    # Rotas públicas
    public_routes = ['/login', '/register']
    
    if req.path in public_routes:
        return True
    
    # Verifica token
    auth_header = req.get_header('authorization')
    if not auth_header or not auth_header.startswith('Bearer '):
        res.status(401).json({
            "error": "Token required"
        })
        return False
    
    token = auth_header[7:]
    
    try:
        payload = jwt.decode(token, JWT_SECRET, algorithms=['HS256'])
        req.user = payload
        return True
    except:
        res.status(401).json({
            "error": "Invalid token"
        })
        return False

app.use(auth_middleware)

# Login
@app.post('/login')
def login(req, res):
    data = req.json_data
    
    # Validação básica
    if not data or 'username' not in data or 'password' not in data:
        res.status(400).json({
            "error": "Username and password required"
        })
        return
    
    # Aqui você faria a validação real
    if data['username'] == 'admin' and data['password'] == 'password':
        payload = {
            'user_id': 1,
            'username': data['username'],
            'exp': datetime.utcnow() + timedelta(seconds=JWT_EXPIRATION)
        }
        
        token = jwt.encode(payload, JWT_SECRET, algorithm='HS256')
        
        res.json({
            "message": "Login successful",
            "token": token,
            "expires_in": JWT_EXPIRATION
        })
    else:
        res.status(401).json({
            "error": "Invalid credentials"
        })

# Rota protegida
@app.get('/profile')
def get_profile(req, res):
    res.json({
        "user_id": req.user['user_id'],
        "username": req.user['username']
    })

if __name__ == '__main__':
    app.listen(port=3000, debug=True)
```

---

## Testes

### Executando Testes

```bash
# Todos os testes
pytest

# Com cobertura
pytest --cov=pyrest

# Testes específicos
pytest tests/test_core.py -v

# Com relatório HTML
pytest --cov=pyrest --cov-report=html
```

### Escrevendo Testes

```python
import unittest
from unittest.mock import Mock
from pyrest import create_app

class TestAPI(unittest.TestCase):
    def setUp(self):
        self.app = create_app()
    
    def test_home_route(self):
        # Simula requisição
        req = Mock()
        req.method = 'GET'
        req.path = '/'
        
        res = Mock()
        res.json = Mock()
        
        # Executa handler
        @self.app.get('/')
        def home(req, res):
            res.json({"message": "Hello"})
        
        # Verifica se rota foi registrada
        self.assertEqual(len(self.app.routes), 1)
        route = self.app.routes[0]
        self.assertEqual(route.method, 'GET')
        self.assertEqual(route.path, '/')
```

### Testes de Integração

```python
import requests

def test_api_integration():
    # Inicia servidor em thread separada
    import threading
    import time
    
    def start_server():
        app.listen(port=3001)
    
    server_thread = threading.Thread(target=start_server)
    server_thread.daemon = True
    server_thread.start()
    
    time.sleep(1)  # Aguarda servidor iniciar
    
    # Testa API
    response = requests.get('http://localhost:3001/')
    assert response.status_code == 200
    assert response.json()['message'] == 'Hello'
```

---

## Deploy

### Ambiente de Desenvolvimento

```bash
# Instalação
pip install -r requirements.txt

# Execução
python app.py

# Ou usando CLI
pyrest serve --debug
```

### Ambiente de Produção

```bash
# Instalação
pip install pyrest-framework

# Execução
pyrest serve --host 0.0.0.0 --port 80
```

### Docker

```dockerfile
FROM python:3.9-slim

WORKDIR /app

COPY requirements.txt .
RUN pip install -r requirements.txt

COPY . .

EXPOSE 3000

CMD ["python", "app.py"]
```

### Nginx (Proxy Reverso)

```nginx
server {
    listen 80;
    server_name api.example.com;
    
    location / {
        proxy_pass http://localhost:3000;
        proxy_set_header Host $host;
        proxy_set_header X-Real-IP $remote_addr;
        proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
        proxy_set_header X-Forwarded-Proto $scheme;
    }
}
```

### Systemd Service

```ini
[Unit]
Description=PyRest API
After=network.target

[Service]
Type=simple
User=www-data
WorkingDirectory=/var/www/api
ExecStart=/usr/bin/python3 app.py
Restart=always

[Install]
WantedBy=multi-user.target
```

---

## Referência da API

Para documentação completa da API, consulte:
- [API Reference](API_REFERENCE.md) - Referência detalhada de todas as classes e métodos
- [Changelog](CHANGELOG.md) - Histórico de versões e mudanças

### Classes Principais

#### PyRestFramework
- `get(path, handler=None)` - Define rota GET
- `post(path, handler=None)` - Define rota POST
- `put(path, handler=None)` - Define rota PUT
- `delete(path, handler=None)` - Define rota DELETE
- `patch(path, handler=None)` - Define rota PATCH
- `options(path, handler=None)` - Define rota OPTIONS
- `use(middleware)` - Adiciona middleware
- `error_handler(status_code)` - Define handler de erro
- `listen(port=3000, host='localhost', debug=False)` - Inicia servidor

#### Request
- `get_header(name, default=None)` - Obtém header
- `get_query(name, default=None)` - Obtém query parameter
- `get_param(name, default=None)` - Obtém parâmetro de rota
- `get_json(key=None, default=None)` - Obtém dados JSON
- `get_form(key=None, default=None)` - Obtém dados de formulário
- `is_json()` - Verifica se é JSON
- `is_form()` - Verifica se é form data
- `is_secure()` - Verifica se é HTTPS

#### Response
- `status(code)` - Define status code
- `header(key, value)` - Define header
- `json(data, indent=None, ensure_ascii=False)` - Resposta JSON
- `send(data)` - Resposta texto
- `html(content)` - Resposta HTML
- `xml(content)` - Resposta XML
- `file(content, filename, mimetype=None)` - Resposta arquivo
- `redirect(url, permanent=False)` - Redirecionamento
- `cookie(name, value, **options)` - Define cookie
- `cors(**options)` - Headers CORS

#### Middlewares
- `cors(**options)` - Middleware CORS
- `logger(format='combined')` - Middleware de logging
- `body_parser()` - Middleware body parser
- `json_parser()` - Middleware JSON parser
- `urlencoded()` - Middleware URL encoded
- `static_files(directory, prefix='/static')` - Middleware static files
- `rate_limit(max_requests=100, window_ms=60000)` - Middleware rate limiting
- `auth_required()` - Middleware de autenticação
- `error_handler()` - Middleware de tratamento de erros
- `security_headers()` - Middleware de headers de segurança

---

## Suporte e Comunidade

### Recursos Adicionais

- **GitHub**: [https://github.com/mamadusamadev/pyrest-framework](https://github.com/mamadusamadev/pyrest-framework)
- **Issues**: Para reportar bugs ou solicitar features
- **Discussions**: Para dúvidas e discussões
- **Wiki**: Documentação adicional e tutoriais

### Contribuindo

1. Fork o projeto
2. Crie uma branch para sua feature
3. Commit suas mudanças
4. Push para a branch
5. Abra um Pull Request

### Licença

Este projeto está licenciado sob a Licença MIT - veja o arquivo [LICENSE](../LICENSE) para detalhes.

---

## Conclusão

O PYREST-FRAMEWORK v2.0.1 oferece uma solução completa e profissional para desenvolvimento de APIs REST em Python. Com sua arquitetura MVC moderna, integração com Prisma ORM, sistema de validação robusto e CLI avançado, é ideal tanto para aprendizado quanto para projetos reais em produção.

### Principais Melhorias da v2.0.1

- ✅ **Arquitetura MVC Completa**: Separação clara entre Controllers, Services, Models e Repositories
- ✅ **Integração com Prisma**: Suporte nativo a PostgreSQL, MySQL e SQLite
- ✅ **Sistema de Validação**: Validação automática de dados com múltiplos validadores
- ✅ **CLI Avançado**: Criação automática de projetos com estrutura profissional
- ✅ **Fallback Inteligente**: Funciona com ou sem banco de dados
- ✅ **Documentação Completa**: Guias detalhados para todas as funcionalidades

Para começar rapidamente:

```bash
# Instalação básica
pip install pyrest-framework

# Instalação com suporte a banco de dados
pip install pyrest-framework[database]

# Criação de projeto com estrutura MVC completa
pyrest create minha-api

# Execução
cd minha-api
pyrest serve --debug
```

**Happy coding! 🚀**

            

Raw data

            {
    "_id": null,
    "home_page": "https://github.com/mamadusamadev/pyrest-framework",
    "name": "pyrest-framework",
    "maintainer": null,
    "docs_url": null,
    "requires_python": ">=3.7",
    "maintainer_email": "Mamadu Sama <mamadusama19@gmail.com>",
    "keywords": "api, rest, framework, web, http, server, express, microframework, ads, education",
    "author": "Mamadu Sama",
    "author_email": "Mamadu Sama <mamadusama19@gmail.com>",
    "download_url": "https://files.pythonhosted.org/packages/fc/91/bc555ae291145dcbeed2c42b97c64ce7968b3702948edb32290983778c78/pyrest_framework-2.0.1.tar.gz",
    "platform": "any",
    "description": "# PYREST-FRAMEWORK v2.0.1 - Documenta\u00e7\u00e3o T\u00e9cnica\r\n\r\n## Vis\u00e3o Geral\r\n\r\nO **PYREST-FRAMEWORK** \u00e9 um framework Python moderno e robusto para cria\u00e7\u00e3o de APIs REST, inspirado no Express.js do Node.js. Desenvolvido especificamente para projetos acad\u00eamicos de An\u00e1lise e Desenvolvimento de Sistemas (ADS), oferece uma experi\u00eancia de desenvolvimento profissional com arquitetura MVC completa.\r\n\r\n### Caracter\u00edsticas Principais\r\n\r\n- \u2705 **Arquitetura MVC Completa**: Controllers, Services, Models e Repositories\r\n- \u2705 **Integra\u00e7\u00e3o com Prisma ORM**: Suporte a PostgreSQL, MySQL e SQLite\r\n- \u2705 **Sistema de Valida\u00e7\u00e3o Robusto**: Valida\u00e7\u00e3o autom\u00e1tica de dados\r\n- \u2705 **CLI Avan\u00e7ado**: Cria\u00e7\u00e3o autom\u00e1tica de projetos com estrutura completa\r\n- \u2705 **Middlewares Avan\u00e7ados**: CORS, logging, auth, rate limiting\r\n- \u2705 **Sintaxe Familiar**: Inspirado no Express.js\r\n- \u2705 **Documenta\u00e7\u00e3o Extensa**: Guias completos e exemplos\r\n- \u2705 **Sistema de Testes**: Cobertura abrangente\r\n- \u2705 **Exemplos Pr\u00e1ticos**: C\u00f3digo real e funcional\r\n\r\n## \u00cdndice\r\n\r\n1. [Instala\u00e7\u00e3o](#instala\u00e7\u00e3o)\r\n2. [Primeiros Passos](#primeiros-passos)\r\n3. [Conceitos Fundamentais](#conceitos-fundamentais)\r\n4. [Roteamento](#roteamento)\r\n5. [Request e Response](#request-e-response)\r\n6. [Middlewares](#middlewares)\r\n7. [Tratamento de Erros](#tratamento-de-erros)\r\n8. [CLI (Command Line Interface)](#cli-command-line-interface)\r\n9. [Exemplos Avan\u00e7ados](#exemplos-avan\u00e7ados)\r\n10. [Testes](#testes)\r\n11. [Deploy](#deploy)\r\n12. [Refer\u00eancia da API](#refer\u00eancia-da-api)\r\n\r\n---\r\n\r\n## Instala\u00e7\u00e3o\r\n\r\n### Requisitos do Sistema\r\n\r\n- **Python**: 3.7 ou superior\r\n- **Sistema Operacional**: Windows, macOS, Linux\r\n- **Mem\u00f3ria**: M\u00ednimo 128MB RAM\r\n- **Espa\u00e7o**: M\u00ednimo 50MB de espa\u00e7o em disco\r\n\r\n### Instala\u00e7\u00e3o via pip\r\n\r\n```bash\r\npip install pyrest-framework\r\n```\r\n\r\n### Instala\u00e7\u00e3o em Desenvolvimento\r\n\r\n```bash\r\ngit clone https://github.com/mamadusamadev/pyrest-framework.git\r\ncd pyrest-framework\r\npip install -e .\r\n```\r\n\r\n### Verifica\u00e7\u00e3o da Instala\u00e7\u00e3o\r\n\r\n```bash\r\n# Testa a instala\u00e7\u00e3o\r\npython install_and_test.py\r\n\r\n# Ou usa o CLI\r\npyrest info\r\n```\r\n\r\n---\r\n\r\n## Primeiros Passos\r\n\r\n### Hello World\r\n\r\n```python\r\nfrom pyrest import create_app\r\n\r\n# Cria a aplica\u00e7\u00e3o\r\napp = create_app()\r\n\r\n# Define uma rota\r\n@app.get('/')\r\ndef hello_world(req, res):\r\n    res.json({\r\n        \"message\": \"Hello, PYREST-FRAMEWORK!\",\r\n        \"version\": \"2.0.1\"\r\n    })\r\n\r\n# Inicia o servidor\r\nif __name__ == '__main__':\r\n    app.listen(port=3000, debug=True)\r\n```\r\n\r\n### Usando o CLI\r\n\r\n```bash\r\n# Cria um novo projeto\r\npyrest create minha-api\r\n\r\n# Entra no projeto\r\ncd minha-api\r\n\r\n# Inicia o servidor\r\npyrest serve --debug\r\n\r\n# Ou inicia um servidor de exemplo\r\npyrest serve --quick\r\n```\r\n\r\n---\r\n\r\n## Conceitos Fundamentais\r\n\r\n### Arquitetura do Framework\r\n\r\nO PYREST-FRAMEWORK segue uma arquitetura modular e extens\u00edvel:\r\n\r\n```\r\n\u250c\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2510\r\n\u2502   Application   \u2502  \u2190 Classe principal\r\n\u251c\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2524\r\n\u2502    Routes       \u2502  \u2190 Sistema de roteamento\r\n\u251c\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2524\r\n\u2502   Middlewares   \u2502  \u2190 Camada de middlewares\r\n\u251c\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2524\r\n\u2502   Request/Res   \u2502  \u2190 Objetos HTTP\r\n\u2514\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2518\r\n```\r\n\r\n### Fluxo de Requisi\u00e7\u00e3o\r\n\r\n1. **Requisi\u00e7\u00e3o HTTP** chega ao servidor\r\n2. **Middlewares** s\u00e3o executados em sequ\u00eancia\r\n3. **Roteamento** encontra o handler correto\r\n4. **Handler** processa a requisi\u00e7\u00e3o\r\n5. **Response** \u00e9 enviada de volta\r\n\r\n### Componentes Principais\r\n\r\n#### PyRestFramework (App)\r\n- Classe principal do framework\r\n- Gerencia rotas, middlewares e configura\u00e7\u00f5es\r\n- Respons\u00e1vel pelo ciclo de vida da aplica\u00e7\u00e3o\r\n\r\n#### Route\r\n- Representa uma rota HTTP\r\n- Suporte a par\u00e2metros din\u00e2micos (`:id`)\r\n- Matching baseado em regex\r\n\r\n#### Request\r\n- Objeto que representa a requisi\u00e7\u00e3o HTTP\r\n- Parsing autom\u00e1tico de JSON e form data\r\n- Acesso a headers, query params, body\r\n\r\n#### Response\r\n- Objeto que representa a resposta HTTP\r\n- M\u00faltiplos formatos de resposta (JSON, HTML, XML)\r\n- Headers de seguran\u00e7a e cache\r\n\r\n---\r\n\r\n## Roteamento\r\n\r\n### M\u00e9todos HTTP Suportados\r\n\r\n```python\r\n@app.get('/users')           # GET\r\n@app.post('/users')          # POST\r\n@app.put('/users/:id')       # PUT\r\n@app.delete('/users/:id')    # DELETE\r\n@app.patch('/users/:id')     # PATCH\r\n@app.options('/users')       # OPTIONS\r\n```\r\n\r\n### Par\u00e2metros de Rota\r\n\r\n```python\r\n@app.get('/users/:id')\r\ndef get_user(req, res):\r\n    user_id = req.params['id']  # Acessa o par\u00e2metro\r\n    res.json({\"id\": user_id})\r\n\r\n# Requisi\u00e7\u00e3o: GET /users/123\r\n# Resultado: {\"id\": \"123\"}\r\n```\r\n\r\n### Query Parameters\r\n\r\n```python\r\n@app.get('/users')\r\ndef get_users(req, res):\r\n    page = req.get_query('page', '1')\r\n    limit = req.get_query('limit', '10')\r\n    \r\n    res.json({\r\n        \"page\": page,\r\n        \"limit\": limit\r\n    })\r\n\r\n# Requisi\u00e7\u00e3o: GET /users?page=2&limit=20\r\n```\r\n\r\n### M\u00faltiplas Rotas\r\n\r\n```python\r\n@app.get('/')\r\n@app.get('/home')\r\ndef home(req, res):\r\n    res.json({\"message\": \"Welcome!\"})\r\n```\r\n\r\n---\r\n\r\n## Request e Response\r\n\r\n### Objeto Request\r\n\r\n#### Propriedades Principais\r\n\r\n```python\r\nreq.method        # M\u00e9todo HTTP (GET, POST, etc.)\r\nreq.path          # Caminho da requisi\u00e7\u00e3o\r\nreq.headers       # Headers HTTP (dict)\r\nreq.body          # Corpo da requisi\u00e7\u00e3o (string)\r\nreq.params        # Par\u00e2metros de rota (dict)\r\nreq.query         # Query parameters (dict)\r\nreq.json_data     # Dados JSON parseados (dict)\r\nreq.form_data     # Dados de formul\u00e1rio (dict)\r\n```\r\n\r\n#### M\u00e9todos \u00dateis\r\n\r\n```python\r\n# Headers\r\nuser_agent = req.get_header('user-agent', 'Unknown')\r\n\r\n# Query Parameters\r\npage = req.get_query('page', '1')\r\n\r\n# Route Parameters\r\nuser_id = req.get_param('id')\r\n\r\n# JSON Data\r\ndata = req.get_json()\r\nname = req.get_json('name', 'Default')\r\n\r\n# Form Data\r\nform_data = req.get_form()\r\nemail = req.get_form('email')\r\n\r\n# Verifica\u00e7\u00f5es\r\nif req.is_json():\r\n    data = req.get_json()\r\n\r\nif req.is_secure():\r\n    # Requisi\u00e7\u00e3o HTTPS\r\n```\r\n\r\n### Objeto Response\r\n\r\n#### M\u00e9todos de Resposta\r\n\r\n```python\r\n# JSON Response\r\nres.json({\"message\": \"Success\"})\r\n\r\n# Text Response\r\nres.send(\"Hello World\")\r\n\r\n# HTML Response\r\nres.html(\"<h1>Hello</h1>\")\r\n\r\n# XML Response\r\nres.xml(\"<root><message>Hello</message></root>\")\r\n\r\n# File Response\r\nres.file(content, \"file.txt\", \"text/plain\")\r\n\r\n# Redirect\r\nres.redirect('/new-page')\r\n```\r\n\r\n#### Headers e Status\r\n\r\n```python\r\n# Status Code\r\nres.status(201).json(data)\r\n\r\n# Headers\r\nres.header('Content-Type', 'application/json')\r\nres.header('Authorization', 'Bearer token')\r\n\r\n# Multiple Headers\r\nres.headers_dict({\r\n    'Content-Type': 'application/json',\r\n    'Cache-Control': 'no-cache'\r\n})\r\n```\r\n\r\n#### Cookies e CORS\r\n\r\n```python\r\n# Cookies\r\nres.cookie('session', 'abc123', max_age=3600, secure=True)\r\nres.clear_cookie('session')\r\n\r\n# CORS\r\nres.cors(origin='https://example.com', credentials=True)\r\n```\r\n\r\n---\r\n\r\n## Middlewares\r\n\r\n### Middlewares Inclu\u00eddos\r\n\r\n#### CORS (Cross-Origin Resource Sharing)\r\n\r\n```python\r\nfrom pyrest import Middlewares\r\n\r\napp.use(Middlewares.cors())\r\napp.use(Middlewares.cors(\r\n    origin='https://example.com',\r\n    credentials=True\r\n))\r\n```\r\n\r\n#### Logger\r\n\r\n```python\r\napp.use(Middlewares.logger())        # combined\r\napp.use(Middlewares.logger('dev'))   # desenvolvimento\r\napp.use(Middlewares.logger('common')) # comum\r\n```\r\n\r\n#### Body Parser\r\n\r\n```python\r\napp.use(Middlewares.body_parser())\r\napp.use(Middlewares.json_parser())\r\napp.use(Middlewares.urlencoded())\r\n```\r\n\r\n#### Security Headers\r\n\r\n```python\r\napp.use(Middlewares.security_headers())\r\n```\r\n\r\n#### Rate Limiting\r\n\r\n```python\r\napp.use(Middlewares.rate_limit(\r\n    max_requests=100,\r\n    window_ms=60000\r\n))\r\n```\r\n\r\n#### Authentication\r\n\r\n```python\r\napp.use(Middlewares.auth_required())\r\n```\r\n\r\n#### Static Files\r\n\r\n```python\r\napp.use(Middlewares.static_files('public', '/static'))\r\n```\r\n\r\n### Middleware Personalizado\r\n\r\n```python\r\ndef custom_middleware(req, res):\r\n    # Adiciona timestamp \u00e0 requisi\u00e7\u00e3o\r\n    req.timestamp = time.time()\r\n    \r\n    # Continua a execu\u00e7\u00e3o\r\n    return True\r\n\r\napp.use(custom_middleware)\r\n```\r\n\r\n### Middleware que Para a Execu\u00e7\u00e3o\r\n\r\n```python\r\ndef auth_middleware(req, res):\r\n    token = req.get_header('authorization')\r\n    \r\n    if not token:\r\n        res.status(401).json({\r\n            \"error\": \"Unauthorized\"\r\n        })\r\n        return False  # Para a execu\u00e7\u00e3o\r\n    \r\n    return True  # Continua a execu\u00e7\u00e3o\r\n\r\napp.use(auth_middleware)\r\n```\r\n\r\n---\r\n\r\n## Tratamento de Erros\r\n\r\n### Handlers de Erro Personalizados\r\n\r\n```python\r\n@app.error_handler(404)\r\ndef not_found(req, res):\r\n    res.json({\r\n        \"error\": \"Not Found\",\r\n        \"message\": f\"Route '{req.path}' not found\"\r\n    })\r\n\r\n@app.error_handler(500)\r\ndef server_error(req, res):\r\n    res.json({\r\n        \"error\": \"Internal Server Error\",\r\n        \"message\": \"Something went wrong\"\r\n    })\r\n```\r\n\r\n### Tratamento de Exce\u00e7\u00f5es\r\n\r\n```python\r\n@app.get('/users/:id')\r\ndef get_user(req, res):\r\n    try:\r\n        user_id = int(req.params['id'])\r\n        user = find_user(user_id)\r\n        \r\n        if not user:\r\n            res.status(404).json({\r\n                \"error\": \"User not found\"\r\n            })\r\n            return\r\n        \r\n        res.json(user)\r\n        \r\n    except ValueError:\r\n        res.status(400).json({\r\n            \"error\": \"Invalid ID format\"\r\n        })\r\n    except Exception as e:\r\n        res.status(500).json({\r\n            \"error\": \"Internal server error\",\r\n            \"message\": str(e)\r\n        })\r\n```\r\n\r\n### Middleware de Tratamento Global\r\n\r\n```python\r\ndef error_handler_middleware(req, res):\r\n    try:\r\n        # Continua a execu\u00e7\u00e3o\r\n        pass\r\n    except Exception as e:\r\n        res.status(500).json({\r\n            \"error\": \"Internal Server Error\",\r\n            \"message\": str(e)\r\n        })\r\n        return False\r\n\r\napp.use(error_handler_middleware)\r\n```\r\n\r\n---\r\n\r\n## CLI (Command Line Interface)\r\n\r\n### Comandos Dispon\u00edveis\r\n\r\n#### `pyrest create <nome>`\r\n\r\nCria um novo projeto com estrutura completa.\r\n\r\n```bash\r\n# Cria\u00e7\u00e3o b\u00e1sica\r\npyrest create minha-api\r\n\r\n# Com diret\u00f3rio espec\u00edfico\r\npyrest create minha-api -o /path/to/output\r\n```\r\n\r\n**Estrutura criada:**\r\n```\r\nminha-api/\r\n\u251c\u2500\u2500 app.py              # Aplica\u00e7\u00e3o principal\r\n\u251c\u2500\u2500 README.md           # Documenta\u00e7\u00e3o\r\n\u251c\u2500\u2500 requirements.txt    # Depend\u00eancias\r\n\u251c\u2500\u2500 .gitignore         # Git ignore\r\n\u251c\u2500\u2500 routes/            # Rotas organizadas\r\n\u251c\u2500\u2500 middlewares/       # Middlewares customizados\r\n\u251c\u2500\u2500 models/            # Modelos de dados\r\n\u251c\u2500\u2500 utils/             # Utilit\u00e1rios\r\n\u2514\u2500\u2500 tests/             # Testes\r\n```\r\n\r\n#### `pyrest serve`\r\n\r\nInicia um servidor PyRest.\r\n\r\n```bash\r\n# Carrega app.py (padr\u00e3o)\r\npyrest serve\r\n\r\n# Carrega arquivo espec\u00edfico\r\npyrest serve app.py\r\n\r\n# Servidor de exemplo\r\npyrest serve --quick\r\n\r\n# Configura\u00e7\u00f5es espec\u00edficas\r\npyrest serve --port 8080 --host 0.0.0.0 --debug\r\n```\r\n\r\n#### `pyrest info`\r\n\r\nMostra informa\u00e7\u00f5es sobre o framework.\r\n\r\n```bash\r\npyrest info\r\n```\r\n\r\n### Op\u00e7\u00f5es do Comando Serve\r\n\r\n| Op\u00e7\u00e3o | Descri\u00e7\u00e3o | Padr\u00e3o |\r\n|-------|-----------|--------|\r\n| `--port` | Porta do servidor | 3000 |\r\n| `--host` | Host do servidor | localhost |\r\n| `--debug` | Modo debug | False |\r\n| `--quick` | Servidor de exemplo | False |\r\n\r\n---\r\n\r\n## Exemplos Avan\u00e7ados\r\n\r\n### API REST Completa\r\n\r\n```python\r\nfrom pyrest import create_app, Middlewares\r\n\r\napp = create_app()\r\n\r\n# Middlewares\r\napp.use(Middlewares.cors())\r\napp.use(Middlewares.logger('dev'))\r\napp.use(Middlewares.json_parser())\r\n\r\n# Simula banco de dados\r\nusers = []\r\n\r\n# GET /users\r\n@app.get('/users')\r\ndef get_users(req, res):\r\n    page = int(req.get_query('page', '1'))\r\n    limit = int(req.get_query('limit', '10'))\r\n    \r\n    start = (page - 1) * limit\r\n    end = start + limit\r\n    \r\n    paginated_users = users[start:end]\r\n    \r\n    res.json({\r\n        \"users\": paginated_users,\r\n        \"pagination\": {\r\n            \"page\": page,\r\n            \"limit\": limit,\r\n            \"total\": len(users)\r\n        }\r\n    })\r\n\r\n# POST /users\r\n@app.post('/users')\r\ndef create_user(req, res):\r\n    data = req.json_data\r\n    \r\n    if not data or 'name' not in data:\r\n        res.status(400).json({\r\n            \"error\": \"Name is required\"\r\n        })\r\n        return\r\n    \r\n    new_user = {\r\n        \"id\": len(users) + 1,\r\n        \"name\": data['name'],\r\n        \"email\": data.get('email', '')\r\n    }\r\n    \r\n    users.append(new_user)\r\n    \r\n    res.status(201).json(new_user)\r\n\r\n# GET /users/:id\r\n@app.get('/users/:id')\r\ndef get_user(req, res):\r\n    try:\r\n        user_id = int(req.params['id'])\r\n        user = next((u for u in users if u['id'] == user_id), None)\r\n        \r\n        if user:\r\n            res.json(user)\r\n        else:\r\n            res.status(404).json({\r\n                \"error\": \"User not found\"\r\n            })\r\n    except ValueError:\r\n        res.status(400).json({\r\n            \"error\": \"Invalid ID\"\r\n        })\r\n\r\n# PUT /users/:id\r\n@app.put('/users/:id')\r\ndef update_user(req, res):\r\n    try:\r\n        user_id = int(req.params['id'])\r\n        data = req.json_data\r\n        \r\n        user_index = next((i for i, u in enumerate(users) \r\n                          if u['id'] == user_id), None)\r\n        \r\n        if user_index is None:\r\n            res.status(404).json({\r\n                \"error\": \"User not found\"\r\n            })\r\n            return\r\n        \r\n        users[user_index].update(data)\r\n        users[user_index]['id'] = user_id\r\n        \r\n        res.json(users[user_index])\r\n        \r\n    except ValueError:\r\n        res.status(400).json({\r\n            \"error\": \"Invalid ID\"\r\n        })\r\n\r\n# DELETE /users/:id\r\n@app.delete('/users/:id')\r\ndef delete_user(req, res):\r\n    try:\r\n        user_id = int(req.params['id'])\r\n        \r\n        user_index = next((i for i, u in enumerate(users) \r\n                          if u['id'] == user_id), None)\r\n        \r\n        if user_index is None:\r\n            res.status(404).json({\r\n                \"error\": \"User not found\"\r\n            })\r\n            return\r\n        \r\n        deleted_user = users.pop(user_index)\r\n        \r\n        res.json({\r\n            \"message\": \"User deleted\",\r\n            \"user\": deleted_user\r\n        })\r\n        \r\n    except ValueError:\r\n        res.status(400).json({\r\n            \"error\": \"Invalid ID\"\r\n        })\r\n\r\nif __name__ == '__main__':\r\n    app.listen(port=3000, debug=True)\r\n```\r\n\r\n### Autentica\u00e7\u00e3o com JWT\r\n\r\n```python\r\nimport jwt\r\nimport hashlib\r\nfrom datetime import datetime, timedelta\r\nfrom pyrest import create_app, Middlewares\r\n\r\napp = create_app()\r\n\r\n# Configura\u00e7\u00f5es\r\nJWT_SECRET = \"your-secret-key\"\r\nJWT_EXPIRATION = 3600\r\n\r\n# Middleware de autentica\u00e7\u00e3o\r\ndef auth_middleware(req, res):\r\n    # Rotas p\u00fablicas\r\n    public_routes = ['/login', '/register']\r\n    \r\n    if req.path in public_routes:\r\n        return True\r\n    \r\n    # Verifica token\r\n    auth_header = req.get_header('authorization')\r\n    if not auth_header or not auth_header.startswith('Bearer '):\r\n        res.status(401).json({\r\n            \"error\": \"Token required\"\r\n        })\r\n        return False\r\n    \r\n    token = auth_header[7:]\r\n    \r\n    try:\r\n        payload = jwt.decode(token, JWT_SECRET, algorithms=['HS256'])\r\n        req.user = payload\r\n        return True\r\n    except:\r\n        res.status(401).json({\r\n            \"error\": \"Invalid token\"\r\n        })\r\n        return False\r\n\r\napp.use(auth_middleware)\r\n\r\n# Login\r\n@app.post('/login')\r\ndef login(req, res):\r\n    data = req.json_data\r\n    \r\n    # Valida\u00e7\u00e3o b\u00e1sica\r\n    if not data or 'username' not in data or 'password' not in data:\r\n        res.status(400).json({\r\n            \"error\": \"Username and password required\"\r\n        })\r\n        return\r\n    \r\n    # Aqui voc\u00ea faria a valida\u00e7\u00e3o real\r\n    if data['username'] == 'admin' and data['password'] == 'password':\r\n        payload = {\r\n            'user_id': 1,\r\n            'username': data['username'],\r\n            'exp': datetime.utcnow() + timedelta(seconds=JWT_EXPIRATION)\r\n        }\r\n        \r\n        token = jwt.encode(payload, JWT_SECRET, algorithm='HS256')\r\n        \r\n        res.json({\r\n            \"message\": \"Login successful\",\r\n            \"token\": token,\r\n            \"expires_in\": JWT_EXPIRATION\r\n        })\r\n    else:\r\n        res.status(401).json({\r\n            \"error\": \"Invalid credentials\"\r\n        })\r\n\r\n# Rota protegida\r\n@app.get('/profile')\r\ndef get_profile(req, res):\r\n    res.json({\r\n        \"user_id\": req.user['user_id'],\r\n        \"username\": req.user['username']\r\n    })\r\n\r\nif __name__ == '__main__':\r\n    app.listen(port=3000, debug=True)\r\n```\r\n\r\n---\r\n\r\n## Testes\r\n\r\n### Executando Testes\r\n\r\n```bash\r\n# Todos os testes\r\npytest\r\n\r\n# Com cobertura\r\npytest --cov=pyrest\r\n\r\n# Testes espec\u00edficos\r\npytest tests/test_core.py -v\r\n\r\n# Com relat\u00f3rio HTML\r\npytest --cov=pyrest --cov-report=html\r\n```\r\n\r\n### Escrevendo Testes\r\n\r\n```python\r\nimport unittest\r\nfrom unittest.mock import Mock\r\nfrom pyrest import create_app\r\n\r\nclass TestAPI(unittest.TestCase):\r\n    def setUp(self):\r\n        self.app = create_app()\r\n    \r\n    def test_home_route(self):\r\n        # Simula requisi\u00e7\u00e3o\r\n        req = Mock()\r\n        req.method = 'GET'\r\n        req.path = '/'\r\n        \r\n        res = Mock()\r\n        res.json = Mock()\r\n        \r\n        # Executa handler\r\n        @self.app.get('/')\r\n        def home(req, res):\r\n            res.json({\"message\": \"Hello\"})\r\n        \r\n        # Verifica se rota foi registrada\r\n        self.assertEqual(len(self.app.routes), 1)\r\n        route = self.app.routes[0]\r\n        self.assertEqual(route.method, 'GET')\r\n        self.assertEqual(route.path, '/')\r\n```\r\n\r\n### Testes de Integra\u00e7\u00e3o\r\n\r\n```python\r\nimport requests\r\n\r\ndef test_api_integration():\r\n    # Inicia servidor em thread separada\r\n    import threading\r\n    import time\r\n    \r\n    def start_server():\r\n        app.listen(port=3001)\r\n    \r\n    server_thread = threading.Thread(target=start_server)\r\n    server_thread.daemon = True\r\n    server_thread.start()\r\n    \r\n    time.sleep(1)  # Aguarda servidor iniciar\r\n    \r\n    # Testa API\r\n    response = requests.get('http://localhost:3001/')\r\n    assert response.status_code == 200\r\n    assert response.json()['message'] == 'Hello'\r\n```\r\n\r\n---\r\n\r\n## Deploy\r\n\r\n### Ambiente de Desenvolvimento\r\n\r\n```bash\r\n# Instala\u00e7\u00e3o\r\npip install -r requirements.txt\r\n\r\n# Execu\u00e7\u00e3o\r\npython app.py\r\n\r\n# Ou usando CLI\r\npyrest serve --debug\r\n```\r\n\r\n### Ambiente de Produ\u00e7\u00e3o\r\n\r\n```bash\r\n# Instala\u00e7\u00e3o\r\npip install pyrest-framework\r\n\r\n# Execu\u00e7\u00e3o\r\npyrest serve --host 0.0.0.0 --port 80\r\n```\r\n\r\n### Docker\r\n\r\n```dockerfile\r\nFROM python:3.9-slim\r\n\r\nWORKDIR /app\r\n\r\nCOPY requirements.txt .\r\nRUN pip install -r requirements.txt\r\n\r\nCOPY . .\r\n\r\nEXPOSE 3000\r\n\r\nCMD [\"python\", \"app.py\"]\r\n```\r\n\r\n### Nginx (Proxy Reverso)\r\n\r\n```nginx\r\nserver {\r\n    listen 80;\r\n    server_name api.example.com;\r\n    \r\n    location / {\r\n        proxy_pass http://localhost:3000;\r\n        proxy_set_header Host $host;\r\n        proxy_set_header X-Real-IP $remote_addr;\r\n        proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;\r\n        proxy_set_header X-Forwarded-Proto $scheme;\r\n    }\r\n}\r\n```\r\n\r\n### Systemd Service\r\n\r\n```ini\r\n[Unit]\r\nDescription=PyRest API\r\nAfter=network.target\r\n\r\n[Service]\r\nType=simple\r\nUser=www-data\r\nWorkingDirectory=/var/www/api\r\nExecStart=/usr/bin/python3 app.py\r\nRestart=always\r\n\r\n[Install]\r\nWantedBy=multi-user.target\r\n```\r\n\r\n---\r\n\r\n## Refer\u00eancia da API\r\n\r\nPara documenta\u00e7\u00e3o completa da API, consulte:\r\n- [API Reference](API_REFERENCE.md) - Refer\u00eancia detalhada de todas as classes e m\u00e9todos\r\n- [Changelog](CHANGELOG.md) - Hist\u00f3rico de vers\u00f5es e mudan\u00e7as\r\n\r\n### Classes Principais\r\n\r\n#### PyRestFramework\r\n- `get(path, handler=None)` - Define rota GET\r\n- `post(path, handler=None)` - Define rota POST\r\n- `put(path, handler=None)` - Define rota PUT\r\n- `delete(path, handler=None)` - Define rota DELETE\r\n- `patch(path, handler=None)` - Define rota PATCH\r\n- `options(path, handler=None)` - Define rota OPTIONS\r\n- `use(middleware)` - Adiciona middleware\r\n- `error_handler(status_code)` - Define handler de erro\r\n- `listen(port=3000, host='localhost', debug=False)` - Inicia servidor\r\n\r\n#### Request\r\n- `get_header(name, default=None)` - Obt\u00e9m header\r\n- `get_query(name, default=None)` - Obt\u00e9m query parameter\r\n- `get_param(name, default=None)` - Obt\u00e9m par\u00e2metro de rota\r\n- `get_json(key=None, default=None)` - Obt\u00e9m dados JSON\r\n- `get_form(key=None, default=None)` - Obt\u00e9m dados de formul\u00e1rio\r\n- `is_json()` - Verifica se \u00e9 JSON\r\n- `is_form()` - Verifica se \u00e9 form data\r\n- `is_secure()` - Verifica se \u00e9 HTTPS\r\n\r\n#### Response\r\n- `status(code)` - Define status code\r\n- `header(key, value)` - Define header\r\n- `json(data, indent=None, ensure_ascii=False)` - Resposta JSON\r\n- `send(data)` - Resposta texto\r\n- `html(content)` - Resposta HTML\r\n- `xml(content)` - Resposta XML\r\n- `file(content, filename, mimetype=None)` - Resposta arquivo\r\n- `redirect(url, permanent=False)` - Redirecionamento\r\n- `cookie(name, value, **options)` - Define cookie\r\n- `cors(**options)` - Headers CORS\r\n\r\n#### Middlewares\r\n- `cors(**options)` - Middleware CORS\r\n- `logger(format='combined')` - Middleware de logging\r\n- `body_parser()` - Middleware body parser\r\n- `json_parser()` - Middleware JSON parser\r\n- `urlencoded()` - Middleware URL encoded\r\n- `static_files(directory, prefix='/static')` - Middleware static files\r\n- `rate_limit(max_requests=100, window_ms=60000)` - Middleware rate limiting\r\n- `auth_required()` - Middleware de autentica\u00e7\u00e3o\r\n- `error_handler()` - Middleware de tratamento de erros\r\n- `security_headers()` - Middleware de headers de seguran\u00e7a\r\n\r\n---\r\n\r\n## Suporte e Comunidade\r\n\r\n### Recursos Adicionais\r\n\r\n- **GitHub**: [https://github.com/mamadusamadev/pyrest-framework](https://github.com/mamadusamadev/pyrest-framework)\r\n- **Issues**: Para reportar bugs ou solicitar features\r\n- **Discussions**: Para d\u00favidas e discuss\u00f5es\r\n- **Wiki**: Documenta\u00e7\u00e3o adicional e tutoriais\r\n\r\n### Contribuindo\r\n\r\n1. Fork o projeto\r\n2. Crie uma branch para sua feature\r\n3. Commit suas mudan\u00e7as\r\n4. Push para a branch\r\n5. Abra um Pull Request\r\n\r\n### Licen\u00e7a\r\n\r\nEste projeto est\u00e1 licenciado sob a Licen\u00e7a MIT - veja o arquivo [LICENSE](../LICENSE) para detalhes.\r\n\r\n---\r\n\r\n## Conclus\u00e3o\r\n\r\nO PYREST-FRAMEWORK v2.0.1 oferece uma solu\u00e7\u00e3o completa e profissional para desenvolvimento de APIs REST em Python. Com sua arquitetura MVC moderna, integra\u00e7\u00e3o com Prisma ORM, sistema de valida\u00e7\u00e3o robusto e CLI avan\u00e7ado, \u00e9 ideal tanto para aprendizado quanto para projetos reais em produ\u00e7\u00e3o.\r\n\r\n### Principais Melhorias da v2.0.1\r\n\r\n- \u2705 **Arquitetura MVC Completa**: Separa\u00e7\u00e3o clara entre Controllers, Services, Models e Repositories\r\n- \u2705 **Integra\u00e7\u00e3o com Prisma**: Suporte nativo a PostgreSQL, MySQL e SQLite\r\n- \u2705 **Sistema de Valida\u00e7\u00e3o**: Valida\u00e7\u00e3o autom\u00e1tica de dados com m\u00faltiplos validadores\r\n- \u2705 **CLI Avan\u00e7ado**: Cria\u00e7\u00e3o autom\u00e1tica de projetos com estrutura profissional\r\n- \u2705 **Fallback Inteligente**: Funciona com ou sem banco de dados\r\n- \u2705 **Documenta\u00e7\u00e3o Completa**: Guias detalhados para todas as funcionalidades\r\n\r\nPara come\u00e7ar rapidamente:\r\n\r\n```bash\r\n# Instala\u00e7\u00e3o b\u00e1sica\r\npip install pyrest-framework\r\n\r\n# Instala\u00e7\u00e3o com suporte a banco de dados\r\npip install pyrest-framework[database]\r\n\r\n# Cria\u00e7\u00e3o de projeto com estrutura MVC completa\r\npyrest create minha-api\r\n\r\n# Execu\u00e7\u00e3o\r\ncd minha-api\r\npyrest serve --debug\r\n```\r\n\r\n**Happy coding! \ud83d\ude80**\r\n",
    "bugtrack_url": null,
    "license": "MIT",
    "summary": "Framework Python para cria\u00e7\u00e3o de APIs REST - Estilo Express.js",
    "version": "2.0.1",
    "project_urls": {
        "Bug Tracker": "https://github.com/mamadusamadev/pyrest-framework/issues",
        "Changelog": "https://github.com/mamadusamadev/pyrest-framework/blob/main/CHANGELOG.md",
        "Documentation": "https://github.com/mamadusamadev/pyrest-framework/blob/main/docs/README.md",
        "Homepage": "https://github.com/mamadusamadev/pyrest-framework",
        "Repository": "https://github.com/mamadusamadev/pyrest-framework"
    },
    "split_keywords": [
        "api",
        " rest",
        " framework",
        " web",
        " http",
        " server",
        " express",
        " microframework",
        " ads",
        " education"
    ],
    "urls": [
        {
            "comment_text": null,
            "digests": {
                "blake2b_256": "2cd5a116018ade05954c2ca41b753ac6637058ac7262390999b7ec6d285be123",
                "md5": "3e54bf1dad280cf94923f8c2b6b85a26",
                "sha256": "0646b091b3f3f3c97ec25ee6b7e6f106cbb06e3f5d9650446695c0a7492ec13b"
            },
            "downloads": -1,
            "filename": "pyrest_framework-2.0.1-py3-none-any.whl",
            "has_sig": false,
            "md5_digest": "3e54bf1dad280cf94923f8c2b6b85a26",
            "packagetype": "bdist_wheel",
            "python_version": "py3",
            "requires_python": ">=3.7",
            "size": 44867,
            "upload_time": "2025-07-26T14:32:01",
            "upload_time_iso_8601": "2025-07-26T14:32:01.344965Z",
            "url": "https://files.pythonhosted.org/packages/2c/d5/a116018ade05954c2ca41b753ac6637058ac7262390999b7ec6d285be123/pyrest_framework-2.0.1-py3-none-any.whl",
            "yanked": false,
            "yanked_reason": null
        },
        {
            "comment_text": null,
            "digests": {
                "blake2b_256": "fc91bc555ae291145dcbeed2c42b97c64ce7968b3702948edb32290983778c78",
                "md5": "521d02df12fca48a48ae531138738099",
                "sha256": "fe7ab8f363d3788033b96aab92bf9dc03a5d925dbbd9223ca3bace4eceb718ef"
            },
            "downloads": -1,
            "filename": "pyrest_framework-2.0.1.tar.gz",
            "has_sig": false,
            "md5_digest": "521d02df12fca48a48ae531138738099",
            "packagetype": "sdist",
            "python_version": "source",
            "requires_python": ">=3.7",
            "size": 76831,
            "upload_time": "2025-07-26T14:32:02",
            "upload_time_iso_8601": "2025-07-26T14:32:02.977955Z",
            "url": "https://files.pythonhosted.org/packages/fc/91/bc555ae291145dcbeed2c42b97c64ce7968b3702948edb32290983778c78/pyrest_framework-2.0.1.tar.gz",
            "yanked": false,
            "yanked_reason": null
        }
    ],
    "upload_time": "2025-07-26 14:32:02",
    "github": true,
    "gitlab": false,
    "bitbucket": false,
    "codeberg": false,
    "github_user": "mamadusamadev",
    "github_project": "pyrest-framework",
    "travis_ci": false,
    "coveralls": false,
    "github_actions": false,
    "requirements": [
        {
            "name": "build",
            "specs": [
                [
                    "==",
                    "1.2.2.post1"
                ]
            ]
        },
        {
            "name": "certifi",
            "specs": [
                [
                    "==",
                    "2025.7.14"
                ]
            ]
        },
        {
            "name": "charset-normalizer",
            "specs": [
                [
                    "==",
                    "3.4.2"
                ]
            ]
        },
        {
            "name": "colorama",
            "specs": [
                [
                    "==",
                    "0.4.6"
                ]
            ]
        },
        {
            "name": "docutils",
            "specs": [
                [
                    "==",
                    "0.21.2"
                ]
            ]
        },
        {
            "name": "id",
            "specs": [
                [
                    "==",
                    "1.5.0"
                ]
            ]
        },
        {
            "name": "idna",
            "specs": [
                [
                    "==",
                    "3.10"
                ]
            ]
        },
        {
            "name": "jaraco.classes",
            "specs": [
                [
                    "==",
                    "3.4.0"
                ]
            ]
        },
        {
            "name": "jaraco.context",
            "specs": [
                [
                    "==",
                    "6.0.1"
                ]
            ]
        },
        {
            "name": "jaraco.functools",
            "specs": [
                [
                    "==",
                    "4.2.1"
                ]
            ]
        },
        {
            "name": "keyring",
            "specs": [
                [
                    "==",
                    "25.6.0"
                ]
            ]
        },
        {
            "name": "markdown-it-py",
            "specs": [
                [
                    "==",
                    "3.0.0"
                ]
            ]
        },
        {
            "name": "mdurl",
            "specs": [
                [
                    "==",
                    "0.1.2"
                ]
            ]
        },
        {
            "name": "more-itertools",
            "specs": [
                [
                    "==",
                    "10.7.0"
                ]
            ]
        },
        {
            "name": "nh3",
            "specs": [
                [
                    "==",
                    "0.3.0"
                ]
            ]
        },
        {
            "name": "packaging",
            "specs": [
                [
                    "==",
                    "25.0"
                ]
            ]
        },
        {
            "name": "Pygments",
            "specs": [
                [
                    "==",
                    "2.19.2"
                ]
            ]
        },
        {
            "name": "pyproject_hooks",
            "specs": [
                [
                    "==",
                    "1.2.0"
                ]
            ]
        },
        {
            "name": "pywin32-ctypes",
            "specs": [
                [
                    "==",
                    "0.2.3"
                ]
            ]
        },
        {
            "name": "readme_renderer",
            "specs": [
                [
                    "==",
                    "44.0"
                ]
            ]
        },
        {
            "name": "requests",
            "specs": [
                [
                    "==",
                    "2.32.4"
                ]
            ]
        },
        {
            "name": "requests-toolbelt",
            "specs": [
                [
                    "==",
                    "1.0.0"
                ]
            ]
        },
        {
            "name": "rfc3986",
            "specs": [
                [
                    "==",
                    "2.0.0"
                ]
            ]
        },
        {
            "name": "rich",
            "specs": [
                [
                    "==",
                    "14.1.0"
                ]
            ]
        },
        {
            "name": "setuptools",
            "specs": [
                [
                    "==",
                    "80.9.0"
                ]
            ]
        },
        {
            "name": "twine",
            "specs": [
                [
                    "==",
                    "6.1.0"
                ]
            ]
        },
        {
            "name": "urllib3",
            "specs": [
                [
                    "==",
                    "2.5.0"
                ]
            ]
        },
        {
            "name": "wheel",
            "specs": [
                [
                    "==",
                    "0.45.1"
                ]
            ]
        }
    ],
    "lcname": "pyrest-framework"
}
        
Elapsed time: 0.82975s