habulaj commited on
Commit
60f50f3
·
verified ·
1 Parent(s): f83678a

Update routers/searchterm.py

Browse files
Files changed (1) hide show
  1. routers/searchterm.py +131 -0
routers/searchterm.py CHANGED
@@ -15,6 +15,8 @@ from fastapi import APIRouter, HTTPException, Body
15
  from fastapi.responses import FileResponse
16
  from newspaper import Article
17
  from threading import Timer
 
 
18
 
19
  router = APIRouter()
20
 
@@ -22,6 +24,10 @@ BRAVE_API_KEY = os.getenv("BRAVE_API_KEY")
22
  if not BRAVE_API_KEY:
23
  raise ValueError("BRAVE_API_KEY não está definido!")
24
 
 
 
 
 
25
  BRAVE_SEARCH_URL = "https://api.search.brave.com/res/v1/web/search"
26
  BRAVE_HEADERS = {
27
  "Accept": "application/json",
@@ -111,6 +117,86 @@ def create_temp_file(data: Dict[str, Any]) -> Dict[str, str]:
111
  }
112
 
113
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
114
  async def search_brave_term(client: httpx.AsyncClient, term: str) -> List[Dict[str, str]]:
115
  params = {"q": term, "count": 10, "safesearch": "off", "summary": "false"}
116
 
@@ -244,6 +330,51 @@ async def search_terms(payload: Dict[str, List[str]] = Body(...)) -> Dict[str, A
244
  }
245
 
246
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
247
  @router.get("/download-temp/{file_id}")
248
  async def download_temp_file(file_id: str):
249
  """Endpoint para download do arquivo temporário"""
 
15
  from fastapi.responses import FileResponse
16
  from newspaper import Article
17
  from threading import Timer
18
+ from google import genai
19
+ from google.genai import types
20
 
21
  router = APIRouter()
22
 
 
24
  if not BRAVE_API_KEY:
25
  raise ValueError("BRAVE_API_KEY não está definido!")
26
 
27
+ GEMINI_API_KEY = os.getenv("GEMINI_API_KEY")
28
+ if not GEMINI_API_KEY:
29
+ raise ValueError("GEMINI_API_KEY não está definido!")
30
+
31
  BRAVE_SEARCH_URL = "https://api.search.brave.com/res/v1/web/search"
32
  BRAVE_HEADERS = {
33
  "Accept": "application/json",
 
117
  }
118
 
119
 
120
+ async def generate_gemini_response(input_text: str) -> str:
121
+ """Gera resposta usando o modelo Gemini"""
122
+ try:
123
+ client = genai.Client(api_key=GEMINI_API_KEY)
124
+ model = "gemini-2.5-flash-lite"
125
+
126
+ contents = [
127
+ types.Content(
128
+ role="user",
129
+ parts=[
130
+ types.Part.from_text(text="Retorne um json de exemplo"),
131
+ ],
132
+ ),
133
+ types.Content(
134
+ role="model",
135
+ parts=[
136
+ types.Part.from_text(text="""Com certeza! Aqui está um exemplo de JSON simples:
137
+ ```json
138
+ {
139
+ \"nome\": \"Maria Silva\",
140
+ \"idade\": 30,
141
+ \"profissao\": \"Engenheira de Software\",
142
+ \"habilidades\": [
143
+ \"Python\",
144
+ \"JavaScript\",
145
+ \"SQL\",
146
+ \"Docker\"
147
+ ],
148
+ \"contato\": {
149
+ \"email\": \"[email protected]\",
150
+ \"telefone\": \"+55 11 98765-4321\"
151
+ },
152
+ \"ativo\": true,
153
+ \"projetos\": null
154
+ }
155
+ ```
156
+ **Explicação dos elementos:**
157
+ * **`{}`**: Representa um objeto JSON.
158
+ * **`\"chave\": valor`**: Um objeto é composto por pares de chave-valor.
159
+ * As **chaves** são sempre strings, delimitadas por aspas duplas.
160
+ * Os **valores** podem ser de diversos tipos:
161
+ * **String:** ` \"Maria Silva\" ` (delimitada por aspas duplas)
162
+ * **Número:** ` 30 ` (inteiro ou decimal)
163
+ * **Booleano:** ` true ` ou ` false `
164
+ * **Array (Lista):** ` [\"Python\", \"JavaScript\", \"SQL\", \"Docker\"] ` (uma lista de valores, delimitada por colchetes `[]`, onde os elementos são separados por vírgulas)
165
+ * **Objeto:** ` {\"email\": \"[email protected]\", \"telefone\": \"+55 11 98765-4321\"} ` (outro objeto JSON aninhado)
166
+ * **`null`**: Representa a ausência de valor.
167
+ Este é um exemplo bastante comum e demonstra a estrutura básica do JSON."""),
168
+ ],
169
+ ),
170
+ types.Content(
171
+ role="user",
172
+ parts=[
173
+ types.Part.from_text(text=input_text),
174
+ ],
175
+ ),
176
+ ]
177
+
178
+ generate_content_config = types.GenerateContentConfig(
179
+ thinking_config=types.ThinkingConfig(
180
+ thinking_budget=0,
181
+ ),
182
+ )
183
+
184
+ # Coletamos toda a resposta em stream
185
+ full_response = ""
186
+ for chunk in client.models.generate_content_stream(
187
+ model=model,
188
+ contents=contents,
189
+ config=generate_content_config,
190
+ ):
191
+ if chunk.text:
192
+ full_response += chunk.text
193
+
194
+ return full_response
195
+
196
+ except Exception as e:
197
+ raise HTTPException(status_code=500, detail=f"Erro ao gerar resposta do Gemini: {str(e)}")
198
+
199
+
200
  async def search_brave_term(client: httpx.AsyncClient, term: str) -> List[Dict[str, str]]:
201
  params = {"q": term, "count": 10, "safesearch": "off", "summary": "false"}
202
 
 
330
  }
331
 
332
 
333
+ @router.post("/inference/terms")
334
+ async def inference_terms(payload: Dict[str, str] = Body(...)) -> Dict[str, Any]:
335
+ """
336
+ Endpoint para fazer inferência com o modelo Gemini
337
+
338
+ Body:
339
+ {
340
+ "input": "Sua pergunta ou texto aqui"
341
+ }
342
+ """
343
+ input_text = payload.get("input")
344
+
345
+ if not input_text or not isinstance(input_text, str):
346
+ raise HTTPException(
347
+ status_code=400,
348
+ detail="Campo 'input' é obrigatório e deve ser uma string."
349
+ )
350
+
351
+ if len(input_text.strip()) == 0:
352
+ raise HTTPException(
353
+ status_code=400,
354
+ detail="Campo 'input' não pode estar vazio."
355
+ )
356
+
357
+ try:
358
+ # Gera resposta usando o Gemini
359
+ response = await generate_gemini_response(input_text)
360
+
361
+ return {
362
+ "input": input_text,
363
+ "response": response,
364
+ "model": "gemini-2.5-flash-lite",
365
+ "timestamp": time.time()
366
+ }
367
+
368
+ except HTTPException:
369
+ # Re-raise HTTPExceptions para manter o status code correto
370
+ raise
371
+ except Exception as e:
372
+ raise HTTPException(
373
+ status_code=500,
374
+ detail=f"Erro interno do servidor: {str(e)}"
375
+ )
376
+
377
+
378
  @router.get("/download-temp/{file_id}")
379
  async def download_temp_file(file_id: str):
380
  """Endpoint para download do arquivo temporário"""