genelastic 0.7.0__py3-none-any.whl → 0.8.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.
- genelastic/api/cli_start_api.py +18 -0
- genelastic/api/extends/example.yml +20 -0
- genelastic/api/server.py +27 -24
- genelastic/api/settings.py +5 -9
- genelastic/api/specification.yml +350 -0
- genelastic/common/__init__.py +6 -1
- genelastic/common/cli.py +52 -0
- genelastic/common/server.py +51 -0
- genelastic/import_data/cli_gen_data.py +52 -25
- genelastic/import_data/random_bundle.py +69 -46
- genelastic/ui/cli_start_ui.py +18 -0
- genelastic/ui/routes.py +86 -0
- genelastic/ui/server.py +9 -82
- genelastic/ui/settings.py +2 -6
- genelastic/ui/templates/analyses.html +11 -0
- genelastic/ui/templates/bi_processes.html +11 -0
- genelastic/ui/templates/home.html +4 -0
- genelastic/ui/templates/layout.html +34 -0
- genelastic/ui/templates/version.html +9 -0
- genelastic/ui/templates/wet_processes.html +11 -0
- {genelastic-0.7.0.dist-info → genelastic-0.8.0.dist-info}/METADATA +7 -3
- {genelastic-0.7.0.dist-info → genelastic-0.8.0.dist-info}/RECORD +25 -13
- {genelastic-0.7.0.dist-info → genelastic-0.8.0.dist-info}/WHEEL +1 -1
- {genelastic-0.7.0.dist-info → genelastic-0.8.0.dist-info}/entry_points.txt +2 -0
- {genelastic-0.7.0.dist-info → genelastic-0.8.0.dist-info}/top_level.txt +0 -0
|
@@ -2,6 +2,8 @@ import argparse
|
|
|
2
2
|
import logging
|
|
3
3
|
from pathlib import Path
|
|
4
4
|
|
|
5
|
+
from biophony import DEFAULT_RATE, MutSimParams
|
|
6
|
+
|
|
5
7
|
from genelastic.common import add_verbose_control_args
|
|
6
8
|
|
|
7
9
|
from .logger import configure_logging
|
|
@@ -13,46 +15,45 @@ logger = logging.getLogger("genelastic")
|
|
|
13
15
|
|
|
14
16
|
|
|
15
17
|
def read_args() -> argparse.Namespace:
|
|
16
|
-
"""Read arguments from command line."""
|
|
18
|
+
"""Read arguments from the command line."""
|
|
17
19
|
parser = argparse.ArgumentParser(
|
|
18
|
-
description="
|
|
20
|
+
description="Random bundle generator. "
|
|
21
|
+
"A bundle is a YAML file format used to import genetic data into an Elasticsearch database. "
|
|
22
|
+
"It can contain one or more analyses; "
|
|
23
|
+
"each analysis including metadata, references to "
|
|
24
|
+
"a wet lab and bioinformatics process "
|
|
25
|
+
"and paths to a VCF file and optionally to a coverage file.",
|
|
19
26
|
formatter_class=argparse.ArgumentDefaultsHelpFormatter,
|
|
20
27
|
allow_abbrev=False,
|
|
21
28
|
)
|
|
22
29
|
add_verbose_control_args(parser)
|
|
23
30
|
parser.add_argument(
|
|
24
|
-
"
|
|
25
|
-
"
|
|
26
|
-
dest="data_folder",
|
|
27
|
-
required=True,
|
|
28
|
-
help="Data destination folder.",
|
|
31
|
+
"output_dir",
|
|
32
|
+
help="Path where analyses VCF and coverage files will be generated.",
|
|
29
33
|
type=Path,
|
|
30
34
|
)
|
|
31
|
-
parser.add_argument(
|
|
32
|
-
"--log-file", dest="log_file", help="Path to a log file."
|
|
33
|
-
)
|
|
35
|
+
parser.add_argument("--log-file", help="Path to a log file.")
|
|
34
36
|
parser.add_argument(
|
|
35
37
|
"-n",
|
|
36
38
|
"--chrom-nb",
|
|
37
|
-
dest="chrom_nb",
|
|
38
39
|
type=int,
|
|
39
40
|
default=5,
|
|
40
41
|
help="Number of chromosomes to include in the generated VCF file.",
|
|
41
42
|
)
|
|
42
43
|
parser.add_argument(
|
|
43
44
|
"-o",
|
|
44
|
-
"--output-
|
|
45
|
-
dest="output_file",
|
|
45
|
+
"--output-bundle",
|
|
46
46
|
default=None,
|
|
47
|
-
help="
|
|
47
|
+
help="Path where the YAML bundle file will be written. "
|
|
48
|
+
"If no path is provided, the bundle is written to stdout.",
|
|
48
49
|
type=Path,
|
|
49
50
|
)
|
|
50
51
|
parser.add_argument(
|
|
51
|
-
"-
|
|
52
|
-
"--sequence-
|
|
52
|
+
"-l",
|
|
53
|
+
"--sequence-length",
|
|
53
54
|
type=int,
|
|
54
55
|
default=2000,
|
|
55
|
-
help="Sequence
|
|
56
|
+
help="Sequence length (number of nucleotides) generated for each chromosome.",
|
|
56
57
|
)
|
|
57
58
|
parser.add_argument(
|
|
58
59
|
"-c",
|
|
@@ -64,7 +65,7 @@ def read_args() -> argparse.Namespace:
|
|
|
64
65
|
"-a",
|
|
65
66
|
"--analyses",
|
|
66
67
|
help="Number of analyses to generate. "
|
|
67
|
-
"Each analysis
|
|
68
|
+
"Each analysis will reference a wet lab and bioinformatics process, "
|
|
68
69
|
"a VCF file and optionally a coverage file.",
|
|
69
70
|
default=1,
|
|
70
71
|
type=int,
|
|
@@ -72,10 +73,31 @@ def read_args() -> argparse.Namespace:
|
|
|
72
73
|
parser.add_argument(
|
|
73
74
|
"-p",
|
|
74
75
|
"--processes",
|
|
75
|
-
help="Number of
|
|
76
|
+
help="Number of wet lab and bioinformatics processes to generate.",
|
|
76
77
|
default=1,
|
|
77
78
|
type=int,
|
|
78
79
|
)
|
|
80
|
+
parser.add_argument(
|
|
81
|
+
"-s",
|
|
82
|
+
"--snp-rate",
|
|
83
|
+
help="Generated VCF SNP rate.",
|
|
84
|
+
type=float,
|
|
85
|
+
default=DEFAULT_RATE,
|
|
86
|
+
)
|
|
87
|
+
parser.add_argument(
|
|
88
|
+
"-i",
|
|
89
|
+
"--ins-rate",
|
|
90
|
+
help="Generated VCF insertion rate.",
|
|
91
|
+
type=float,
|
|
92
|
+
default=DEFAULT_RATE,
|
|
93
|
+
)
|
|
94
|
+
parser.add_argument(
|
|
95
|
+
"-d",
|
|
96
|
+
"--del-rate",
|
|
97
|
+
help="Generated VCF deletion rate.",
|
|
98
|
+
type=float,
|
|
99
|
+
default=DEFAULT_RATE,
|
|
100
|
+
)
|
|
79
101
|
return parser.parse_args()
|
|
80
102
|
|
|
81
103
|
|
|
@@ -83,10 +105,10 @@ def main() -> None:
|
|
|
83
105
|
"""Entry point of the gen-data script."""
|
|
84
106
|
# Read command line arguments
|
|
85
107
|
args = read_args()
|
|
86
|
-
|
|
108
|
+
output_dir = args.output_dir.resolve()
|
|
87
109
|
|
|
88
|
-
if not
|
|
89
|
-
msg = f"ERROR: '{
|
|
110
|
+
if not output_dir.is_dir():
|
|
111
|
+
msg = f"ERROR: '{output_dir}' does not exist or is not a directory."
|
|
90
112
|
raise SystemExit(msg)
|
|
91
113
|
|
|
92
114
|
if args.analyses < 1:
|
|
@@ -103,13 +125,18 @@ def main() -> None:
|
|
|
103
125
|
|
|
104
126
|
# Write to stdout or file
|
|
105
127
|
RandomBundle(
|
|
106
|
-
|
|
128
|
+
output_dir,
|
|
107
129
|
args.analyses,
|
|
108
130
|
args.processes,
|
|
109
131
|
args.chrom_nb,
|
|
110
|
-
args.
|
|
132
|
+
args.sequence_length,
|
|
133
|
+
MutSimParams(
|
|
134
|
+
snp_rate=args.snp_rate,
|
|
135
|
+
ins_rate=args.ins_rate,
|
|
136
|
+
del_rate=args.del_rate,
|
|
137
|
+
),
|
|
111
138
|
do_gen_coverage=args.coverage,
|
|
112
|
-
).to_yaml(args.
|
|
139
|
+
).to_yaml(args.output_bundle)
|
|
113
140
|
|
|
114
141
|
|
|
115
142
|
if __name__ == "__main__":
|
|
@@ -1,6 +1,5 @@
|
|
|
1
1
|
import copy
|
|
2
2
|
import random
|
|
3
|
-
import shutil
|
|
4
3
|
import sys
|
|
5
4
|
import tempfile
|
|
6
5
|
import typing
|
|
@@ -8,7 +7,14 @@ from abc import ABC, abstractmethod
|
|
|
8
7
|
from pathlib import Path
|
|
9
8
|
|
|
10
9
|
import yaml
|
|
11
|
-
from biophony import
|
|
10
|
+
from biophony import (
|
|
11
|
+
BioSeqGen,
|
|
12
|
+
CovGen,
|
|
13
|
+
Elements,
|
|
14
|
+
FastaWriter,
|
|
15
|
+
MutSim,
|
|
16
|
+
MutSimParams,
|
|
17
|
+
)
|
|
12
18
|
|
|
13
19
|
from genelastic.common import (
|
|
14
20
|
RandomAnalysisData,
|
|
@@ -184,25 +190,39 @@ class RandomBiProcess(RandomBundleItem):
|
|
|
184
190
|
|
|
185
191
|
|
|
186
192
|
class RandomAnalysis(RandomBundleItem):
|
|
187
|
-
"""Generate a random analysis.
|
|
193
|
+
"""Generate a random analysis.
|
|
194
|
+
|
|
195
|
+
:param fasta_dir: Directory where to create the FASTA file used as a basis to generate the analysis VCF file.
|
|
196
|
+
:param output_dir: Directory where the analysis VCF file
|
|
197
|
+
(and coverage file if `do_gen_coverage` is set to True) is generated.
|
|
198
|
+
|
|
199
|
+
:raises RuntimeError: Could not generate a VCF file with the given simulation parameters.
|
|
200
|
+
"""
|
|
188
201
|
|
|
189
202
|
def __init__( # noqa: PLR0913
|
|
190
203
|
self,
|
|
191
|
-
|
|
204
|
+
fasta_dir: Path,
|
|
205
|
+
output_dir: Path,
|
|
192
206
|
seq_len: int,
|
|
193
207
|
nb_chrom: int,
|
|
194
208
|
wet_proc_id: str,
|
|
195
209
|
bi_proc_id: str,
|
|
210
|
+
sim_params: MutSimParams,
|
|
196
211
|
*,
|
|
197
212
|
do_gen_coverage: bool,
|
|
198
213
|
) -> None:
|
|
199
|
-
self.
|
|
214
|
+
self._fasta_dir = fasta_dir
|
|
215
|
+
self._output_dir = output_dir
|
|
200
216
|
self._seq_len = seq_len
|
|
201
217
|
self._nb_chrom = nb_chrom
|
|
202
|
-
self._sample_name = "HG0003"
|
|
203
|
-
self._source = "CNRGH"
|
|
204
218
|
self._wet_process_id = wet_proc_id
|
|
205
219
|
self._bi_process_id = bi_proc_id
|
|
220
|
+
|
|
221
|
+
self._sample_name = "HG000" + str(random.randint(1, 9))
|
|
222
|
+
sim_params.sample_name = self._sample_name
|
|
223
|
+
self._sim_params = sim_params
|
|
224
|
+
|
|
225
|
+
self._source = "CNRGH"
|
|
206
226
|
self._barcode = self._random_alphanum_str(n=6)
|
|
207
227
|
self._reference_genome = "hg38"
|
|
208
228
|
self._prefix = (
|
|
@@ -215,37 +235,32 @@ class RandomAnalysis(RandomBundleItem):
|
|
|
215
235
|
self.gen_cov_file()
|
|
216
236
|
|
|
217
237
|
def _gen_vcf_file(self) -> None:
|
|
218
|
-
"""Generate a dummy VCF file.
|
|
219
|
-
temp_dir = Path(tempfile.mkdtemp())
|
|
220
|
-
|
|
221
|
-
try:
|
|
222
|
-
fasta_out_file = temp_dir / "seq.fasta"
|
|
223
|
-
vcf_out_file = self._folder / f"{self._prefix}.vcf"
|
|
238
|
+
"""Generate a dummy VCF file.
|
|
224
239
|
|
|
225
|
-
|
|
226
|
-
|
|
227
|
-
|
|
228
|
-
|
|
229
|
-
with fasta_out_file.open("w", encoding="utf-8") as f:
|
|
230
|
-
FastaWriter(f, header=False).write_seqs(gen)
|
|
240
|
+
:raises RuntimeError: The call to `mutation-simulator` returned a non-zero exit status.
|
|
241
|
+
"""
|
|
242
|
+
fasta_out_file = self._fasta_dir / "seq.fasta"
|
|
243
|
+
vcf_out_file = self._output_dir / f"{self._prefix}.vcf"
|
|
231
244
|
|
|
232
|
-
|
|
233
|
-
|
|
234
|
-
|
|
235
|
-
|
|
236
|
-
|
|
237
|
-
|
|
238
|
-
del_rate=0.01,
|
|
239
|
-
).run()
|
|
245
|
+
# 1 - Generate a FASTA file and save it to a temporary directory.
|
|
246
|
+
gen = BioSeqGen(
|
|
247
|
+
elements=Elements(), seqlen=self._seq_len, count=self._nb_chrom
|
|
248
|
+
)
|
|
249
|
+
with fasta_out_file.open("w", encoding="utf-8") as f:
|
|
250
|
+
FastaWriter(f, header=False).write_seqs(gen)
|
|
240
251
|
|
|
241
|
-
|
|
242
|
-
|
|
252
|
+
# 2 - Generate a VCF from the previously created FASTA file.
|
|
253
|
+
MutSim(
|
|
254
|
+
fasta_file=str(fasta_out_file),
|
|
255
|
+
vcf_file=str(vcf_out_file),
|
|
256
|
+
sim_params=self._sim_params,
|
|
257
|
+
).run()
|
|
243
258
|
|
|
244
259
|
def gen_cov_file(self) -> None:
|
|
245
260
|
"""Generate a dummy coverage file."""
|
|
246
261
|
chrom_end = self._seq_len - 1
|
|
247
262
|
|
|
248
|
-
output_path = self.
|
|
263
|
+
output_path = self._output_dir / f"{self._prefix}.cov.tsv"
|
|
249
264
|
with output_path.open("w", encoding="utf-8") as f:
|
|
250
265
|
for chrom in range(1, self._nb_chrom + 1):
|
|
251
266
|
coverage = CovGen(
|
|
@@ -280,7 +295,7 @@ class RandomAnalysis(RandomBundleItem):
|
|
|
280
295
|
"DUAL228",
|
|
281
296
|
"DUAL289",
|
|
282
297
|
],
|
|
283
|
-
"data_path": str(self.
|
|
298
|
+
"data_path": str(self._output_dir),
|
|
284
299
|
}
|
|
285
300
|
|
|
286
301
|
|
|
@@ -289,15 +304,16 @@ class RandomBundle(RandomBundleItem):
|
|
|
289
304
|
|
|
290
305
|
def __init__( # noqa: PLR0913
|
|
291
306
|
self,
|
|
292
|
-
|
|
307
|
+
output_dir: Path,
|
|
293
308
|
analyses_count: int,
|
|
294
309
|
processes_count: int,
|
|
295
310
|
nb_chrom: int,
|
|
296
311
|
seq_len: int,
|
|
312
|
+
sim_params: MutSimParams,
|
|
297
313
|
*,
|
|
298
314
|
do_gen_coverage: bool,
|
|
299
315
|
) -> None:
|
|
300
|
-
self.
|
|
316
|
+
self._output_dir = output_dir
|
|
301
317
|
self._analyses_count = analyses_count
|
|
302
318
|
self._processes_count = processes_count
|
|
303
319
|
self._nb_chrom = nb_chrom
|
|
@@ -319,19 +335,26 @@ class RandomBundle(RandomBundleItem):
|
|
|
319
335
|
self._bi_processes, self._analyses_count
|
|
320
336
|
)
|
|
321
337
|
|
|
322
|
-
|
|
323
|
-
|
|
324
|
-
|
|
325
|
-
|
|
326
|
-
|
|
327
|
-
|
|
328
|
-
|
|
329
|
-
|
|
330
|
-
|
|
331
|
-
|
|
332
|
-
|
|
333
|
-
|
|
334
|
-
|
|
338
|
+
with tempfile.TemporaryDirectory() as fasta_dir:
|
|
339
|
+
try:
|
|
340
|
+
self._analyses.extend(
|
|
341
|
+
[
|
|
342
|
+
RandomAnalysis(
|
|
343
|
+
Path(fasta_dir),
|
|
344
|
+
self._output_dir,
|
|
345
|
+
self._seq_len,
|
|
346
|
+
self._nb_chrom,
|
|
347
|
+
str(self._assigned_wet_processes[i]["proc_id"]),
|
|
348
|
+
str(self._assigned_bi_processes[i]["proc_id"]),
|
|
349
|
+
sim_params,
|
|
350
|
+
do_gen_coverage=self._do_gen_coverage,
|
|
351
|
+
).to_dict()
|
|
352
|
+
for i in range(self._analyses_count)
|
|
353
|
+
]
|
|
354
|
+
)
|
|
355
|
+
except RuntimeError as e:
|
|
356
|
+
msg = f"VCF file generation for one analysis failed. {e}"
|
|
357
|
+
raise SystemExit(msg) from None
|
|
335
358
|
|
|
336
359
|
@staticmethod
|
|
337
360
|
def _assign_processes(
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
from genelastic.common import parse_server_launch_args
|
|
2
|
+
from genelastic.common.server import start_dev_server, start_prod_server
|
|
3
|
+
|
|
4
|
+
|
|
5
|
+
def main() -> None:
|
|
6
|
+
app_module = "genelastic.ui.server:app"
|
|
7
|
+
args = parse_server_launch_args("Start UI server.", 8001)
|
|
8
|
+
if args.env == "dev":
|
|
9
|
+
start_dev_server(app_module, args)
|
|
10
|
+
elif args.env == "prod":
|
|
11
|
+
start_prod_server(app_module, args)
|
|
12
|
+
else:
|
|
13
|
+
msg = f"Environment '{args.env}' is not implemented."
|
|
14
|
+
raise NotImplementedError(msg)
|
|
15
|
+
|
|
16
|
+
|
|
17
|
+
if __name__ == "__main__":
|
|
18
|
+
main()
|
genelastic/ui/routes.py
ADDED
|
@@ -0,0 +1,86 @@
|
|
|
1
|
+
import requests
|
|
2
|
+
from flask import Blueprint, current_app, render_template
|
|
3
|
+
|
|
4
|
+
routes_bp = Blueprint("routes", __name__)
|
|
5
|
+
|
|
6
|
+
|
|
7
|
+
@routes_bp.route("/")
|
|
8
|
+
def home() -> str:
|
|
9
|
+
api_url = current_app.config["GENUI_API_URL"]
|
|
10
|
+
try:
|
|
11
|
+
version_reponse = requests.get(f"{api_url}version", timeout=20)
|
|
12
|
+
version = version_reponse.json().get("version")
|
|
13
|
+
wet_processes_reponse = requests.get(
|
|
14
|
+
f"{api_url}wet_processes", timeout=20
|
|
15
|
+
)
|
|
16
|
+
wet_processes = wet_processes_reponse.json()
|
|
17
|
+
bi_processes_reponse = requests.get(
|
|
18
|
+
f"{api_url}bi_processes", timeout=20
|
|
19
|
+
)
|
|
20
|
+
bi_processes = bi_processes_reponse.json()
|
|
21
|
+
analyses_reponse = requests.get(f"{api_url}analyses", timeout=20)
|
|
22
|
+
analyses = analyses_reponse.json()
|
|
23
|
+
except requests.exceptions.RequestException:
|
|
24
|
+
version = "API not reachable"
|
|
25
|
+
wet_processes = []
|
|
26
|
+
bi_processes = []
|
|
27
|
+
analyses = []
|
|
28
|
+
return render_template(
|
|
29
|
+
"home.html",
|
|
30
|
+
version=version,
|
|
31
|
+
wet_processes=wet_processes,
|
|
32
|
+
bi_processes=bi_processes,
|
|
33
|
+
analyses=analyses,
|
|
34
|
+
)
|
|
35
|
+
|
|
36
|
+
|
|
37
|
+
@routes_bp.route("/analyses")
|
|
38
|
+
def show_analyses() -> str:
|
|
39
|
+
api_url = current_app.config["GENUI_API_URL"]
|
|
40
|
+
try:
|
|
41
|
+
analyses_reponse = requests.get(f"{api_url}analyses", timeout=20)
|
|
42
|
+
analyses = analyses_reponse.json()
|
|
43
|
+
except requests.exceptions.RequestException:
|
|
44
|
+
analyses = ["Error fetching data."]
|
|
45
|
+
|
|
46
|
+
return render_template("analyses.html", analyses=analyses)
|
|
47
|
+
|
|
48
|
+
|
|
49
|
+
@routes_bp.route("/bi_processes")
|
|
50
|
+
def show_bi_processes() -> str:
|
|
51
|
+
api_url = current_app.config["GENUI_API_URL"]
|
|
52
|
+
try:
|
|
53
|
+
bi_processes_reponse = requests.get(
|
|
54
|
+
f"{api_url}bi_processes", timeout=20
|
|
55
|
+
)
|
|
56
|
+
bi_processes = bi_processes_reponse.json()
|
|
57
|
+
except requests.exceptions.RequestException:
|
|
58
|
+
bi_processes = ["Error fetching data."]
|
|
59
|
+
|
|
60
|
+
return render_template("bi_processes.html", bi_processes=bi_processes)
|
|
61
|
+
|
|
62
|
+
|
|
63
|
+
@routes_bp.route("/wet_processes")
|
|
64
|
+
def show_wet_processes() -> str:
|
|
65
|
+
api_url = current_app.config["GENUI_API_URL"]
|
|
66
|
+
try:
|
|
67
|
+
wet_processes_reponse = requests.get(
|
|
68
|
+
f"{api_url}wet_processes", timeout=20
|
|
69
|
+
)
|
|
70
|
+
wet_processes = wet_processes_reponse.json()
|
|
71
|
+
except requests.exceptions.RequestException:
|
|
72
|
+
wet_processes = ["Error fetching data."]
|
|
73
|
+
|
|
74
|
+
return render_template("wet_processes.html", wet_processes=wet_processes)
|
|
75
|
+
|
|
76
|
+
|
|
77
|
+
@routes_bp.route("/version")
|
|
78
|
+
def show_version() -> str:
|
|
79
|
+
api_url = current_app.config["GENUI_API_URL"]
|
|
80
|
+
try:
|
|
81
|
+
version_reponse = requests.get(f"{api_url}version", timeout=20)
|
|
82
|
+
version = version_reponse.json().get("version", "Version not found")
|
|
83
|
+
except requests.exceptions.RequestException:
|
|
84
|
+
version = "Error fetching version."
|
|
85
|
+
|
|
86
|
+
return render_template("version.html", version=version)
|
genelastic/ui/server.py
CHANGED
|
@@ -1,87 +1,14 @@
|
|
|
1
|
-
import
|
|
2
|
-
from flask import Flask
|
|
1
|
+
from asgiref.wsgi import WsgiToAsgi
|
|
2
|
+
from flask import Flask
|
|
3
3
|
|
|
4
|
-
|
|
5
|
-
app.config.from_object("src.genelastic.ui.settings.Config")
|
|
4
|
+
from .routes import routes_bp
|
|
6
5
|
|
|
7
6
|
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
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
|
-
|
|
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
|
-
|
|
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()
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
{% extends "layout.html" %}
|
|
2
|
+
{% block title %}Bi Processes{% endblock %}
|
|
3
|
+
{% block content %}
|
|
4
|
+
<h2>List of Bi Processes</h2>
|
|
5
|
+
<ul>
|
|
6
|
+
{% for bi_process in bi_processes %}
|
|
7
|
+
<li>{{ bi_process }}</li>
|
|
8
|
+
{% endfor %}
|
|
9
|
+
</ul>
|
|
10
|
+
<a href="/">Back to Home</a>
|
|
11
|
+
{% endblock %}
|
|
@@ -0,0 +1,34 @@
|
|
|
1
|
+
<!DOCTYPE html>
|
|
2
|
+
<html lang="en">
|
|
3
|
+
<head>
|
|
4
|
+
<meta charset="UTF-8">
|
|
5
|
+
<meta name="viewport" content="width=device-width, initial-scale=1">
|
|
6
|
+
<title>{% block title %}Genelastic{% endblock %}</title>
|
|
7
|
+
<link href="https://cdn.jsdelivr.net/npm/bootstrap@5.3.3/dist/css/bootstrap.min.css"
|
|
8
|
+
rel="stylesheet"
|
|
9
|
+
integrity="sha384-QWTKZyjpPEjISv5WaRU9OFeRpok6YctnYmDr5pNlyT2bRjXh0JMhjY6hW+ALEwIH"
|
|
10
|
+
crossorigin="anonymous"
|
|
11
|
+
>
|
|
12
|
+
|
|
13
|
+
</head>
|
|
14
|
+
<body>
|
|
15
|
+
<h1>Welcome to DEMO - genelastic UI</h1>
|
|
16
|
+
<nav>
|
|
17
|
+
<a href="/">Home</a>
|
|
18
|
+
<a href="/analyses">Analyses</a>
|
|
19
|
+
<a href="/wet_processes">Wet Processes</a>
|
|
20
|
+
<a href="/bi_processes">Bi Processes</a>
|
|
21
|
+
<a href="/version">Version</a>
|
|
22
|
+
</nav>
|
|
23
|
+
<hr>
|
|
24
|
+
<div id="content">
|
|
25
|
+
{% block content %}{% endblock %}
|
|
26
|
+
</div>
|
|
27
|
+
|
|
28
|
+
|
|
29
|
+
<script src="https://cdn.jsdelivr.net/npm/bootstrap@5.3.3/dist/js/bootstrap.bundle.min.js"
|
|
30
|
+
integrity="sha384-YvpcrYf0tY3lHB60NNkmXc5s9fDVZLESaAA55NDzOxhy9GkcIdslK1eN7N6jIeHz"
|
|
31
|
+
crossorigin="anonymous">
|
|
32
|
+
</script>
|
|
33
|
+
</body>
|
|
34
|
+
</html>
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
{% extends "layout.html" %}
|
|
2
|
+
{% block title %}Version{% endblock %}
|
|
3
|
+
{% block content %}
|
|
4
|
+
<h2 class="text-center">Genelastic Version</h2>
|
|
5
|
+
<p class="text-center">{{ version }}</p>
|
|
6
|
+
<div class="mt-4 text-center">
|
|
7
|
+
<a href="/" class="btn btn-primary">Back to Home</a>
|
|
8
|
+
</div>
|
|
9
|
+
{% endblock %}
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
{% extends "layout.html" %}
|
|
2
|
+
{% block title %}Wet Processes{% endblock %}
|
|
3
|
+
{% block content %}
|
|
4
|
+
<h2>List of Wet Processes</h2>
|
|
5
|
+
<ul>
|
|
6
|
+
{% for wet_process in wet_processes %}
|
|
7
|
+
<li>{{ wet_process }}</li>
|
|
8
|
+
{% endfor %}
|
|
9
|
+
</ul>
|
|
10
|
+
<a href="/">Back to Home</a>
|
|
11
|
+
{% endblock %}
|