vioott commited on
Commit
694ce62
·
1 Parent(s): 1200eeb

refactor(css): extract inline styles to css classes and update README with technical details

Browse files
Files changed (4) hide show
  1. README.md +39 -21
  2. static/style.css +53 -19
  3. templates/chat.html +3 -3
  4. templates/start.html +2 -2
README.md CHANGED
@@ -7,31 +7,40 @@ sdk: docker
7
  app_port: 7860
8
  license: mit
9
  pinned: true
10
- short_description: Uma aplicação web de recomendação de livros com IA
11
  ---
 
12
  # 📚 BookMatch AI
13
 
14
- Uma aplicação web de recomendação de livros com IA, desenvolvida com Python e Flask, integrada ao modelo Gemini da Google.
 
 
15
 
16
- Usuários criam um perfil com seus gêneros favoritos, tiram dúvidas e se informam sobre qualquer assunto no universo literário e recebem sugestões personalizadas de leitura. Tudo isso via chat com IA.
17
 
18
- 👉 [Teste agora no Hugging Face Spaces](https://huggingface.co/spaces/vioott/BookMatchAI-Python-GeminiAPI)
19
 
20
- ## 🔧 Tecnologias utilizadas
21
 
22
- - 🐍 Python + Flask (back-end web)
23
- - 🌐 HTML + CSS (front-end responsivo)
24
- - 🤖 Google Gemini 1.5 Flash (modelo de IA)
25
- - 🧠 Sistema de logging para histórico de interações
 
 
26
 
27
- ## Funcionalidades
28
 
29
- - Criação e edição de perfis de usuário com preferências literárias
30
- - Interface web responsiva para chat com IA
31
- - Respostas personalizadas com base nas preferências salvas
32
- - Log de interações com histórico e recomendações da IA
 
 
 
 
33
 
34
- ## 🚀 Como executar localmente
35
 
36
  1. Clone o repositório e entre na pasta do projeto.
37
  ```
@@ -57,16 +66,25 @@ pip install -r requirements.txt
57
  GOOGLE_API_KEY=sua-chave-aqui
58
  ```
59
 
60
- 5. Execute o app:
 
 
 
 
61
 
62
- ```
63
- python app.py
64
- ```
 
 
 
 
 
65
 
66
  ## 🧠 Sobre o projeto
67
 
68
- Este projeto foi criado como solução para o exercício "Implementando um 'If Mágico' em uma Aplicação de E-commerce", do curso "IA para Programação com Python", da [Trybe](https://www.betrybe.com/), para explorar aplicações de IA generativa na recomendação literária, com foco em UX, personalização e uso real de modelos LLM.
69
 
70
  ---
71
 
72
- Desenvolvido por Vania Ioott – Full-Stack Developer & AI Enthusiast.
 
7
  app_port: 7860
8
  license: mit
9
  pinned: true
10
+ short_description: Assistente literário inteligente com Python, Flask e Google Gemini.
11
  ---
12
+
13
  # 📚 BookMatch AI
14
 
15
+ **Seu Assistente Literário Inteligente.**
16
+
17
+ O **BookMatch AI** é uma aplicação web interativa que utiliza Inteligência Artificial Generativa para oferecer recomendações de livros personalizadas e conversas profundas sobre literatura. Desenvolvido como um projeto de portfólio Full-Stack, ele demonstra a integração prática entre **Python**, **Flask** e a **Google Gemini API**.
18
 
19
+ 👉 **[Teste a aplicação ao vivo no Hugging Face Spaces](https://huggingface.co/spaces/vioott/BookMatchAI-Python-GeminiAPI)**
20
 
21
+ ---
22
 
23
+ ## Funcionalidades Principais
24
 
25
+ * **🤖 Seleção Dinâmica de IA:** O sistema consulta a API do Google em tempo real para listar e utilizar os modelos Gemini mais recentes (como *Gemini 2.5 Flash*, *2.0 Flash*, etc.), adaptando-se automaticamente a atualizações da Google.
26
+ * **👤 Perfil Personalizado:** Criação de perfil com nome e preferências de gênero literário (Terror, Romance, Ficção, etc.) que influenciam a personalidade e as respostas da IA.
27
+ * **💬 Chat Interativo:** Interface de chat moderna e responsiva para conversar sobre livros, autores e histórias.
28
+ * **⚡ Performance Otimizada:** Implementação de **Cache (TTL)** para evitar chamadas redundantes à API e garantir carregamento rápido da lista de modelos.
29
+ * **🛡️ Logs:** Tratamento avançado de erros (incluindo esgotamento de cota da API) e sistema de logs persistentes que mantém o histórico de conversas e preferências mesmo após reinício do servidor.
30
+ * **🎨 UI/UX Profissional:** Modal de boas-vindas informativo, feedback visual de carregamento ("Aguarde..."), validação de formulários e design responsivo.
31
 
32
+ ## 🛠️ Stack Tecnológica
33
 
34
+ * **Backend:** Python 3.10+, Flask (Microframework Web).
35
+ * **Inteligência Artificial:** Google Gemini API (`google-generativeai`).
36
+ * **Frontend:** HTML5, CSS3 (com design system próprio e responsivo), JavaScript.
37
+ * **Infraestrutura:** Docker (Containerização), Gunicorn (Servidor WSGI), Hugging Face Spaces (Hospedagem).
38
+ * **Bibliotecas Chave:**
39
+ * `google-generativeai`: Integração com LLMs.
40
+ * `cachetools`: Cache em memória para otimização.
41
+ * `python-dotenv`: Gerenciamento seguro de variáveis de ambiente.
42
 
43
+ ## 🚀 Como Executar Localmente
44
 
45
  1. Clone o repositório e entre na pasta do projeto.
46
  ```
 
66
  GOOGLE_API_KEY=sua-chave-aqui
67
  ```
68
 
69
+ 5. **Execute a aplicação:**
70
+ ```
71
+ python app.py
72
+ ```
73
+ Acesse `http://localhost:5000` no seu navegador.
74
 
75
+ ## 📂 Estrutura do Projeto
76
+
77
+ * `app.py`: Ponto de entrada da aplicação Flask.
78
+ * `routes/`: Módulos de rotas (Home, Chat, Perfil) seguindo padrão MVC.
79
+ * `services/`: Lógica de negócio e integração com a IA (`genai_service.py`).
80
+ * `templates/`: Arquivos HTML Jinja2.
81
+ * `static/`: Arquivos CSS e assets.
82
+ * `logs.py`: Sistema customizado de persistência de dados em arquivo.
83
 
84
  ## 🧠 Sobre o projeto
85
 
86
+ Este projeto foi criado como solução para o exercício "Implementando um 'If Mágico' em uma Aplicação de E-commerce", do curso "IA para Programação com Python", da [Trybe](https://www.betrybe.com/), para explorar aplicações de IA generativa na recomendação literária, com foco em UX, personalização e uso real de modelos LLM.
87
 
88
  ---
89
 
90
+ Desenvolvido por **Vania Ioott** – Full-Stack Developer & AI Enthusiast.
static/style.css CHANGED
@@ -2,7 +2,7 @@ body {
2
  font-family: 'Segoe UI', Tahoma, Geneva, Verdana, sans-serif;
3
  background-color: #f0f2f5;
4
  display: block;
5
- padding-top: 60px; /* Aumentado levemente para acomodar a navbar fixa */
6
  min-height: 100vh;
7
  margin: 0 auto;
8
  }
@@ -87,7 +87,7 @@ button:hover {
87
  .chat-container {
88
  flex-direction: column;
89
  }
90
-
91
  .chat-box, .response-box {
92
  width: 70%;
93
  align-self: center;
@@ -129,7 +129,7 @@ button:hover {
129
 
130
  /* --- Navigation Bar --- */
131
  .navbar {
132
- background-color: #28a745; /* Verde igual aos botões */
133
  overflow: hidden;
134
  position: fixed;
135
  top: 0;
@@ -153,7 +153,7 @@ button:hover {
153
  }
154
 
155
  .navbar a:hover {
156
- background-color: #218838; /* Verde um pouco mais escuro no hover */
157
  color: white;
158
  }
159
 
@@ -164,31 +164,31 @@ button:hover {
164
 
165
  /* --- Welcome Modal --- */
166
  .modal {
167
- display: none;
168
- position: fixed;
169
- z-index: 2000;
170
  left: 0;
171
  top: 0;
172
- width: 100%;
173
- height: 100%;
174
- overflow: auto;
175
- background-color: rgba(0,0,0,0.7); /* Fundo um pouco mais escuro */
176
- backdrop-filter: blur(2px); /* Efeito de desfoque no fundo */
177
  animation: fadeIn 0.3s;
178
  }
179
 
180
  .modal-content {
181
  background-color: #fff;
182
- margin: 8% auto;
183
- padding: 40px; /* Mais padding */
184
  border: none;
185
- width: 85%;
186
  max-width: 650px;
187
- border-radius: 16px; /* Cantos mais arredondados */
188
  box-shadow: 0 10px 30px rgba(0,0,0,0.3);
189
  text-align: center;
190
  position: relative;
191
- animation: slideDown 0.4s cubic-bezier(0.16, 1, 0.3, 1); /* Animação mais fluida */
192
  font-family: 'Segoe UI', sans-serif;
193
  }
194
 
@@ -269,7 +269,7 @@ button:hover {
269
  }
270
 
271
  @keyframes fadeIn {
272
- from {opacity: 0}
273
  to {opacity: 1}
274
  }
275
 
@@ -295,10 +295,44 @@ button:hover {
295
  cursor: pointer;
296
  z-index: 1900;
297
  transition: transform 0.3s, background-color 0.3s;
298
- display: none; /* Começa escondido, só aparece quando fecha o modal */
299
  }
300
 
301
  .info-fab:hover {
302
  background-color: #218838;
303
  transform: scale(1.1);
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
304
  }
 
2
  font-family: 'Segoe UI', Tahoma, Geneva, Verdana, sans-serif;
3
  background-color: #f0f2f5;
4
  display: block;
5
+ padding-top: 60px;
6
  min-height: 100vh;
7
  margin: 0 auto;
8
  }
 
87
  .chat-container {
88
  flex-direction: column;
89
  }
90
+
91
  .chat-box, .response-box {
92
  width: 70%;
93
  align-self: center;
 
129
 
130
  /* --- Navigation Bar --- */
131
  .navbar {
132
+ background-color: #28a745;
133
  overflow: hidden;
134
  position: fixed;
135
  top: 0;
 
153
  }
154
 
155
  .navbar a:hover {
156
+ background-color: #218838;
157
  color: white;
158
  }
159
 
 
164
 
165
  /* --- Welcome Modal --- */
166
  .modal {
167
+ display: none;
168
+ position: fixed;
169
+ z-index: 2000;
170
  left: 0;
171
  top: 0;
172
+ width: 100%;
173
+ height: 100%;
174
+ overflow: auto;
175
+ background-color: rgba(0,0,0,0.7);
176
+ backdrop-filter: blur(2px);
177
  animation: fadeIn 0.3s;
178
  }
179
 
180
  .modal-content {
181
  background-color: #fff;
182
+ margin: 8% auto;
183
+ padding: 40px;
184
  border: none;
185
+ width: 85%;
186
  max-width: 650px;
187
+ border-radius: 16px;
188
  box-shadow: 0 10px 30px rgba(0,0,0,0.3);
189
  text-align: center;
190
  position: relative;
191
+ animation: slideDown 0.4s cubic-bezier(0.16, 1, 0.3, 1);
192
  font-family: 'Segoe UI', sans-serif;
193
  }
194
 
 
269
  }
270
 
271
  @keyframes fadeIn {
272
+ from {opacity: 0}
273
  to {opacity: 1}
274
  }
275
 
 
295
  cursor: pointer;
296
  z-index: 1900;
297
  transition: transform 0.3s, background-color 0.3s;
298
+ display: none;
299
  }
300
 
301
  .info-fab:hover {
302
  background-color: #218838;
303
  transform: scale(1.1);
304
+ }
305
+
306
+ .modal-text-content {
307
+ font-size: 1em;
308
+ text-align: left;
309
+ margin-bottom: 15px;
310
+ }
311
+
312
+ .error-msg {
313
+ color: red;
314
+ display: none;
315
+ font-size: 0.9em;
316
+ margin-top: 5px;
317
+ }
318
+
319
+ .model-selector {
320
+ margin-bottom: 15px;
321
+ }
322
+
323
+ .model-label {
324
+ font-size: 0.9em;
325
+ color: #555;
326
+ }
327
+
328
+ .model-select {
329
+ padding: 5px;
330
+ border-radius: 5px;
331
+ border: 1px solid #ccc;
332
+ max-width: 100%;
333
+ }
334
+
335
+ .nav-disabled {
336
+ opacity: 0.5;
337
+ cursor: not-allowed;
338
  }
templates/chat.html CHANGED
@@ -16,9 +16,9 @@
16
  <form method="post">
17
  <h1>Chat com a IA</h1>
18
 
19
- <div class="model-selector" style="margin-bottom: 15px;">
20
- <label for="model_name" style="font-size: 0.9em; color: #555;">Escolha o Modelo:</label>
21
- <select name="model_name" id="model_name" style="padding: 5px; border-radius: 5px; border: 1px solid #ccc; max-width: 100%;">
22
  {% for model in models %}
23
  <option value="{{ model.id }}" {% if model.id == current_model %}selected{% endif %}>
24
  {{ model.name }}
 
16
  <form method="post">
17
  <h1>Chat com a IA</h1>
18
 
19
+ <div class="model-selector">
20
+ <label for="model_name" class="model-label">Escolha o Modelo:</label>
21
+ <select name="model_name" id="model_name" class="model-select">
22
  {% for model in models %}
23
  <option value="{{ model.id }}" {% if model.id == current_model %}selected{% endif %}>
24
  {{ model.name }}
templates/start.html CHANGED
@@ -21,7 +21,7 @@
21
  <div class="modal-content">
22
  <span class="close-btn" onclick="closeModal()">&times;</span>
23
  <h2 class="modal-title">BookMatchAI: Seu Assistente Literário Inteligente 📚</h2>
24
- <p class="modal-desc" style="font-size: 1em; text-align: left; margin-bottom: 15px;">
25
  <strong>O que este projeto faz:</strong><br>
26
  Este é um assistente conversacional capaz de entender o perfil do usuário (gêneros favoritos e nome) para fazer recomendações de livros personalizadas e discutir literatura em linguagem natural.
27
  </p>
@@ -66,7 +66,7 @@
66
  </label>
67
  {% endfor %}
68
  </div>
69
- <p id="genre-error" style="color: red; display: none; font-size: 0.9em; margin-top: 5px;">⚠️ Selecione pelo menos um gênero.</p>
70
 
71
  <br>
72
  <button type="submit">Começar</button>
 
21
  <div class="modal-content">
22
  <span class="close-btn" onclick="closeModal()">&times;</span>
23
  <h2 class="modal-title">BookMatchAI: Seu Assistente Literário Inteligente 📚</h2>
24
+ <p class="modal-desc modal-text-content">
25
  <strong>O que este projeto faz:</strong><br>
26
  Este é um assistente conversacional capaz de entender o perfil do usuário (gêneros favoritos e nome) para fazer recomendações de livros personalizadas e discutir literatura em linguagem natural.
27
  </p>
 
66
  </label>
67
  {% endfor %}
68
  </div>
69
+ <p id="genre-error" class="error-msg">⚠️ Selecione pelo menos um gênero.</p>
70
 
71
  <br>
72
  <button type="submit">Começar</button>