iatoolkit 0.7.10__py3-none-any.whl → 0.7.12__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/__init__.py +18 -14
- iatoolkit/base_company.py +5 -5
- iatoolkit/cli_commands.py +5 -3
- {common → iatoolkit/common}/auth.py +3 -3
- {common → iatoolkit/common}/routes.py +19 -19
- {common → iatoolkit/common}/util.py +2 -2
- iatoolkit/iatoolkit.py +37 -38
- {infra → iatoolkit/infra}/call_service.py +1 -1
- {infra → iatoolkit/infra}/connectors/file_connector_factory.py +5 -5
- {infra → iatoolkit/infra}/connectors/google_cloud_storage_connector.py +1 -1
- {infra → iatoolkit/infra}/connectors/google_drive_connector.py +1 -1
- {infra → iatoolkit/infra}/connectors/local_file_connector.py +2 -2
- {infra → iatoolkit/infra}/connectors/s3_connector.py +1 -1
- {infra → iatoolkit/infra}/gemini_adapter.py +2 -2
- {infra → iatoolkit/infra}/google_chat_app.py +1 -1
- {infra → iatoolkit/infra}/llm_client.py +7 -7
- {infra → iatoolkit/infra}/llm_proxy.py +6 -6
- {infra → iatoolkit/infra}/mail_app.py +1 -1
- {infra → iatoolkit/infra}/openai_adapter.py +2 -2
- {repositories → iatoolkit/repositories}/database_manager.py +1 -1
- {repositories → iatoolkit/repositories}/document_repo.py +3 -3
- {repositories → iatoolkit/repositories}/llm_query_repo.py +2 -2
- {repositories → iatoolkit/repositories}/profile_repo.py +2 -2
- {repositories → iatoolkit/repositories}/tasks_repo.py +2 -2
- {repositories → iatoolkit/repositories}/vs_repo.py +3 -3
- {services → iatoolkit/services}/benchmark_service.py +3 -3
- {services → iatoolkit/services}/dispatcher_service.py +9 -8
- {services → iatoolkit/services}/document_service.py +1 -1
- {services → iatoolkit/services}/excel_service.py +2 -2
- {services → iatoolkit/services}/file_processor_service.py +2 -2
- {services → iatoolkit/services}/history_service.py +4 -3
- {services → iatoolkit/services}/load_documents_service.py +11 -10
- {services → iatoolkit/services}/mail_service.py +2 -2
- {services → iatoolkit/services}/profile_service.py +6 -6
- {services → iatoolkit/services}/prompt_manager_service.py +5 -4
- {services → iatoolkit/services}/query_service.py +12 -11
- {services → iatoolkit/services}/search_service.py +2 -2
- {services → iatoolkit/services}/sql_service.py +4 -3
- {services → iatoolkit/services}/tasks_service.py +6 -6
- {services → iatoolkit/services}/user_feedback_service.py +3 -3
- {services → iatoolkit/services}/user_session_context_service.py +1 -1
- iatoolkit/static/images/arrow_up.png +0 -0
- iatoolkit/static/images/diagrama_iatoolkit.jpg +0 -0
- iatoolkit/static/images/logo_clinica.png +0 -0
- iatoolkit/static/images/logo_iatoolkit.png +0 -0
- iatoolkit/static/images/logo_maxxa.png +0 -0
- iatoolkit/static/images/logo_notaria.png +0 -0
- iatoolkit/static/images/logo_tarjeta.png +0 -0
- iatoolkit/static/images/logo_umayor.png +0 -0
- iatoolkit/static/images/upload.png +0 -0
- iatoolkit/static/js/chat_feedback.js +115 -0
- iatoolkit/static/js/chat_filepond.js +85 -0
- iatoolkit/static/js/chat_history.js +117 -0
- iatoolkit/static/js/chat_main.js +436 -0
- iatoolkit/static/styles/chat_iatoolkit.css +701 -0
- iatoolkit/static/styles/chat_info.css +53 -0
- iatoolkit/static/styles/chat_modal.css +136 -0
- iatoolkit/static/styles/llm_output.css +115 -0
- iatoolkit/static/temp/024f44a9-cc7e-4bde-9a3c-11903a8f5d3d.xlsx +0 -0
- iatoolkit/static/temp/0b97768e-79e8-43ec-b17e-ba3137f94e93.xlsx +0 -0
- iatoolkit/static/temp/202883ee-763e-4b40-9bb6-bfacfc5e65fe.xlsx +0 -0
- iatoolkit/static/temp/28287491-08b7-4863-a2a3-49fcb64a0906.xlsx +0 -0
- iatoolkit/static/temp/36780cac-7a46-4db4-ac98-7338a51aaf52.xlsx +0 -0
- iatoolkit/static/temp/5c1b66f6-d58f-4684-8a7a-df3bb1a35eaa.xlsx +0 -0
- iatoolkit/static/temp/5d5a3500-ec57-4e07-a554-8799a906d1ab.xlsx +0 -0
- iatoolkit/static/temp/65887e40-cf64-49aa-8d1f-651cb0f8cdf0.xlsx +0 -0
- iatoolkit/static/temp/6fa64b13-e8e5-40ad-8257-00fd1682dad8.xlsx +0 -0
- iatoolkit/static/temp/7ab7071f-ad9b-49e6-8e63-f08410625ce7.xlsx +0 -0
- iatoolkit/static/temp/824346d9-d54d-40c6-b5c2-9e1d84d0ae90.xlsx +0 -0
- iatoolkit/static/temp/9ca80c3d-d196-4dfc-8179-582584fae04c.xlsx +0 -0
- iatoolkit/static/temp/a34cb8a6-85fb-4ea8-aabe-889967cd83b5.xlsx +0 -0
- iatoolkit/static/temp/a7fc9c13-c509-4499-b4be-23bfa57cac31.xlsx +0 -0
- iatoolkit/static/temp/b83084f5-fe54-4580-885e-412b4388cbda.xlsx +0 -0
- iatoolkit/static/temp/c17c6864-34e1-448f-b0e9-380354256ea9.xlsx +0 -0
- iatoolkit/static/temp/customer_clusters.parquet +0 -0
- iatoolkit/static/temp/customer_clusters.xlsx +0 -0
- iatoolkit/static/temp/d1af98b8-18a9-4b94-b9bc-607d19a87d0d.xlsx +0 -0
- iatoolkit/templates/about.html +13 -0
- iatoolkit/templates/base.html +45 -0
- iatoolkit/templates/change_password.html +45 -0
- iatoolkit/templates/chat.html +180 -0
- iatoolkit/templates/chat_modals.html +115 -0
- iatoolkit/templates/error.html +15 -0
- iatoolkit/templates/forgot_password.html +33 -0
- iatoolkit/templates/header.html +31 -0
- iatoolkit/templates/home.html +201 -0
- iatoolkit/templates/login.html +43 -0
- iatoolkit/templates/signup.html +78 -0
- iatoolkit/templates/test.html +9 -0
- {views → iatoolkit/views}/change_password_view.py +1 -1
- {views → iatoolkit/views}/chat_token_request_view.py +2 -2
- {views → iatoolkit/views}/chat_view.py +3 -3
- {views → iatoolkit/views}/download_file_view.py +3 -3
- {views → iatoolkit/views}/external_chat_login_view.py +5 -5
- {views → iatoolkit/views}/external_login_view.py +2 -2
- {views → iatoolkit/views}/file_store_view.py +2 -2
- {views → iatoolkit/views}/forgot_password_view.py +1 -1
- {views → iatoolkit/views}/history_view.py +2 -2
- {views → iatoolkit/views}/home_view.py +1 -1
- {views → iatoolkit/views}/llmquery_view.py +2 -2
- {views → iatoolkit/views}/login_view.py +1 -1
- {views → iatoolkit/views}/prompt_view.py +2 -2
- {views → iatoolkit/views}/signup_view.py +1 -1
- {views → iatoolkit/views}/tasks_review_view.py +2 -2
- {views → iatoolkit/views}/tasks_view.py +2 -2
- {views → iatoolkit/views}/user_feedback_view.py +2 -2
- {views → iatoolkit/views}/verify_user_view.py +1 -1
- {iatoolkit-0.7.10.dist-info → iatoolkit-0.7.12.dist-info}/METADATA +1 -1
- iatoolkit-0.7.12.dist-info/RECORD +194 -0
- iatoolkit-0.7.12.dist-info/top_level.txt +2 -0
- tests/__init__.py +5 -0
- tests/common/__init__.py +0 -0
- tests/common/test_auth.py +279 -0
- tests/common/test_routes.py +42 -0
- tests/common/test_session_manager.py +59 -0
- tests/common/test_util.py +444 -0
- tests/companies/__init__.py +5 -0
- tests/conftest.py +36 -0
- tests/infra/__init__.py +5 -0
- tests/infra/connectors/__init__.py +5 -0
- tests/infra/connectors/test_google_drive_connector.py +107 -0
- tests/infra/connectors/test_local_file_connector.py +85 -0
- tests/infra/connectors/test_s3_connector.py +95 -0
- tests/infra/test_call_service.py +92 -0
- tests/infra/test_database_manager.py +59 -0
- tests/infra/test_gemini_adapter.py +137 -0
- tests/infra/test_google_chat_app.py +68 -0
- tests/infra/test_llm_client.py +165 -0
- tests/infra/test_llm_proxy.py +122 -0
- tests/infra/test_mail_app.py +94 -0
- tests/infra/test_openai_adapter.py +105 -0
- tests/infra/test_redis_session_manager_service.py +117 -0
- tests/repositories/__init__.py +5 -0
- tests/repositories/test_database_manager.py +87 -0
- tests/repositories/test_document_repo.py +76 -0
- tests/repositories/test_llm_query_repo.py +340 -0
- tests/repositories/test_models.py +38 -0
- tests/repositories/test_profile_repo.py +142 -0
- tests/repositories/test_tasks_repo.py +76 -0
- tests/repositories/test_vs_repo.py +107 -0
- tests/services/__init__.py +5 -0
- tests/services/test_dispatcher_service.py +274 -0
- tests/services/test_document_service.py +181 -0
- tests/services/test_excel_service.py +208 -0
- tests/services/test_file_processor_service.py +121 -0
- tests/services/test_history_service.py +164 -0
- tests/services/test_jwt_service.py +255 -0
- tests/services/test_load_documents_service.py +112 -0
- tests/services/test_mail_service.py +70 -0
- tests/services/test_profile_service.py +379 -0
- tests/services/test_prompt_manager_service.py +190 -0
- tests/services/test_query_service.py +243 -0
- tests/services/test_search_service.py +39 -0
- tests/services/test_sql_service.py +160 -0
- tests/services/test_tasks_service.py +252 -0
- tests/services/test_user_feedback_service.py +389 -0
- tests/services/test_user_session_context_service.py +132 -0
- tests/views/__init__.py +5 -0
- tests/views/test_change_password_view.py +191 -0
- tests/views/test_chat_token_request_view.py +188 -0
- tests/views/test_chat_view.py +98 -0
- tests/views/test_download_file_view.py +149 -0
- tests/views/test_external_chat_login_view.py +120 -0
- tests/views/test_external_login_view.py +102 -0
- tests/views/test_file_store_view.py +128 -0
- tests/views/test_forgot_password_view.py +142 -0
- tests/views/test_history_view.py +336 -0
- tests/views/test_home_view.py +61 -0
- tests/views/test_llm_query_view.py +154 -0
- tests/views/test_login_view.py +114 -0
- tests/views/test_prompt_view.py +111 -0
- tests/views/test_signup_view.py +140 -0
- tests/views/test_tasks_review_view.py +104 -0
- tests/views/test_tasks_view.py +130 -0
- tests/views/test_user_feedback_view.py +214 -0
- tests/views/test_verify_user_view.py +110 -0
- iatoolkit-0.7.10.dist-info/RECORD +0 -80
- iatoolkit-0.7.10.dist-info/top_level.txt +0 -6
- {common → iatoolkit/common}/__init__.py +0 -0
- {common → iatoolkit/common}/exceptions.py +0 -0
- {common → iatoolkit/common}/session_manager.py +0 -0
- {infra → iatoolkit/infra}/__init__.py +0 -0
- {infra → iatoolkit/infra}/connectors/__init__.py +0 -0
- {infra → iatoolkit/infra}/connectors/file_connector.py +0 -0
- {infra → iatoolkit/infra}/llm_response.py +0 -0
- {infra → iatoolkit/infra}/redis_session_manager.py +0 -0
- {repositories → iatoolkit/repositories}/__init__.py +0 -0
- {repositories → iatoolkit/repositories}/models.py +0 -0
- {services → iatoolkit/services}/__init__.py +0 -0
- {services → iatoolkit/services}/jwt_service.py +0 -0
- {views → iatoolkit/views}/__init__.py +0 -0
- {iatoolkit-0.7.10.dist-info → iatoolkit-0.7.12.dist-info}/WHEEL +0 -0
|
@@ -0,0 +1,115 @@
|
|
|
1
|
+
<!-- Modal para mostrar archivos cargados -->
|
|
2
|
+
<div class="modal fade" id="uploadedFilesModal" tabindex="-1" aria-labelledby="uploadedFilesModalLabel" aria-hidden="true">
|
|
3
|
+
<div class="modal-dialog">
|
|
4
|
+
<div class="modal-content">
|
|
5
|
+
<div class="modal-header">
|
|
6
|
+
<h5 class="modal-title" id="uploadedFilesModalLabel">Archivos Cargados</h5>
|
|
7
|
+
<button type="button" class="btn-close" data-bs-dismiss="modal" aria-label="Close"></button>
|
|
8
|
+
</div>
|
|
9
|
+
<div class="modal-body">
|
|
10
|
+
<ul id="uploaded-files-list" class="list-group">
|
|
11
|
+
<!-- Los nombres de los archivos se agregarán aquí por JS -->
|
|
12
|
+
</ul>
|
|
13
|
+
</div>
|
|
14
|
+
<div class="modal-footer">
|
|
15
|
+
<button type="button" class="btn btn-secondary" data-bs-dismiss="modal">Cerrar</button>
|
|
16
|
+
</div>
|
|
17
|
+
</div>
|
|
18
|
+
</div>
|
|
19
|
+
</div>
|
|
20
|
+
|
|
21
|
+
<!-- Modal para feedback -->
|
|
22
|
+
<div class="modal fade" id="feedbackModal" tabindex="-1" aria-labelledby="feedbackModalLabel" aria-hidden="true">
|
|
23
|
+
<div class="modal-dialog modal-dialog-centered">
|
|
24
|
+
<div class="modal-content">
|
|
25
|
+
<div class="modal-header">
|
|
26
|
+
<h5 class="modal-title" id="feedbackModalLabel">
|
|
27
|
+
<i class="bi bi-chat-dots me-3"></i>Tu Opinión es Importante
|
|
28
|
+
</h5>
|
|
29
|
+
<button type="button" class="btn-close" data-bs-dismiss="modal" aria-label="Close"></button>
|
|
30
|
+
</div>
|
|
31
|
+
<div class="modal-body">
|
|
32
|
+
<p class="text-center mb-2"><strong>¿Qué tan útil fue la respuesta del asistente?</strong></p>
|
|
33
|
+
|
|
34
|
+
<!-- ▼▼▼ ESTE ES EL BLOQUE DE HTML QUE FALTABA ▼▼▼ -->
|
|
35
|
+
<div class="rating-stars mb-4">
|
|
36
|
+
<span class="star" data-rating="1" onclick="gfg(1)"></span>
|
|
37
|
+
<span class="star" data-rating="2" onclick="gfg(2)"></span>
|
|
38
|
+
<span class="star" data-rating="3" onclick="gfg(3)"></span>
|
|
39
|
+
<span class="star" data-rating="4" onclick="gfg(4)"></span>
|
|
40
|
+
<span class="star" data-rating="5" onclick="gfg(5)"></span>
|
|
41
|
+
</div>
|
|
42
|
+
<!-- ▲▲▲ FIN DEL BLOQUE DE HTML QUE FALTABA ▲▲▲ -->
|
|
43
|
+
|
|
44
|
+
<div class="form-group">
|
|
45
|
+
<label for="feedback-text" class="form-label text-muted">Tu comentario nos ayuda a mejorar:</label>
|
|
46
|
+
<textarea
|
|
47
|
+
class="form-control feedback-text"
|
|
48
|
+
id="feedback-text"
|
|
49
|
+
rows="4"
|
|
50
|
+
placeholder="Escribe aquí tu opinión, sugerencias o comentarios..."
|
|
51
|
+
style="resize: vertical; min-height: 100px;"></textarea>
|
|
52
|
+
</div>
|
|
53
|
+
</div>
|
|
54
|
+
<div class="modal-footer">
|
|
55
|
+
<button type="button" class="btn btn-secondary" data-bs-dismiss="modal">
|
|
56
|
+
<i class="bi bi-x-circle me-1"></i>Cancelar
|
|
57
|
+
</button>
|
|
58
|
+
<button type="button" class="btn btn-primary" id="submit-feedback">
|
|
59
|
+
<i class="bi bi-send me-1"></i>Enviar
|
|
60
|
+
</button>
|
|
61
|
+
</div>
|
|
62
|
+
</div>
|
|
63
|
+
</div>
|
|
64
|
+
</div>
|
|
65
|
+
|
|
66
|
+
<!-- Modal para historial -->
|
|
67
|
+
<div class="modal fade" id="historyModal" tabindex="-1" aria-labelledby="historyModalLabel" aria-hidden="true">
|
|
68
|
+
<div class="modal-dialog modal-lg modal-dialog-centered">
|
|
69
|
+
<div class="modal-content">
|
|
70
|
+
<div class="modal-header">
|
|
71
|
+
<h5 class="modal-title" id="historyModalLabel">
|
|
72
|
+
<i class="bi bi-clock-history me-3"></i>Historial de Consultas
|
|
73
|
+
</h5>
|
|
74
|
+
<button type="button" class="btn-close" data-bs-dismiss="modal" aria-label="Close"></button>
|
|
75
|
+
</div>
|
|
76
|
+
<div class="modal-body">
|
|
77
|
+
<div id="history-loading" style="display: none;" class="text-center p-4">
|
|
78
|
+
<div class="spinner-border text-primary" role="status">
|
|
79
|
+
<span class="visually-hidden">Cargando...</span>
|
|
80
|
+
</div>
|
|
81
|
+
<p class="mt-2">Cargando historial...</p>
|
|
82
|
+
</div>
|
|
83
|
+
<div id="history-error" style="display: none;" class="alert alert-danger">
|
|
84
|
+
<!-- Los errores se mostrarán aquí -->
|
|
85
|
+
</div>
|
|
86
|
+
<div id="history-content" style="display: none;">
|
|
87
|
+
<!-- Texto explicativo -->
|
|
88
|
+
<div class="alert alert-info mb-3" role="alert">
|
|
89
|
+
<i class="bi bi-info-circle me-2"></i>
|
|
90
|
+
<strong>Tip:</strong> Haz clic en cualquier pregunta del historial para copiarla automáticamente al área de texto.
|
|
91
|
+
</div>
|
|
92
|
+
<div class="table-responsive">
|
|
93
|
+
<table class="table table-striped table-hover">
|
|
94
|
+
<thead class="thead-dark">
|
|
95
|
+
<tr>
|
|
96
|
+
<th scope="col">#</th>
|
|
97
|
+
<th scope="col">Fecha</th>
|
|
98
|
+
<th scope="col">Consulta</th>
|
|
99
|
+
</tr>
|
|
100
|
+
</thead>
|
|
101
|
+
<tbody id="history-table-body">
|
|
102
|
+
<!-- Los datos se cargarán aquí -->
|
|
103
|
+
</tbody>
|
|
104
|
+
</table>
|
|
105
|
+
</div>
|
|
106
|
+
</div>
|
|
107
|
+
</div>
|
|
108
|
+
<div class="modal-footer">
|
|
109
|
+
<button type="button" class="btn btn-secondary" data-bs-dismiss="modal">
|
|
110
|
+
<i class="bi bi-x-circle me-1"></i>Cerrar
|
|
111
|
+
</button>
|
|
112
|
+
</div>
|
|
113
|
+
</div>
|
|
114
|
+
</div>
|
|
115
|
+
</div>
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
{% extends "base.html" %}
|
|
2
|
+
|
|
3
|
+
{% block title %}Error - IAToolkit{% endblock %}
|
|
4
|
+
|
|
5
|
+
{% block content %}
|
|
6
|
+
<div class="container vh-100 d-flex justify-content-center align-items-center">
|
|
7
|
+
<div class="text-center col-11 col-md-8 col-lg-6 border rounded p-4 shadow-sm bg-light">
|
|
8
|
+
<h1 class="text-danger fw-bold">¡Ups! Ha ocurrido un error</h1>
|
|
9
|
+
<p class="mt-3 text-muted">
|
|
10
|
+
{{ message }}
|
|
11
|
+
</p>
|
|
12
|
+
<a href="{{ url_for('home') }}" class="btn btn-primary mt-4">Volver al Inicio</a>
|
|
13
|
+
</div>
|
|
14
|
+
</div>
|
|
15
|
+
{% endblock %}
|
|
@@ -0,0 +1,33 @@
|
|
|
1
|
+
{% extends "base.html" %}
|
|
2
|
+
|
|
3
|
+
{% block title %}Recuperar Contraseña{% 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">Recuperar Contraseña</h4>
|
|
9
|
+
|
|
10
|
+
<form action="{{ url_for('forgot_password', company_short_name=company_short_name) }}" method="post">
|
|
11
|
+
<div class="mb-3">
|
|
12
|
+
<label for="email" class="form-label text-muted">Correo Electrónico</label>
|
|
13
|
+
<input type="email" id="email" name="email"
|
|
14
|
+
class="form-control text-muted"
|
|
15
|
+
required value="{{ form_data.email if form_data else '' }}"
|
|
16
|
+
style="text-align: justify;">
|
|
17
|
+
</div>
|
|
18
|
+
|
|
19
|
+
<button type="submit" class="btn btn-primary w-100">Enviar Contraseña</button>
|
|
20
|
+
|
|
21
|
+
<!-- Mensaje descriptivo -->
|
|
22
|
+
<p class="text-muted text-start mt-3" style="text-align: justify;">
|
|
23
|
+
Recibirás un correo con una nueva contraseña temporal junto con un código de seguridad.
|
|
24
|
+
Usa este código para cambiar tu contraseña de forma segura y mantener tu cuenta protegida.
|
|
25
|
+
</p>
|
|
26
|
+
|
|
27
|
+
<div class="text-center mt-3">
|
|
28
|
+
<a href="{{ url_for('login', company_short_name=company_short_name) }}" class="text-muted text-decoration-none fw-semibold">Volver al Login</a>
|
|
29
|
+
</div>
|
|
30
|
+
</form>
|
|
31
|
+
</div>
|
|
32
|
+
</div>
|
|
33
|
+
{% endblock %}
|
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
{% if not external_login %}
|
|
2
|
+
<header class="modern-header">
|
|
3
|
+
{% if not is_mobile or not user %}
|
|
4
|
+
<div class="logo-section">
|
|
5
|
+
<a href="{{ url_for('chat', company_short_name=company_short_name) }}" title="Ir a Inicio">
|
|
6
|
+
{% if company_short_name %}
|
|
7
|
+
<img src="{{ url_for('static', filename='images/' + company.logo_file) }}" alt="Logo de la empresa">
|
|
8
|
+
{% else %}
|
|
9
|
+
<img src="{{ url_for('static', filename='images/logo_iatoolkit.png') }}" alt="Logo predeterminado">
|
|
10
|
+
{% endif %}
|
|
11
|
+
</a>
|
|
12
|
+
</div>
|
|
13
|
+
{% endif %}
|
|
14
|
+
{% if user and user_company == company_short_name %}
|
|
15
|
+
<div class="d-flex ms-auto align-items-center">
|
|
16
|
+
<!-- Nombres del usuario y empresa -->
|
|
17
|
+
<div class="d-flex flex-column {% if not is_mobile %} align-items-end {% endif %} me-3">
|
|
18
|
+
<span class="text-white fw-semibold">
|
|
19
|
+
{{ user.email }}
|
|
20
|
+
</span>
|
|
21
|
+
</div>
|
|
22
|
+
|
|
23
|
+
<!-- Icono de cerrar sesión -->
|
|
24
|
+
<a href="{{ url_for('logout', company_short_name=company_short_name) }}"
|
|
25
|
+
| class="text-white fs-4 ms-3" title="Cerrar sesión">
|
|
26
|
+
<i class="bi bi-box-arrow-right"></i>
|
|
27
|
+
</a>
|
|
28
|
+
</div>
|
|
29
|
+
{% endif %}
|
|
30
|
+
</header>
|
|
31
|
+
{% endif %}
|
|
@@ -0,0 +1,201 @@
|
|
|
1
|
+
{% extends "base.html" %}
|
|
2
|
+
|
|
3
|
+
{% block title %}Inicio - IAToolkit{% endblock %}
|
|
4
|
+
|
|
5
|
+
{% block content %}
|
|
6
|
+
|
|
7
|
+
<!-- Contenido principal con espaciado adicional respecto al header -->
|
|
8
|
+
<div class="row flex-fill mt-5 flex-wrap">
|
|
9
|
+
|
|
10
|
+
{% if not user or user_company != company_short_name %}
|
|
11
|
+
<!-- Sección de login (se coloca primero en el HTML para mobile) -->
|
|
12
|
+
<div class="col-12 col-lg-5 offset-lg-1">
|
|
13
|
+
<div class="border rounded p-4 shadow-sm bg-light">
|
|
14
|
+
<h4 class="text-muted fw-semibold text-start mb-3">login integrado (IAToolkit)</h4>
|
|
15
|
+
<form id="login-form"
|
|
16
|
+
action="{{ url_for('home', company_short_name=company_short_name) }}"
|
|
17
|
+
method="post">
|
|
18
|
+
<div class="mb-3">
|
|
19
|
+
<label for="company_short_name" class="form-label d-block text-muted">Empresa</label>
|
|
20
|
+
<select id="company_short_name" name="company_short_name" class="form-select" required>
|
|
21
|
+
<option value="" disabled selected>Selecciona una empresa</option>
|
|
22
|
+
{% for company in companies %}
|
|
23
|
+
<option value="{{ company.short_name }}"
|
|
24
|
+
{% if company.short_name == company_short_name %}selected{% endif %}>
|
|
25
|
+
{{ company.short_name }}
|
|
26
|
+
</option>
|
|
27
|
+
{% endfor %}
|
|
28
|
+
</select>
|
|
29
|
+
</div>
|
|
30
|
+
|
|
31
|
+
<div class="mb-3">
|
|
32
|
+
<label for="email" class="form-label d-block text-muted">Correo Electrónico</label>
|
|
33
|
+
<input type="email" id="email" name="email" class="form-control" required>
|
|
34
|
+
</div>
|
|
35
|
+
<div class="mb-3">
|
|
36
|
+
<label for="password" class="form-label d-block text-muted">Contraseña</label>
|
|
37
|
+
<input type="password" id="password" name="password" class="form-control" required>
|
|
38
|
+
</div>
|
|
39
|
+
<button type="submit" class="btn btn-primary w-100">
|
|
40
|
+
Iniciar Sesión</button>
|
|
41
|
+
</form>
|
|
42
|
+
|
|
43
|
+
<div class="text-center mt-3">
|
|
44
|
+
<a href="{% if company_short_name %}{{ url_for('signup', company_short_name=company_short_name) }}{% else %}#{% endif %}"
|
|
45
|
+
id="signup-link"
|
|
46
|
+
class="btn btn-outline-primary w-100">Registrarse</a>
|
|
47
|
+
</div>
|
|
48
|
+
<div class="text-center mt-3">
|
|
49
|
+
<a href="{{ url_for('forgot_password', company_short_name=company_short_name) }}" class="text-decoration-none text-muted fw-semibold">
|
|
50
|
+
¿Olvidaste tu contraseña?
|
|
51
|
+
</a>
|
|
52
|
+
</div>
|
|
53
|
+
</div>
|
|
54
|
+
</div>
|
|
55
|
+
{% endif %}
|
|
56
|
+
|
|
57
|
+
<!-- Sección de JWT -->
|
|
58
|
+
<div class="col-12 col-lg-5 offset-lg-1">
|
|
59
|
+
<div class="border rounded p-4 shadow-sm bg-light">
|
|
60
|
+
<h4 class="text-muted fw-semibold text-start mb-3">login externo (api-key)</h4>
|
|
61
|
+
<form id="jwt-form" method="post">
|
|
62
|
+
<div class="mb-3">
|
|
63
|
+
<label for="company_name" class="form-label d-block text-muted">Empresa</label>
|
|
64
|
+
<select id="company_name" name="company_short_name" class="form-select" required>
|
|
65
|
+
<option value="" disabled selected>Selecciona una empresa</option>
|
|
66
|
+
{% for company in companies %}
|
|
67
|
+
{% if company.allow_jwt %}
|
|
68
|
+
<option value="{{ company.short_name }}"> {{ company.short_name }}
|
|
69
|
+
</option>
|
|
70
|
+
{% endif %}
|
|
71
|
+
{% endfor %}
|
|
72
|
+
</select>
|
|
73
|
+
</div>
|
|
74
|
+
|
|
75
|
+
<div class="mb-3">
|
|
76
|
+
<label for="external_user_id" class="form-label d-block text-muted">External user ID</label>
|
|
77
|
+
<input type="text" id="external_user_id" name="external_user_id" class="form-control" required>
|
|
78
|
+
</div>
|
|
79
|
+
|
|
80
|
+
<button type="button"
|
|
81
|
+
id="initiateJwtChatButton"
|
|
82
|
+
class="ml-5 btn btn-primary">
|
|
83
|
+
<span class="spinner-border spinner-border-sm d-none" role="status" aria-hidden="true"></span>
|
|
84
|
+
Iniciar Sesión JWT
|
|
85
|
+
</button>
|
|
86
|
+
</form>
|
|
87
|
+
</div>
|
|
88
|
+
</div>
|
|
89
|
+
|
|
90
|
+
</div>
|
|
91
|
+
|
|
92
|
+
{% endblock %}
|
|
93
|
+
|
|
94
|
+
{% block scripts %}
|
|
95
|
+
|
|
96
|
+
<script>
|
|
97
|
+
// Variables pasadas desde Flask (HomeView)
|
|
98
|
+
const CHAT_TOKEN_REQUEST_URL = "{{ chat_token_request_url|safe }}";
|
|
99
|
+
const PUBLIC_CHAT_URL_TEMPLATE = "{{ public_chat_url_template|safe }}";
|
|
100
|
+
const API_KEY = "{{ api_key|safe }}";
|
|
101
|
+
|
|
102
|
+
$(document).ready(function () {
|
|
103
|
+
// Función para actualizar el enlace de "Registrarse" y el action del formulario "Iniciar Sesión"
|
|
104
|
+
function updateLinksAndForm() {
|
|
105
|
+
const selectedCompany = $('#company_short_name').val(); // Obtenemos el valor del select
|
|
106
|
+
|
|
107
|
+
// Actualizar enlace "Registrarse"
|
|
108
|
+
if (selectedCompany && selectedCompany.trim() !== '') {
|
|
109
|
+
const signupUrl = '/' + selectedCompany + '/signup';
|
|
110
|
+
$('#signup-link').attr('href', signupUrl); // Actualizamos el href del botón "Registrarse"
|
|
111
|
+
} else {
|
|
112
|
+
$('#signup-link').attr('href', '#'); // Enlace a "#" si no hay empresa seleccionada
|
|
113
|
+
}
|
|
114
|
+
|
|
115
|
+
// Actualizar action del formulario "Iniciar Sesión"
|
|
116
|
+
if (selectedCompany && selectedCompany.trim() !== '') {
|
|
117
|
+
const loginAction = '/' + selectedCompany + '/login';
|
|
118
|
+
$('#login-form').attr('action', loginAction); // Actualizamos la URL del form
|
|
119
|
+
} else {
|
|
120
|
+
$('#login-form').attr('action', '#'); // URL genérica si no hay selección
|
|
121
|
+
}
|
|
122
|
+
}
|
|
123
|
+
|
|
124
|
+
// Actualizamos al cargar la página
|
|
125
|
+
updateLinksAndForm();
|
|
126
|
+
|
|
127
|
+
// Escuchamos el evento de cambio en el dropdown para actualizar dinámicamente
|
|
128
|
+
$('#company_short_name').on('change', function () {
|
|
129
|
+
updateLinksAndForm();
|
|
130
|
+
});
|
|
131
|
+
|
|
132
|
+
// Interceptamos el click en "Registrarse"
|
|
133
|
+
$('#signup-link').on('click', function (e) {
|
|
134
|
+
const selectedCompany = $('#company_short_name').val();
|
|
135
|
+
|
|
136
|
+
if (!selectedCompany || selectedCompany.trim() === '') {
|
|
137
|
+
e.preventDefault(); // evitar navegación al #
|
|
138
|
+
Swal.fire({
|
|
139
|
+
icon: 'warning',
|
|
140
|
+
title: 'Empresa no seleccionada',
|
|
141
|
+
text: 'Por favor, selecciona una empresa antes de registrarte.'
|
|
142
|
+
});
|
|
143
|
+
}
|
|
144
|
+
});
|
|
145
|
+
|
|
146
|
+
// Event listener para el botón de "Abrir Chat (JWT)"
|
|
147
|
+
$('#initiateJwtChatButton').on('click', function() {
|
|
148
|
+
|
|
149
|
+
const selectedCompany = $('#company_name').val();
|
|
150
|
+
const externalUserId = $('#external_user_id').val();
|
|
151
|
+
|
|
152
|
+
if (!selectedCompany || !externalUserId.trim()) {
|
|
153
|
+
Swal.fire({ icon: 'warning', title: 'Campos Requeridos', text: 'Por favor, selecciona una empresa e ingresa un ID de usuario.' });
|
|
154
|
+
return;
|
|
155
|
+
}
|
|
156
|
+
if (!API_KEY || API_KEY.includes("defecto")) {
|
|
157
|
+
Swal.fire({ icon: 'error', title: 'Error de Configuración', text: 'La API Key de la aplicación no está disponible.' });
|
|
158
|
+
return;
|
|
159
|
+
}
|
|
160
|
+
|
|
161
|
+
const $button = $(this);
|
|
162
|
+
const $spinner = $button.find('.spinner-border');
|
|
163
|
+
$button.prop('disabled', true);
|
|
164
|
+
$spinner.removeClass('d-none');
|
|
165
|
+
|
|
166
|
+
fetch(`/${selectedCompany}/chat_login`, {
|
|
167
|
+
method: 'POST',
|
|
168
|
+
headers: {
|
|
169
|
+
'Content-Type': 'application/json',
|
|
170
|
+
'Authorization': `Bearer ${API_KEY}`
|
|
171
|
+
},
|
|
172
|
+
body: JSON.stringify({
|
|
173
|
+
external_user_id: externalUserId
|
|
174
|
+
})
|
|
175
|
+
})
|
|
176
|
+
.then(async response => {
|
|
177
|
+
if (response.ok) { // Si el status es 200, la respuesta es el HTML
|
|
178
|
+
return response.text();
|
|
179
|
+
} else { // Si hay un error, el cuerpo es JSON
|
|
180
|
+
const errorData = await response.json();
|
|
181
|
+
throw new Error(errorData.error || 'Ocurrió un error desconocido.');
|
|
182
|
+
}
|
|
183
|
+
})
|
|
184
|
+
.then(htmlContent => {
|
|
185
|
+
// Éxito: Abrimos el HTML que nos devolvió el servidor en una nueva pestaña.
|
|
186
|
+
const newTab = window.open();
|
|
187
|
+
newTab.document.write(htmlContent);
|
|
188
|
+
newTab.document.close();
|
|
189
|
+
})
|
|
190
|
+
.catch(error => {
|
|
191
|
+
Swal.fire({ icon: 'error', title: 'Error de Inicio de Sesión', text: error.message });
|
|
192
|
+
})
|
|
193
|
+
.finally(() => {
|
|
194
|
+
$button.prop('disabled', false);
|
|
195
|
+
$spinner.addClass('d-none');
|
|
196
|
+
});
|
|
197
|
+
|
|
198
|
+
});
|
|
199
|
+
});
|
|
200
|
+
</script>
|
|
201
|
+
{% endblock %}
|
|
@@ -0,0 +1,43 @@
|
|
|
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 %}
|
|
@@ -0,0 +1,78 @@
|
|
|
1
|
+
{% extends "base.html" %}
|
|
2
|
+
|
|
3
|
+
{% block title %}Registro de Usuario{% endblock %}
|
|
4
|
+
|
|
5
|
+
{% block content %}
|
|
6
|
+
|
|
7
|
+
|
|
8
|
+
<div class="d-flex align-items-center p-3 border-bottom border-light-subtle">
|
|
9
|
+
<div class="col-11 col-md-8 col-lg-5 p-3">
|
|
10
|
+
<h4 class="text-muted fw-semibold mb-2 text-start">Crea tu cuenta</h4>
|
|
11
|
+
<p class="text-muted mb-3 text-start" style="text-align: justify;">
|
|
12
|
+
Regístrate para acceder a todas las funcionalidades de nuestra plataforma.
|
|
13
|
+
</p>
|
|
14
|
+
<form action="{{ url_for('signup', company_short_name=company_short_name) }}" method="post" >
|
|
15
|
+
<div class="mb-3 ">
|
|
16
|
+
<label for="email" class="form-label text-secondary">Correo Electrónico</label>
|
|
17
|
+
<input type="email" autocomplete="off" id="email" name="email"
|
|
18
|
+
class="form-control" required
|
|
19
|
+
value="{{ form_data.email if form_data else '' }}">
|
|
20
|
+
</div>
|
|
21
|
+
|
|
22
|
+
{% if is_mobile %}
|
|
23
|
+
<!-- En móvil, cada input ocupa una fila -->
|
|
24
|
+
<div class="mb-3">
|
|
25
|
+
<label for="first_name" class="form-label text-secondary">Nombre</label>
|
|
26
|
+
<input type="text" id="first_name" name="first_name"
|
|
27
|
+
class="form-control" required
|
|
28
|
+
value="{{ form_data.first_name if form_data else '' }}">
|
|
29
|
+
</div>
|
|
30
|
+
<div class="mb-3">
|
|
31
|
+
<label for="last_name" class="form-label text-secondary">Apellido</label>
|
|
32
|
+
<input type="text" id="last_name" name="last_name"
|
|
33
|
+
class="form-control" required
|
|
34
|
+
value="{{ form_data.last_name if form_data else '' }}">
|
|
35
|
+
</div>
|
|
36
|
+
{% else %}
|
|
37
|
+
<div class="row">
|
|
38
|
+
<!-- En escritorio, los inputs están en la misma fila -->
|
|
39
|
+
<div class="col-md-6 mb-3">
|
|
40
|
+
<label for="first_name" class="form-label text-secondary">Nombre</label>
|
|
41
|
+
<input type="text" id="first_name" name="first_name"
|
|
42
|
+
class="form-control" required
|
|
43
|
+
value="{{ form_data.first_name if form_data else '' }}">
|
|
44
|
+
</div>
|
|
45
|
+
<div class="col-md-6 mb-3">
|
|
46
|
+
<label for="last_name" class="form-label text-secondary">Apellido</label>
|
|
47
|
+
<input type="text" id="last_name" name="last_name"
|
|
48
|
+
class="form-control" required
|
|
49
|
+
value="{{ form_data.last_name if form_data else '' }}">
|
|
50
|
+
</div>
|
|
51
|
+
</div>
|
|
52
|
+
|
|
53
|
+
{% endif %}
|
|
54
|
+
|
|
55
|
+
<div class="mb-3">
|
|
56
|
+
<label for="password" class="form-label text-secondary">Contraseña</label>
|
|
57
|
+
<input type="password" id="password" name="password" class="form-control" required>
|
|
58
|
+
<small class="form-text text-muted">
|
|
59
|
+
La contraseña debe contener al menos 8 caracteres, una letra mayúscula, una letra minúscula, un número y un carácter especial.
|
|
60
|
+
</small>
|
|
61
|
+
|
|
62
|
+
</div>
|
|
63
|
+
<div class="mb-3">
|
|
64
|
+
<label for="confirm_password" class="form-label text-secondary">Confirmar Contraseña</label>
|
|
65
|
+
<input type="password" id="confirm_password" name="confirm_password" class="form-control" required>
|
|
66
|
+
</div>
|
|
67
|
+
<button type="submit" class="btn btn-primary w-100">Registrarse</button>
|
|
68
|
+
</form>
|
|
69
|
+
<!-- Nota sobre privacidad -->
|
|
70
|
+
<p class="text-muted small mb-0 text-start mt-3" style="text-align: justify;">
|
|
71
|
+
🔒 Valoramos tu privacidad. Tus datos serán utilizados exclusivamente para brindarte una mejor experiencia
|
|
72
|
+
y no serán compartidos con terceros sin tu consentimiento. Para más información, consulta nuestra
|
|
73
|
+
<a href="#" class="text-decoration-none fw-semibold">Política de Privacidad</a>.
|
|
74
|
+
</p>
|
|
75
|
+
</p>
|
|
76
|
+
</div>
|
|
77
|
+
</div>
|
|
78
|
+
{% endblock %}
|
|
@@ -5,7 +5,7 @@
|
|
|
5
5
|
|
|
6
6
|
from flask.views import MethodView
|
|
7
7
|
from flask import render_template, request
|
|
8
|
-
from services.profile_service import ProfileService
|
|
8
|
+
from iatoolkit.services.profile_service import ProfileService
|
|
9
9
|
from itsdangerous import URLSafeTimedSerializer, SignatureExpired
|
|
10
10
|
from flask_bcrypt import Bcrypt
|
|
11
11
|
from injector import inject
|
|
@@ -7,8 +7,8 @@ from flask import request, jsonify, current_app
|
|
|
7
7
|
from flask.views import MethodView
|
|
8
8
|
from injector import inject
|
|
9
9
|
import logging
|
|
10
|
-
from repositories.profile_repo import ProfileRepo
|
|
11
|
-
from services.jwt_service import JWTService
|
|
10
|
+
from iatoolkit.repositories.profile_repo import ProfileRepo
|
|
11
|
+
from iatoolkit.services.jwt_service import JWTService
|
|
12
12
|
from typing import Optional
|
|
13
13
|
|
|
14
14
|
|
|
@@ -4,12 +4,12 @@
|
|
|
4
4
|
# IAToolkit is open source software.
|
|
5
5
|
|
|
6
6
|
from flask import render_template, request, jsonify
|
|
7
|
-
from services.profile_service import ProfileService
|
|
7
|
+
from iatoolkit.services.profile_service import ProfileService
|
|
8
8
|
from flask.views import MethodView
|
|
9
9
|
from injector import inject
|
|
10
10
|
import os
|
|
11
|
-
from common.auth import IAuthentication
|
|
12
|
-
from services.prompt_manager_service import PromptService
|
|
11
|
+
from iatoolkit.common.auth import IAuthentication
|
|
12
|
+
from iatoolkit.services.prompt_manager_service import PromptService
|
|
13
13
|
|
|
14
14
|
|
|
15
15
|
class ChatView(MethodView):
|
|
@@ -10,9 +10,9 @@ from flask import current_app, jsonify, send_from_directory
|
|
|
10
10
|
from flask.views import MethodView
|
|
11
11
|
from injector import inject
|
|
12
12
|
|
|
13
|
-
from common.auth import IAuthentication
|
|
14
|
-
from services.excel_service import ExcelService
|
|
15
|
-
from services.profile_service import ProfileService
|
|
13
|
+
from iatoolkit.common.auth import IAuthentication
|
|
14
|
+
from iatoolkit.services.excel_service import ExcelService
|
|
15
|
+
from iatoolkit.services.profile_service import ProfileService
|
|
16
16
|
|
|
17
17
|
|
|
18
18
|
class DownloadFileView(MethodView):
|
|
@@ -8,11 +8,11 @@ import logging
|
|
|
8
8
|
from flask import request, jsonify, render_template
|
|
9
9
|
from flask.views import MethodView
|
|
10
10
|
from injector import inject
|
|
11
|
-
from common.auth import IAuthentication
|
|
12
|
-
from services.profile_service import ProfileService
|
|
13
|
-
from services.query_service import QueryService
|
|
14
|
-
from services.prompt_manager_service import PromptService
|
|
15
|
-
from services.jwt_service import JWTService
|
|
11
|
+
from iatoolkit.common.auth import IAuthentication
|
|
12
|
+
from iatoolkit.services.profile_service import ProfileService
|
|
13
|
+
from iatoolkit.services.query_service import QueryService
|
|
14
|
+
from iatoolkit.services.prompt_manager_service import PromptService
|
|
15
|
+
from iatoolkit.services.jwt_service import JWTService
|
|
16
16
|
|
|
17
17
|
class ExternalChatLoginView(MethodView):
|
|
18
18
|
@inject
|
|
@@ -5,8 +5,8 @@
|
|
|
5
5
|
|
|
6
6
|
from flask.views import MethodView
|
|
7
7
|
from injector import inject
|
|
8
|
-
from common.auth import IAuthentication
|
|
9
|
-
from services.query_service import QueryService
|
|
8
|
+
from iatoolkit.common.auth import IAuthentication
|
|
9
|
+
from iatoolkit.services.query_service import QueryService
|
|
10
10
|
from flask import jsonify
|
|
11
11
|
import logging
|
|
12
12
|
|
|
@@ -5,8 +5,8 @@
|
|
|
5
5
|
|
|
6
6
|
from flask.views import MethodView
|
|
7
7
|
from flask import request, jsonify
|
|
8
|
-
from services.load_documents_service import LoadDocumentsService
|
|
9
|
-
from repositories.profile_repo import ProfileRepo
|
|
8
|
+
from iatoolkit.services.load_documents_service import LoadDocumentsService
|
|
9
|
+
from iatoolkit.repositories.profile_repo import ProfileRepo
|
|
10
10
|
from injector import inject
|
|
11
11
|
import base64
|
|
12
12
|
|
|
@@ -6,7 +6,7 @@
|
|
|
6
6
|
from flask.views import MethodView
|
|
7
7
|
from flask import render_template, request, url_for
|
|
8
8
|
from injector import inject
|
|
9
|
-
from services.profile_service import ProfileService
|
|
9
|
+
from iatoolkit.services.profile_service import ProfileService
|
|
10
10
|
from itsdangerous import URLSafeTimedSerializer
|
|
11
11
|
import os
|
|
12
12
|
|
|
@@ -5,8 +5,8 @@
|
|
|
5
5
|
|
|
6
6
|
from flask import request, jsonify, render_template
|
|
7
7
|
from flask.views import MethodView
|
|
8
|
-
from services.history_service import HistoryService
|
|
9
|
-
from common.auth import IAuthentication
|
|
8
|
+
from iatoolkit.services.history_service import HistoryService
|
|
9
|
+
from iatoolkit.common.auth import IAuthentication
|
|
10
10
|
from injector import inject
|
|
11
11
|
import logging
|
|
12
12
|
|