Este repositório contém o código-fonte de uma API RESTful para consulta de informações sobre livros, extraídas do site "Books to Scrape". O projeto inclui um pipeline de dados completo (web scraping, armazenamento em banco de dados) e uma API com funcionalidades de consulta, estatísticas e integração com um modelo de Machine Learning (clusterização).
Deploy da API: A API está disponível publicamente em: https://turetto-api-livros-3a30130b990d.herokuapp.com/
Documentação Interativa (Swagger): https://turetto-api-livros-3a30130b990d.herokuapp.com/apidocs/
- Fonte de Dados: Books to Scrape (https://books.toscrape.com/)
- Web Scraping: Script Python (
scripts/scraper.py) usandorequestseBeautifulSouppara extrair dados de todos os livros e categorias. - Armazenamento Temporário: Arquivo
data/livros.csvgerado pelo scraper (ignorado pelo Git). - Banco de Dados: PostgreSQL (no Heroku,
heroku-postgresql:essential-0) acessado via SQLAlchemy. Modelos definidos emapi/modelo.py. - API: Aplicação Flask (
api/app.py) servida com Gunicorn. - Machine Learning:
- Treinamento (offline): Script
scripts/train_model.pyusapandasescikit-learnpara treinar um modelo K-Means com base em preço e avaliação. - Artefatos: O modelo treinado (
kmeans_model.joblib) e o scaler (scaler.joblib) são salvos na pastamodels/. - Inferência (online): A API carrega os artefatos e usa o endpoint
POST /api/v1/ml/predictionspara prever o cluster de novos livros.
- Treinamento (offline): Script
- Documentação: Gerada automaticamente com
Flasgger(Swagger UI). - Deploy: Hospedado na plataforma Heroku.
A API oferece os seguintes endpoints principais (prefixo /api/v1):
- Livros:
GET /books: Lista todos os livros.GET /books/{id}: Detalhes de um livro específico.GET /books/search: Busca livros por título e/ou categoria.GET /books/top-rated: Lista os livros com avaliação 5 estrelas.GET /books/price-range: Filtra livros por faixa de preço.
- Categorias:
GET /categories: Lista todas as categorias únicas.
- Insights:
GET /stats/overview: Estatísticas gerais da coleção.GET /stats/categories: Estatísticas detalhadas por categoria.
- Autenticação:
POST /auth/login: Autentica um usuário e retorna um token JWT.
- Admin (Protegido):
POST /admin/scraping/trigger: Dispara o pipeline de atualização de dados (requer token de admin).
- Machine Learning:
GET /ml/training-data: Retorna todos os dados brutos para treinamento.GET /ml/features: Retorna features processadas para todos os livros.GET /ml/features/{id}: Retorna features processadas para um livro específico.POST /ml/predictions: Prevê o cluster de um livro (requer preço e avaliação).
- Health Check:
GET /health: Verifica se a API está operacional.
Para detalhes completos sobre parâmetros e respostas, consulte a Documentação Interativa (Swagger).
Pré-requisitos:
- Python 3.10+
- Git
psql(cliente de linha de comando do PostgreSQL, opcional para banco local SQLite)- Um ambiente virtual (recomendado)
Instalação:
- Clone o repositório usando o comando
git clonecom a URL do seu repositório GitHub e navegue para a pasta do projeto. - Crie um ambiente virtual com
python -m venv venve ative-o (usandovenv\Scripts\activateno Windows ousource venv/bin/activateno macOS/Linux). - Instale todas as dependências necessárias, incluindo as de treinamento, usando o comando
pip install -r requirements.txt. - Crie a pasta
data/na raiz do projeto, caso ela ainda não exista.
Configuração do Banco de Dados (Local - SQLite):
O código usará um arquivo data/books.db automaticamente se a variável de ambiente DATABASE_URL não estiver definida.
Execução do Pipeline de Dados (Local):
- Execute o scraper para gerar o arquivo
livros.csvusando o comando:python -m scripts.scraper. - Crie as tabelas no banco de dados SQLite usando o comando:
python -m scripts.init_db. - Popule a tabela de livros com os dados do CSV usando o comando:
python -m scripts.populate_db. - Crie um usuário administrador. Execute o script
create_admin.pydiretamente (python scripts/create_admin.py) para que ele peça interativamente o nome de usuário e a senha. - Treine o modelo de Machine Learning e salve os arquivos do modelo e do scaler usando o comando:
python -m scripts.train_model.
Iniciando a API (Local):
flask --app api/app run --port 5000Execute o comando flask --app api/app run --port 5000 para iniciar o servidor de desenvolvimento do Flask. A API estará acessível em http://127.0.0.1:5000 e a documentação em http://127.0.0.1:5000/apidocs/.
1. Listar Todos os Livros
- Requisição:
curl -X GET "https://turetto-api-livros-3a30130b990d.herokuapp.com/api/v1/books/" - Resposta Esperada (Status 200 OK - Trecho):
[ { "avaliacao": "Three", "categoria": "Poetry", "disponibilidade": "In stock", "id": 1, "preco": 51.77, "titulo": "A Light in the Attic", "url_imagem": "https://turetto-api-livros-3a30130b990d.herokuapp.com/media/cache/2c/da/2cdad67c44b002e7ead0cc35693c0e8b.jpg" }, { "avaliacao": "One", "categoria": "Historical Fiction", "disponibilidade": "In stock", "id": 2, "preco": 53.74, "titulo": "Tipping the Velvet", "url_imagem": "https://turetto-api-livros-3a30130b990d.herokuapp.com/media/cache/26/0c/260c6ae16bce31c8f8c95daddd9f4a1c.jpg" } // ... (restante dos 1000 livros) ]
2. Obter Detalhes de um Livro Específico (ID: 5)
- Requisição:
curl -X GET "https://https://turetto-api-livros-3a30130b990d.herokuapp.com/api/v1/books/5/" - Resposta Esperada (Status 200 OK):
{ "avaliacao": "One", "categoria": "Historical Fiction", "disponibilidade": "In stock", "id": 5, "preco": 44.18, "titulo": "The Black Maria", "url_imagem": "https://turetto-api-livros-3a30130b990d.herokuapp.com/media/cache/6b/06/6b06af7f5f3ef7f671b5c4e402a3a99c.jpg" }
3. Buscar Livros (Categoria: History, Título contém: Star)
- Requisição:
curl -X GET "https://turetto-api-livros-3a30130b990d.herokuapp.com/api/v1/books/search?category=History&title=Star" - Resposta Esperada (Status 200 OK - Exemplo):
[ { "avaliacao": "Two", "categoria": "History", "disponibilidade": "In stock", "id": 993, "preco": 23.58, "titulo": "The Star-Touched Queen", "url_imagem": "https://turetto-api-livros-3a30130b990d.herokuapp.com/media/cache/20/0c/200caef3740d51785507b987a718d810.jpg" } // ... (pode haver outros resultados ou ser uma lista vazia) ]
4. Fazer Login (Obter Token JWT)
- Requisição:
curl -X POST "https://turetto-api-livros-3a30130b990d.herokuapp.com/api/v1/auth/login" \ -H "Content-Type: application/json" \ -d '{ "username": "admin", "password": "sua_senha_aqui" }'
- Resposta Esperada (Status 200 OK):
{ "access_token": "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJmcmVzaCI6ZmFsc2UsImlhdCI6MTc2..." }
5. Disparar o Pipeline de Scraping (Requer Autenticação)
- Requisição:
curl -X POST "https://turetto-api-livros-3a30130b990d.herokuapp.com/api/v1/admin/scraping/trigger" \ -H "Authorization: Bearer <SEU_TOKEN>"
- Resposta Esperada (Status 202 Accepted):
{ "msg": "Processo de atualização de dados iniciado com sucesso." }
6. Prever o Cluster de um Livro
- Requisição:
curl -X POST "https://turetto-api-livros-3a30130b990d.herokuapp.com/api/v1/ml/predictions" \ -H "Content-Type: application/json" \ -d '{ "preco": 35.50, "avaliacao": "Four" }'
- Resposta Esperada (Status 200 OK):
(O índice e nome do cluster podem variar)
{ "input_data": { "preco": 35.5, "avaliacao": "Four" }, "predicted_cluster_index": 1, "predicted_cluster_name": "Bom Custo-Benefício" }
O projeto inclui um dashboard interativo simples, construído com a biblioteca Streamlit, que consome os endpoints da API online (hospedada na Heroku) para visualizar informações sobre a coleção de livros.
Funcionalidades do Dashboard:
- Visão Geral: Exibe cartões com o número total de livros e o preço médio.
- Distribuição de Avaliações: Mostra um gráfico de barras com a quantidade de livros para cada nota de avaliação (1 a 5 estrelas).
- Navegador de Livros: Apresenta uma tabela interativa com todos os livros da coleção, permitindo pesquisa e ordenação.
- Recarregamento: Um botão permite buscar os dados mais recentes da API.
Como Executar o Dashboard Localmente:
-
Pré-requisitos:
- Certifique-se de que você já seguiu os passos de instalação do projeto principal e ativou seu ambiente virtual (
venv). - As bibliotecas
streamlit,requests, epandasdevem estar instaladas (elas estão incluídas norequirements-training.txtou podem ser instaladas separadamente compip install streamlit requests pandas). - A API principal precisa estar em execução e acessível pela internet (implantada na Heroku), pois o dashboard buscará os dados dela.
- Certifique-se de que você já seguiu os passos de instalação do projeto principal e ativou seu ambiente virtual (
-
Verifique a URL da API:
- Abra o arquivo
dashboard/app_dashboard.py. - Confirme se a variável
API_BASE_URLno início do script contém a URL correta da sua API implantada na Heroku (ex:https://turetto-api-livros-3a30130b990d.herokuapp.com).
- Abra o arquivo
-
Execute o Streamlit:
- No seu terminal, na raiz do projeto (
turetto-api-livros), execute o seguinte comando:streamlit run dashboard/app_dashboard.py - O Streamlit iniciará um servidor local e abrirá automaticamente uma nova aba no seu navegador padrão, exibindo a interface do dashboard.
- No seu terminal, na raiz do projeto (
-
Interaja:
- Explore as métricas, o gráfico e a tabela de dados.
- Use o botão "Recarregar Dados" para buscar informações atualizadas da API, caso o pipeline de scraping tenha sido executado recentemente.
-
Configuração Avançada de Logging com Gunicorn: Criar um arquivo de configuração dedicado (gunicorn.conf.py) para instruir o Gunicorn a usar o python-json-logger para formatar todos os seus logs (incluindo os logs de acesso) como JSON estruturado.
-
Paginação: Adicionar paginação ao endpoint /api/v1/books para lidar eficientemente com grandes quantidades de dados.
-
Testes Automatizados: Escrever testes (unitários, integração) usando pytest para garantir a robustez da API.
