iatoolkit 0.22.1__py3-none-any.whl → 0.50.2__py3-none-any.whl
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Potentially problematic release.
This version of iatoolkit might be problematic. Click here for more details.
- iatoolkit/common/routes.py +31 -31
- iatoolkit/common/session_manager.py +0 -1
- iatoolkit/common/util.py +0 -21
- iatoolkit/iatoolkit.py +5 -18
- iatoolkit/infra/llm_client.py +3 -5
- iatoolkit/infra/redis_session_manager.py +48 -2
- iatoolkit/repositories/models.py +1 -2
- iatoolkit/services/auth_service.py +74 -0
- iatoolkit/services/dispatcher_service.py +12 -21
- iatoolkit/services/excel_service.py +15 -15
- iatoolkit/services/history_service.py +2 -11
- iatoolkit/services/profile_service.py +83 -25
- iatoolkit/services/query_service.py +132 -82
- iatoolkit/services/tasks_service.py +1 -1
- iatoolkit/services/user_feedback_service.py +3 -6
- iatoolkit/services/user_session_context_service.py +112 -54
- iatoolkit/static/js/chat_feedback.js +1 -1
- iatoolkit/static/js/chat_history.js +1 -5
- iatoolkit/static/js/chat_main.js +1 -1
- iatoolkit/static/styles/landing_page.css +62 -2
- iatoolkit/system_prompts/query_main.prompt +3 -12
- iatoolkit/templates/_login_widget.html +6 -8
- iatoolkit/templates/chat.html +78 -4
- iatoolkit/templates/error.html +1 -1
- iatoolkit/templates/index.html +38 -11
- iatoolkit/templates/{home.html → login_test.html} +11 -51
- iatoolkit/views/external_login_view.py +50 -111
- iatoolkit/views/{file_store_view.py → file_store_api_view.py} +4 -4
- iatoolkit/views/history_api_view.py +52 -0
- iatoolkit/views/init_context_api_view.py +62 -0
- iatoolkit/views/llmquery_api_view.py +50 -0
- iatoolkit/views/llmquery_web_view.py +38 -0
- iatoolkit/views/{home_view.py → login_test_view.py} +2 -5
- iatoolkit/views/login_view.py +79 -56
- iatoolkit/views/{prompt_view.py → prompt_api_view.py} +4 -4
- iatoolkit/views/{user_feedback_view.py → user_feedback_api_view.py} +16 -19
- {iatoolkit-0.22.1.dist-info → iatoolkit-0.50.2.dist-info}/METADATA +2 -2
- {iatoolkit-0.22.1.dist-info → iatoolkit-0.50.2.dist-info}/RECORD +40 -41
- iatoolkit/common/auth.py +0 -200
- iatoolkit/templates/login.html +0 -43
- iatoolkit/views/download_file_view.py +0 -58
- iatoolkit/views/history_view.py +0 -57
- iatoolkit/views/init_context_view.py +0 -35
- iatoolkit/views/llmquery_view.py +0 -65
- {iatoolkit-0.22.1.dist-info → iatoolkit-0.50.2.dist-info}/WHEEL +0 -0
- {iatoolkit-0.22.1.dist-info → iatoolkit-0.50.2.dist-info}/top_level.txt +0 -0
iatoolkit/common/auth.py
DELETED
|
@@ -1,200 +0,0 @@
|
|
|
1
|
-
# Copyright (c) 2024 Fernando Libedinsky
|
|
2
|
-
# Product: IAToolkit
|
|
3
|
-
#
|
|
4
|
-
# IAToolkit is open source software.
|
|
5
|
-
|
|
6
|
-
from flask import redirect, url_for
|
|
7
|
-
from iatoolkit.common.session_manager import SessionManager
|
|
8
|
-
from datetime import datetime, timezone
|
|
9
|
-
from injector import inject
|
|
10
|
-
from iatoolkit.repositories.profile_repo import ProfileRepo
|
|
11
|
-
from iatoolkit.services.jwt_service import JWTService
|
|
12
|
-
import logging
|
|
13
|
-
from flask import request
|
|
14
|
-
from typing import Optional
|
|
15
|
-
|
|
16
|
-
MAX_INACTIVITY_SECONDS = 60*30
|
|
17
|
-
|
|
18
|
-
class IAuthentication:
|
|
19
|
-
@inject
|
|
20
|
-
|
|
21
|
-
def __init__(self,
|
|
22
|
-
profile_repo: ProfileRepo,
|
|
23
|
-
jwt_service: JWTService):
|
|
24
|
-
self.profile_repo = profile_repo
|
|
25
|
-
self.jwt_service = jwt_service
|
|
26
|
-
|
|
27
|
-
def verify(self, company_short_name: str, body_external_user_id: str = None) -> dict:
|
|
28
|
-
# authentication is in this orden: JWT, API Key, Sesión
|
|
29
|
-
local_user_id = None
|
|
30
|
-
company_id = None
|
|
31
|
-
auth_method = None
|
|
32
|
-
external_user_id = None # for JWT or API Key
|
|
33
|
-
|
|
34
|
-
# 1. try auth via JWT
|
|
35
|
-
jwt_company_id, jwt_external_user_id, jwt_error_info = self._authenticate_via_chat_jwt(company_short_name)
|
|
36
|
-
|
|
37
|
-
if jwt_company_id is not None and jwt_external_user_id is not None:
|
|
38
|
-
auth_method = "JWT"
|
|
39
|
-
company_id = jwt_company_id
|
|
40
|
-
external_user_id = jwt_external_user_id
|
|
41
|
-
local_user_id = 0
|
|
42
|
-
elif jwt_error_info is not None:
|
|
43
|
-
# explicit error in JWT (inválido, expirado, etc.)
|
|
44
|
-
logging.warning(f"Fallo de autenticación JWT: {jwt_error_info}")
|
|
45
|
-
return {"error_message": "Fallo de autenticación JWT"}
|
|
46
|
-
else:
|
|
47
|
-
# 2. JWT not apply, try by API Key
|
|
48
|
-
api_key_company_id, api_key_error_info = self._authenticate_via_api_key(company_short_name)
|
|
49
|
-
|
|
50
|
-
if api_key_company_id is not None:
|
|
51
|
-
auth_method = "API Key"
|
|
52
|
-
company_id = api_key_company_id
|
|
53
|
-
external_user_id = body_external_user_id # API Key usa external_user_id del body
|
|
54
|
-
local_user_id = 0
|
|
55
|
-
elif api_key_error_info is not None:
|
|
56
|
-
# explicit error in API Key (inválida, incorrecta, error interno)
|
|
57
|
-
logging.warning(f"Fallo de autenticación API Key: {api_key_error_info}")
|
|
58
|
-
return {"error_message": api_key_error_info}
|
|
59
|
-
else:
|
|
60
|
-
# 3. no JWT and API Key auth, try by Session
|
|
61
|
-
self.check_if_user_is_logged_in(company_short_name) # raise exception or redirect if not logged in
|
|
62
|
-
|
|
63
|
-
# In case not logged in check_if_user_is_logged_in redirects to login page
|
|
64
|
-
auth_method = "Session"
|
|
65
|
-
local_user_id = SessionManager.get('user_id')
|
|
66
|
-
company_id = SessionManager.get('company_id')
|
|
67
|
-
external_user_id = ""
|
|
68
|
-
|
|
69
|
-
if not company_id or not local_user_id:
|
|
70
|
-
logging.error(
|
|
71
|
-
f"Sesión válida para {company_short_name} pero falta company_id o user_id en SessionManager.")
|
|
72
|
-
return {"error_message": "Fallo interno en la autenticación o no autenticado"}
|
|
73
|
-
|
|
74
|
-
# last verification of authentication
|
|
75
|
-
if company_id is None or auth_method is None or local_user_id is None:
|
|
76
|
-
# this condition should never happen,
|
|
77
|
-
logging.error(
|
|
78
|
-
f"Fallo inesperado en la lógica de autenticación para {company_short_name}. Ningún método tuvo éxito o devolvió error.")
|
|
79
|
-
return {"error_message": "Fallo interno en la autenticación o no autenticado"}
|
|
80
|
-
|
|
81
|
-
return {
|
|
82
|
-
'success': True,
|
|
83
|
-
"auth_method": auth_method,
|
|
84
|
-
"company_id": company_id,
|
|
85
|
-
"auth_method": auth_method,
|
|
86
|
-
"local_user_id": local_user_id,
|
|
87
|
-
"external_user_id": external_user_id
|
|
88
|
-
}
|
|
89
|
-
|
|
90
|
-
def _authenticate_via_api_key(self, company_short_name_from_url: str):
|
|
91
|
-
"""
|
|
92
|
-
try to authenticate using an API Key from the header 'Authorization'.
|
|
93
|
-
Retorna (company_id, None) en éxito.
|
|
94
|
-
Retorna (None, error_message) en fallo.
|
|
95
|
-
"""
|
|
96
|
-
api_key_header = request.headers.get('Authorization')
|
|
97
|
-
api_key_value = None
|
|
98
|
-
|
|
99
|
-
# extract the key
|
|
100
|
-
if api_key_header and api_key_header.startswith('Bearer '):
|
|
101
|
-
api_key_value = api_key_header.split('Bearer ')[1]
|
|
102
|
-
else:
|
|
103
|
-
# there is no key in the headers expected
|
|
104
|
-
return None, None
|
|
105
|
-
|
|
106
|
-
# validate the api-key using ProfileRepo
|
|
107
|
-
try:
|
|
108
|
-
api_key_entry = self.profile_repo.get_active_api_key_entry(api_key_value)
|
|
109
|
-
if not api_key_entry:
|
|
110
|
-
logging.warning(f"Intento de acceso con API Key inválida o inactiva: {api_key_value[:5]}...")
|
|
111
|
-
return None, "API Key inválida o inactiva"
|
|
112
|
-
|
|
113
|
-
# check that the key belongs to the company
|
|
114
|
-
# api_key_entry.company already loaded by joinedload
|
|
115
|
-
if not api_key_entry.company or api_key_entry.company.short_name != company_short_name_from_url:
|
|
116
|
-
return None, f"API Key no es válida para la compañía {company_short_name_from_url}"
|
|
117
|
-
|
|
118
|
-
# successfull auth by API Key
|
|
119
|
-
company_id = api_key_entry.company_id
|
|
120
|
-
|
|
121
|
-
return company_id, None
|
|
122
|
-
|
|
123
|
-
except Exception as e:
|
|
124
|
-
logging.exception(f"Error interno durante validación de API Key: {e}")
|
|
125
|
-
return None, "Error interno del servidor al validar API Key"
|
|
126
|
-
|
|
127
|
-
def _authenticate_via_chat_jwt(self, company_short_name_from_url: str) -> tuple[
|
|
128
|
-
Optional[int], Optional[str], Optional[str]]:
|
|
129
|
-
"""
|
|
130
|
-
authenticate using an JWT chat session in the del header 'X-Chat-Token'.
|
|
131
|
-
Return (company_id, external_user_id, None) on exit
|
|
132
|
-
Returns (None, None, error_message) on fail.
|
|
133
|
-
"""
|
|
134
|
-
chat_jwt = request.headers.get('X-Chat-Token')
|
|
135
|
-
if not chat_jwt:
|
|
136
|
-
return None, None, None
|
|
137
|
-
|
|
138
|
-
# open the jwt token and retrieve the payload
|
|
139
|
-
jwt_payload = self.jwt_service.validate_chat_jwt(chat_jwt, company_short_name_from_url)
|
|
140
|
-
if not jwt_payload:
|
|
141
|
-
# validation fails (token expired, incorrect signature, company , etc.)
|
|
142
|
-
# validate_chat_jwt logs the specific failure
|
|
143
|
-
return None, None, "Token de chat expirado, debes reingresar al chat"
|
|
144
|
-
|
|
145
|
-
# JWT is validated: extract the company_id and external_user_id
|
|
146
|
-
company_id = jwt_payload.get('company_id')
|
|
147
|
-
external_user_id = jwt_payload.get('external_user_id')
|
|
148
|
-
|
|
149
|
-
# Sanity check aditional, should never happen
|
|
150
|
-
if not isinstance(company_id, int) or not external_user_id:
|
|
151
|
-
logging.error(
|
|
152
|
-
f"LLMQuery: JWT payload incompleto tras validación exitosa. CompanyID: {company_id}, UserID: {external_user_id}")
|
|
153
|
-
return None, None, "Token de chat con formato interno incorrecto"
|
|
154
|
-
|
|
155
|
-
return company_id, external_user_id, None
|
|
156
|
-
|
|
157
|
-
def check_if_user_is_logged_in(self, company_short_name: str):
|
|
158
|
-
if not SessionManager.get('user'):
|
|
159
|
-
if company_short_name:
|
|
160
|
-
return redirect(url_for('login', company_short_name=company_short_name))
|
|
161
|
-
else:
|
|
162
|
-
return redirect(url_for('home'))
|
|
163
|
-
|
|
164
|
-
if company_short_name != SessionManager.get('company_short_name'):
|
|
165
|
-
return redirect(url_for('login', company_short_name=company_short_name))
|
|
166
|
-
|
|
167
|
-
# check session timeout
|
|
168
|
-
if not self.check_session_timeout():
|
|
169
|
-
SessionManager.clear()
|
|
170
|
-
return redirect(url_for('login', company_short_name=company_short_name))
|
|
171
|
-
|
|
172
|
-
# update last_activity
|
|
173
|
-
SessionManager.set('last_activity', datetime.now(timezone.utc).timestamp())
|
|
174
|
-
|
|
175
|
-
def check_session_timeout(self):
|
|
176
|
-
# get last activity from session manager
|
|
177
|
-
last_activity = SessionManager.get('last_activity')
|
|
178
|
-
if not last_activity:
|
|
179
|
-
return False
|
|
180
|
-
|
|
181
|
-
# Tiempo actual en timestamp
|
|
182
|
-
current_time = datetime.now(timezone.utc).timestamp()
|
|
183
|
-
|
|
184
|
-
# get inactivity duration
|
|
185
|
-
inactivity_duration = current_time - last_activity
|
|
186
|
-
|
|
187
|
-
# verify if inactivity duration is greater than MAX_INACTIVITY_SECONDS
|
|
188
|
-
if inactivity_duration > MAX_INACTIVITY_SECONDS:
|
|
189
|
-
# close session
|
|
190
|
-
return False
|
|
191
|
-
|
|
192
|
-
# update last activity timestamp
|
|
193
|
-
SessionManager.set('last_activity', current_time)
|
|
194
|
-
|
|
195
|
-
return True # session is active
|
|
196
|
-
|
|
197
|
-
|
|
198
|
-
|
|
199
|
-
|
|
200
|
-
|
iatoolkit/templates/login.html
DELETED
|
@@ -1,43 +0,0 @@
|
|
|
1
|
-
{% extends "base.html" %}
|
|
2
|
-
|
|
3
|
-
{% block title %}Inicio de Sesión{% endblock %}
|
|
4
|
-
|
|
5
|
-
{% block content %}
|
|
6
|
-
<div class="container d-flex justify-content-center align-items-center vh-100">
|
|
7
|
-
<div class="col-11 col-md-6 col-lg-4 border rounded p-3 shadow-sm">
|
|
8
|
-
<h4 class="text-muted fw-semibold text-start mb-3">Iniciar Sesión - {{ company.name }}
|
|
9
|
-
</h4>
|
|
10
|
-
<form action="{{ url_for('login', company_short_name=company_short_name) }}"
|
|
11
|
-
method="post">
|
|
12
|
-
<div class="mb-3">
|
|
13
|
-
<label for="email" class="form-label text-muted">Correo Electrónico</label>
|
|
14
|
-
<input type="email" id="email" name="email"
|
|
15
|
-
class="form-control" required
|
|
16
|
-
value="{{ form_data.email if form_data else '' }}">
|
|
17
|
-
</div>
|
|
18
|
-
<div class="mb-3">
|
|
19
|
-
<label for="password" class="form-label">Contraseña</label>
|
|
20
|
-
<input type="password" id="password" name="password"
|
|
21
|
-
class="form-control" required
|
|
22
|
-
value="{{ form_data.password if form_data else '' }}">
|
|
23
|
-
</div>
|
|
24
|
-
<button type="submit" class="btn btn-primary w-100">Iniciar Sesión</button>
|
|
25
|
-
|
|
26
|
-
<p class="text-muted text-start mt-3" style="text-align: justify;">
|
|
27
|
-
Ingresa tus credenciales para acceder a tu cuenta. Si olvidaste tu contraseña,
|
|
28
|
-
puedes recuperarla fácilmente a través del siguiente enlace.
|
|
29
|
-
</p>
|
|
30
|
-
<div class="text-center mt-3">
|
|
31
|
-
<a href="{{ url_for('signup', company_short_name=company_short_name) }}">
|
|
32
|
-
¿No tienes cuenta? Regístrate
|
|
33
|
-
</a>
|
|
34
|
-
</div>
|
|
35
|
-
<div class="text-center mt-3">
|
|
36
|
-
<a href="{{ url_for('forgot_password', company_short_name=company_short_name) }}">
|
|
37
|
-
¿Olvidaste tu contraseña?
|
|
38
|
-
</a>
|
|
39
|
-
</div>
|
|
40
|
-
</form>
|
|
41
|
-
</div>
|
|
42
|
-
</div>
|
|
43
|
-
{% endblock %}
|
|
@@ -1,58 +0,0 @@
|
|
|
1
|
-
# Copyright (c) 2024 Fernando Libedinsky
|
|
2
|
-
# Product: IAToolkit
|
|
3
|
-
#
|
|
4
|
-
# IAToolkit is open source software.
|
|
5
|
-
|
|
6
|
-
import logging
|
|
7
|
-
import os
|
|
8
|
-
|
|
9
|
-
from flask import current_app, jsonify, send_from_directory
|
|
10
|
-
from flask.views import MethodView
|
|
11
|
-
from injector import inject
|
|
12
|
-
|
|
13
|
-
from iatoolkit.common.auth import IAuthentication
|
|
14
|
-
from iatoolkit.services.excel_service import ExcelService
|
|
15
|
-
from iatoolkit.services.profile_service import ProfileService
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
class DownloadFileView(MethodView):
|
|
19
|
-
@inject
|
|
20
|
-
def __init__(self, iauthentication: IAuthentication, profile_service: ProfileService, excel_service: ExcelService):
|
|
21
|
-
self.iauthentication = iauthentication
|
|
22
|
-
self.profile_service = profile_service
|
|
23
|
-
self.excel_service = excel_service
|
|
24
|
-
|
|
25
|
-
def get(self, company_short_name: str, external_user_id: str, filename: str):
|
|
26
|
-
if not external_user_id:
|
|
27
|
-
return jsonify({"error": "Falta external_user_id"}), 400
|
|
28
|
-
|
|
29
|
-
iauth = self.iauthentication.verify(
|
|
30
|
-
company_short_name,
|
|
31
|
-
body_external_user_id=external_user_id
|
|
32
|
-
)
|
|
33
|
-
if not iauth.get("success"):
|
|
34
|
-
return jsonify(iauth), 401
|
|
35
|
-
|
|
36
|
-
company = self.profile_service.get_company_by_short_name(company_short_name)
|
|
37
|
-
if not company:
|
|
38
|
-
return jsonify({"error": "Empresa no encontrada"}), 404
|
|
39
|
-
|
|
40
|
-
file_validation = self.excel_service.validate_file_access(filename)
|
|
41
|
-
if file_validation:
|
|
42
|
-
return file_validation
|
|
43
|
-
|
|
44
|
-
temp_dir = os.path.join(current_app.root_path, 'static', 'temp')
|
|
45
|
-
|
|
46
|
-
try:
|
|
47
|
-
response = send_from_directory(
|
|
48
|
-
temp_dir,
|
|
49
|
-
filename,
|
|
50
|
-
as_attachment=True,
|
|
51
|
-
mimetype='application/octet-stream'
|
|
52
|
-
)
|
|
53
|
-
logging.info(f"Archivo descargado via API: {filename}")
|
|
54
|
-
return response
|
|
55
|
-
except Exception as e:
|
|
56
|
-
logging.error(f"Error descargando archivo {filename}: {str(e)}")
|
|
57
|
-
return jsonify({"error": "Error descargando archivo"}), 500
|
|
58
|
-
|
iatoolkit/views/history_view.py
DELETED
|
@@ -1,57 +0,0 @@
|
|
|
1
|
-
# Copyright (c) 2024 Fernando Libedinsky
|
|
2
|
-
# Product: IAToolkit
|
|
3
|
-
#
|
|
4
|
-
# IAToolkit is open source software.
|
|
5
|
-
|
|
6
|
-
from flask import request, jsonify, render_template
|
|
7
|
-
from flask.views import MethodView
|
|
8
|
-
from iatoolkit.services.history_service import HistoryService
|
|
9
|
-
from iatoolkit.common.auth import IAuthentication
|
|
10
|
-
from injector import inject
|
|
11
|
-
import logging
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
class HistoryView(MethodView):
|
|
15
|
-
@inject
|
|
16
|
-
def __init__(self,
|
|
17
|
-
iauthentication: IAuthentication,
|
|
18
|
-
history_service: HistoryService ):
|
|
19
|
-
self.iauthentication = iauthentication
|
|
20
|
-
self.history_service = history_service
|
|
21
|
-
|
|
22
|
-
def post(self, company_short_name):
|
|
23
|
-
try:
|
|
24
|
-
data = request.get_json()
|
|
25
|
-
except Exception:
|
|
26
|
-
return jsonify({"error_message": "Cuerpo de la solicitud JSON inválido o faltante"}), 400
|
|
27
|
-
|
|
28
|
-
if not data:
|
|
29
|
-
return jsonify({"error_message": "Cuerpo de la solicitud JSON inválido o faltante"}), 400
|
|
30
|
-
|
|
31
|
-
# get access credentials
|
|
32
|
-
iaut = self.iauthentication.verify(company_short_name, data.get("external_user_id"))
|
|
33
|
-
if not iaut.get("success"):
|
|
34
|
-
return jsonify(iaut), 401
|
|
35
|
-
|
|
36
|
-
external_user_id = data.get("external_user_id")
|
|
37
|
-
local_user_id = iaut.get("local_user_id", 0)
|
|
38
|
-
|
|
39
|
-
try:
|
|
40
|
-
response = self.history_service.get_history(
|
|
41
|
-
company_short_name=company_short_name,
|
|
42
|
-
external_user_id=external_user_id,
|
|
43
|
-
local_user_id=local_user_id
|
|
44
|
-
)
|
|
45
|
-
|
|
46
|
-
if "error" in response:
|
|
47
|
-
return {'error_message': response["error"]}, 402
|
|
48
|
-
|
|
49
|
-
return response, 200
|
|
50
|
-
except Exception as e:
|
|
51
|
-
logging.exception(
|
|
52
|
-
f"Error inesperado al obtener el historial de consultas para company {company_short_name}: {e}")
|
|
53
|
-
if local_user_id:
|
|
54
|
-
return render_template("error.html",
|
|
55
|
-
message="Ha ocurrido un error inesperado."), 500
|
|
56
|
-
else:
|
|
57
|
-
return jsonify({"error_message": str(e)}), 500
|
|
@@ -1,35 +0,0 @@
|
|
|
1
|
-
from flask.views import MethodView
|
|
2
|
-
from injector import inject
|
|
3
|
-
from iatoolkit.common.auth import IAuthentication
|
|
4
|
-
from iatoolkit.services.query_service import QueryService
|
|
5
|
-
from flask import jsonify
|
|
6
|
-
import logging
|
|
7
|
-
|
|
8
|
-
class InitContextView(MethodView):
|
|
9
|
-
|
|
10
|
-
@inject
|
|
11
|
-
def __init__(self,
|
|
12
|
-
iauthentication: IAuthentication,
|
|
13
|
-
query_service: QueryService
|
|
14
|
-
):
|
|
15
|
-
self.iauthentication = iauthentication
|
|
16
|
-
self.query_service = query_service
|
|
17
|
-
|
|
18
|
-
def get(self, company_short_name: str, external_user_id: str):
|
|
19
|
-
# 1. get access credentials
|
|
20
|
-
iaut = self.iauthentication.verify(company_short_name, external_user_id)
|
|
21
|
-
if not iaut.get("success"):
|
|
22
|
-
return jsonify(iaut), 401
|
|
23
|
-
|
|
24
|
-
try:
|
|
25
|
-
# initialize the context
|
|
26
|
-
self.query_service.llm_init_context(
|
|
27
|
-
company_short_name=company_short_name,
|
|
28
|
-
external_user_id=external_user_id
|
|
29
|
-
)
|
|
30
|
-
|
|
31
|
-
return {'status': 'OK'}, 200
|
|
32
|
-
except Exception as e:
|
|
33
|
-
logging.exception(
|
|
34
|
-
f"Error inesperado al inicializar el contexto durante el login para company {company_short_name}: {e}")
|
|
35
|
-
return jsonify({"error_message": str(e)}), 500
|
iatoolkit/views/llmquery_view.py
DELETED
|
@@ -1,65 +0,0 @@
|
|
|
1
|
-
# Copyright (c) 2024 Fernando Libedinsky
|
|
2
|
-
# Product: IAToolkit
|
|
3
|
-
#
|
|
4
|
-
# IAToolkit is open source software.
|
|
5
|
-
|
|
6
|
-
from flask import request, jsonify, render_template
|
|
7
|
-
from flask.views import MethodView
|
|
8
|
-
from iatoolkit.services.query_service import QueryService
|
|
9
|
-
from iatoolkit.common.auth import IAuthentication
|
|
10
|
-
from injector import inject
|
|
11
|
-
import logging
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
class LLMQueryView(MethodView):
|
|
15
|
-
@inject
|
|
16
|
-
def __init__(self,
|
|
17
|
-
iauthentication: IAuthentication,
|
|
18
|
-
query_service: QueryService,
|
|
19
|
-
):
|
|
20
|
-
self.iauthentication = iauthentication
|
|
21
|
-
self.query_service = query_service
|
|
22
|
-
|
|
23
|
-
def post(self, company_short_name):
|
|
24
|
-
data = request.get_json()
|
|
25
|
-
if not data:
|
|
26
|
-
return jsonify({"error_message": "Cuerpo de la solicitud JSON inválido o faltante"}), 400
|
|
27
|
-
|
|
28
|
-
# get access credentials
|
|
29
|
-
iaut = self.iauthentication.verify(company_short_name, data.get("external_user_id"))
|
|
30
|
-
if not iaut.get("success"):
|
|
31
|
-
return jsonify(iaut), 401
|
|
32
|
-
|
|
33
|
-
company_id = iaut.get("company_id")
|
|
34
|
-
external_user_id = iaut.get("external_user_id")
|
|
35
|
-
local_user_id = iaut.get("local_user_id")
|
|
36
|
-
|
|
37
|
-
# now check the form
|
|
38
|
-
question = data.get("question")
|
|
39
|
-
files = data.get("files", [])
|
|
40
|
-
client_data = data.get("client_data", {})
|
|
41
|
-
prompt_name = data.get("prompt_name")
|
|
42
|
-
if not question and not prompt_name:
|
|
43
|
-
return jsonify({"error_message": "Falta la consulta o el prompt_name"}), 400
|
|
44
|
-
|
|
45
|
-
try:
|
|
46
|
-
response = self.query_service.llm_query(
|
|
47
|
-
company_short_name=company_short_name,
|
|
48
|
-
external_user_id=external_user_id,
|
|
49
|
-
local_user_id=local_user_id,
|
|
50
|
-
question=question,
|
|
51
|
-
prompt_name=prompt_name,
|
|
52
|
-
client_data=client_data,
|
|
53
|
-
files=files)
|
|
54
|
-
if "error" in response:
|
|
55
|
-
return {'error_message': response.get("error_message", '')}, 401
|
|
56
|
-
|
|
57
|
-
return response, 200
|
|
58
|
-
except Exception as e:
|
|
59
|
-
logging.exception(
|
|
60
|
-
f"Error inesperado al procesar llm_query para company {company_short_name}: {e}")
|
|
61
|
-
if local_user_id:
|
|
62
|
-
return render_template("error.html",
|
|
63
|
-
message="Ha ocurrido un error inesperado."), 500
|
|
64
|
-
else:
|
|
65
|
-
return jsonify({"error_message": str(e)}), 500
|
|
File without changes
|
|
File without changes
|