[Fix] Remove all Scenarios, catch empty SMILES, prevent default Package delete (#134)

Co-authored-by: Tim Lorsbach <tim@lorsba.ch>
Reviewed-on: enviPath/enviPy#134
This commit is contained in:
2025-09-30 19:10:57 +13:00
parent b757a07f91
commit 3f5bb76633
9 changed files with 215 additions and 53 deletions

View File

@ -233,6 +233,11 @@ def breadcrumbs(first_level_object=None, second_level_namespace=None, second_lev
def set_scenarios(current_user, attach_object, scenario_urls: List[str]):
scens = []
for scenario_url in scenario_urls:
# As empty lists will be removed in POST request well send ['']
if scenario_url == '':
continue
package = PackageManager.get_package_by_url(current_user, scenario_url)
scen = Scenario.objects.get(package=package, uuid=scenario_url.split('/')[-1])
scens.append(scen)
@ -743,33 +748,43 @@ def package_model(request, package_uuid, model_uuid):
current_model = EPModel.objects.get(package=current_package, uuid=model_uuid)
if request.method == 'GET':
classify = request.GET.get('classify', False)
ad_assessment = request.GET.get('app-domain-assessment', False)
if request.GET.get('classify', False):
smiles = request.GET['smiles']
stand_smiles = FormatConverter.standardize(smiles)
pred_res = current_model.predict(stand_smiles)
res = []
if classify or ad_assessment:
smiles = request.GET.get('smiles', '').strip()
for pr in pred_res:
if len(pr) > 0:
products = []
for prod_set in pr.product_sets:
logger.debug(f"Checking {prod_set}")
products.append(tuple([x for x in prod_set]))
# Check if smiles is non empty and valid
if smiles == '':
return JsonResponse({'error': 'Received empty SMILES'}, status=400)
res.append({
'products': list(set(products)),
'probability': pr.probability,
'btrule': {k: getattr(pr.rule, k) for k in ['url', 'name']} if pr.rule is not None else None
})
try:
stand_smiles = FormatConverter.standardize(smiles)
except ValueError as e:
return JsonResponse({'error': f'"{smiles}" is not a valid SMILES'}, status=400)
return JsonResponse(res, safe=False)
if classify:
pred_res = current_model.predict(stand_smiles)
res = []
elif request.GET.get('app-domain-assessment', False):
smiles = request.GET['smiles']
stand_smiles = FormatConverter.standardize(smiles)
app_domain_assessment = current_model.app_domain.assess(stand_smiles)[0]
return JsonResponse(app_domain_assessment, safe=False)
for pr in pred_res:
if len(pr) > 0:
products = []
for prod_set in pr.product_sets:
logger.debug(f"Checking {prod_set}")
products.append(tuple([x for x in prod_set]))
res.append({
'products': list(set(products)),
'probability': pr.probability,
'btrule': {k: getattr(pr.rule, k) for k in ['url', 'name']} if pr.rule is not None else None
})
return JsonResponse(res, safe=False)
else:
app_domain_assessment = current_model.app_domain.assess(stand_smiles)[0]
return JsonResponse(app_domain_assessment, safe=False)
context = get_base_context(request)
context['title'] = f'enviPath - {current_package.name} - {current_model.name}'
@ -860,6 +875,11 @@ def package(request, package_uuid):
if hidden := request.POST.get('hidden', None):
if hidden == 'delete':
if current_user.default_package == current_package:
return error(request, f'Package "{current_package.name}" is the default and cannot be deleted!',
'You cannot delete the default package. If you want to delete this package you have to set another default package first.')
logger.debug(current_package.delete())
return redirect(s.SERVER_URL + '/package')
elif hidden == 'publish-package':
@ -1017,9 +1037,9 @@ def package_compound(request, package_uuid, compound_uuid):
else:
return HttpResponseBadRequest()
selected_scenarios = request.POST.getlist('selected-scenarios')
if 'selected-scenarios' in request.POST:
selected_scenarios = request.POST.getlist('selected-scenarios')
if selected_scenarios is not None:
set_scenarios(current_user, current_compound, selected_scenarios)
return redirect(current_compound.url)
@ -1126,9 +1146,9 @@ def package_compound_structure(request, package_uuid, compound_uuid, structure_u
else:
return HttpResponseBadRequest()
selected_scenarios = request.POST.getlist('selected-scenarios')
if 'selected-scenarios' in request.POST:
selected_scenarios = request.POST.getlist('selected-scenarios')
if selected_scenarios is not None:
set_scenarios(current_user, current_structure, selected_scenarios)
return redirect(current_structure.url)
@ -1253,9 +1273,9 @@ def package_rule(request, package_uuid, rule_uuid):
else:
return HttpResponseBadRequest()
selected_scenarios = request.POST.getlist('selected-scenarios')
if 'selected-scenarios' in request.POST:
selected_scenarios = request.POST.getlist('selected-scenarios')
if selected_scenarios is not None:
set_scenarios(current_user, current_rule, selected_scenarios)
return redirect(current_rule.url)
@ -1356,9 +1376,9 @@ def package_reaction(request, package_uuid, reaction_uuid):
else:
return HttpResponseBadRequest()
selected_scenarios = request.POST.getlist('selected-scenarios')
if 'selected-scenarios' in request.POST:
selected_scenarios = request.POST.getlist('selected-scenarios')
if selected_scenarios is not None:
set_scenarios(current_user, current_reaction, selected_scenarios)
return redirect(current_reaction.url)
@ -1421,10 +1441,10 @@ def package_pathways(request, package_uuid):
name = request.POST.get('name')
description = request.POST.get('description')
pw_mode = request.POST.get('predict', 'predict')
smiles = request.POST.get('smiles')
pw_mode = request.POST.get('predict', 'predict').strip()
smiles = request.POST.get('smiles', '').strip()
if smiles is None or smiles.strip() == '':
if 'smiles' in request.POST and smiles == '':
return error(request, "Pathway prediction failed!",
"Pathway prediction failed due to missing or empty SMILES")
@ -1543,9 +1563,9 @@ def package_pathway(request, package_uuid, pathway_uuid):
else:
return HttpResponseBadRequest()
selected_scenarios = request.POST.getlist('selected-scenarios')
if 'selected-scenarios' in request.POST:
selected_scenarios = request.POST.getlist('selected-scenarios')
if selected_scenarios is not None:
set_scenarios(current_user, current_pathway, selected_scenarios)
return redirect(current_pathway.url)
@ -1689,9 +1709,9 @@ def package_pathway_node(request, package_uuid, pathway_uuid, node_uuid):
else:
return HttpResponseBadRequest()
selected_scenarios = request.POST.getlist('selected-scenarios')
if 'selected-scenarios' in request.POST:
selected_scenarios = request.POST.getlist('selected-scenarios')
if selected_scenarios is not None:
set_scenarios(current_user, current_node, selected_scenarios)
return redirect(current_node.url)
@ -1798,9 +1818,9 @@ def package_pathway_edge(request, package_uuid, pathway_uuid, edge_uuid):
current_edge.delete()
return redirect(current_pathway.url)
selected_scenarios = request.POST.getlist('selected-scenarios')
if 'selected-scenarios' in request.POST:
selected_scenarios = request.POST.getlist('selected-scenarios')
if selected_scenarios is not None:
set_scenarios(current_user, current_edge, selected_scenarios)
return redirect(current_edge.url)