mirror of
https://github.com/sartography/cr-connect-workflow.git
synced 2025-02-23 05:08:32 +00:00
2. Added two api endpoints that will allow us to get all the logs for a specific workflow or study. 3. Assured that requests for logs are paginated, sortable, and can be limited to a specific code if needed. 4. Assure that we only use logging levels that match the log levels of Python.
125 lines
5.1 KiB
Python
125 lines
5.1 KiB
Python
from datetime import datetime
|
|
|
|
from flask import g
|
|
from sqlalchemy.exc import IntegrityError
|
|
|
|
from crc import session
|
|
from crc.api.common import ApiError, ApiErrorSchema
|
|
from crc.models.protocol_builder import ProtocolBuilderStatus
|
|
from crc.models.study import Study, StudyEvent, StudyEventType, StudyModel, StudySchema, StudyForUpdateSchema, \
|
|
StudyStatus, StudyAssociatedSchema
|
|
from crc.models.task_log import TaskLogModelSchema, TaskLogQuery, TaskLogQuerySchema
|
|
from crc.services.study_service import StudyService
|
|
from crc.services.task_logging_service import TaskLoggingService
|
|
from crc.services.user_service import UserService
|
|
from crc.services.workflow_service import WorkflowService
|
|
|
|
|
|
def add_study(body):
|
|
"""Or any study like object. Body should include a title, and primary_investigator_id """
|
|
if 'primary_investigator_id' not in body:
|
|
raise ApiError("missing_pi", "Can't create a new study without a Primary Investigator.")
|
|
if 'title' not in body:
|
|
raise ApiError("missing_title", "Can't create a new study without a title.")
|
|
|
|
study_model = StudyModel(user_uid=UserService.current_user().uid,
|
|
title=body['title'],
|
|
primary_investigator_id=body['primary_investigator_id'],
|
|
last_updated=datetime.utcnow(),
|
|
status=StudyStatus.in_progress)
|
|
session.add(study_model)
|
|
StudyService.add_study_update_event(study_model,
|
|
status=StudyStatus.in_progress,
|
|
event_type=StudyEventType.user,
|
|
user_uid=g.user.uid)
|
|
|
|
errors = StudyService._add_all_workflow_specs_to_study(study_model)
|
|
session.commit()
|
|
study = StudyService().get_study(study_model.id, do_status=True)
|
|
study_data = StudySchema().dump(study)
|
|
study_data["errors"] = ApiErrorSchema(many=True).dump(errors)
|
|
return study_data
|
|
|
|
|
|
def update_study(study_id, body):
|
|
"""Pretty limited, but allows manual modifications to the study status """
|
|
if study_id is None:
|
|
raise ApiError('unknown_study', 'Please provide a valid Study ID.')
|
|
|
|
study_model = session.query(StudyModel).filter_by(id=study_id).first()
|
|
if study_model is None:
|
|
raise ApiError('unknown_study', 'The study "' + study_id + '" is not recognized.')
|
|
|
|
study: Study = StudyForUpdateSchema().load(body)
|
|
|
|
status = StudyStatus(study.status)
|
|
study_model.last_updated = datetime.utcnow()
|
|
|
|
if study_model.status != status:
|
|
study_model.status = status
|
|
StudyService.add_study_update_event(study_model, status, StudyEventType.user,
|
|
user_uid=UserService.current_user().uid if UserService.has_user() else None,
|
|
comment='' if not hasattr(study, 'comment') else study.comment,
|
|
)
|
|
|
|
if status == StudyStatus.open_for_enrollment:
|
|
study_model.enrollment_date = study.enrollment_date
|
|
|
|
session.add(study_model)
|
|
session.commit()
|
|
|
|
if status == StudyStatus.abandoned or status == StudyStatus.hold:
|
|
WorkflowService.process_workflows_for_cancels(study_id)
|
|
|
|
# Need to reload the full study to return it to the frontend
|
|
study = StudyService.get_study(study_id)
|
|
return StudySchema().dump(study)
|
|
|
|
|
|
def get_study(study_id, update_status=False):
|
|
study = StudyService.get_study(study_id, do_status=update_status)
|
|
if (study is None):
|
|
raise ApiError("unknown_study", 'The study "' + study_id + '" is not recognized.', status_code=404)
|
|
return StudySchema().dump(study)
|
|
|
|
|
|
def get_study_associates(study_id):
|
|
return StudyAssociatedSchema(many=True).dump(StudyService.get_study_associates(study_id))
|
|
|
|
|
|
def get_logs_for_study(study_id, body):
|
|
task_log_query = TaskLogQuery(**body)
|
|
return TaskLogQuerySchema().dump(
|
|
TaskLoggingService.get_logs_for_study(study_id, task_log_query))
|
|
|
|
|
|
def delete_study(study_id):
|
|
try:
|
|
StudyService.delete_study(study_id)
|
|
except IntegrityError as ie:
|
|
session.rollback()
|
|
message = "Failed to delete Study #%i due to an Integrity Error: %s" % (study_id, str(ie))
|
|
raise ApiError(code="study_integrity_error", message=message)
|
|
|
|
|
|
def user_studies():
|
|
"""Returns all the studies associated with the current user. """
|
|
user = UserService.current_user(allow_admin_impersonate=True)
|
|
StudyService.synch_with_protocol_builder_if_enabled(user)
|
|
studies = StudyService().get_studies_for_user(user)
|
|
if len(studies) == 0:
|
|
studies = StudyService().get_studies_for_user(user, include_invalid=True)
|
|
if len(studies) > 0:
|
|
message = f"All studies associated with User: {user.uid} failed study validation"
|
|
raise ApiError(code="study_integrity_error", message=message)
|
|
|
|
results = StudySchema(many=True).dump(studies)
|
|
return results
|
|
|
|
|
|
def all_studies():
|
|
"""Returns all studies (regardless of user) with submitted files"""
|
|
studies = StudyService.get_all_studies_with_files()
|
|
results = StudySchema(many=True).dump(studies)
|
|
return results
|