Ejemplo n.º 1
0
class InvestigatorListAPI(CRUDView):
    """
    Investigator API
    """
    endpoint = 'investigators_list'
    rule = '/investigators'
    schemas = {'Investigator': InvestigatorSchema}

    @paginated
    @use_args(filter_schema_factory(InvestigatorSchema), locations=('query', ))
    def get(self, filter_params, after, limit):
        """
        Get a paginated investigators
        ---
        template:
          path:
            get_list.yml
          properties:
            resource:
              Investigator
        """
        # Get study id and remove from model filter params
        study_id = filter_params.pop('study_id', None)

        q = (Investigator.query.filter_by(**filter_params))

        # Filter by study
        from dataservice.api.study.models import Study
        if study_id:
            q = (q.join(Investigator.studies).filter(Study.kf_id == study_id))

        return (InvestigatorSchema(many=True).jsonify(
            Pagination(q, after, limit)))

    def post(self):
        """
        Create a new investigator
        ---
        template:
          path:
            new_resource.yml
          properties:
            resource:
              Investigator
        """
        body = request.get_json(force=True)
        try:
            inv = InvestigatorSchema(strict=True).load(body).data
        except ValidationError as err:
            abort(400,
                  'could not create investigator: {}'.format(err.messages))

        db.session.add(inv)
        db.session.commit()
        return InvestigatorSchema(201, 'investigator {} created'.format(
            inv.kf_id)).jsonify(inv), 201
Ejemplo n.º 2
0
class FamilyListAPI(CRUDView):
    """
    Family API
    """
    endpoint = 'families_list'
    rule = '/families'
    schemas = {'Family': FamilySchema}

    @paginated
    @use_args(filter_schema_factory(FamilySchema), locations=('query', ))
    def get(self, filter_params, after, limit):
        """
        Get a paginated familys
        ---
        template:
          path:
            get_list.yml
          properties:
            resource:
              Family
        """
        # Get study id and remove from model filter params
        study_id = filter_params.pop('study_id', None)

        q = (Family.query.filter_by(**filter_params))

        # Filter by study
        from dataservice.api.participant.models import Participant
        if study_id:
            q = (q.join(Family.participants).filter(
                Participant.study_id == study_id).group_by(Family.kf_id))

        return (FamilySchema(many=True).jsonify(Pagination(q, after, limit)))

    def post(self):
        """
        Create a new family
        ---
        template:
          path:
            new_resource.yml
          properties:
            resource:
              Family
        """
        body = request.get_json(force=True)
        try:
            fam = FamilySchema(strict=True).load(body).data
        except ValidationError as err:
            abort(400, 'could not create family: {}'.format(err.messages))

        db.session.add(fam)
        db.session.commit()
        return FamilySchema(201, 'family {} created'.format(
            fam.kf_id)).jsonify(fam), 201
Ejemplo n.º 3
0
class StudyListAPI(CRUDView):
    """
    Study API
    """
    endpoint = 'studies_list'
    rule = '/studies'
    schemas = {'Study': StudySchema}

    @paginated
    @use_args(filter_schema_factory(StudySchema),
              locations=('query',))
    def get(self, filter_params, after, limit):
        """
        Get a paginated studies
        ---
        template:
          path:
            get_list.yml
          properties:
            resource:
              Study
        """
        filter_params.pop('study_id', None)

        q = (Study.query
             .filter_by(**filter_params))

        return (StudySchema(many=True)
                .jsonify(Pagination(q, after, limit)))

    def post(self):
        """
        Create a new study
        ---
        template:
          path:
            new_resource.yml
          properties:
            resource:
              Study
        """
        body = request.get_json(force=True)
        try:
            st = StudySchema(strict=True).load(body).data
        except ValidationError as err:
            abort(400, 'could not create study: {}'.format(err.messages))

        db.session.add(st)
        db.session.commit()
        return StudySchema(
            201, 'study {} created'.format(st.kf_id)
        ).jsonify(st), 201
Ejemplo n.º 4
0
class ParticipantListAPI(CRUDView):
    """
    Participant API
    """
    endpoint = 'participants_list'
    rule = '/participants'
    schemas = {'Participant': ParticipantSchema}

    @paginated
    @use_args(filter_schema_factory(ParticipantSchema), locations=('query', ))
    def get(self, filter_params, after, limit):
        """
        Get a paginated participants
        ---
        template:
          path:
            get_list.yml
          properties:
            resource:
              Participant
        """
        # Apply entity filter params
        q = (Participant.query.filter_by(**filter_params))

        return (ParticipantSchema(many=True).jsonify(
            Pagination(q, after, limit)))

    def post(self):
        """
        Create a new participant
        ---
        template:
          path:
            new_resource.yml
          properties:
            resource:
              Participant
        """
        body = request.get_json(force=True)
        try:
            p = ParticipantSchema(strict=True).load(body).data
        except ValidationError as err:
            abort(400, 'could not create participant: {}'.format(err.messages))

        db.session.add(p)
        db.session.commit()
        return ParticipantSchema(201, 'participant {} created'.format(
            p.kf_id)).jsonify(p), 201
Ejemplo n.º 5
0
class GenomicFileListAPI(CRUDView):
    """
    GenomicFile API
    """
    endpoint = 'genomic_files_list'
    rule = '/genomic-files'
    schemas = {'GenomicFile': GenomicFileSchema}

    @paginated
    @use_args(filter_schema_factory(GenomicFileFilterSchema),
              locations=('query', ))
    def get(self, filter_params, after, limit):
        """
        Get paginated genomic_files

        Retrieves the genomic files stored in the datamodel, then fetch
        additional properties that are stored in indexd under the same uuid.
        ---
        template:
          path:
            get_list.yml
          properties:
            resource:
              GenomicFile
        """
        # Remove non-genomic_file attributes from genomic_file filter params
        study_id = filter_params.pop('study_id', None)
        sequencing_experiment_id = filter_params.pop(
            'sequencing_experiment_id', None)
        read_group_id = filter_params.pop('read_group_id', None)
        biospecimen_id = filter_params.pop('biospecimen_id', None)

        # Apply model filter params
        q = (GenomicFile.query.filter_by(**filter_params))

        # Filter by study
        from dataservice.api.participant.models import Participant
        from dataservice.api.biospecimen.models import Biospecimen
        from dataservice.api.biospecimen_genomic_file.models import (
            BiospecimenGenomicFile)
        if study_id:
            q = (q.join(GenomicFile.biospecimen_genomic_files).join(
                BiospecimenGenomicFile.biospecimen).join(
                    Biospecimen.participant).filter(
                        Participant.study_id == study_id).group_by(
                            GenomicFile.kf_id))

        from dataservice.api.read_group.models import ReadGroupGenomicFile
        from dataservice.api.sequencing_experiment.models import (
            SequencingExperimentGenomicFile)

        if sequencing_experiment_id:
            q = (q.join(SequencingExperimentGenomicFile).filter(
                SequencingExperimentGenomicFile.sequencing_experiment_id ==
                sequencing_experiment_id))
        if read_group_id:
            q = (q.join(ReadGroupGenomicFile).filter(
                ReadGroupGenomicFile.read_group_id == read_group_id))
        if biospecimen_id and not study_id:
            q = (q.join(BiospecimenGenomicFile).filter(
                BiospecimenGenomicFile.biospecimen_id == biospecimen_id))
        # This check is to remove duplicate join on biospecimen genomic file
        if biospecimen_id and study_id:
            q = (q.filter(
                BiospecimenGenomicFile.biospecimen_id == biospecimen_id))
        pager = indexd_pagination(q, after, limit)

        return (GenomicFileSchema(many=True).jsonify(pager))

    def post(self):
        """
        Create a new genomic_file
        ---
        template:
          path:
            new_resource.yml
          properties:
            resource:
              GenomicFile
        """
        body = request.get_json(force=True)
        try:
            gf = GenomicFileSchema(strict=True).load(body).data
        except ValidationError as err:
            abort(400,
                  'could not create genomic_file: {}'.format(err.messages))

        db.session.add(gf)
        db.session.commit()

        return GenomicFileSchema(201, 'genomic_file {} created'.format(
            gf.kf_id)).jsonify(gf), 201
Ejemplo n.º 6
0
class BiospecimenGenomicFileListAPI(CRUDView):
    """
    BiospecimenGenomicFile List API
    """
    endpoint = 'biospecimen_genomic_files_list'
    rule = '/biospecimen-genomic-files'
    schemas = {'BiospecimenGenomicFile': BiospecimenGenomicFileSchema}

    @paginated
    @use_args(filter_schema_factory(BiospecimenGenomicFileSchema),
              locations=('query', ))
    def get(self, filter_params, after, limit):
        """
        Get a paginated biospecimen_genomic_files
        ---
        template:
          path:
            get_list.yml
          properties:
            resource:
              BiospecimenGenomicFile
        """
        # Get study id and remove from model filter params
        study_id = filter_params.pop('study_id', None)

        q = BiospecimenGenomicFile.query.filter_by(**filter_params)

        # Filter by study
        from dataservice.api.participant.models import Participant
        from dataservice.api.biospecimen.models import Biospecimen

        if study_id:
            q = (q.join(BiospecimenGenomicFile.biospecimen).join(
                Biospecimen.participant).filter(
                    Participant.study_id == study_id))

        return (BiospecimenGenomicFileSchema(many=True).jsonify(
            Pagination(q, after, limit)))

    def post(self):
        """
        Create a new biospecimen_genomic_file
        ---
        template:
          path:
            new_resource.yml
          properties:
            resource:
              BiospecimenGenomicFile
        """
        body = request.get_json(force=True)
        try:
            bs_gf = (BiospecimenGenomicFileSchema(strict=True).load(body).data)
        except ValidationError as err:
            abort(
                400, 'could not create biospecimen_genomic_file: {}'.format(
                    err.messages))

        db.session.add(bs_gf)
        db.session.commit()
        return BiospecimenGenomicFileSchema(
            201, 'biospecimen_genomic_file {} created'.format(
                bs_gf.kf_id)).jsonify(bs_gf), 201
Ejemplo n.º 7
0
class OutcomeListAPI(CRUDView):
    """
    Outcome REST API
    """
    endpoint = 'outcomes_list'
    rule = '/outcomes'
    schemas = {'Outcome': OutcomeSchema}

    @paginated
    @use_args(filter_schema_factory(OutcomeSchema), locations=('query', ))
    def get(self, filter_params, after, limit):
        """
        Get all outcomes
        ---
        description: Get all outcomes
        template:
          path:
            get_list.yml
          properties:
            resource:
              Outcome
        """
        # Get study id and remove from model filter params
        study_id = filter_params.pop('study_id', None)

        q = Outcome.query.filter_by(**filter_params)

        # Filter by study
        from dataservice.api.participant.models import Participant
        if study_id:
            q = (q.join(
                Participant.outcomes).filter(Participant.study_id == study_id))

        return (OutcomeSchema(many=True).jsonify(Pagination(q, after, limit)))

    def post(self):
        """
        Create a new outcome
        ---
        template:
          path:
            new_resource.yml
          properties:
            resource:
              Outcome
        """

        body = request.get_json(force=True)

        # Deserialize
        try:
            o = OutcomeSchema(strict=True).load(body).data
        # Request body not valid
        except ValidationError as e:
            abort(400, 'could not create outcome: {}'.format(e.messages))

        # Add to and save in database
        db.session.add(o)
        db.session.commit()

        return OutcomeSchema(201, 'outcome {} created'.format(
            o.kf_id)).jsonify(o), 201
Ejemplo n.º 8
0
class SequencingCenterListAPI(CRUDView):
    """
    SequencingCenter REST API
    """
    endpoint = 'sequencing_centers_list'
    rule = '/sequencing-centers'
    schemas = {'SequencingCenter': SequencingCenterSchema}

    @paginated
    @use_args(filter_schema_factory(SequencingCenterSchema),
              locations=('query', ))
    def get(self, filter_params, after, limit):
        """
        Get all sequencing_centers
        ---
        description: Get all sequencing_centers
        template:
          path:
            get_list.yml
          properties:
            resource:
              SequencingCenter
        """
        # Get study id and remove from model filter params
        study_id = filter_params.pop('study_id', None)

        q = (SequencingCenter.query.filter_by(**filter_params))
        # Filter by study
        from dataservice.api.participant.models import Participant
        from dataservice.api.biospecimen.models import Biospecimen
        if study_id:
            q = (q.join(SequencingCenter.biospecimens).join(
                Biospecimen.participant).filter(
                    Participant.study_id == study_id))

        return (SequencingCenterSchema(many=True).jsonify(
            Pagination(q, after, limit)))

    def post(self):
        """
        Create a new sequencing_center
        ---
        template:
          path:
            new_resource.yml
          properties:
            resource:
              SequencingCenter
        """

        body = request.get_json(force=True)

        # Deserialize
        try:
            se = SequencingCenterSchema(strict=True).load(body).data
        # Request body not valid
        except ValidationError as e:
            abort(400,
                  'could not create sequencing_center: {}'.format(e.messages))

        # Add to and save in database
        db.session.add(se)
        db.session.commit()

        return SequencingCenterSchema(
            201,
            'sequencing_center {} created'.format(se.kf_id)).jsonify(se), 201
Ejemplo n.º 9
0
class TaskListAPI(CRUDView):
    """
    Task List API
    """
    endpoint = 'tasks_list'
    rule = '/tasks'
    schemas = {'Task': TaskSchema}

    @paginated
    @use_args(filter_schema_factory(TaskSchema), locations=('query', ))
    def get(self, filter_params, after, limit):
        """
        Get a paginated tasks
        ---
        template:
          path:
            get_list.yml
          properties:
            resource:
              Task
        """
        # Get study id and remove from model filter params
        study_id = filter_params.pop('study_id', None)

        q = (Task.query.filter_by(**filter_params))

        # Filter by study
        from dataservice.api.participant.models import Participant
        from dataservice.api.biospecimen.models import Biospecimen
        from dataservice.api.genomic_file.models import GenomicFile
        from dataservice.api.task.models import (TaskGenomicFile)
        from dataservice.api.biospecimen_genomic_file.models import (
            BiospecimenGenomicFile)

        if study_id:
            q = (q.join(Task.task_genomic_files).join(
                TaskGenomicFile.genomic_file).join(
                    GenomicFile.biospecimen_genomic_files).join(
                        BiospecimenGenomicFile.biospecimen).join(
                            Biospecimen.participant).filter(
                                Participant.study_id == study_id).group_by(
                                    Task.kf_id))

        return (TaskSchema(many=True).jsonify(Pagination(q, after, limit)))

    def post(self):
        """
        Create a new task
        ---
        template:
          path:
            new_resource.yml
          properties:
            resource:
              Task
        """
        body = request.get_json(force=True)
        try:
            app = TaskSchema(strict=True).load(body).data
        except ValidationError as err:
            abort(400, 'could not create task: {}'.format(err.messages))

        db.session.add(app)
        db.session.commit()
        return TaskSchema(201, 'task {} created'.format(
            app.kf_id)).jsonify(app), 201
Ejemplo n.º 10
0
class DiagnosisListAPI(CRUDView):
    """
    Diagnosis REST API
    """
    endpoint = 'diagnoses_list'
    rule = '/diagnoses'
    schemas = {'Diagnosis': DiagnosisSchema}

    @paginated
    @use_args(filter_schema_factory(DiagnosisFilterSchema),
              locations=('query',))
    def get(self, filter_params, after, limit):
        """
        Get all diagnoses
        ---
        description: Get all diagnoses
        template:
          path:
            get_list.yml
          properties:
            resource:
              Diagnosis
        """
        # Get study id and remove from model filter params
        study_id = filter_params.pop('study_id', None)

        # Get biospecimen_id and remove from model filter params
        biospecimen_id = filter_params.pop('biospecimen_id', None)

        # Apply entity filter params
        q = Diagnosis.query.filter_by(**filter_params)

        # Apply study_id filter and biospecimen_id filter
        from dataservice.api.participant.models import Participant
        from dataservice.api.biospecimen.models import BiospecimenDiagnosis

        if study_id:
            q = (q.join(Participant.diagnoses)
                 .filter(Participant.study_id == study_id))

        if biospecimen_id:
            q = (q.join(BiospecimenDiagnosis)
                 .filter(
                 BiospecimenDiagnosis.biospecimen_id == biospecimen_id))

        return (DiagnosisSchema(many=True)
                .jsonify(Pagination(q, after, limit)))

    def post(self):
        """
        Create a new diagnosis
        ---
        template:
          path:
            new_resource.yml
          properties:
            resource:
              Diagnosis
        """

        body = request.get_json(force=True)

        # Deserialize
        try:
            d = DiagnosisSchema(strict=True).load(body).data
        # Request body not valid
        except ValidationError as e:
            abort(400, 'could not create diagnosis: {}'.format(e.messages))

        # Add to and save in database
        db.session.add(d)
        db.session.commit()

        return DiagnosisSchema(201, 'diagnosis {} created'
                               .format(d.kf_id)).jsonify(d), 201
Ejemplo n.º 11
0
class BiospecimenListAPI(CRUDView):
    """
    Biospecimen REST API
    """
    endpoint = 'biospecimens_list'
    rule = '/biospecimens'
    schemas = {'Biospecimen': BiospecimenSchema}

    @paginated
    @use_args(filter_schema_factory(BiospecimenFilterSchema),
              locations=('query', ))
    def get(self, filter_params, after, limit):
        """
        Get all biospecimens
        ---
        description: Get all biospecimens
        template:
          path:
            get_list.yml
          properties:
            resource:
              Biospecimen
        """
        # Get and remove special filter params that are not attributes of model
        study_id = filter_params.pop('study_id', None)
        diagnosis_id = filter_params.pop('diagnosis_id', None)
        genomic_file_id = filter_params.pop('genomic_file_id', None)

        # Get and remove any list type filter params that need to be
        # handled differently than others
        duo_ids = filter_params.pop('duo_ids', None)

        # Apply filter params
        q = (Biospecimen.query.filter_by(**filter_params))

        # Apply duo_ids filter
        # Get specimens whose duo ids list includes all values in duo_ids
        if duo_ids:
            duo_ids = [id_.strip() for id_ in duo_ids[0].split(',')]
            q = q.filter(Biospecimen.duo_ids.contains(duo_ids))

        # Apply study_id filter and diagnosis_id filter
        from dataservice.api.participant.models import Participant

        if study_id:
            q = (q.join(Participant.biospecimens).filter(
                Participant.study_id == study_id))
        if diagnosis_id:
            q = (q.join(BiospecimenDiagnosis).filter(
                BiospecimenDiagnosis.diagnosis_id == diagnosis_id))
        if genomic_file_id:
            q = (q.join(BiospecimenGenomicFile).filter(
                BiospecimenGenomicFile.genomic_file_id == genomic_file_id))

        return (BiospecimenSchema(many=True).jsonify(
            Pagination(q, after, limit)))

    def post(self):
        """
        Create a new biospecimen
        ---
        template:
          path:
            new_resource.yml
          properties:
            resource:
              Biospecimen
        """

        body = request.get_json(force=True)

        # Deserialize
        try:
            s = BiospecimenSchema(strict=True).load(body).data
        # Request body not valid
        except ValidationError as e:
            abort(400, 'could not create biospecimen: {}'.format(e.messages))

        # Add to and save in database
        db.session.add(s)
        db.session.commit()

        return BiospecimenSchema(201, 'biospecimen {} created'.format(
            s.kf_id)).jsonify(s), 201
Ejemplo n.º 12
0
class ReadGroupListAPI(CRUDView):
    """
    ReadGroup REST API
    """
    endpoint = 'read_groups_list'
    rule = '/read-groups'
    schemas = {'ReadGroup': ReadGroupSchema}

    @paginated
    @use_args(filter_schema_factory(ReadGroupFilterSchema),
              locations=('query', ))
    def get(self, filter_params, after, limit):
        """
        Get all read_groups
        ---
        description: Get all read_groups
        template:
          path:
            get_list.yml
          properties:
            resource:
              ReadGroup
        """
        # Get study id and remove from model filter params
        study_id = filter_params.pop('study_id', None)

        # Get genomic file id and remove from model filter params
        genomic_file_id = filter_params.pop('genomic_file_id', None)

        # Apply model filter params
        q = ReadGroup.query.filter_by(**filter_params)

        # Filter by study
        from dataservice.api.participant.models import Participant
        from dataservice.api.biospecimen.models import Biospecimen
        from dataservice.api.genomic_file.models import GenomicFile
        from dataservice.api.biospecimen_genomic_file.models import (
            BiospecimenGenomicFile)
        if study_id:
            q = (q.join(ReadGroup.read_group_genomic_files).join(
                ReadGroupGenomicFile.genomic_file).join(
                    GenomicFile.biospecimen_genomic_files).join(
                        BiospecimenGenomicFile.biospecimen).join(
                            Biospecimen.participant).filter(
                                Participant.study_id == study_id).group_by(
                                    ReadGroup.kf_id))

        # Filter by genomic_file_id
        if genomic_file_id:
            q = (q.join(
                ReadGroupGenomicFile,
                ReadGroup.kf_id == ReadGroupGenomicFile.read_group_id).filter(
                    ReadGroupGenomicFile.genomic_file_id == genomic_file_id))

        return (ReadGroupSchema(many=True).jsonify(Pagination(q, after,
                                                              limit)))

    def post(self):
        """
        Create a new read_group
        ---
        template:
          path:
            new_resource.yml
          properties:
            resource:
              ReadGroup
        """

        body = request.get_json(force=True)

        # Deserialize
        try:
            rg = ReadGroupSchema(strict=True).load(body).data
        # Request body not valid
        except ValidationError as e:
            abort(400, 'could not create read_group: {}'.format(e.messages))

        # Add to and save in database
        db.session.add(rg)
        db.session.commit()

        return ReadGroupSchema(201, 'read_group {} created'.format(
            rg.kf_id)).jsonify(rg), 201
Ejemplo n.º 13
0
class FamilyRelationshipListAPI(CRUDView):
    """
    FamilyRelationship REST API
    """
    endpoint = 'family_relationships_list'
    rule = '/family-relationships'
    schemas = {'FamilyRelationship': FamilyRelationshipSchema}

    @paginated
    @use_args(filter_schema_factory(FamilyRelationshipFilterSchema),
              locations=('query',))
    def get(self, filter_params, after, limit):
        """
        Get all family_relationships
        ---
        description: Get all family_relationships
        template:
          path:
            get_list.yml
          properties:
            resource:
              FamilyRelationship
        """
        # Get and remove special filter parameters - those which are not
        # part of model properties
        # Study id
        study_id = filter_params.pop('study_id', None)
        # Participant id
        participant_id = filter_params.pop('participant_id', None)

        # Get family relationships joined w participants
        q = FamilyRelationship.query_all_relationships(
            participant_kf_id=participant_id,
            model_filter_params=filter_params)

        # Filter by study
        if study_id:
            from dataservice.api.participant.models import Participant
            q = (q.filter(Participant.study_id == study_id))

        return (FamilyRelationshipSchema(many=True)
                .jsonify(Pagination(q, after, limit)))

    def post(self):
        """
        Create a new family_relationship
        ---
        template:
          path:
            new_resource.yml
          properties:
            resource:
              FamilyRelationship
        """

        body = request.get_json(force=True)

        # Deserialize
        try:
            fr = FamilyRelationshipSchema(strict=True).load(body).data
        # Request body not valid
        except ValidationError as e:
            abort(400, 'could not create family_relationship: {}'
                  .format(e.messages))

        # Add to and save in database
        db.session.add(fr)
        db.session.commit()

        return FamilyRelationshipSchema(201, 'family_relationship {} created'
                                        .format(fr.kf_id)).jsonify(fr), 201
Ejemplo n.º 14
0
class BiospecimenListAPI(CRUDView):
    """
    Biospecimen REST API
    """
    endpoint = 'biospecimens_list'
    rule = '/biospecimens'
    schemas = {'Biospecimen': BiospecimenSchema}

    @paginated
    @use_args(filter_schema_factory(BiospecimenFilterSchema),
              locations=('query',))
    def get(self, filter_params, after, limit):
        """
        Get all biospecimens
        ---
        description: Get all biospecimens
        template:
          path:
            get_list.yml
          properties:
            resource:
              Biospecimen
        """
        # Get study id, diagnosis_id and remove from model filter params
        study_id = filter_params.pop('study_id', None)
        diagnosis_id = filter_params.pop('diagnosis_id', None)

        # Apply filter params
        q = (Biospecimen.query
             .filter_by(**filter_params))

        # Apply study_id filter and diagnosis_id filter
        from dataservice.api.participant.models import Participant

        if study_id:
            q = (q.join(Participant.biospecimens)
                 .filter(Participant.study_id == study_id))
        if diagnosis_id:
            q = (q.join(BiospecimenDiagnosis)
                 .filter(BiospecimenDiagnosis.diagnosis_id == diagnosis_id))

        return (BiospecimenSchema(many=True)
                .jsonify(Pagination(q, after, limit)))

    def post(self):
        """
        Create a new biospecimen
        ---
        template:
          path:
            new_resource.yml
          properties:
            resource:
              Biospecimen
        """

        body = request.get_json(force=True)

        # Deserialize
        try:
            s = BiospecimenSchema(strict=True).load(body).data
        # Request body not valid
        except ValidationError as e:
            abort(400, 'could not create biospecimen: {}'.format(e.messages))

        # Add to and save in database
        db.session.add(s)
        db.session.commit()

        return BiospecimenSchema(201, 'biospecimen {} created'
                                 .format(s.kf_id)).jsonify(s), 201