caarleexx commited on
Commit
27e6ace
·
verified ·
1 Parent(s): 19c73de

Update app.py

Browse files
Files changed (1) hide show
  1. app.py +110 -0
app.py CHANGED
@@ -1038,8 +1038,118 @@ def clear_cache():
1038
  # ============================================
1039
  # NOVO ENDPOINT SIMPLIFICADO /busca (com payload exato)
1040
  # ============================================
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1041
  @app.route('/busca')
1042
  def busca_simplificada():
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1043
  """
1044
  Endpoint público para busca simplificada de jurisprudência.
1045
  Usa o payload completo do curl (com boosts, aggs, highlight) e retorna apenas os campos essenciais.
 
1038
  # ============================================
1039
  # NOVO ENDPOINT SIMPLIFICADO /busca (com payload exato)
1040
  # ============================================
1041
+
1042
+
1043
+ # ============================================
1044
+ # Função get_fresh_token modificada (aceita force_refresh)
1045
+ # ============================================
1046
+ def get_fresh_token(force_refresh=False):
1047
+ global token_cache
1048
+ if not force_refresh and token_cache["token"] and time.time() < token_cache["expires_at"]:
1049
+ logger.info("Usando token em cache")
1050
+ return token_cache["token"]
1051
+
1052
+ logger.info("Obtendo novo token via Playwright" + (" (forçado)" if force_refresh else ""))
1053
+ try:
1054
+ with sync_playwright() as p:
1055
+ browser = p.chromium.launch(headless=True, args=['--no-sandbox'])
1056
+ context = browser.new_context(
1057
+ viewport={'width': 1920, 'height': 1080},
1058
+ user_agent='Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36'
1059
+ )
1060
+ page = context.new_page()
1061
+ page.goto("https://jurisprudencia.stf.jus.br/pages/search", wait_until='domcontentloaded', timeout=30000)
1062
+ page.wait_for_timeout(3000)
1063
+ cookies = context.cookies()
1064
+ token = None
1065
+ for cookie in cookies:
1066
+ if cookie.get('name') == 'aws-waf-token':
1067
+ token = cookie.get('value')
1068
+ break
1069
+ browser.close()
1070
+ if token:
1071
+ # Cache por 10 minutos (600 segundos) – ajustável
1072
+ token_cache["token"] = token
1073
+ token_cache["expires_at"] = time.time() + 600
1074
+ logger.info(f"Token obtido: {token[:30]}...")
1075
+ return token
1076
+ else:
1077
+ logger.warning("Token não encontrado nos cookies")
1078
+ return None
1079
+ except Exception as e:
1080
+ logger.error(f"Erro ao obter token: {str(e)}")
1081
+ return None
1082
+
1083
+ # ============================================
1084
+ # Endpoint /busca com tratamento de 202
1085
+ # ============================================
1086
  @app.route('/busca')
1087
  def busca_simplificada():
1088
+ query = request.args.get('q', '')
1089
+ if not query:
1090
+ return jsonify({"erro": "Parâmetro 'q' é obrigatório"}), 400
1091
+
1092
+ token = get_fresh_token()
1093
+ if not token:
1094
+ return jsonify({"erro": "Não foi possível obter token de acesso"}), 503
1095
+
1096
+ payload = PAYLOAD_BUSCA_BASE.copy()
1097
+ payload_str = json.dumps(payload).replace("__TERMO__", query)
1098
+ payload = json.loads(payload_str)
1099
+
1100
+ headers = HEADERS.copy()
1101
+ headers['Cookie'] = f'aws-waf-token={token}'
1102
+
1103
+ # Tentativa inicial
1104
+ try:
1105
+ response = requests.post(URL_API, headers=headers, json=payload, verify=False, timeout=30)
1106
+ except Exception as e:
1107
+ return jsonify({"erro": f"Falha na comunicação com a API: {str(e)}"}), 502
1108
+
1109
+ # Se recebeu 202 (token expirado), tenta renovar e faz uma segunda tentativa
1110
+ if response.status_code == 202:
1111
+ logger.info("Recebido status 202, forçando renovação do token...")
1112
+ token = get_fresh_token(force_refresh=True)
1113
+ if token:
1114
+ headers['Cookie'] = f'aws-waf-token={token}'
1115
+ try:
1116
+ response = requests.post(URL_API, headers=headers, json=payload, verify=False, timeout=30)
1117
+ except Exception as e:
1118
+ return jsonify({"erro": f"Falha na comunicação com a API após renovação: {str(e)}"}), 502
1119
+ else:
1120
+ return jsonify({"erro": "Não foi possível renovar o token"}), 503
1121
+
1122
+ if response.status_code != 200:
1123
+ return jsonify({"erro": f"API retornou status {response.status_code}"}), response.status_code
1124
+
1125
+ data = response.json()
1126
+ hits = data.get('result', {}).get('hits', {}).get('hits', [])
1127
+
1128
+ resultados = []
1129
+ for hit in hits:
1130
+ source = hit.get('_source', {})
1131
+ item = {
1132
+ "id": source.get('id') or hit.get('_id'),
1133
+ "titulo": source.get('titulo'),
1134
+ "processo": source.get('processo_codigo_completo'),
1135
+ "relator": source.get('relator_processo_nome'),
1136
+ "orgao": source.get('orgao_julgador'),
1137
+ "data": source.get('julgamento_data'),
1138
+ "ementa": source.get('ementa_texto'),
1139
+ "url_documento": source.get('inteiro_teor_url'),
1140
+ "score": hit.get('_score')
1141
+ }
1142
+ item = {k: v for k, v in item.items() if v is not None}
1143
+ resultados.append(item)
1144
+
1145
+ return jsonify({
1146
+ "q": query,
1147
+ "total": data.get('result', {}).get('hits', {}).get('total', {}).get('value', 0),
1148
+ "resultados": resultados
1149
+ })
1150
+
1151
+ @app.route('/busca1')
1152
+ def busca_simplificada1():
1153
  """
1154
  Endpoint público para busca simplificada de jurisprudência.
1155
  Usa o payload completo do curl (com boosts, aggs, highlight) e retorna apenas os campos essenciais.