Dan Funk 2699f5c65c Refactor the stats models, and assure they are very correct across all tests with the workflow api.
I noticed we were saving the workflow every time we loaded it up, rather than only when we were making changes to it.  Refactored this to be a little more careful.
Centralized the saving of the workflow into one location in the processor, so we can make sure we update all the details about that workflow every time we save.
The workflow service has a method that will log any task action taken in a consistent way.
The stats models were removed from the API completely.  Will wait for a use case for dealing with this later.
2020-05-04 10:57:09 -04:00

89 lines
2.9 KiB
Python

from typing import List
from connexion import NoContent
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, ProtocolBuilderStudy
from crc.models.study import StudySchema, StudyModel, Study
from crc.services.protocol_builder import ProtocolBuilderService
from crc.services.study_service import StudyService
def add_study(body):
"""This should never get called, and is subject to deprication. Studies
should be added through the protocol builder only."""
study: Study = StudySchema().load(body)
study_model = StudyModel(**study.model_args())
session.add(study_model)
errors = StudyService._add_all_workflow_specs_to_study(study)
session.commit()
study_data = StudySchema().dump(study)
study_data["errors"] = ApiErrorSchema(many=True).dump(errors)
return study_data
def update_study(study_id, body):
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 = StudySchema().load(body)
study.update_model(study_model)
session.add(study_model)
session.commit()
return StudySchema().dump(study)
def get_study(study_id):
study_service = StudyService()
study = study_service.get_study(study_id)
if(study is None):
raise ApiError("Study not found", status_code=404)
schema = StudySchema()
return schema.dump(study)
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 all_studies():
"""Returns all the studies associated with the current user. Assures we are
in sync with values read in from the protocol builder. """
StudyService.synch_all_studies_with_protocol_builder(g.user)
studies = StudyService.get_studies_for_user(g.user)
results = StudySchema(many=True).dump(studies)
return results
def post_update_study_from_protocol_builder(study_id):
"""Update a single study based on data received from
the protocol builder."""
db_study = session.query(StudyModel).filter_by(study_id=study_id).all()
pb_studies: List[ProtocolBuilderStudy] = ProtocolBuilderService.get_studies(g.user.uid)
pb_study = next((pbs for pbs in pb_studies if pbs.STUDYID == study_id), None)
if pb_study:
db_study.update_from_protocol_builder(pb_study)
else:
db_study.inactive = True
db_study.protocol_builder_status = ProtocolBuilderStatus.ABANDONED
return NoContent, 304