• Home
  • Features
  • Pricing
  • Docs
  • Announcements
  • Sign In

askomics / flaskomics / 6590008757

20 Oct 2023 03:58PM UTC coverage: 83.758% (+0.4%) from 83.31%
6590008757

push

github-actions

web-flow
Merge pull request #420 from askomics/dev

Release 4.5.0

633 of 633 new or added lines in 29 files covered. (100.0%)

6240 of 7450 relevant lines covered (83.76%)

0.84 hits per line

Source File
Press 'n' to go to next uncovered line, 'b' for previous

77.25
/askomics/api/admin.py
1
"""Admin routes"""
2
import sys
1✔
3
import traceback
1✔
4

5
from askomics.api.auth import api_auth, admin_required
1✔
6
from askomics.libaskomics.DatasetsHandler import DatasetsHandler
1✔
7
from askomics.libaskomics.FilesHandler import FilesHandler
1✔
8
from askomics.libaskomics.LocalAuth import LocalAuth
1✔
9
from askomics.libaskomics.Mailer import Mailer
1✔
10
from askomics.libaskomics.PrefixManager import PrefixManager
1✔
11
from askomics.libaskomics.OntologyManager import OntologyManager
1✔
12
from askomics.libaskomics.Result import Result
1✔
13
from askomics.libaskomics.ResultsHandler import ResultsHandler
1✔
14

15
from flask import (Blueprint, current_app, jsonify, request, session)
1✔
16

17
admin_bp = Blueprint('admin', __name__, url_prefix='/')
1✔
18

19

20
@admin_bp.route('/api/admin/getusers', methods=['GET'])
1✔
21
@api_auth
1✔
22
@admin_required
1✔
23
def get_users():
1✔
24
    """Get all users
25

26
    Returns
27
    -------
28
    json
29
        users: list of all users info
30
        error: True if error, else False
31
        errorMessage: the error message of error, else an empty string
32
    """
33
    try:
1✔
34
        local_auth = LocalAuth(current_app, session)
1✔
35
        all_users = local_auth.get_all_users()
1✔
36
    except Exception as e:
×
37
        traceback.print_exc(file=sys.stdout)
×
38
        return jsonify({
×
39
            'users': [],
40
            'error': True,
41
            'errorMessage': str(e)
42
        }), 500
43

44
    return jsonify({
1✔
45
        'users': all_users,
46
        'error': False,
47
        'errorMessage': ''
48
    })
49

50

51
@admin_bp.route('/api/admin/getdatasets', methods=['GET'])
1✔
52
@api_auth
1✔
53
@admin_required
1✔
54
def get_datasets():
1✔
55
    """Get all datasets
56

57
    Returns
58
    -------
59
    json
60
        users: list of all datasets
61
        error: True if error, else False
62
        errorMessage: the error message of error, else an empty string
63
    """
64
    try:
1✔
65
        datasets_handler = DatasetsHandler(current_app, session)
1✔
66
        datasets = datasets_handler.get_all_datasets()
1✔
67
    except Exception as e:
×
68
        traceback.print_exc(file=sys.stdout)
×
69
        return jsonify({
×
70
            'datasets': [],
71
            'error': True,
72
            'errorMessage': str(e)
73
        }), 500
74

75
    return jsonify({
1✔
76
        'datasets': datasets,
77
        'error': False,
78
        'errorMessage': ''
79
    })
80

81

82
@admin_bp.route('/api/admin/getfiles', methods=['GET'])
1✔
83
@api_auth
1✔
84
@admin_required
1✔
85
def get_files():
1✔
86
    """Get all files info
87
    Returns
88
    -------
89
    json
90
        files: list of all files
91
        error: True if error, else False
92
        errorMessage: the error message of error, else an empty string
93
    """
94

95
    try:
1✔
96
        files_handler = FilesHandler(current_app, session)
1✔
97
        files = files_handler.get_all_files_infos()
1✔
98

99
    except Exception as e:
×
100
        traceback.print_exc(file=sys.stdout)
×
101
        return jsonify({
×
102
            'files': [],
103
            'error': True,
104
            'errorMessage': str(e)
105
        }), 500
106

107
    return jsonify({
1✔
108
        'files': files,
109
        'error': False,
110
        'errorMessage': ''
111
    })
112

113

114
@admin_bp.route('/api/admin/getqueries', methods=['GET'])
1✔
115
@api_auth
1✔
116
@admin_required
1✔
117
def get_queries():
1✔
118
    """Get all public queries
119
    (And anonymous queries)
120
    Returns
121
    -------
122
    json
123
        startpoint: list of public queries
124
        error: True if error, else False
125
        errorMessage: the error message of error, else an empty string
126
    """
127
    try:
1✔
128
        results_handler = ResultsHandler(current_app, session)
1✔
129
        queries = results_handler.get_admin_queries()
1✔
130

131
    except Exception as e:
×
132
        traceback.print_exc(file=sys.stdout)
×
133
        return jsonify({
×
134
            "queries": [],
135
            'error': True,
136
            'errorMessage': str(e)
137
        }), 500
138

139
    return jsonify({
1✔
140
        "queries": queries,
141
        'error': False,
142
        'errorMessage': ''
143
    })
144

145

146
@admin_bp.route('/api/admin/setadmin', methods=['POST'])
1✔
147
@api_auth
1✔
148
@admin_required
1✔
149
def set_admin():
1✔
150
    """change admin status of a user
151

152
    Returns
153
    -------
154
    json
155
        error: True if error, else False
156
        errorMessage: the error message of error, else an empty string
157
    """
158
    data = request.get_json()
1✔
159

160
    try:
1✔
161
        local_auth = LocalAuth(current_app, session)
1✔
162
        local_auth.set_admin(data['newAdmin'], data['username'])
1✔
163
    except Exception as e:
×
164
        traceback.print_exc(file=sys.stdout)
×
165
        return jsonify({
×
166
            'error': True,
167
            'errorMessage': str(e)
168
        }), 500
169

170
    return jsonify({
1✔
171
        'error': False,
172
        'errorMessage': ''
173
    })
174

175

176
@admin_bp.route('/api/admin/setquota', methods=["POST"])
1✔
177
@api_auth
1✔
178
@admin_required
1✔
179
def set_quota():
1✔
180
    """Change quota of a user
181

182
    Returns
183
    -------
184
    json
185
        users: updated users
186
        error: True if error, else False
187
        errorMessage: the error message of error, else an empty string
188
    """
189
    data = request.get_json()
1✔
190

191
    try:
1✔
192
        local_auth = LocalAuth(current_app, session)
1✔
193
        local_auth.set_quota(data['quota'], data['username'])
1✔
194
        all_users = local_auth.get_all_users()
1✔
195
    except Exception as e:
×
196
        traceback.print_exc(file=sys.stdout)
×
197
        return jsonify({
×
198
            'users': [],
199
            'error': True,
200
            'errorMessage': str(e)
201
        }), 500
202

203
    return jsonify({
1✔
204
        'users': all_users,
205
        'error': False,
206
        'errorMessage': ''
207
    })
208

209

210
@admin_bp.route('/api/admin/setblocked', methods=['POST'])
1✔
211
@api_auth
1✔
212
@admin_required
1✔
213
def set_blocked():
1✔
214
    """Change blocked status of a user
215

216
    Returns
217
    -------
218
    json
219
        error: True if error, else False
220
        errorMessage: the error message of error, else an empty string
221
    """
222
    data = request.get_json()
1✔
223

224
    try:
1✔
225
        local_auth = LocalAuth(current_app, session)
1✔
226
        local_auth.set_blocked(data['newBlocked'], data['username'])
1✔
227
    except Exception as e:
×
228
        traceback.print_exc(file=sys.stdout)
×
229
        return jsonify({
×
230
            'error': True,
231
            'errorMessage': str(e)
232
        }), 500
233

234
    return jsonify({
1✔
235
        'error': False,
236
        'errorMessage': ''
237
    })
238

239

240
@admin_bp.route('/api/admin/publicize_dataset', methods=['POST'])
1✔
241
@api_auth
1✔
242
@admin_required
1✔
243
def toogle_public_dataset():
1✔
244
    """Toggle public status of a dataset
245

246
    Returns
247
    -------
248
    json
249
        error: True if error, else False
250
        errorMessage: the error message of error, else an empty string
251
    """
252
    data = request.get_json()
1✔
253
    datasets_info = [{'id': data["datasetId"]}]
1✔
254

255
    try:
1✔
256
        # Change status to queued for all datasets
257
        datasets_handler = DatasetsHandler(current_app, session, datasets_info=datasets_info)
1✔
258
        datasets_handler.handle_datasets(admin=True)
1✔
259

260
        for dataset in datasets_handler.datasets:
1✔
261
            if (not data.get("newStatus", False) and dataset.ontology):
1✔
262
                return jsonify({
×
263
                    'datasets': [],
264
                    'error': True,
265
                    'errorMessage': "Cannot unpublicize a dataset linked to an ontology"
266
                }), 400
267
            current_app.logger.debug(data["newStatus"])
1✔
268
            dataset.toggle_public(data["newStatus"], admin=True)
1✔
269

270
        datasets = datasets_handler.get_all_datasets()
1✔
271

272
    except Exception as e:
×
273
        traceback.print_exc(file=sys.stdout)
×
274
        return jsonify({
×
275
            'datasets': [],
276
            'error': True,
277
            'errorMessage': str(e)
278
        }), 500
279

280
    return jsonify({
1✔
281
        'datasets': datasets,
282
        'error': False,
283
        'errorMessage': ''
284
    })
285

286

287
@admin_bp.route('/api/admin/publicize_query', methods=['POST'])
1✔
288
@api_auth
1✔
289
@admin_required
1✔
290
def toggle_public_query():
1✔
291
    """Publish a query template from a result
292

293
    Returns
294
    -------
295
    json
296
        error: True if error, else False
297
        errorMessage: the error message of error, else an empty string
298
    """
299
    try:
1✔
300
        json = request.get_json()
1✔
301
        result_info = {"id": json["queryId"]}
1✔
302

303
        result = Result(current_app, session, result_info)
1✔
304
        result.publish_query(json["newStatus"], admin=True)
1✔
305

306
        results_handler = ResultsHandler(current_app, session)
1✔
307
        public_queries = results_handler.get_admin_queries()
1✔
308

309
    except Exception as e:
×
310
        traceback.print_exc(file=sys.stdout)
×
311
        return jsonify({
×
312
            'queries': [],
313
            'error': True,
314
            'errorMessage': 'Failed to publish query: \n{}'.format(str(e))
315
        }), 500
316

317
    return jsonify({
1✔
318
        'queries': public_queries,
319
        'error': False,
320
        'errorMessage': ''
321
    })
322

323

324
@admin_bp.route('/api/admin/update_description', methods=['POST'])
1✔
325
@api_auth
1✔
326
@admin_required
1✔
327
def update_query_description():
1✔
328
    """Update a query description
329

330
    Returns
331
    -------
332
    json
333
        error: True if error, else False
334
        errorMessage: the error message of error, else an empty string
335
    """
336
    try:
1✔
337
        data = request.get_json()
1✔
338
        if not (data and data.get("queryId") and data.get("newDesc")):
1✔
339
            return jsonify({
×
340
                'files': [],
341
                'error': True,
342
                'errorMessage': "Missing parameters"
343
            }), 400
344

345
        result_info = {"id": data["queryId"]}
1✔
346
        new_desc = data["newDesc"]
1✔
347

348
        result = Result(current_app, session, result_info, admin=True)
1✔
349
        if not result:
1✔
350
            return jsonify({
×
351
                'files': [],
352
                'error': True,
353
                'errorMessage': "You do not have access to this result"
354
            }), 500
355
        result.update_description(new_desc, admin=True)
1✔
356

357
        results_handler = ResultsHandler(current_app, session)
1✔
358
        queries = results_handler.get_admin_queries()
1✔
359

360
    except Exception as e:
×
361
        traceback.print_exc(file=sys.stdout)
×
362
        return jsonify({
×
363
            'queries': [],
364
            'error': True,
365
            'errorMessage': 'Failed to update description: \n{}'.format(str(e))
366
        }), 500
367

368
    return jsonify({
1✔
369
        'queries': queries,
370
        'error': False,
371
        'errorMessage': ''
372
    })
373

374

375
@admin_bp.route("/api/admin/adduser", methods=["POST"])
1✔
376
@api_auth
1✔
377
@admin_required
1✔
378
def add_user():
1✔
379
    """Change blocked status of a user
380

381
    Returns
382
    -------
383
    json
384
        instanceUrl: The instance URL
385
        user: the new created user
386
        displayPassword: Display password on the interface ?
387
        error: True if error, else False
388
        errorMessage: the error message of error, else an empty string
389
    """
390
    data = request.get_json()
1✔
391

392
    user = {}
1✔
393
    display_password = True
1✔
394

395
    try:
1✔
396
        local_auth = LocalAuth(current_app, session)
1✔
397
        local_auth.check_inputs(data, admin_add=True)
1✔
398

399
        if not local_auth.get_error():
1✔
400
            # Create a user
401
            user = local_auth.persist_user_admin(data)
1✔
402
            local_auth.create_user_directories(user['id'], user['username'])
1✔
403
            # Send a email to this user (if askomics can send emails)
404

405
            mailer = Mailer(current_app, session)
1✔
406
            if mailer.check_mailer():
1✔
407
                display_password = False
×
408
                current_app.celery.send_task('send_mail_new_user', ({'user': session['user']}, user))
×
409
                # Don't send password user to frontend
410
                user.pop("password")
×
411

412
    except Exception as e:
×
413
        traceback.print_exc(file=sys.stdout)
×
414
        return jsonify({
×
415
            'instanceUrl': "",
416
            'user': user,
417
            'displayPassword': False,
418
            'error': True,
419
            'errorMessage': str(e)
420
        }), 500
421

422
    return jsonify({
1✔
423
        'instanceUrl': current_app.iniconfig.get("askomics", "instance_url"),
424
        'user': user,
425
        'displayPassword': display_password,
426
        'error': local_auth.get_error(),
427
        'errorMessage': local_auth.get_error_message()
428
    })
429

430

431
@admin_bp.route("/api/admin/delete_users", methods=["POST"])
1✔
432
@api_auth
1✔
433
@admin_required
1✔
434
def delete_users():
1✔
435
    """Delete users data
436

437
    Returns
438
    -------
439
    json
440
        users: remaining users
441
        error: True if error, else False
442
        errorMessage: the error message of error, else an empty string
443
    """
444
    data = request.get_json()
1✔
445

446
    try:
1✔
447
        usernames = data["usersToDelete"]
1✔
448
        users = []
1✔
449

450
        # Remove current user from the list
451
        if session["user"]["username"] in usernames:
1✔
452
            usernames.remove(session["user"]["username"])
1✔
453

454
        # Remove users from database
455
        local_auth = LocalAuth(current_app, session)
1✔
456
        for username in usernames:
1✔
457
            # Get user info
458
            users.append(local_auth.get_user(username))
1✔
459
            local_auth.delete_user_database(username)
1✔
460

461
        # Celery task to delete users' data from filesystem and rdf triplestore
462
        session_dict = {'user': session['user']}
1✔
463
        current_app.celery.send_task('delete_users_data', (session_dict, users, True))
1✔
464

465
        # Get remaining users
466
        users = local_auth.get_all_users()
1✔
467

468
    except Exception as e:
×
469
        traceback.print_exc(file=sys.stdout)
×
470
        return jsonify({
×
471
            'users': [],
472
            'error': True,
473
            'errorMessage': str(e)
474
        }), 500
475

476
    return jsonify({
1✔
477
        'users': users,
478
        'error': local_auth.get_error(),
479
        'errorMessage': local_auth.get_error_message()
480
    })
481

482

483
@admin_bp.route("/api/admin/delete_files", methods=["POST"])
1✔
484
@api_auth
1✔
485
@admin_required
1✔
486
def delete_files():
1✔
487
    """Delete files
488

489
    Returns
490
    -------
491
    json
492
        files: list of all files of current user
493
        error: True if error, else False
494
        errorMessage: the error message of error, else an empty string
495
    """
496
    data = request.get_json()
1✔
497

498
    try:
1✔
499
        files = FilesHandler(current_app, session)
1✔
500
        remaining_files = files.delete_files(data['filesIdToDelete'], admin=True)
1✔
501
    except Exception as e:
×
502
        traceback.print_exc(file=sys.stdout)
×
503
        return jsonify({
×
504
            'files': [],
505
            'error': True,
506
            'errorMessage': str(e)
507
        }), 500
508

509
    return jsonify({
1✔
510
        'files': remaining_files,
511
        'error': False,
512
        'errorMessage': ''
513
    })
514

515

516
@admin_bp.route("/api/admin/delete_datasets", methods=["POST"])
1✔
517
@api_auth
1✔
518
@admin_required
1✔
519
def delete_datasets():
1✔
520
    """Delete some datasets (db and triplestore) with a celery task
521

522
    Returns
523
    -------
524
    json
525
        error: True if error, else False
526
        errorMessage: the error message of error, else an empty string
527
    """
528
    data = request.get_json()
1✔
529
    datasets_info = []
1✔
530
    for dataset_id in data['datasetsIdToDelete']:
1✔
531
        datasets_info.append({'id': dataset_id})
1✔
532

533
    session_dict = {'user': session['user']}
1✔
534

535
    try:
1✔
536
        # Change status to queued for all datasets
537
        datasets_handler = DatasetsHandler(current_app, session, datasets_info=datasets_info)
1✔
538
        datasets_handler.handle_datasets(admin=True)
1✔
539
        datasets_handler.update_status_in_db('queued', admin=True)
1✔
540

541
        # Launch a celery task for each datasets to delete
542
        for dataset in datasets_handler.datasets:
1✔
543
            dataset_info = [{
1✔
544
                "id": dataset.id
545
            }, ]
546
            current_app.logger.debug(dataset_info)
1✔
547

548
            # kill integration celery task
549
            current_app.celery.control.revoke(dataset.celery_id, terminate=True)
1✔
550

551
            # Trigger the celery task to delete the dataset
552
            task = current_app.celery.send_task('delete_datasets', (session_dict, dataset_info, True))
1✔
553

554
            # replace the task id with the new
555
            dataset.update_celery(task.id, admin=True)
1✔
556

557
        datasets = datasets_handler.get_all_datasets()
1✔
558

559
    except Exception as e:
×
560
        traceback.print_exc(file=sys.stdout)
×
561
        return jsonify({
×
562
            'datasets': [],
563
            'error': True,
564
            'errorMessage': str(e)
565
        }), 500
566

567
    return jsonify({
1✔
568
        'datasets': datasets,
569
        'error': False,
570
        'errorMessage': ''
571
    })
572

573

574
@admin_bp.route("/api/admin/delete_queries", methods=["POST"])
1✔
575
@api_auth
1✔
576
@admin_required
1✔
577
def delete_queries():
1✔
578
    """Delete queries
579

580
    Returns
581
    -------
582
    json
583
        queries: list of all queries (either public or anonymous)
584
        error: True if error, else False
585
        errorMessage: the error message of error, else an empty string
586
    """
587
    data = request.get_json()
1✔
588
    if not data.get("queriesIdToDelete"):
1✔
589
        return jsonify({
×
590
            'queries': [],
591
            'error': True,
592
            'errorMessage': "Missing queriesIdToDelete key"
593
        }), 400
594

595
    try:
1✔
596
        queries_id = data["queriesIdToDelete"]
1✔
597
        results_handler = ResultsHandler(current_app, session)
1✔
598
        remaining_queries = results_handler.delete_results(queries_id, admin=True)
1✔
599

600
    except Exception as e:
×
601
        traceback.print_exc(file=sys.stdout)
×
602
        return jsonify({
×
603
            'queries': [],
604
            'error': True,
605
            'errorMessage': str(e)
606
        }), 500
607

608
    return jsonify({
1✔
609
        'queries': remaining_queries,
610
        'error': False,
611
        'errorMessage': ''
612
    })
613

614

615
@admin_bp.route("/api/admin/getprefixes", methods=["GET"])
1✔
616
@api_auth
1✔
617
@admin_required
1✔
618
def get_prefixes():
1✔
619
    """Get all custom prefixes
620

621
    Returns
622
    -------
623
    json
624
        prefixes: list of all custom prefixes
625
        error: True if error, else False
626
        errorMessage: the error message of error, else an empty string
627
    """
628
    try:
1✔
629
        pm = PrefixManager(current_app, session)
1✔
630
        prefixes = pm.get_custom_prefixes()
1✔
631
    except Exception as e:
×
632
        traceback.print_exc(file=sys.stdout)
×
633
        return jsonify({
×
634
            'prefixes': [],
635
            'error': True,
636
            'errorMessage': str(e)
637
        }), 500
638

639
    return jsonify({
1✔
640
        'prefixes': prefixes,
641
        'error': False,
642
        'errorMessage': ''
643
    })
644

645

646
@admin_bp.route("/api/admin/addprefix", methods=["POST"])
1✔
647
@api_auth
1✔
648
@admin_required
1✔
649
def add_prefix():
1✔
650
    """Create a new prefix
651

652
    Returns
653
    -------
654
    json
655
        prefixes: list of all custom prefixes
656
        error: True if error, else False
657
        errorMessage: the error message of error, else an empty string
658
    """
659

660
    data = request.get_json()
1✔
661
    if not data or not (data.get("prefix") and data.get("namespace")):
1✔
662
        return jsonify({
×
663
            'prefixes': [],
664
            'error': True,
665
            'errorMessage': "Missing parameter"
666
        }), 400
667

668
    pm = PrefixManager(current_app, session)
1✔
669
    prefixes = pm.get_custom_prefixes()
1✔
670

671
    prefix = data.get("prefix")
1✔
672
    namespace = data.get("namespace")
1✔
673

674
    if any([prefix == custom['prefix'] for custom in prefixes]):
1✔
675
        return jsonify({
×
676
            'prefixes': [],
677
            'error': True,
678
            'errorMessage': "Prefix {} is already in use".format(prefix)
679
        }), 400
680

681
    try:
1✔
682
        pm.add_custom_prefix(prefix, namespace)
1✔
683
        prefixes = pm.get_custom_prefixes()
1✔
684
    except Exception as e:
×
685
        traceback.print_exc(file=sys.stdout)
×
686
        return jsonify({
×
687
            'prefixes': [],
688
            'error': True,
689
            'errorMessage': str(e)
690
        }), 500
691

692
    return jsonify({
1✔
693
        'prefixes': prefixes,
694
        'error': False,
695
        'errorMessage': ''
696
    })
697

698

699
@admin_bp.route("/api/admin/delete_prefixes", methods=["POST"])
1✔
700
@api_auth
1✔
701
@admin_required
1✔
702
def delete_prefix():
1✔
703
    """Delete a prefix
704

705
    Returns
706
    -------
707
    json
708
        prefixes: list of all custom prefixes
709
        error: True if error, else False
710
        errorMessage: the error message of error, else an empty string
711
    """
712

713
    data = request.get_json()
1✔
714
    if not data or not data.get("prefixesIdToDelete"):
1✔
715
        return jsonify({
×
716
            'prefixes': [],
717
            'error': True,
718
            'errorMessage': "Missing prefixesIdToDelete parameter"
719
        }), 400
720

721
    pm = PrefixManager(current_app, session)
1✔
722
    try:
1✔
723
        pm.remove_custom_prefixes(data.get("prefixesIdToDelete"))
1✔
724
        prefixes = pm.get_custom_prefixes()
1✔
725
    except Exception as e:
×
726
        traceback.print_exc(file=sys.stdout)
×
727
        return jsonify({
×
728
            'prefixes': [],
729
            'error': True,
730
            'errorMessage': str(e)
731
        }), 500
732

733
    return jsonify({
1✔
734
        'prefixes': prefixes,
735
        'error': False,
736
        'errorMessage': ''
737
    })
738

739

740
@admin_bp.route("/api/admin/getontologies", methods=["GET"])
1✔
741
@api_auth
1✔
742
@admin_required
1✔
743
def get_ontologies():
1✔
744
    """Get all ontologies
745

746
    Returns
747
    -------
748
    json
749
        prefixes: list of all custom prefixes
750
        error: True if error, else False
751
        errorMessage: the error message of error, else an empty string
752
    """
753
    try:
1✔
754
        om = OntologyManager(current_app, session)
1✔
755
        ontologies = om.list_full_ontologies()
1✔
756
    except Exception as e:
×
757
        traceback.print_exc(file=sys.stdout)
×
758
        return jsonify({
×
759
            'ontologies': [],
760
            'error': True,
761
            'errorMessage': str(e)
762
        }), 500
763

764
    return jsonify({
1✔
765
        'ontologies': ontologies,
766
        'error': False,
767
        'errorMessage': ''
768
    })
769

770

771
@admin_bp.route("/api/admin/addontology", methods=["POST"])
1✔
772
@api_auth
1✔
773
@admin_required
1✔
774
def add_ontology():
1✔
775
    """Create a new ontology
776

777
    Returns
778
    -------
779
    json
780
        ontologies: list of all ontologies
781
        error: True if error, else False
782
        errorMessage: the error message of error, else an empty string
783
    """
784

785
    data = request.get_json()
1✔
786
    if not data or not (data.get("name") and data.get("uri") and data.get("shortName") and data.get("type") and data.get("datasetId") and data.get("labelUri")):
1✔
787
        return jsonify({
×
788
            'ontologies': [],
789
            'error': True,
790
            'errorMessage': "Missing parameter"
791
        }), 400
792

793
    name = data.get("name").strip()
1✔
794
    uri = data.get("uri").strip()
1✔
795
    short_name = data.get("shortName")
1✔
796
    type = data.get("type").strip()
1✔
797
    dataset_id = data.get("datasetId")
1✔
798
    label_uri = data.get("labelUri").strip()
1✔
799

800
    om = OntologyManager(current_app, session)
1✔
801

802
    if type == "ols" and not om.test_ols_ontology(short_name):
1✔
803
        return jsonify({
×
804
            'ontologies': [],
805
            'error': True,
806
            'errorMessage': "{} ontology not found in OLS".format(short_name)
807
        }), 400
808

809
    om = OntologyManager(current_app, session)
1✔
810
    ontologies = om.list_full_ontologies()
1✔
811

812
    if type not in ["none", "local", "ols"]:
1✔
813
        return jsonify({
×
814
            'ontologies': [],
815
            'error': True,
816
            'errorMessage': "Invalid type"
817
        }), 400
818

819
    datasets_info = [{'id': dataset_id}]
1✔
820

821
    try:
1✔
822
        datasets_handler = DatasetsHandler(current_app, session, datasets_info=datasets_info)
1✔
823
        datasets_handler.handle_datasets()
1✔
824
    except IndexError:
×
825
        return jsonify({
×
826
            'ontologies': [],
827
            'error': True,
828
            'errorMessage': "Dataset {} not found".format(dataset_id)
829
        }), 400
830

831
    if not len(datasets_handler.datasets) == 1 or not datasets_handler.datasets[0].public:
1✔
832
        return jsonify({
1✔
833
            'ontologies': [],
834
            'error': True,
835
            'errorMessage': "Invalid dataset id"
836
        }), 400
837

838
    dataset = datasets_handler.datasets[0]
1✔
839

840
    if any([name == onto['name'] or short_name == onto['short_name'] for onto in ontologies]):
1✔
841
        return jsonify({
×
842
            'ontologies': [],
843
            'error': True,
844
            'errorMessage': "Name and short name must be unique"
845
        }), 400
846

847
    if any([dataset_id == onto['dataset_id'] for onto in ontologies]):
1✔
848
        return jsonify({
×
849
            'ontologies': [],
850
            'error': True,
851
            'errorMessage': "Dataset is already linked to another ontology"
852
        }), 400
853

854
    try:
1✔
855
        om.add_ontology(name, uri, short_name, dataset.id, dataset.graph_name, dataset.endpoint, remote_graph=dataset.remote_graph, type=type, label_uri=label_uri)
1✔
856
        ontologies = om.list_full_ontologies()
1✔
857
    except Exception as e:
×
858
        traceback.print_exc(file=sys.stdout)
×
859
        return jsonify({
×
860
            'ontologies': [],
861
            'error': True,
862
            'errorMessage': str(e)
863
        }), 500
864

865
    return jsonify({
1✔
866
        'ontologies': ontologies,
867
        'error': False,
868
        'errorMessage': ''
869
    })
870

871

872
@admin_bp.route("/api/admin/delete_ontologies", methods=["POST"])
1✔
873
@api_auth
1✔
874
@admin_required
1✔
875
def delete_ontologies():
1✔
876
    """Delete one or more ontologies
877

878
    Returns
879
    -------
880
    json
881
        ontologies: list of all ontologies
882
        error: True if error, else False
883
        errorMessage: the error message of error, else an empty string
884
    """
885

886
    data = request.get_json()
1✔
887
    if not data or not data.get("ontologiesIdToDelete"):
1✔
888
        return jsonify({
×
889
            'ontologies': [],
890
            'error': True,
891
            'errorMessage': "Missing ontologiesIdToDelete parameter"
892
        }), 400
893

894
    om = OntologyManager(current_app, session)
1✔
895

896
    ontologies = om.list_full_ontologies()
1✔
897
    onto_to_delete = [{"id": ontology['id'], "dataset_id": ontology['dataset_id']} for ontology in ontologies if ontology['id'] in data.get("ontologiesIdToDelete")]
1✔
898

899
    try:
1✔
900
        om.remove_ontologies(onto_to_delete)
1✔
901
        ontologies = om.list_full_ontologies()
1✔
902
    except Exception as e:
×
903
        traceback.print_exc(file=sys.stdout)
×
904
        return jsonify({
×
905
            'ontologies': [],
906
            'error': True,
907
            'errorMessage': str(e)
908
        }), 500
909

910
    return jsonify({
1✔
911
        'ontologies': ontologies,
912
        'error': False,
913
        'errorMessage': ''
914
    })
STATUS · Troubleshooting · Open an Issue · Sales · Support · CAREERS · ENTERPRISE · START FREE · SCHEDULE DEMO
ANNOUNCEMENTS · TWITTER · TOS & SLA · Supported CI Services · What's a CI service? · Automated Testing

© 2025 Coveralls, Inc