[Feature] Search API Endpoint (#227)

Co-authored-by: Tim Lorsbach <tim@lorsba.ch>
Reviewed-on: enviPath/enviPy#227
This commit is contained in:
2025-11-20 09:56:11 +13:00
parent fa8a191383
commit b6c35fea76

View File

@ -6,11 +6,12 @@ from django.contrib.auth import get_user_model
from django.http import HttpResponse
from django.shortcuts import redirect
from ninja import Field, Form, Router, Schema, Query
from ninja.security import SessionAuth
from utilities.chem import FormatConverter
from utilities.misc import PackageExporter
from .logic import GroupManager, PackageManager, SettingManager, UserManager
from .logic import GroupManager, PackageManager, SettingManager, UserManager, SearchManager
from .models import (
Compound,
CompoundStructure,
@ -36,8 +37,7 @@ def _anonymous_or_real(request):
return get_user_model().objects.get(username="anonymous")
# router = Router(auth=SessionAuth())
router = Router()
router = Router(auth=SessionAuth(csrf=False))
class Error(Schema):
@ -132,7 +132,7 @@ class SimpleModel(SimpleObject):
################
# Login/Logout #
################
@router.post("/", response={200: SimpleUser, 403: Error})
@router.post("/", response={200: SimpleUser, 403: Error}, auth=None)
def login(request, loginusername: Form[str], loginpassword: Form[str]):
from django.contrib.auth import authenticate, login
@ -200,6 +200,61 @@ def get_user(request, user_uuid):
}
class Search(Schema):
packages: List[str] = Field(alias="packages[]")
search: str
method: str
@router.get("/search", response={200: Any, 403: Error})
def search(request, search: Query[Search]):
try:
packs = []
for package in search.packages:
packs.append(PackageManager.get_package_by_url(request.user, package))
method = None
if search.method == "text":
method = "text"
elif search.method == "inchikey":
method = "inchikey"
elif search.method == "defaultSmiles":
method = "default"
elif search.method == "canonicalSmiles":
method = "canonical"
elif search.method == "exactSmiles":
method = "exact"
if method is None:
raise ValueError(f"Search method {search.method} is not supported!")
search_res = SearchManager.search(packs, search.search, method)
res = {}
if "Compounds" in search_res:
res["compound"] = search_res["Compounds"]
if "Compound Structures" in search_res:
res["structure"] = search_res["Compound Structures"]
if "Reaction" in search_res:
res["reaction"] = search_res["Reaction"]
if "Pathway" in search_res:
res["pathway"] = search_res["Pathway"]
if "Rules" in search_res:
res["rule"] = search_res["Rules"]
for key in res:
for v in res[key]:
v["id"] = v["url"].replace("simple-ambit-rule", "simple-rule")
return res
except ValueError as e:
return 403, {"message": f"Search failed due to {e}"}
###########
# Package #
###########