Skip to content

Commit

Permalink
Use FastAPI BackgroundTasks to improve the responsiveness of the `POS…
Browse files Browse the repository at this point in the history
…T /results/` endpoint
  • Loading branch information
apdavison committed Oct 17, 2024
1 parent d521ce4 commit ad21e19
Show file tree
Hide file tree
Showing 2 changed files with 33 additions and 13 deletions.
43 changes: 30 additions & 13 deletions validation_service_api/validation_service/resources/results.py
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
from uuid import UUID
from uuid import UUID, uuid4
from enum import Enum
from typing import List
from datetime import datetime
Expand All @@ -15,7 +15,7 @@
import fairgraph.openminds.core as omcore
import fairgraph.openminds.computation as omcmp

from fastapi import APIRouter, Depends, Header, Query, HTTPException, status
from fastapi import APIRouter, Depends, Header, Query, HTTPException, status, BackgroundTasks
from fastapi.security import HTTPBearer, HTTPAuthorizationCredentials
from pydantic import ValidationError

Expand Down Expand Up @@ -271,25 +271,42 @@ def query_results_summary(
"VF_ValidationResultSummary", from_index, size, user)


def _save_result(validation_activity, kg_client):
# todo: move this function to db module
activity_log = None
logger.warning(f"Saving outputs ({datetime.now().isoformat()})")
for output in as_list(validation_activity.outputs):
logger.warning(f" - {output.iri} ({datetime.now().isoformat()})")
output.save(kg_client, recursive=False, activity_log=activity_log, space=validation_activity.space)
logger.warning(f"Saving custom_property_sets.data_location ({datetime.now().isoformat()})")
if validation_activity.custom_property_sets:
validation_activity.custom_property_sets.data_location.save(
kg_client, recursive=True, activity_log=activity_log, space=validation_activity.space
)
logger.warning(f"Saving ModelValidation object ({datetime.now().isoformat()})")
validation_activity.save(kg_client, recursive=False, activity_log=activity_log, space=validation_activity.space)
logger.warning(f"Background task complete: results saved for model validation {validation_activity.uuid}")



@router.post("/results/", response_model=ValidationResult, status_code=status.HTTP_201_CREATED)
def create_result(result: ValidationResult, token: HTTPAuthorizationCredentials = Depends(auth)):
async def create_result(
result: ValidationResult,
background_tasks: BackgroundTasks,
token: HTTPAuthorizationCredentials = Depends(auth)
):
_check_service_status()
logger.warning(f"Beginning post result ({datetime.now().isoformat()})")
user = User(token, allow_anonymous=False)
kg_client = get_kg_client_for_user_account(token)

validation_activity = result.to_kg_objects(kg_client)
space = space_from_project_id(result.project_id)
activity_log = None
# we set our own ID, since we need to return this before the save operation completes
validation_activity.id = kg_client.uri_from_uuid(uuid4())
validation_activity._space = space_from_project_id(result.project_id)

background_tasks.add_task(_save_result, validation_activity, kg_client)

logger.warning(f"Saving outputs ({datetime.now().isoformat()})")
for output in as_list(validation_activity.outputs):
output.save(kg_client, recursive=False, activity_log=activity_log, space=space)
logger.warning(f"Saving custom_property_sets.data_location ({datetime.now().isoformat()})")
if validation_activity.custom_property_sets:
validation_activity.custom_property_sets.data_location.save(kg_client, recursive=True, activity_log=activity_log, space=space)
logger.warning(f"Saving ModelValidation object ({datetime.now().isoformat()})")
validation_activity.save(kg_client, recursive=False, activity_log=activity_log, space=space)
logger.warning(f"Returning validation result ({datetime.now().isoformat()})")
return ValidationResult.from_kg_object(validation_activity, kg_client)

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@
from datetime import datetime
from urllib.parse import urlparse
import logging
from time import sleep

from fastapi import status

Expand Down Expand Up @@ -262,6 +263,8 @@ def test_create_and_delete_validation_result(caplog):
posted_result = response.json()
check_validation_result(posted_result)

sleep(30)

# retrieve result
response = client.get(f"/results/{posted_result['id']}", headers=AUTH_HEADER)
assert response.status_code == 200
Expand Down

0 comments on commit ad21e19

Please sign in to comment.