Skip to content

Commit 38d974e

Browse files
authored
Merge branch 'release-2025.5.0' into jstone-dev/score-set-search-result-optimization
2 parents ebde590 + a150ebd commit 38d974e

File tree

4 files changed

+61
-4
lines changed

4 files changed

+61
-4
lines changed

src/mavedb/routers/alphafold.py

Lines changed: 50 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,50 @@
1+
from fastapi import APIRouter, HTTPException
2+
import httpx
3+
import xml.etree.ElementTree as ET
4+
import re
5+
6+
from mavedb.lib.logging.logged_route import LoggedRoute
7+
8+
ALPHAFOLD_BASE = "https://alphafold.ebi.ac.uk/files/"
9+
10+
router = APIRouter(
11+
prefix="/api/v1",
12+
tags=["alphafold files"],
13+
responses={404: {"description": "Not found"}},
14+
route_class=LoggedRoute,
15+
)
16+
17+
@router.get("/alphafold-files/version")
18+
async def proxy_alphafold_index():
19+
"""
20+
Proxy the AlphaFold files index (XML document).
21+
"""
22+
async with httpx.AsyncClient(follow_redirects=True, timeout=30) as client:
23+
resp = await client.get(ALPHAFOLD_BASE, headers={"Accept": "application/xml"})
24+
if resp.status_code != 200:
25+
raise HTTPException(status_code=resp.status_code, detail="Upstream error fetching AlphaFold files index")
26+
27+
# parse XML response
28+
try:
29+
root = ET.fromstring(resp.content)
30+
31+
# Detect default namespace
32+
if root.tag.startswith("{"):
33+
ns_uri = root.tag.split("}", 1)[0][1:]
34+
ns = {"x": ns_uri}
35+
next_marker_tag = "x:NextMarker"
36+
else:
37+
ns = {}
38+
next_marker_tag = "NextMarker"
39+
40+
next_marker_el = root.find(next_marker_tag, ns)
41+
next_marker = next_marker_el.text if next_marker_el is not None else None
42+
43+
match = re.search(r"model_(v\d+)\.pdb$", next_marker, re.IGNORECASE)
44+
if not match:
45+
raise HTTPException(status_code=500, detail="Malformed AlphaFold PDB ID in XML")
46+
version = match.group(1)
47+
return {"version": version.lower()}
48+
49+
except ET.ParseError as e:
50+
raise HTTPException(status_code=502, detail=f"Failed to parse upstream XML: {e}")

src/mavedb/routers/score_sets.py

Lines changed: 6 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -179,10 +179,12 @@ def search_score_sets(
179179

180180
score_sets, num_score_sets = _search_score_sets(db, None, search).values()
181181
enriched_score_sets = []
182-
for ss in score_sets:
183-
enriched_experiment = enrich_experiment_with_num_score_sets(ss.experiment, user_data)
184-
response_item = score_set.ScoreSet.model_validate(ss).copy(update={"experiment": enriched_experiment})
185-
enriched_score_sets.append(response_item)
182+
if search.include_experiment_score_set_urns_and_count and updated_score_sets:
183+
for ss in score_sets:
184+
enriched_experiment = enrich_experiment_with_num_score_sets(ss.experiment, user_data)
185+
response_item = score_set.ScoreSet.model_validate(ss).copy(update={"experiment": enriched_experiment})
186+
enriched_score_sets.append(response_item)
187+
score_sets = enriched_score_sets
186188

187189
return {"score_sets": enriched_score_sets, "num_score_sets": num_score_sets}
188190

src/mavedb/server_main.py

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@
77
from fastapi.encoders import jsonable_encoder
88
from fastapi.exceptions import RequestValidationError
99
from fastapi.middleware.cors import CORSMiddleware
10+
from fastapi.middleware.gzip import GZipMiddleware
1011
from fastapi.openapi.utils import get_openapi
1112
from sqlalchemy.orm import configure_mappers
1213
from starlette import status
@@ -58,6 +59,7 @@
5859
taxonomies,
5960
users,
6061
variants,
62+
alphafold,
6163
)
6264

6365
logger = logging.getLogger(__name__)
@@ -82,6 +84,7 @@
8284
allow_methods=["*"],
8385
allow_headers=["*"],
8486
)
87+
app.add_middleware(GZipMiddleware, minimum_size=1000, compresslevel=5)
8588
app.include_router(access_keys.router)
8689
app.include_router(api_information.router)
8790
app.include_router(collections.router)
@@ -106,6 +109,7 @@
106109
app.include_router(taxonomies.router)
107110
app.include_router(users.router)
108111
app.include_router(variants.router)
112+
app.include_router(alphafold.router)
109113

110114

111115
@app.exception_handler(PermissionException)

src/mavedb/view_models/search.py

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -27,6 +27,7 @@ class ScoreSetsSearch(BaseModel):
2727
publication_identifiers: Optional[list[str]] = None
2828
keywords: Optional[list[str]] = None
2929
text: Optional[str] = None
30+
include_experiment_score_set_urns_and_count: Optional[bool] = True
3031
offset: Optional[int] = None
3132
limit: Optional[int] = None
3233

0 commit comments

Comments
 (0)