Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Feature/devsu 2349 add async report loading #4

Merged
merged 11 commits into from
Jul 9, 2024
60 changes: 57 additions & 3 deletions pori_python/ipr/connection.py
Original file line number Diff line number Diff line change
Expand Up @@ -4,8 +4,9 @@
import os
import zlib
from typing import Dict, List

import time
from .constants import DEFAULT_URL
from .util import logger

IMAGE_MAX = 20 # cannot upload more than 20 images at a time

Expand Down Expand Up @@ -62,8 +63,61 @@ def post(self, uri: str, data: Dict = {}, **kwargs) -> Dict:
**kwargs,
)

def upload_report(self, content: Dict) -> Dict:
return self.post('reports', content)
def get(self, uri: str, data: Dict = {}, **kwargs) -> Dict:
"""Convenience method for making get requests"""
return self.request(
uri,
method='GET',
data=zlib.compress(json.dumps(data, allow_nan=False).encode('utf-8')),
**kwargs,
)

def upload_report(
self, content: Dict, mins_to_wait: int = 5, async_upload: bool = False
) -> Dict:
if async_upload:
initial_result = self.post('reports-async', content)
report_id = initial_result["ident"]

def check_status(interval: int = 5, num_attempts: int = 5):
for i in range(num_attempts):
logger.info(f'checking report loading status in {interval} seconds')
time.sleep(interval)
current_status = self.get(f'reports-async/{report_id}')
if current_status['state'] not in [
'active',
'ready',
'waiting',
'completed',
'failed',
]:
raise Exception(
f'async report upload in unexpected state: {current_status}'
)
if current_status['state'] == 'failed':
raise Exception(
f'report upload failed with reason: {current_status["failedReason"]}'
)
if current_status['state'] in ['ready', 'completed']:
return current_status
return current_status

current_status = check_status()

if current_status['state'] in ['active', 'waiting']:
current_status = check_status(interval=30)

if current_status['state'] in ['active', 'waiting']:
current_status = check_status(interval=60, num_attempts=mins_to_wait)

if current_status['state'] in ['active', 'waiting']:
raise Exception(
f'async report upload taking longer than expected: {current_status}'
)

return current_status
else:
return self.post('reports', content)

def set_analyst_comments(self, report_id: str, data: Dict) -> Dict:
"""
Expand Down
6 changes: 5 additions & 1 deletion pori_python/ipr/main.py
Original file line number Diff line number Diff line change
Expand Up @@ -216,6 +216,8 @@ def ipr_report(
generate_comments: bool = True,
match_germline: bool = False,
custom_kb_match_filter=None,
async_upload: bool = False,
mins_to_wait: int = 5,
) -> Dict:
"""Run the matching and create the report JSON for upload to IPR.

Expand All @@ -234,6 +236,8 @@ def ipr_report(
generate_comments: create the analyst comments section for upload with the report
match_germline: match only germline statements to germline events and non-germline statements to non-germline events.
custom_kb_match_filter: function(List[kbMatch]) -> List[kbMatch]
async_upload: use report_async endpoint to upload reports
mins_to_wait: if using report_async, number of minutes to wait for success before exception raised

Returns:
ipr_conn.upload_report return dictionary
Expand Down Expand Up @@ -444,7 +448,7 @@ def ipr_report(
if ipr_upload:
try:
logger.info(f'Uploading to IPR {ipr_conn.url}')
ipr_result = ipr_conn.upload_report(output)
ipr_result = ipr_conn.upload_report(output, async_upload, mins_to_wait)
logger.info(ipr_result)
output.update(ipr_result)
except Exception as err:
Expand Down
Loading