genelastic 0.7.0__py3-none-any.whl → 0.9.0__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.
Files changed (90) hide show
  1. genelastic/api/.env +4 -0
  2. genelastic/api/cli_start_api.py +18 -0
  3. genelastic/api/errors.py +52 -0
  4. genelastic/api/extends/example.py +0 -6
  5. genelastic/api/extends/example.yml +0 -0
  6. genelastic/api/routes.py +313 -181
  7. genelastic/api/server.py +34 -26
  8. genelastic/api/settings.py +5 -9
  9. genelastic/api/specification.yml +512 -0
  10. genelastic/common/__init__.py +0 -39
  11. genelastic/common/cli.py +100 -0
  12. genelastic/common/elastic.py +374 -46
  13. genelastic/common/exceptions.py +34 -2
  14. genelastic/common/server.py +59 -0
  15. genelastic/common/types.py +1 -14
  16. genelastic/import_data/__init__.py +0 -27
  17. genelastic/import_data/checker.py +99 -0
  18. genelastic/import_data/checker_observer.py +13 -0
  19. genelastic/import_data/cli/__init__.py +0 -0
  20. genelastic/import_data/cli/cli_check.py +136 -0
  21. genelastic/import_data/cli/gen_data.py +143 -0
  22. genelastic/import_data/cli/import_data.py +346 -0
  23. genelastic/import_data/cli/info.py +247 -0
  24. genelastic/import_data/{cli_integrity.py → cli/integrity.py} +29 -7
  25. genelastic/import_data/cli/validate.py +146 -0
  26. genelastic/import_data/collect.py +185 -0
  27. genelastic/import_data/constants.py +136 -11
  28. genelastic/import_data/import_bundle.py +102 -59
  29. genelastic/import_data/import_bundle_factory.py +70 -149
  30. genelastic/import_data/importers/__init__.py +0 -0
  31. genelastic/import_data/importers/importer_base.py +131 -0
  32. genelastic/import_data/importers/importer_factory.py +85 -0
  33. genelastic/import_data/importers/importer_types.py +223 -0
  34. genelastic/import_data/logger.py +2 -1
  35. genelastic/import_data/models/__init__.py +0 -0
  36. genelastic/import_data/models/analyses.py +178 -0
  37. genelastic/import_data/models/analysis.py +144 -0
  38. genelastic/import_data/models/data_file.py +110 -0
  39. genelastic/import_data/models/process.py +45 -0
  40. genelastic/import_data/models/processes.py +84 -0
  41. genelastic/import_data/models/tags.py +170 -0
  42. genelastic/import_data/models/unique_list.py +109 -0
  43. genelastic/import_data/models/validate.py +26 -0
  44. genelastic/import_data/patterns.py +90 -0
  45. genelastic/import_data/random_bundle.py +79 -54
  46. genelastic/import_data/resolve.py +157 -0
  47. genelastic/ui/.env +1 -0
  48. genelastic/ui/cli_start_ui.py +20 -0
  49. genelastic/ui/routes.py +333 -0
  50. genelastic/ui/server.py +9 -82
  51. genelastic/ui/settings.py +2 -6
  52. genelastic/ui/static/cea-cnrgh.ico +0 -0
  53. genelastic/ui/static/cea.ico +0 -0
  54. genelastic/ui/static/layout.ico +0 -0
  55. genelastic/ui/static/novaseq6000.png +0 -0
  56. genelastic/ui/static/style.css +430 -0
  57. genelastic/ui/static/ui.js +458 -0
  58. genelastic/ui/templates/analyses.html +98 -0
  59. genelastic/ui/templates/analysis_detail.html +44 -0
  60. genelastic/ui/templates/bi_process_detail.html +129 -0
  61. genelastic/ui/templates/bi_processes.html +116 -0
  62. genelastic/ui/templates/explorer.html +356 -0
  63. genelastic/ui/templates/home.html +207 -0
  64. genelastic/ui/templates/layout.html +153 -0
  65. genelastic/ui/templates/version.html +21 -0
  66. genelastic/ui/templates/wet_process_detail.html +131 -0
  67. genelastic/ui/templates/wet_processes.html +116 -0
  68. genelastic-0.9.0.dist-info/METADATA +686 -0
  69. genelastic-0.9.0.dist-info/RECORD +76 -0
  70. genelastic-0.9.0.dist-info/WHEEL +4 -0
  71. genelastic-0.9.0.dist-info/entry_points.txt +10 -0
  72. genelastic-0.9.0.dist-info/licenses/LICENSE +519 -0
  73. genelastic/import_data/analyses.py +0 -69
  74. genelastic/import_data/analysis.py +0 -205
  75. genelastic/import_data/bi_process.py +0 -27
  76. genelastic/import_data/bi_processes.py +0 -49
  77. genelastic/import_data/cli_gen_data.py +0 -116
  78. genelastic/import_data/cli_import.py +0 -379
  79. genelastic/import_data/cli_info.py +0 -256
  80. genelastic/import_data/cli_validate.py +0 -54
  81. genelastic/import_data/data_file.py +0 -87
  82. genelastic/import_data/filename_pattern.py +0 -57
  83. genelastic/import_data/tags.py +0 -123
  84. genelastic/import_data/wet_process.py +0 -28
  85. genelastic/import_data/wet_processes.py +0 -53
  86. genelastic-0.7.0.dist-info/METADATA +0 -105
  87. genelastic-0.7.0.dist-info/RECORD +0 -40
  88. genelastic-0.7.0.dist-info/WHEEL +0 -5
  89. genelastic-0.7.0.dist-info/entry_points.txt +0 -6
  90. genelastic-0.7.0.dist-info/top_level.txt +0 -1
@@ -0,0 +1,333 @@
1
+ from typing import Any
2
+
3
+ import requests
4
+ from flask import Blueprint, current_app, render_template, request
5
+
6
+ routes_bp = Blueprint("routes", __name__)
7
+
8
+
9
+ def clean_field_name(field: str) -> str:
10
+ return field.replace("metadata.", "").replace("_", " ").title()
11
+
12
+
13
+ @routes_bp.route("/")
14
+ def home() -> str:
15
+ api_url = current_app.config["GENUI_API_URL"]
16
+
17
+ response = requests.get(
18
+ f"{api_url}analyses/count_key_value_analyses_index", timeout=20
19
+ ).json()
20
+ analyse_count = response.get("result", {})
21
+
22
+ response = requests.get(
23
+ f"{api_url}wet_processes/count_key_value_wet_processes_index",
24
+ timeout=20,
25
+ ).json()
26
+ wet_count = response.get("result", {})
27
+
28
+ response = requests.get(
29
+ f"{api_url}bi_processes/count_key_value_bi_processes_index", timeout=20
30
+ ).json()
31
+ bi_count = response.get("result", {})
32
+
33
+ total_analyses = (
34
+ sum(sum(values.values()) for values in analyse_count.values())
35
+ if analyse_count
36
+ else 0
37
+ )
38
+ total_wet = (
39
+ sum(sum(values.values()) for values in wet_count.values())
40
+ if wet_count
41
+ else 0
42
+ )
43
+ total_bi = (
44
+ sum(sum(values.values()) for values in bi_count.values())
45
+ if bi_count
46
+ else 0
47
+ )
48
+
49
+ total_analyses_per_key = {}
50
+ if analyse_count:
51
+ for key, values in analyse_count.items():
52
+ total_analyses_per_key[key] = sum(values.values())
53
+
54
+ return render_template(
55
+ "home.html",
56
+ analyse_count=analyse_count,
57
+ wet_count=wet_count,
58
+ bi_count=bi_count,
59
+ total_analyses=total_analyses,
60
+ total_wet=total_wet,
61
+ total_bi=total_bi,
62
+ total_analyses_per_key=total_analyses_per_key,
63
+ )
64
+
65
+
66
+ @routes_bp.route("/analyses")
67
+ def show_analyses() -> str:
68
+ api_url = current_app.config["GENUI_API_URL"]
69
+ try:
70
+ response = requests.get(f"{api_url}analyses", timeout=20)
71
+ analyses = response.json()["result"]
72
+ except requests.exceptions.RequestException:
73
+ analyses = ["Error fetching data."]
74
+
75
+ return render_template("analyses.html", analyses=analyses)
76
+
77
+
78
+ @routes_bp.route("/analysis/<analysis_id>")
79
+ def show_analysis_detail(analysis_id: str) -> str:
80
+ api_url = current_app.config["GENUI_API_URL"]
81
+ source = request.args.get(
82
+ "source"
83
+ ) # récupère ?source=wet ou ?source=bi si présent
84
+
85
+ try:
86
+ wet_response = requests.get(f"{api_url}wet_processes", timeout=20)
87
+ bi_response = requests.get(f"{api_url}bi_processes", timeout=20)
88
+ wet_processes = wet_response.json()["result"]
89
+ bi_processes = bi_response.json()["result"]
90
+ except requests.exceptions.RequestException:
91
+ wet_processes = []
92
+ bi_processes = []
93
+
94
+ matched_wet = [wp for wp in wet_processes if wp in analysis_id]
95
+ matched_bi = [bp for bp in bi_processes if bp in analysis_id]
96
+
97
+ return render_template(
98
+ "analysis_detail.html",
99
+ analysis_id=analysis_id,
100
+ wet_processes=matched_wet,
101
+ bi_processes=matched_bi,
102
+ source=source,
103
+ )
104
+
105
+
106
+ @routes_bp.route("/bi_processes", methods=["GET"])
107
+ def show_bi_processes() -> str:
108
+ api_url = current_app.config["GENUI_API_URL"]
109
+ selected_bi_processes = request.args.getlist("bi_processes")
110
+
111
+ try:
112
+ bi_processes, analyses = get_processes_and_analyses(
113
+ api_url, "bi_processes", selected_bi_processes
114
+ )
115
+ except requests.exceptions.RequestException:
116
+ bi_processes = []
117
+ analyses = []
118
+
119
+ return render_template(
120
+ "bi_processes.html",
121
+ bi_processes=bi_processes,
122
+ selected_bi_processes=selected_bi_processes,
123
+ analyses=analyses,
124
+ )
125
+
126
+
127
+ @routes_bp.route("/wet_processes", methods=["GET"])
128
+ def show_wet_processes() -> str:
129
+ api_url = current_app.config["GENUI_API_URL"]
130
+ selected_wet_processes = request.args.getlist("wet_processes")
131
+
132
+ try:
133
+ wet_processes, analyses = get_processes_and_analyses(
134
+ api_url, "wet_processes", selected_wet_processes
135
+ )
136
+ except requests.exceptions.RequestException:
137
+ wet_processes = []
138
+ analyses = []
139
+
140
+ return render_template(
141
+ "wet_processes.html",
142
+ wet_processes=wet_processes,
143
+ selected_wet_processes=selected_wet_processes,
144
+ analyses=analyses,
145
+ )
146
+
147
+
148
+ def get_processes_and_analyses(
149
+ api_url: str, process_type: str, selected_processes: list[str]
150
+ ) -> tuple[list[dict[str, Any]], list[dict[str, Any]]]:
151
+ analyses = []
152
+
153
+ try:
154
+ processes_response = requests.get(
155
+ f"{api_url}{process_type}", timeout=20
156
+ )
157
+ processes = processes_response.json()["result"]
158
+
159
+ if selected_processes:
160
+ analyses_response = requests.get(f"{api_url}analyses", timeout=20)
161
+ all_analyses = analyses_response.json()["result"]
162
+ analyses = [
163
+ analysis
164
+ for analysis in all_analyses
165
+ if any(process in analysis for process in selected_processes)
166
+ ]
167
+ except requests.exceptions.RequestException:
168
+ processes = []
169
+ analyses = []
170
+
171
+ return processes, analyses
172
+
173
+
174
+ @routes_bp.route("/wet_process/details/<wet_process_id>")
175
+ def wet_process_detail(wet_process_id: str) -> str:
176
+ api_url = current_app.config["GENUI_API_URL"]
177
+
178
+ try:
179
+ wet_response = requests.get(
180
+ f"{api_url}wet_processes/{wet_process_id}", timeout=20
181
+ )
182
+ wet_response.raise_for_status()
183
+ wet_process = wet_response.json()["result"]
184
+ except requests.exceptions.HTTPError as e:
185
+ return render_template(
186
+ "wet_process_detail.html",
187
+ proc_id=wet_process_id,
188
+ error=e.response.json(),
189
+ )
190
+
191
+ # Récupérer tous les bi-processus pour la sélection
192
+ try:
193
+ bi_list_response = requests.get(f"{api_url}bi_processes", timeout=20)
194
+ bi_processes = bi_list_response.json()["result"]
195
+ except requests.exceptions.RequestException:
196
+ bi_processes = []
197
+
198
+ # Si un bi_process_id est présent en paramètre GET, on le charge pour comparaison
199
+ bi_process_id = request.args.get("compare_with")
200
+ bi_process_data = None
201
+ if bi_process_id:
202
+ try:
203
+ bi_response = requests.get(
204
+ f"{api_url}bi_processes/{bi_process_id}", timeout=20
205
+ )
206
+ bi_response.raise_for_status()
207
+ bi_process_data = bi_response.json()["result"]
208
+ except requests.exceptions.RequestException:
209
+ bi_process_data = {"error": "Could not fetch bi process"}
210
+
211
+ return render_template(
212
+ "wet_process_detail.html",
213
+ proc_id=wet_process_id,
214
+ wet_process=wet_process,
215
+ bi_processes=bi_processes,
216
+ selected_bi=bi_process_id,
217
+ bi_process_data=bi_process_data,
218
+ )
219
+
220
+
221
+ @routes_bp.route("/bi_process/details/<bi_process_id>")
222
+ def bi_process_detail(bi_process_id: str) -> str:
223
+ api_url = current_app.config["GENUI_API_URL"]
224
+
225
+ # Récupérer les données du bi process principal
226
+ try:
227
+ response = requests.get(
228
+ f"{api_url}bi_processes/{bi_process_id}", timeout=20
229
+ )
230
+ response.raise_for_status()
231
+ bi_process = response.json()["result"]
232
+ except requests.exceptions.HTTPError as e:
233
+ return render_template(
234
+ "bi_process_detail.html",
235
+ proc_id=bi_process_id,
236
+ error=e.response.json(),
237
+ )
238
+
239
+ # Charger tous les wet processes pour le menu déroulant
240
+ try:
241
+ wet_list_response = requests.get(f"{api_url}wet_processes", timeout=20)
242
+ wet_processes = wet_list_response.json()["result"]
243
+ except requests.exceptions.RequestException:
244
+ wet_processes = []
245
+
246
+ # Récupérer le wet process sélectionné pour la comparaison
247
+ wet_process_id = request.args.get("compare_with")
248
+ wet_process_data = None
249
+ if wet_process_id:
250
+ try:
251
+ wet_response = requests.get(
252
+ f"{api_url}wet_processes/{wet_process_id}", timeout=20
253
+ )
254
+ wet_response.raise_for_status()
255
+ wet_process_data = wet_response.json()["result"]
256
+ except requests.exceptions.RequestException:
257
+ wet_process_data = {"error": "Could not fetch wet process"}
258
+
259
+ return render_template(
260
+ "bi_process_detail.html",
261
+ proc_id=bi_process_id,
262
+ bi_process=bi_process,
263
+ wet_processes=wet_processes,
264
+ selected_wet=wet_process_id,
265
+ wet_process_data=wet_process_data,
266
+ )
267
+
268
+
269
+ @routes_bp.route("/version")
270
+ def version() -> str:
271
+ api_url = current_app.config["GENUI_API_URL"]
272
+ try:
273
+ response = requests.get(f"{api_url}version", timeout=20)
274
+ vers = response.json()["result"].get("version", "Version not found")
275
+ except requests.exceptions.RequestException:
276
+ vers = "Error fetching version."
277
+
278
+ return render_template("version.html", version=vers)
279
+
280
+
281
+ @routes_bp.route("/search_analyses")
282
+ def search_analyses() -> dict[str, list[str]]:
283
+ api_url = current_app.config["GENUI_API_URL"]
284
+ query = request.args.get("q", "").lower()
285
+
286
+ try:
287
+ analyses_response = requests.get(f"{api_url}analyses", timeout=20)
288
+ analyses = analyses_response.json()["result"]
289
+ except requests.exceptions.RequestException:
290
+ return {"results": []}
291
+
292
+ filtered = [a for a in analyses if query in a.lower()]
293
+
294
+ filtered = filtered[:10]
295
+
296
+ return {"results": filtered}
297
+
298
+
299
+ @routes_bp.route("/explorer")
300
+ def explorer() -> str:
301
+ api_url = current_app.config["GENUI_API_URL"]
302
+
303
+ try:
304
+ wet_count = requests.get(
305
+ f"{api_url}wet_processes/count_key_value_wet_processes_index",
306
+ timeout=20,
307
+ ).json()["result"]
308
+ except requests.exceptions.RequestException:
309
+ wet_count = {}
310
+
311
+ try:
312
+ bi_count = requests.get(
313
+ f"{api_url}bi_processes/count_key_value_bi_processes_index",
314
+ timeout=20,
315
+ ).json()["result"]
316
+ except requests.exceptions.RequestException:
317
+ bi_count = {}
318
+
319
+ # Fusionner les deux dictionnaires et exclure les champs contenant "index"
320
+ metadata_counts: dict[str, dict[str | None, int]] = {}
321
+
322
+ for dataset in [wet_count, bi_count]:
323
+ for key, values in dataset.items():
324
+ if "index" in key:
325
+ continue # on saute les champs techniques
326
+ if key not in metadata_counts:
327
+ metadata_counts[key] = {}
328
+ for val, count in values.items():
329
+ metadata_counts[key][val] = (
330
+ metadata_counts[key].get(val, 0) + count
331
+ )
332
+
333
+ return render_template("explorer.html", metadata_counts=metadata_counts)
genelastic/ui/server.py CHANGED
@@ -1,87 +1,14 @@
1
- import requests
2
- from flask import Flask, render_template
1
+ from asgiref.wsgi import WsgiToAsgi
2
+ from flask import Flask
3
3
 
4
- app = Flask(__name__)
5
- app.config.from_object("src.genelastic.ui.settings.Config")
4
+ from .routes import routes_bp
6
5
 
7
6
 
8
- @app.route("/")
9
- def home() -> str:
10
- api_url = app.config["GENUI_API_URL"]
11
- try:
12
- version_reponse = requests.get(f"{api_url}version", timeout=20)
13
- version = version_reponse.json().get("version")
14
- wet_processes_reponse = requests.get(
15
- f"{api_url}wet_processes", timeout=20
16
- )
17
- wet_processes = wet_processes_reponse.json()
18
- bi_processes_reponse = requests.get(
19
- f"{api_url}bi_processes", timeout=20
20
- )
21
- bi_processes = bi_processes_reponse.json()
22
- analyses_reponse = requests.get(f"{api_url}analyses", timeout=20)
23
- analyses = analyses_reponse.json()
24
- except requests.exceptions.RequestException:
25
- version = "API not reachable"
26
- wet_processes = []
27
- bi_processes = []
28
- analyses = []
29
- return render_template(
30
- "home.html",
31
- version=version,
32
- wet_processes=wet_processes,
33
- bi_processes=bi_processes,
34
- analyses=analyses,
35
- )
7
+ def create_app() -> WsgiToAsgi:
8
+ flask_app = Flask(__name__)
9
+ flask_app.config.from_object("genelastic.ui.settings")
10
+ flask_app.register_blueprint(routes_bp)
11
+ return WsgiToAsgi(flask_app) # type: ignore[no-untyped-call]
36
12
 
37
13
 
38
- @app.route("/analyses")
39
- def show_analyses() -> str:
40
- api_url = app.config["GENUI_API_URL"]
41
- try:
42
- analyses_reponse = requests.get(f"{api_url}analyses", timeout=20)
43
- analyses = analyses_reponse.json()
44
- except requests.exceptions.RequestException:
45
- analyses = ["Error fetching data."]
46
-
47
- return render_template("analyses.html", analyses=analyses)
48
-
49
-
50
- @app.route("/bi_processes")
51
- def show_bi_processes() -> str:
52
- api_url = app.config["GENUI_API_URL"]
53
- try:
54
- bi_processes_reponse = requests.get(
55
- f"{api_url}bi_processes", timeout=20
56
- )
57
- bi_processes = bi_processes_reponse.json()
58
- except requests.exceptions.RequestException:
59
- bi_processes = ["Error fetching data."]
60
-
61
- return render_template("bi_processes.html", bi_processes=bi_processes)
62
-
63
-
64
- @app.route("/wet_processes")
65
- def show_wet_processes() -> str:
66
- api_url = app.config["GENUI_API_URL"]
67
- try:
68
- wet_processes_reponse = requests.get(
69
- f"{api_url}wet_processes", timeout=20
70
- )
71
- wet_processes = wet_processes_reponse.json()
72
- except requests.exceptions.RequestException:
73
- wet_processes = ["Error fetching data."]
74
-
75
- return render_template("wet_processes.html", wet_processes=wet_processes)
76
-
77
-
78
- @app.route("/version")
79
- def show_version() -> str:
80
- api_url = app.config["GENUI_API_URL"]
81
- try:
82
- version_reponse = requests.get(f"{api_url}version", timeout=20)
83
- version = version_reponse.json().get("version", "Version not found")
84
- except requests.exceptions.RequestException:
85
- version = "Error fetching version."
86
-
87
- return render_template("version.html", version=version)
14
+ app = create_app()
genelastic/ui/settings.py CHANGED
@@ -3,9 +3,5 @@ from environs import Env
3
3
  env = Env()
4
4
  env.read_env()
5
5
 
6
-
7
- class Config:
8
- """Flask config class."""
9
-
10
- # Charger toutes les variables d'environnement nécessaires
11
- GENUI_API_URL = env.url("GENUI_API_URL").geturl()
6
+ # Charger toutes les variables d'environnement nécessaires
7
+ GENUI_API_URL = env.url("GENUI_API_URL").geturl()
Binary file
Binary file
Binary file
Binary file