From c85b2ffa41f2735d77eb2b525d50775bb38d6631 Mon Sep 17 00:00:00 2001 From: Max Wang Date: Thu, 17 Jul 2025 10:59:53 -0400 Subject: [PATCH 1/5] Change from gzip to zstandard --- app/server.py | 6 +++--- requirements-lock.txt | 1 + requirements.txt | 3 ++- 3 files changed, 6 insertions(+), 4 deletions(-) diff --git a/app/server.py b/app/server.py index 5a16ad3..e12a03d 100644 --- a/app/server.py +++ b/app/server.py @@ -1,10 +1,10 @@ -import gzip import json import logging import os import redis import traceback import warnings +import zstandard from fastapi import HTTPException, status, Request from fastapi.responses import JSONResponse, Response @@ -158,7 +158,7 @@ async def sync_get_appraisal(request: Request): if request.headers.get("content-encoding") == "gzip": try: raw_body = await request.body() - query = json.loads(gzip.decompress(raw_body)) + query = json.loads(zstandard.decompress(raw_body)) compressed = True except Exception: return Response("Invalid request. Failed to decompress and ingest.", 400) @@ -180,7 +180,7 @@ async def sync_get_appraisal(request: Request): except Exception: logger.error(f"Something went wrong while appraising: {traceback.format_exc()}") if compressed: - query = gzip.compress(json.dumps(query).encode()) + query = zstandard.compress(json.dumps(query).encode()) else: query = json.dumps(query) logger.info("Done appraising") diff --git a/requirements-lock.txt b/requirements-lock.txt index 252cd45..76f603e 100644 --- a/requirements-lock.txt +++ b/requirements-lock.txt @@ -50,3 +50,4 @@ uvicorn==0.31.0 wheel==0.43.0 wrapt==1.16.0 zipp==3.20.2 +zstandard==0.23.0 diff --git a/requirements.txt b/requirements.txt index 713544d..dee8e81 100644 --- a/requirements.txt +++ b/requirements.txt @@ -13,4 +13,5 @@ redis scipy scikit-learn tqdm -uvicorn \ No newline at end of file +uvicorn +zstandard \ No newline at end of file From c159259df9073dabac29a85f49bda3aaf26023eb Mon Sep 17 00:00:00 2001 From: Max Wang Date: Thu, 17 Jul 2025 13:07:05 -0400 Subject: [PATCH 2/5] Add a test --- app/server.py | 2 +- tests/test_server.py | 28 ++++++++++++++++++++++++++++ 2 files changed, 29 insertions(+), 1 deletion(-) diff --git a/app/server.py b/app/server.py index e12a03d..7d52931 100644 --- a/app/server.py +++ b/app/server.py @@ -155,7 +155,7 @@ async def sync_get_appraisal(request: Request): logger = get_logger(qid, "INFO") logger.info("Starting sync appraisal") compressed = False - if request.headers.get("content-encoding") == "gzip": + if request.headers.get("content-encoding") == "zstd": try: raw_body = await request.body() query = json.loads(zstandard.decompress(raw_body)) diff --git a/tests/test_server.py b/tests/test_server.py index 783ce30..c5e87e8 100644 --- a/tests/test_server.py +++ b/tests/test_server.py @@ -1,3 +1,6 @@ +import json +import zstandard + from fastapi.testclient import TestClient from app.server import APP @@ -12,3 +15,28 @@ def test_sync_get_appraisal_400(): json={"message": {}}, ) assert response.status_code == 400 + + +def test_zstd_compression(): + """Test that server decompressed zstandard payloads.""" + message = { + "message": { + "query_graph": {}, + "knowledge_graph": {}, + "results": [], + } + } + payload = zstandard.compress(json.dumps(message).encode()) + response = testclient.post( + "/get_appraisal", + headers={ + "Content-Encoding": "zstd", + "Content-Type": "application/json", + }, + data=payload, + ) + + assert response.status_code == 400 + err = response.json() + # we were able to parse the zipped payload and found no results + assert err["description"] == "No Results." From f7e3df7b79549e008b50b5ce10d0f69589e6aa02 Mon Sep 17 00:00:00 2001 From: Max Wang Date: Thu, 17 Jul 2025 13:10:45 -0400 Subject: [PATCH 3/5] Bump reasoner_pydantic version to TRAPI 1.6 --- requirements-lock.txt | 2 +- requirements.txt | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/requirements-lock.txt b/requirements-lock.txt index 76f603e..5831e07 100644 --- a/requirements-lock.txt +++ b/requirements-lock.txt @@ -33,7 +33,7 @@ pydantic==1.10.18 python-dateutil==2.9.0.post0 pytz==2024.2 rdkit==2024.3.5 -reasoner-pydantic==5.0.6 +reasoner-pydantic==5.1.1 redis==5.1.1 scikit-learn==1.5.2 scipy==1.14.1 diff --git a/requirements.txt b/requirements.txt index dee8e81..4fc1d6e 100644 --- a/requirements.txt +++ b/requirements.txt @@ -8,7 +8,7 @@ opentelemetry-exporter-jaeger opentelemetry-instrumentation-httpx pandas rdkit -reasoner-pydantic +reasoner-pydantic==5.1.1 redis scipy scikit-learn From 33c63e3e28ee6d869e456eada74959fbe665a6ed Mon Sep 17 00:00:00 2001 From: Max Wang Date: Thu, 17 Jul 2025 13:19:33 -0400 Subject: [PATCH 4/5] Bump version and trapi version --- app/server.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/app/server.py b/app/server.py index 7d52931..656f23f 100644 --- a/app/server.py +++ b/app/server.py @@ -22,10 +22,10 @@ openapi_args = dict( title="SRI Answer Appraiser", - version="0.7.0", + version="0.8.0", terms_of_service="", description="SRI service that provides metrics for scoring and ordering of results", - trapi="1.5.0", + trapi="1.6.0", biolink_version="4.2.0", contact={ "name": "Max Wang", From 29a71d9ed401f790b4837190ac59265ffa94b1e3 Mon Sep 17 00:00:00 2001 From: Max Wang Date: Thu, 17 Jul 2025 13:43:24 -0400 Subject: [PATCH 5/5] Remove reasoner_pydantic from requirements files --- requirements-lock.txt | 1 - requirements.txt | 1 - 2 files changed, 2 deletions(-) diff --git a/requirements-lock.txt b/requirements-lock.txt index 5831e07..da57046 100644 --- a/requirements-lock.txt +++ b/requirements-lock.txt @@ -33,7 +33,6 @@ pydantic==1.10.18 python-dateutil==2.9.0.post0 pytz==2024.2 rdkit==2024.3.5 -reasoner-pydantic==5.1.1 redis==5.1.1 scikit-learn==1.5.2 scipy==1.14.1 diff --git a/requirements.txt b/requirements.txt index 4fc1d6e..508a031 100644 --- a/requirements.txt +++ b/requirements.txt @@ -8,7 +8,6 @@ opentelemetry-exporter-jaeger opentelemetry-instrumentation-httpx pandas rdkit -reasoner-pydantic==5.1.1 redis scipy scikit-learn