forked from enviPath/enviPy
[Feature] PEPPER in enviPath (#332)
Co-authored-by: Tim Lorsbach <tim@lorsba.ch> Reviewed-on: enviPath/enviPy#332
This commit is contained in:
158
epdb/views.py
158
epdb/views.py
@ -1,7 +1,7 @@
|
||||
import json
|
||||
import logging
|
||||
from datetime import datetime
|
||||
from typing import Any, Dict, List
|
||||
from typing import Any, Dict, List, Iterable
|
||||
|
||||
import nh3
|
||||
from django.conf import settings as s
|
||||
@ -28,6 +28,7 @@ from .logic import (
|
||||
UserManager,
|
||||
)
|
||||
from .models import (
|
||||
AdditionalInformation,
|
||||
APIToken,
|
||||
Compound,
|
||||
CompoundStructure,
|
||||
@ -46,6 +47,7 @@ from .models import (
|
||||
Node,
|
||||
Pathway,
|
||||
Permission,
|
||||
PropertyPluginModel,
|
||||
Reaction,
|
||||
Rule,
|
||||
RuleBasedRelativeReasoning,
|
||||
@ -401,7 +403,7 @@ def breadcrumbs(
|
||||
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 ['']
|
||||
# As empty lists will be removed in POST request we'll send ['']
|
||||
if scenario_url == "":
|
||||
continue
|
||||
|
||||
@ -413,6 +415,7 @@ def set_scenarios(current_user, attach_object, scenario_urls: List[str]):
|
||||
|
||||
|
||||
def set_aliases(current_user, attach_object, aliases: List[str]):
|
||||
# As empty lists will be removed in POST request we'll send ['']
|
||||
if aliases == [""]:
|
||||
aliases = []
|
||||
|
||||
@ -421,7 +424,7 @@ def set_aliases(current_user, attach_object, aliases: List[str]):
|
||||
|
||||
|
||||
def copy_object(current_user, target_package: "Package", source_object_url: str):
|
||||
# Ensures that source is readable
|
||||
# Ensures that source object is readable
|
||||
source_package = PackageManager.get_package_by_url(current_user, source_object_url)
|
||||
|
||||
if source_package == target_package:
|
||||
@ -429,7 +432,7 @@ def copy_object(current_user, target_package: "Package", source_object_url: str)
|
||||
|
||||
parser = EPDBURLParser(source_object_url)
|
||||
|
||||
# if the url won't contain a package or is a plain package
|
||||
# if the url don't contain a package or is a plain package
|
||||
if not parser.contains_package_url():
|
||||
raise ValueError(f"Object {source_object_url} can't be copied!")
|
||||
|
||||
@ -714,12 +717,36 @@ def models(request):
|
||||
|
||||
# Keep model_types for potential modal/action use
|
||||
context["model_types"] = {
|
||||
"ML Relative Reasoning": "ml-relative-reasoning",
|
||||
"Rule Based Relative Reasoning": "rule-based-relative-reasoning",
|
||||
"EnviFormer": "enviformer",
|
||||
"ML Relative Reasoning": {
|
||||
"type": "ml-relative-reasoning",
|
||||
"requires_rule_packages": True,
|
||||
"requires_data_packages": True,
|
||||
},
|
||||
"Rule Based Relative Reasoning": {
|
||||
"type": "rule-based-relative-reasoning",
|
||||
"requires_rule_packages": True,
|
||||
"requires_data_packages": True,
|
||||
},
|
||||
"EnviFormer": {
|
||||
"type": "enviformer",
|
||||
"requires_rule_packages": False,
|
||||
"requires_data_packages": True,
|
||||
},
|
||||
}
|
||||
for k, v in s.CLASSIFIER_PLUGINS.items():
|
||||
context["model_types"][v.display()] = k
|
||||
|
||||
if s.FLAGS.get("PLUGINS", False):
|
||||
for k, v in s.CLASSIFIER_PLUGINS.items():
|
||||
context["model_types"][v().display()] = {
|
||||
"type": k,
|
||||
"requires_rule_packages": True,
|
||||
"requires_data_packages": True,
|
||||
}
|
||||
for k, v in s.PROPERTY_PLUGINS.items():
|
||||
context["model_types"][v().display()] = {
|
||||
"type": k,
|
||||
"requires_rule_packages": v().requires_rule_packages,
|
||||
"requires_data_packages": v().requires_data_packages,
|
||||
}
|
||||
|
||||
# Context for paginated template
|
||||
context["entity_type"] = "model"
|
||||
@ -830,16 +857,36 @@ def package_models(request, package_uuid):
|
||||
)
|
||||
|
||||
context["model_types"] = {
|
||||
"ML Relative Reasoning": "mlrr",
|
||||
"Rule Based Relative Reasoning": "rbrr",
|
||||
"ML Relative Reasoning": {
|
||||
"type": "ml-relative-reasoning",
|
||||
"requires_rule_packages": True,
|
||||
"requires_data_packages": True,
|
||||
},
|
||||
"Rule Based Relative Reasoning": {
|
||||
"type": "rule-based-relative-reasoning",
|
||||
"requires_rule_packages": True,
|
||||
"requires_data_packages": True,
|
||||
},
|
||||
"EnviFormer": {
|
||||
"type": "enviformer",
|
||||
"requires_rule_packages": False,
|
||||
"requires_data_packages": True,
|
||||
},
|
||||
}
|
||||
|
||||
if s.FLAGS.get("ENVIFORMER", False):
|
||||
context["model_types"]["EnviFormer"] = "enviformer"
|
||||
|
||||
if s.FLAGS.get("PLUGINS", False):
|
||||
for k, v in s.CLASSIFIER_PLUGINS.items():
|
||||
context["model_types"][v.display()] = k
|
||||
context["model_types"][v().display()] = {
|
||||
"type": k,
|
||||
"requires_rule_packages": True,
|
||||
"requires_data_packages": True,
|
||||
}
|
||||
for k, v in s.PROPERTY_PLUGINS.items():
|
||||
context["model_types"][v().display()] = {
|
||||
"type": k,
|
||||
"requires_rule_packages": v().requires_rule_packages,
|
||||
"requires_data_packages": v().requires_data_packages,
|
||||
}
|
||||
|
||||
return render(request, "collections/models_paginated.html", context)
|
||||
|
||||
@ -900,8 +947,24 @@ def package_models(request, package_uuid):
|
||||
]
|
||||
|
||||
mod = RuleBasedRelativeReasoning.create(**params)
|
||||
elif s.FLAGS.get("PLUGINS", False) and model_type in s.CLASSIFIER_PLUGINS.values():
|
||||
elif s.FLAGS.get("PLUGINS", False) and model_type in s.CLASSIFIER_PLUGINS:
|
||||
pass
|
||||
elif s.FLAGS.get("PLUGINS", False) and model_type in s.PROPERTY_PLUGINS:
|
||||
params["plugin_identifier"] = model_type
|
||||
impl = s.PROPERTY_PLUGINS[model_type]
|
||||
inst = impl()
|
||||
|
||||
if inst.requires_rule_packages():
|
||||
params["rule_packages"] = [
|
||||
PackageManager.get_package_by_url(current_user, p) for p in rule_packages
|
||||
]
|
||||
else:
|
||||
params["rule_packages"] = []
|
||||
|
||||
if not inst.requires_data_packages():
|
||||
del params["data_packages"]
|
||||
|
||||
mod = PropertyPluginModel.create(**params)
|
||||
else:
|
||||
return error(
|
||||
request, "Invalid model type.", f'Model type "{model_type}" is not supported."'
|
||||
@ -925,14 +988,18 @@ def package_model(request, package_uuid, model_uuid):
|
||||
if request.method == "GET":
|
||||
classify = request.GET.get("classify", False)
|
||||
ad_assessment = request.GET.get("app-domain-assessment", False)
|
||||
# TODO this needs to be generic
|
||||
half_life = request.GET.get("half_life", False)
|
||||
|
||||
if classify or ad_assessment:
|
||||
if any([classify, ad_assessment, half_life]):
|
||||
smiles = request.GET.get("smiles", "").strip()
|
||||
|
||||
# Check if smiles is non empty and valid
|
||||
if smiles == "":
|
||||
return JsonResponse({"error": "Received empty SMILES"}, status=400)
|
||||
|
||||
stereo = FormatConverter.has_stereo(smiles)
|
||||
|
||||
try:
|
||||
stand_smiles = FormatConverter.standardize(smiles, remove_stereo=True)
|
||||
except ValueError:
|
||||
@ -966,6 +1033,19 @@ def package_model(request, package_uuid, model_uuid):
|
||||
|
||||
return JsonResponse(res, safe=False)
|
||||
|
||||
elif half_life:
|
||||
from epdb.tasks import dispatch_eager, predict_simple
|
||||
|
||||
_, run_res = dispatch_eager(
|
||||
current_user, predict_simple, current_model.pk, stand_smiles, include_svg=True
|
||||
)
|
||||
|
||||
# Here we expect a single result
|
||||
if isinstance(run_res.result, Iterable):
|
||||
return JsonResponse(run_res.result[0].model_dump(mode="json"), safe=False)
|
||||
|
||||
return JsonResponse(run_res.result.model_dump(mode="json"), safe=False)
|
||||
|
||||
else:
|
||||
app_domain_assessment = current_model.app_domain.assess(stand_smiles)
|
||||
return JsonResponse(app_domain_assessment, safe=False)
|
||||
@ -980,7 +1060,11 @@ def package_model(request, package_uuid, model_uuid):
|
||||
context["model"] = current_model
|
||||
context["current_object"] = current_model
|
||||
|
||||
return render(request, "objects/model.html", context)
|
||||
if isinstance(current_model, PropertyPluginModel):
|
||||
context["plugin_identifier"] = current_model.plugin_identifier
|
||||
return render(request, "objects/model/property_model.html", context)
|
||||
else:
|
||||
return render(request, "objects/model/classification_model.html", context)
|
||||
|
||||
elif request.method == "POST":
|
||||
if hidden := request.POST.get("hidden", None):
|
||||
@ -1940,6 +2024,7 @@ def package_pathways(request, package_uuid):
|
||||
prediction_setting = SettingManager.get_setting_by_url(current_user, prediction_setting)
|
||||
else:
|
||||
prediction_setting = current_user.prediction_settings()
|
||||
|
||||
pw = Pathway.create(
|
||||
current_package,
|
||||
stand_smiles,
|
||||
@ -2504,8 +2589,10 @@ def package_scenario(request, package_uuid, scenario_uuid):
|
||||
context["breadcrumbs"] = breadcrumbs(current_package, "scenario", current_scenario)
|
||||
|
||||
context["scenario"] = current_scenario
|
||||
# Get scenarios that have current_scenario as a parent
|
||||
context["children"] = current_scenario.scenario_set.order_by("name")
|
||||
|
||||
context["associated_additional_information"] = AdditionalInformation.objects.filter(
|
||||
scenario=current_scenario
|
||||
)
|
||||
|
||||
# Note: Modals now fetch schemas and data from API endpoints
|
||||
# Keeping these for backwards compatibility if needed elsewhere
|
||||
@ -2612,11 +2699,22 @@ def user(request, user_uuid):
|
||||
|
||||
context["user"] = requested_user
|
||||
|
||||
model_qs = EPModel.objects.none()
|
||||
for p in PackageManager.get_all_readable_packages(requested_user, include_reviewed=True):
|
||||
model_qs |= p.models
|
||||
accessible_packages = PackageManager.get_all_readable_packages(
|
||||
requested_user, include_reviewed=True
|
||||
)
|
||||
|
||||
context["models"] = model_qs
|
||||
property_models = PropertyPluginModel.objects.filter(
|
||||
package__in=accessible_packages
|
||||
).order_by("name")
|
||||
|
||||
tp_prediction_models = (
|
||||
EPModel.objects.filter(package__in=accessible_packages)
|
||||
.exclude(id__in=[pm.id for pm in property_models])
|
||||
.order_by("name")
|
||||
)
|
||||
|
||||
context["models"] = tp_prediction_models
|
||||
context["property_models"] = property_models
|
||||
|
||||
context["tokens"] = APIToken.objects.filter(user=requested_user)
|
||||
|
||||
@ -2853,6 +2951,18 @@ def settings(request):
|
||||
else:
|
||||
raise BadRequest("Neither Model-Based nor Rule-Based as Method selected!")
|
||||
|
||||
property_model_urls = request.POST.getlist("prediction-setting-property-models")
|
||||
|
||||
if property_model_urls:
|
||||
mods = []
|
||||
for pm_url in property_model_urls:
|
||||
model = PropertyPluginModel.objects.get(url=pm_url)
|
||||
|
||||
if PackageManager.readable(current_user, model.package):
|
||||
mods.append(model)
|
||||
|
||||
params["property_models"] = mods
|
||||
|
||||
created_setting = SettingManager.create_setting(
|
||||
current_user,
|
||||
name=name,
|
||||
|
||||
Reference in New Issue
Block a user