Esempio n. 1
0
    def test_acquisition_files(self):
        fw = self.fw
        
        project = fw.get_project(self.project_id)
        session = fw.get_session(self.session_id)
        acquisition = fw.get_acquisition(self.acquisition_id)

        # Upload a file to session and acquisition
        poem1 = 'When a vast image out of Spiritus Mundi'
        fw.upload_file_to_session(self.session_id, flywheel.FileSpec('yeats1.txt', poem1))

        poem2 = 'Troubles my sight: a waste of desert sand;'
        fw.upload_file_to_acquisition(self.acquisition_id, flywheel.FileSpec('yeats2.txt', poem2))

        # Create the download ticket for the container
        node = flywheel.DownloadNode(level='session', id=self.session_id)
        downloadSpec = flywheel.DownloadInput(nodes=[node], optional=True)

        ticket = fw.create_download_ticket(downloadSpec)
        self.assertIsNotNone(ticket)
        self.assertIsNotNone(ticket.ticket)
        self.assertEqual(2, ticket.file_cnt)
        self.assertGreater(ticket.size, 1)

        fd, self.tmpfile = tempfile.mkstemp(suffix='.tar.gz')
        os.close(fd)

        # Attempt to complete the download
        fw.download_ticket(ticket.ticket, self.tmpfile)

        self.assertTrue(os.path.isfile(self.tmpfile))
        self.assertGreater(os.path.getsize(self.tmpfile), 0)

        sess_path = '{}/{}/{}/{}'.format(self.group_id, project['label'], session.get('subject', {}).get('code', 'unknown_subject'), session['label'])
        sess_file = '{}/{}'.format(sess_path, 'yeats1.txt')

        acq_path = '{}/{}'.format(sess_path, acquisition['label'])
        acq_file = '{}/{}'.format(acq_path, 'yeats2.txt')

        # Verify the download structure
        with tarfile.open(self.tmpfile, mode='r') as tar:
            tar_names = tar.getnames()

            self.assertEqual(2, len(tar_names))
            self.assertIn(sess_file, tar_names)
            self.assertIn(acq_file, tar_names)

            # Read member data
            mem_f = tar.extractfile(sess_file)
            data = mem_f.read()
            self.assertEqual(six.u(poem1), data.decode('utf-8'))
            mem_f.close()

            mem_f = tar.extractfile(acq_file)
            data = mem_f.read()
            self.assertEqual(six.u(poem2), data.decode('utf-8'))
            mem_f.close()
Esempio n. 2
0
    def test_batch(self):
        fw = self.fw_device

        poem = 'The falcon cannot hear the falconer;'
        fw.upload_file_to_acquisition(self.acquisition_id,
                                      flywheel.FileSpec('yeats.txt', poem))

        # Add
        tag = self.rand_string()
        acq = fw.get_acquisition(self.acquisition_id)
        gear = fw.get_gear(self.gear_id)

        proposal = gear.propose_batch([acq], tags=[tag])
        self.assertIsNotNone(proposal)

        self.assertNotEmpty(proposal.id)
        self.assertEquals(proposal.gear_id, self.gear_id)
        self.assertIsNotNone(proposal.origin)
        self.assertEqual(proposal.origin.type, 'device')
        self.assertNotEmpty(proposal.origin.id)

        self.assertEqual(len(proposal.matched), 1)
        match = proposal.matched[0]
        self.assertEqual(match.id, self.acquisition_id)
        self.assertEqual(len(match.files), 1)
        self.assertEqual(match.files[0].name, 'yeats.txt')

        self.assertEmpty(proposal.ambiguous)
        self.assertEmpty(proposal.not_matched)
        self.assertEmpty(proposal.improper_permissions)

        self.assertTimestampBeforeNow(proposal.created)
        self.assertGreaterEqual(proposal.modified, proposal.created)

        # Get
        r_batch = fw.get_batch(proposal.id)
        self.assertIsNotNone(r_batch)
        self.assertEqual(r_batch.gear_id, self.gear_id)
        self.assertEqual(r_batch.state, 'pending')

        # Get all
        batches = fw.get_all_batches()
        self.assertIn(r_batch, batches)

        # Start
        jobs = proposal.run()
        self.assertEqual(len(jobs), 1)

        # Get again
        r_batch2 = fw.get_batch(proposal.id)
        self.assertEqual(r_batch2.state, 'running')
        self.assertTimestampAfter(r_batch2.modified, r_batch.modified)

        # Cancel
        cancelled = r_batch2.cancel()
        self.assertEqual(cancelled, 1)
Esempio n. 3
0
    def test_analysis_files(self):
        fw = self.fw

        # Upload to session
        poem = 'A gaze blank and pitiless as the sun,'
        fw.upload_file_to_session(self.session_id,
                                  flywheel.FileSpec('yeats.txt', poem))

        file_ref = flywheel.FileReference(id=self.session_id,
                                          type='session',
                                          name='yeats.txt')

        analysis = flywheel.AnalysisInput(label=self.rand_string(),
                                          description=self.rand_string(),
                                          inputs=[file_ref])

        # Add
        analysis_id = fw.add_session_analysis(self.session_id, analysis)

        # Download the input file and check content
        self.assertDownloadFileTextEquals(
            fw.download_input_from_analysis_as_data, analysis_id, 'yeats.txt',
            poem)
        self.assertDownloadFileTextEqualsWithTicket(
            fw.get_analysis_input_download_url, analysis_id, 'yeats.txt', poem)

        poem_out = 'Surely the Second Coming is at hand.'
        r_analysis = fw.get(analysis_id)
        r_analysis.upload_output(flywheel.FileSpec('yeats-out.txt', poem_out))

        r_analysis = r_analysis.reload()
        self.assertEqual(len(r_analysis.files), 1)
        self.assertEqual(r_analysis.files[0].name, 'yeats-out.txt')
        self.assertEqual(r_analysis.files[0].size, 36)
        self.assertEqual(r_analysis.files[0].mimetype, 'text/plain')

        # Download and check content
        self.assertDownloadFileTextEquals(
            fw.download_output_from_analysis_as_data, analysis_id,
            'yeats-out.txt', poem_out)
        self.assertDownloadFileTextEqualsWithTicket(
            fw.get_analysis_output_download_url, analysis_id, 'yeats-out.txt',
            poem_out)
Esempio n. 4
0
    def test_bad_uploads(self):
        fw = self.fw

        acquisition_id = 'INVALID_ACQUISITION_ID'

        # invalid file spec
        self.assertRaises(RuntimeError, fw.upload_file_to_acquisition,
                          acquisition_id, flywheel.FileSpec(None))

        # Non-existant upload path
        self.assertRaises(IOError, fw.upload_file_to_acquisition,
                          acquisition_id,
                          flywheel.FileSpec('/dev/null/does-not-exist'))

        # Invalid upload path
        poem = 'Are full of passionate intensity.'
        try:
            fw.upload_file_to_acquisition(acquisition_id,
                                          flywheel.FileSpec('yeats.txt', poem))
            self.fail(
                'Expected ApiException when uploading to nonexistent location')
        except flywheel.ApiException as e:
            self.assertEqual(e.status, 404)
Esempio n. 5
0
    def upload(self, container, name, fileobj, metadata=None):
        upload_fn = getattr(
            self.fw, 'upload_file_to_{}'.format(container.container_type),
            None)

        if not upload_fn:
            print('Skipping unsupported upload to container: {}'.format(
                container.container_type))
            return

        log.debug('Uploading file %s to %s=%s', name, container.container_type,
                  container.id)
        if self.supports_signed_url():
            self.signed_url_upload(container, name, fileobj, metadata=metadata)
        else:
            upload_fn(container.id,
                      flywheel.FileSpec(name, fileobj),
                      metadata=json.dumps(metadata))
Esempio n. 6
0
    def test_session_analysis(self):
        fw = self.fw

        session = flywheel.Session(project=self.project_id,
                                   label=self.rand_string())

        # Add
        session_id = fw.add_session(session)
        self.assertNotEmpty(session_id)

        poem = 'When a vast image out of Spiritus Mundi'
        fw.upload_file_to_session(session_id,
                                  flywheel.FileSpec('yeats.txt', poem))

        file_ref = flywheel.FileReference(id=session_id,
                                          type='session',
                                          name='yeats.txt')

        analysis = flywheel.AnalysisInput(label=self.rand_string(),
                                          description=self.rand_string(),
                                          inputs=[file_ref])

        # Add
        analysis_id = fw.add_session_analysis(session_id, analysis)
        self.assertNotEmpty(analysis_id)

        # Get the list of analyses in the session
        analyses = fw.get_session_analyses(session_id)
        self.assertEqual(len(analyses), 1)

        r_analysis = analyses[0]

        self.assertEqual(r_analysis.id, analysis_id)
        self.assertEmpty(r_analysis.job)

        self.assertTimestampBeforeNow(r_analysis.created)
        self.assertGreaterEqual(r_analysis.modified, r_analysis.created)

        self.assertEqual(len(r_analysis.inputs), 1)
        self.assertEqual(r_analysis.inputs[0].name, 'yeats.txt')
Esempio n. 7
0
    def test_project_analysis(self):
        fw = self.fw

        project = flywheel.Project(group=self.group_id,
                                   label=self.rand_string())

        # Add
        self.project_id = project_id = fw.add_project(project)
        self.assertNotEmpty(project_id)

        poem = 'The Second Coming! Hardly are those words out'
        fw.upload_file_to_project(project_id,
                                  flywheel.FileSpec('yeats.txt', poem))

        file_ref = flywheel.FileReference(id=project_id,
                                          type='project',
                                          name='yeats.txt')

        analysis = flywheel.AnalysisInput(label=self.rand_string(),
                                          description=self.rand_string(),
                                          inputs=[file_ref])

        # Add
        analysis_id = fw.add_project_analysis(project_id, analysis)
        self.assertNotEmpty(analysis_id)

        # Get the list of analyses in the project
        analyses = fw.get_project_analyses(project_id)
        self.assertEqual(len(analyses), 1)

        r_analysis = analyses[0]

        self.assertEqual(r_analysis.id, analysis_id)
        self.assertEmpty(r_analysis.job)

        self.assertTimestampBeforeNow(r_analysis.created)
        self.assertGreaterEqual(r_analysis.modified, r_analysis.created)

        self.assertEqual(len(r_analysis.inputs), 1)
        self.assertEqual(r_analysis.inputs[0].name, 'yeats.txt')
Esempio n. 8
0
    def test_container_analysis(self):
        fw = self.fw

        acquisition = flywheel.Acquisition(session=self.session_id,
                                           label=self.rand_string())

        # Add
        acquisition_id = fw.add_acquisition(acquisition)
        self.assertNotEmpty(acquisition_id)

        poem = 'Troubles my sight: a waste of desert sand;'
        fw.upload_file_to_container(acquisition_id,
                                    flywheel.FileSpec('yeats.txt', poem))

        file_ref = flywheel.FileReference(id=acquisition_id,
                                          type='acquisition',
                                          name='yeats.txt')

        analysis = flywheel.AnalysisInput(label=self.rand_string(),
                                          description=self.rand_string(),
                                          inputs=[file_ref])

        # Add
        analysis_id = fw.add_container_analysis(acquisition_id, analysis)
        self.assertNotEmpty(analysis_id)

        # Get the list of analyses in the acquisition
        analyses = fw.get_container_analyses(acquisition_id)
        self.assertEqual(len(analyses), 1)

        r_analysis = analyses[0]

        self.assertEqual(r_analysis.id, analysis_id)
        self.assertEmpty(r_analysis.job)

        self.assertTimestampBeforeNow(r_analysis.created)
        self.assertGreaterEqual(r_analysis.modified, r_analysis.created)

        self.assertEqual(len(r_analysis.inputs), 1)
        self.assertEqual(r_analysis.inputs[0].name, 'yeats.txt')
Esempio n. 9
0
    def test_collection_analysis(self):
        fw = self.fw

        collection = flywheel.Collection(label=self.rand_string())

        # Add
        self.collection_id = collection_id = fw.add_collection(collection)
        self.assertNotEmpty(collection_id)

        poem = 'A shape with lion body and the head of a man,'
        fw.upload_file_to_collection(collection_id,
                                     flywheel.FileSpec('yeats.txt', poem))

        file_ref = flywheel.FileReference(id=collection_id,
                                          type='collection',
                                          name='yeats.txt')

        analysis = flywheel.AnalysisInput(label=self.rand_string(),
                                          description=self.rand_string(),
                                          inputs=[file_ref])

        # Add
        analysis_id = fw.add_collection_analysis(collection_id, analysis)
        self.assertNotEmpty(analysis_id)

        # Get the list of analyses in the collection
        r_collection = fw.get_collection(collection_id)
        self.assertEqual(len(r_collection.analyses), 1)

        r_analysis = r_collection.analyses[0]

        self.assertEqual(r_analysis.id, analysis_id)
        self.assertEmpty(r_analysis.job)

        self.assertTimestampBeforeNow(r_analysis.created)
        self.assertGreaterEqual(r_analysis.modified, r_analysis.created)

        self.assertEqual(len(r_analysis.inputs), 1)
        self.assertEqual(r_analysis.inputs[0].name, 'yeats.txt')
Esempio n. 10
0
def create_hierarchy(fw):
    # Create group, project, session, subject, acquisitions
    fw.add_group({'_id': GROUP_ID})
    project_id = fw.add_project({'group': GROUP_ID, 'label': PROJECT_LABEL})
    subject_id = fw.add_subject({'project': project_id, 'code': SUBJECT_CODE})
    session_id = fw.add_session({
        'project': project_id,
        'subject': {
            '_id': subject_id
        },
        'label': SESSION_LABEL
    })
    acquisition_id = fw.add_acquisition({
        'session': session_id,
        'label': ACQUISITION_LABEL
    })

    for filename in filenames():
        fw.upload_file_to_acquisition(
            acquisition_id, flywheel.FileSpec(filename, 'Hello World'))

    return fw.get(acquisition_id)
Esempio n. 11
0
    def test_container_files(self):
        fw = self.fw

        acquisition = flywheel.Acquisition(label=self.rand_string(),
                                           session=self.session_id)
        acquisition_id = fw.add_acquisition(acquisition)

        # Upload a file
        poem = 'Turning and turning in the widening gyre'
        fw.upload_file_to_container(acquisition_id,
                                    flywheel.FileSpec('yeats.txt', poem))

        # Check that the file was added to the acquisition
        c_acquisition = fw.get_container(acquisition_id)
        self.assertEqual(len(c_acquisition.files), 1)
        self.assertEqual(c_acquisition.files[0].name, 'yeats.txt')
        self.assertEqual(c_acquisition.files[0].size, 40)
        self.assertEqual(c_acquisition.files[0].mimetype, 'text/plain')

        # Download the file and check content
        self.assertDownloadFileTextEquals(
            fw.download_file_from_container_as_data, acquisition_id,
            'yeats.txt', poem)

        # Test unauthorized download with ticket for the file
        self.assertDownloadFileTextEqualsWithTicket(
            fw.get_container_download_url, acquisition_id, 'yeats.txt', poem)

        # Test file attributes
        self.assertEqual(c_acquisition.files[0].modality, None)
        self.assertEmpty(c_acquisition.files[0].classification)
        self.assertEqual(c_acquisition.files[0].type, 'text')

        resp = fw.modify_container_file(
            acquisition_id, 'yeats.txt',
            flywheel.FileEntry(modality='modality', type='type'))

        # Check that no jobs were triggered, and attrs were modified
        self.assertEqual(resp.jobs_spawned, 0)

        c_acquisition = fw.get_container(acquisition_id)
        self.assertEqual(c_acquisition.files[0].modality, "modality")
        self.assertEmpty(c_acquisition.files[0].classification)
        self.assertEqual(c_acquisition.files[0].type, 'type')

        # Test classifications
        resp = fw.modify_container_file_classification(
            acquisition_id, 'yeats.txt', {
                'modality': 'modality2',
                'replace': {
                    'Custom': ['measurement1', 'measurement2'],
                }
            })
        self.assertEqual(resp.modified, 1)
        self.assertEqual(resp.jobs_spawned, 0)

        c_acquisition = fw.get_container(acquisition_id)
        self.assertEqual(c_acquisition.files[0].modality, 'modality2')
        self.assertEqual(c_acquisition.files[0].classification,
                         {'Custom': ['measurement1', 'measurement2']})

        resp = fw.set_container_file_classification(acquisition_id,
                                                    'yeats.txt',
                                                    {'Custom': ['HelloWorld']})
        self.assertEqual(resp.modified, 1)
        self.assertEqual(resp.jobs_spawned, 0)

        resp = fw.delete_container_file_classification_fields(
            acquisition_id, 'yeats.txt', {'Custom': ['measurement2']})
        self.assertEqual(resp.modified, 1)
        self.assertEqual(resp.jobs_spawned, 0)

        c_acquisition = fw.get_container(acquisition_id)
        self.assertEqual(c_acquisition.files[0].classification, {
            'Custom': ['measurement1', 'HelloWorld'],
        })

        # Test file info
        self.assertEmpty(c_acquisition.files[0].info)
        fw.replace_container_file_info(acquisition_id, 'yeats.txt', {
            'a': 1,
            'b': 2,
            'c': 3,
            'd': 4
        })

        fw.set_container_file_info(acquisition_id, 'yeats.txt', {'c': 5})

        c_acquisition = fw.get_container(acquisition_id)
        self.assertEqual(c_acquisition.files[0].info['a'], 1)
        self.assertEqual(c_acquisition.files[0].info['b'], 2)
        self.assertEqual(c_acquisition.files[0].info['c'], 5)
        self.assertEqual(c_acquisition.files[0].info['d'], 4)

        fw.delete_container_file_info_fields(acquisition_id, 'yeats.txt',
                                             ['c', 'd'])
        c_acquisition = fw.get_container(acquisition_id)
        self.assertEqual(c_acquisition.files[0].info['a'], 1)
        self.assertEqual(c_acquisition.files[0].info['b'], 2)
        self.assertNotIn('c', c_acquisition.files[0].info)
        self.assertNotIn('d', c_acquisition.files[0].info)

        fw.replace_container_file_info(acquisition_id, 'yeats.txt', {})
        c_acquisition = fw.get_container(acquisition_id)
        self.assertEmpty(c_acquisition.files[0].info)

        # Delete file
        fw.delete_container_file(acquisition_id, 'yeats.txt')
        c_acquisition = fw.get_container(acquisition_id)
        self.assertEmpty(c_acquisition.files)

        # Delete acquisition
        fw.delete_container(acquisition_id)
Esempio n. 12
0
    def test_project_files(self):
        fw = self.fw

        project = flywheel.Project(label=self.rand_string(),
                                   group=self.group_id)
        self.project_id = project_id = fw.add_project(project)

        # Upload a file
        poem = 'The ceremony of innocence is drowned;'
        fw.upload_file_to_project(project_id,
                                  flywheel.FileSpec('yeats.txt', poem))

        # Check that the file was added to the project
        r_project = fw.get_project(project_id)
        self.assertEqual(len(r_project.files), 1)
        self.assertEqual(r_project.files[0].name, 'yeats.txt')
        self.assertEqual(r_project.files[0].size, 37)
        self.assertEqual(r_project.files[0].mimetype, 'text/plain')

        # Download the file and check content
        self.assertDownloadFileTextEquals(
            fw.download_file_from_project_as_data, project_id, 'yeats.txt',
            poem)

        # Test unauthorized download with ticket for the file
        self.assertDownloadFileTextEqualsWithTicket(
            fw.get_project_download_url, project_id, 'yeats.txt', poem)

        # Test file attributes
        self.assertEqual(r_project.files[0].modality, None)
        self.assertEmpty(r_project.files[0].classification)
        self.assertEqual(r_project.files[0].type, 'text')

        resp = fw.modify_project_file(
            project_id, 'yeats.txt',
            flywheel.FileEntry(modality='modality', type='type'))

        # Check that no jobs were triggered, and attrs were modified
        self.assertEqual(resp.jobs_spawned, 0)

        r_project = fw.get_project(project_id)
        self.assertEqual(r_project.files[0].modality, "modality")
        self.assertEmpty(r_project.files[0].classification)
        self.assertEqual(r_project.files[0].type, 'type')

        # Test classifications
        resp = fw.modify_project_file_classification(
            project_id, 'yeats.txt',
            {'replace': {
                'Custom': ['measurement1', 'measurement2'],
            }})
        self.assertEqual(resp.modified, 1)
        self.assertEqual(resp.jobs_spawned, 0)

        r_project = fw.get_project(project_id)
        self.assertEqual(r_project.files[0].classification,
                         {'Custom': ['measurement1', 'measurement2']})

        resp = fw.modify_project_file_classification(
            project_id, 'yeats.txt', {
                'add': {
                    'Custom': ['HelloWorld'],
                },
                'delete': {
                    'Custom': ['measurement2']
                }
            })
        self.assertEqual(resp.modified, 1)
        self.assertEqual(resp.jobs_spawned, 0)

        r_project = fw.get_project(project_id)
        self.assertEqual(r_project.files[0].classification, {
            'Custom': ['measurement1', 'HelloWorld'],
        })

        # Test file info
        self.assertEmpty(r_project.files[0].info)
        fw.replace_project_file_info(project_id, 'yeats.txt', {
            'a': 1,
            'b': 2,
            'c': 3,
            'd': 4
        })

        fw.set_project_file_info(project_id, 'yeats.txt', {'c': 5})

        r_project = fw.get_project(project_id)
        self.assertEqual(r_project.files[0].info['a'], 1)
        self.assertEqual(r_project.files[0].info['b'], 2)
        self.assertEqual(r_project.files[0].info['c'], 5)
        self.assertEqual(r_project.files[0].info['d'], 4)

        fw.delete_project_file_info_fields(project_id, 'yeats.txt', ['c', 'd'])
        r_project = fw.get_project(project_id)
        self.assertEqual(r_project.files[0].info['a'], 1)
        self.assertEqual(r_project.files[0].info['b'], 2)
        self.assertNotIn('c', r_project.files[0].info)
        self.assertNotIn('d', r_project.files[0].info)

        fw.replace_project_file_info(project_id, 'yeats.txt', {})
        r_project = fw.get_project(project_id)
        self.assertEmpty(r_project.files[0].info)

        # Delete file
        fw.delete_project_file(project_id, 'yeats.txt')
        r_project = fw.get_project(project_id)
        self.assertEmpty(r_project.files)
Esempio n. 13
0
    def test_ad_hoc_analysis(self):
        fw = self.fw

        # Upload to session
        poem = 'A gaze blank and pitiless as the sun,'
        fw.upload_file_to_session(self.session_id,
                                  flywheel.FileSpec('yeats.txt', poem))

        file_ref = flywheel.FileReference(id=self.session_id,
                                          type='session',
                                          name='yeats.txt')

        analysis = flywheel.AnalysisInput(label=self.rand_string(),
                                          description=self.rand_string(),
                                          inputs=[file_ref])

        # Add
        analysis_id = fw.add_session_analysis(self.session_id, analysis)
        self.assertNotEmpty(analysis_id)

        session = fw.get_session(self.session_id)
        self.assertEqual(len(session.analyses), 1)

        r_analysis = session.analyses[0]
        self.assertEqual(r_analysis.id, analysis_id)
        self.assertIsNone(r_analysis.job)
        self.assertTimestampBeforeNow(r_analysis.created)
        self.assertGreaterEqual(r_analysis.modified, r_analysis.created)
        self.assertEqual(len(r_analysis.inputs), 1)
        self.assertEqual(r_analysis.inputs[0].name, 'yeats.txt')

        # Access analysis directly
        r_analysis2 = fw.get_analysis(analysis_id)
        self.assertEqual(r_analysis, r_analysis2)

        # Generic Get is equivalent
        self.assertEqual(fw.get(analysis_id).to_dict(), r_analysis2.to_dict())

        # Analysis Notes
        text = self.rand_string()
        fw.add_session_analysis_note(self.session_id, analysis_id, text)

        # Check
        session = fw.get_session(self.session_id)
        self.assertEqual(len(session.analyses), 1)

        r_analysis = session.analyses[0]
        self.assertEqual(len(r_analysis.notes), 1)
        self.assertNotEmpty(r_analysis.notes[0].user)
        self.assertEqual(r_analysis.notes[0].text, text)
        self.assertTimestampBeforeNow(r_analysis.notes[0].created)
        self.assertTimestampBeforeNow(r_analysis.notes[0].modified)
        self.assertTimestampAfter(r_analysis.notes[0].modified,
                                  r_analysis.created)
        self.assertGreaterEqual(r_analysis.notes[0].modified,
                                r_analysis.notes[0].created)

        self.assertEqual(r_analysis.parent.id, session.id)

        # Access multiple analyses
        analysis2 = session.add_analysis(label=analysis.label,
                                         description=analysis.description,
                                         inputs=analysis.inputs)
        self.assertIsNotNone(analysis2)
        analysis_id2 = analysis2.id

        # Try getting analysis incorrectly
        self.assertRaises(flywheel.ApiException, fw.get_analyses, 'session',
                          self.session_id, 'projects')

        # Get all Session level analyses in group
        analyses = fw.get_analyses('groups', self.group_id, 'sessions')
        self.assertEqual(len(analyses), 2)

        self.assertEqual(
            1, len(list(filter(lambda x: x.id == r_analysis.id, analyses))))
        self.assertEqual(
            1, len(list(filter(lambda x: x.id == analysis_id2, analyses))))

        # Get project level analyses in group (will be zero)
        analyses = fw.get_analyses('groups', self.group_id, 'projects')
        self.assertEmpty(analyses)

        # Info, tags
        tag = 'example-tag'
        fw.add_analysis_tag(analysis_id, tag)

        # Replace info
        fw.replace_analysis_info(analysis_id, {'foo': 3, 'bar': 'qaz'})

        # Set info
        fw.set_analysis_info(analysis_id, {'foo': 42, 'hello': 'world'})

        # Check
        r_analysis = fw.get_analysis(analysis_id)
        self.assertEqual(r_analysis.tags, [tag])
        self.assertEqual(r_analysis.info, {
            'foo': 42,
            'bar': 'qaz',
            'hello': 'world'
        })

        # Delete info fields
        fw.delete_analysis_info_fields(analysis_id, ['foo', 'bar'])
        r_analysis = fw.get_analysis(analysis_id)
        self.assertEqual(r_analysis.info, {'hello': 'world'})
Esempio n. 14
0
    def test_data_view_files(self):
        fw = self.fw

        self.test_acquisition_id = fw.add_acquisition({'session': self.session_id, 'label': 'Acquisition2'})

        data = 'col1,col2\n1,10\n2,20'
        fw.upload_file_to_acquisition(self.test_acquisition_id, flywheel.FileSpec('data1.csv', data))
        fw.upload_file_to_acquisition(self.test_acquisition_id, flywheel.FileSpec('data2.csv', data))

        # Get file data
        view = fw.View(container='acquisition', filename='*.csv', match='all', 
            columns=['file.name', ('file_data.col2', 'value2', 'int')])

        with fw.read_view_data(view, self.project_id) as resp:
            result = json.load(resp)

        self.assertIsNotNone(result)
        self.assertIn('data', result)
        rows = result['data']
        self.assertEqual(len(rows), 5)

        self.assertEqual(rows[0]['acquisition.label'], 'Acquisition2')
        self.assertEqual(rows[0]['file.name'], 'data1.csv')
        self.assertEqual(rows[0]['col1'], '1')
        self.assertEqual(rows[0]['value2'], 10)

        self.assertEqual(rows[1]['acquisition.label'], 'Acquisition2')
        self.assertEqual(rows[1]['file.name'], 'data1.csv')
        self.assertEqual(rows[1]['col1'], '2')
        self.assertEqual(rows[1]['value2'], 20)

        self.assertEqual(rows[2]['acquisition.label'], 'Acquisition2')
        self.assertEqual(rows[2]['file.name'], 'data2.csv')
        self.assertEqual(rows[2]['col1'], '1')
        self.assertEqual(rows[2]['value2'], 10)

        self.assertEqual(rows[3]['acquisition.label'], 'Acquisition2')
        self.assertEqual(rows[3]['file.name'], 'data2.csv')
        self.assertEqual(rows[3]['col1'], '2')
        self.assertEqual(rows[3]['value2'], 20)

        self.assertEqual(rows[4]['acquisition.id'], self.acquisition_id)
        self.assertEqual(rows[4]['file.name'], None)
        self.assertEqual(rows[4]['col1'], None)
        self.assertEqual(rows[4]['value2'], None)

        # Test list files
        view = fw.View(columns=['acquisition.file'])
        with fw.read_view_data(view, self.project_id) as resp:
            result = json.load(resp)

        self.assertIsNotNone(result)
        self.assertIn('data', result)
        data = result['data']
        self.assertEqual(len(data), 2)

        row = data[0]
        self.assertEqual(row['project.id'], self.project_id)
        self.assertEqual(row['subject.id'], self.subject.id)
        self.assertEqual(row['session.id'], self.session_id)
        self.assertEqual(row['acquisition.id'], self.test_acquisition_id)
        self.assertEqual(row['acquisition.file.name'], 'data1.csv')
        self.assertEqual(row['acquisition.file.size'], 19)
        self.assertEqual(row['acquisition.file.type'], 'tabular data')
        self.assertIn('acquisition.file.id', row)
        self.assertIn('acquisition.file.classification', row)
        
        row = data[1]
        self.assertEqual(row['project.id'], self.project_id)
        self.assertEqual(row['subject.id'], self.subject.id)
        self.assertEqual(row['session.id'], self.session_id)
        self.assertEqual(row['acquisition.id'], self.test_acquisition_id)
        self.assertEqual(row['acquisition.file.name'], 'data2.csv')
        self.assertEqual(row['acquisition.file.size'], 19)
        self.assertEqual(row['acquisition.file.type'], 'tabular data')

        # List files, only 2 columns
        view = fw.View(columns=['acquisition.file.name', 'acquisition.file.size'])
        
        with fw.read_view_data(view, self.project_id) as resp:
            result = json.load(resp)

        self.assertIsNotNone(result)
        self.assertIn('data', result)
        data = result['data']
        self.assertEqual(len(data), 2)

        row = data[0]
        self.assertEqual(row['project.id'], self.project_id)
        self.assertEqual(row['subject.id'], self.subject.id)
        self.assertEqual(row['session.id'], self.session_id)
        self.assertEqual(row['acquisition.id'], self.test_acquisition_id)
        self.assertEqual(row['acquisition.file.name'], 'data1.csv')
        self.assertEqual(row['acquisition.file.size'], 19)
        self.assertNotIn('acquisition.file.type', row)
        self.assertNotIn('acquisition.file.id', row)
        self.assertNotIn('acquisition.file.classification', row)
        
        row = data[1]
        self.assertEqual(row['project.id'], self.project_id)
        self.assertEqual(row['subject.id'], self.subject.id)
        self.assertEqual(row['session.id'], self.session_id)
        self.assertEqual(row['acquisition.id'], self.test_acquisition_id)
        self.assertEqual(row['acquisition.file.name'], 'data2.csv')
        self.assertEqual(row['acquisition.file.size'], 19)
Esempio n. 15
0
    def test_job_based_analysis(self):
        fw = self.fw

        gear = fw.get_gear(self.gear_id)

        # Upload to session
        poem = 'A gaze blank and pitiless as the sun,'
        fw.upload_file_to_session(self.session_id,
                                  flywheel.FileSpec('yeats.txt', poem))

        session = fw.get_session(self.session_id)
        any_file = session.files[0]
        self.assertEqual(any_file.name, 'yeats.txt')

        tag = self.rand_string()
        analysis_label = self.rand_string()

        # Add
        analysis_id = gear.run(analysis_label=analysis_label,
                               destination=session,
                               tags=[tag],
                               inputs={'any-file': any_file})
        self.assertNotEmpty(analysis_id)

        session = session.reload()
        self.assertEqual(len(session.analyses), 1)

        r_analysis = session.analyses[0]
        self.assertEqual(r_analysis.id, analysis_id)

        gear_info = r_analysis.gear_info
        self.assertEqual(gear_info.id, self.gear_id)
        self.assertEqual(gear_info.category, gear.category)
        self.assertEqual(gear_info.name, gear.gear.name)
        self.assertEqual(gear_info.version, gear.gear.version)
        self.assertEqual(r_analysis.job.state, 'pending')
        self.assertTimestampBeforeNow(r_analysis.created)
        self.assertGreaterEqual(r_analysis.modified, r_analysis.created)
        self.assertEqual(len(r_analysis.inputs), 1)
        self.assertEqual(r_analysis.inputs[0].name, 'yeats.txt')

        # Verify job
        r_job = fw.get_job(r_analysis.job.id)
        self.assertEqual(r_analysis.job.state, 'pending')

        # Access analysis directly
        r_analysis2 = fw.get_analysis(analysis_id)
        self.assertEqual(r_analysis, r_analysis2)

        # Project based analysis
        project = fw.get_project(self.project_id)

        # Add
        analysis_id = gear.run(analysis_label=analysis_label,
                               destination=project,
                               tags=[tag],
                               inputs={'any-file': any_file})
        self.assertNotEmpty(analysis_id)

        project = fw.get_project(self.project_id)
        self.assertEqual(len(project.analyses), 1)

        r_analysis = project.analyses[0]
        self.assertEqual(r_analysis.id, analysis_id)

        # Verify job
        r_job = fw.get_job(r_analysis.job.id)
        self.assertEqual(r_analysis.job.state, 'pending')

        # Access analysis directly
        r_analysis2 = fw.get_analysis(analysis_id)
        self.assertEqual(r_analysis, r_analysis2)
Esempio n. 16
0
    def test_job(self):
        fw = self.fw

        gear = fw.get_gear(self.gear_id)
        self.assertIsNotNone(gear)

        poem = 'Mere anarchy is loosed upon the world,'
        fw.upload_file_to_acquisition(self.acquisition_id,
                                      flywheel.FileSpec('yeats.txt', poem))

        tag = self.rand_string()

        # Get the acquisition destination and file input
        acq = fw.get_acquisition(self.acquisition_id)
        any_file = acq.files[0]
        self.assertEqual(any_file.name, 'yeats.txt')

        # Add
        job_id = gear.run(destination=acq,
                          tags=[tag],
                          inputs={'any-file': any_file})
        self.assertNotEmpty(job_id)

        # Get
        r_job = fw.get_job(job_id)
        self.assertEqual(r_job.gear_id, self.gear_id)
        gear_info = r_job.gear_info
        self.assertEqual(gear_info.category, gear.category)
        self.assertEqual(gear_info.name, gear.gear.name)
        self.assertEqual(gear_info.version, gear.gear.version)
        self.assertEqual(r_job.state, 'pending')
        self.assertEqual(r_job.attempt, 1)
        self.assertIsNotNone(r_job.origin)
        self.assertEqual(r_job.origin.type, 'user')
        self.assertNotEmpty(r_job.origin.id)
        self.assertIn(tag, r_job.tags)
        self.assertTimestampBeforeNow(r_job.created)
        self.assertGreaterEqual(r_job.modified, r_job.created)

        # Modify
        tag2 = self.rand_string()
        r_job.update(tags=[tag2])

        # Check
        r_job = fw.get_job(job_id)
        self.assertEqual(r_job.state, 'pending')
        self.assertNotIn(tag, r_job.tags)
        self.assertIn(tag2, r_job.tags)

        # Get session jobs
        jobs = fw.get_session_jobs(self.session_id)
        self.assertIsNotNone(jobs)
        self.assertIsNotNone(jobs.jobs)
        self.assertEqual(1, len(jobs.jobs))

        # job list doesn't info field
        r_job.config['inputs']['any-file']['object'].pop('info', None)
        self.assertIn(r_job, jobs.jobs)

        # Get all jobs
        jobs = fw.jobs(limit=100, sort='created:desc')
        self.assertIsNotNone(jobs)
        self.assertGreaterEqual(len(jobs), 1)
        self.assertTrue(any([job.id == job_id for job in jobs]))

        # Cancel
        job_mod = flywheel.Job(state='cancelled')
        fw.modify_job(job_id, job_mod)

        # Check
        r_job = fw.get_job(job_id)
        self.assertEqual(r_job.state, 'cancelled')
Esempio n. 17
0
    def test_child_mixins(self):
        fw = self.fw

        # Upload file to project
        poem = b'When a vast image out of Spiritus Mundi'
        fw.upload_file_to_project(self.project_id, flywheel.FileSpec('yeats.dat', poem))

        # TODO: Test Analyses

        # GROUP
        r_group = fw.get_group(self.group_id)
        projects = r_group.projects()

        self.assertIsNotNone(projects)
        self.assertEqual(len(projects), 1)
        r_project = projects[0]

        self.assertEqual(r_project.id, self.project_id)
        self.assertEqual(r_project.container_type, 'project')

        sessions = r_project.sessions()
        self.assertEqual(1, len(sessions))
        r_session = sessions[0]
        self.assertEqual(r_session.id, self.session_id)
        self.assertEqual(r_session.project, self.project_id)

        # Assert that file has a parent
        self.assertEqual(1, len(r_project.files))
        self.assertEqual(r_project.files[0].parent, r_project)

        # Test load files
        r_project._files = None

        project_files = r_project.get_files()
        self.assertEqual(1, len(project_files))
        r_file = project_files[0]
        self.assertEqual(r_file.parent, r_project)
        self.assertEqual(r_file.name, 'yeats.dat')
        self.assertEqual(r_file.size, len(poem))

        # Read file
        data = r_file.read()
        self.assertEqual(data, poem)

        # Get url
        ticket_url1 = r_file.url()
        self.assertIsNotNone(ticket_url1)
        ticket_url2 = r_file.url()
        self.assertNotEqual(ticket_url1, ticket_url2)

        # Download file
        fd, path = tempfile.mkstemp()
        os.close(fd)

        try:
            r_file.download(path)

            with open(path, 'rb') as f:
                data = f.read()
            self.assertEqual(data, poem)
        finally:
            os.remove(path)

        # Read acquisitions
        acquisitions = r_session.acquisitions()
        self.assertIsNotNone(acquisitions)
        self.assertEqual(len(acquisitions), 1)

        r_acquisition = acquisitions[0]
        self.assertEqual(r_acquisition.id, self.acquisition_id)
        self.assertEqual(r_acquisition.session, self.session_id)
Esempio n. 18
0
    def test_resolver(self):
        fw = self.fw
        group_id = self.group_id

        # Create test gear
        self.gear_id = create_test_gear()
        gear = self.fw.get_gear(self.gear_id)
        self.assertIsNotNone(gear)

        # Upload file acquisition
        poem = 'The Second Coming! Hardly are those words out'
        fw.upload_file_to_acquisition(self.acquisition_id,
                                      flywheel.FileSpec('yeats.txt', poem))

        # Resolve group children
        result = fw.resolve([group_id])

        self.assertEqual(len(result.path), 1)
        r_group = result.path[0]
        self.assertEqual(r_group.id, group_id)

        self.assertEqual(len(result.children), 1)
        r_project = result.children[0]
        self.assertEqual(r_project.id, self.project_id)

        # Resolve project children
        result = fw.resolve('{0}/{1}'.format(group_id, r_project.label))
        self.assertEqual(len(result.path), 2)
        self.assertEqual(result.path[0], r_group)
        self.assertEqual(result.path[1], r_project)

        self.assertEqual(len(result.children), 1)
        r_subject = result.children[0]
        self.assertEqual(r_subject.project, self.project_id)
        self.assertEqual(r_subject.id, self.subject_id)

        # Resolve subject children (using id string)
        result = fw.resolve('{0}/{1}/<id:{2}>'.format(group_id,
                                                      r_project.label,
                                                      self.subject_id))
        self.assertEqual(len(result.path), 3)
        self.assertEqual(result.path[0], r_group)
        self.assertEqual(result.path[1], r_project)
        self.assertEqual(result.path[2], r_subject)

        self.assertEqual(len(result.children), 1)
        r_session = result.children[0]
        self.assertEqual(r_session.project, self.project_id)
        self.assertEqual(r_session.subject.id, self.subject_id)
        self.assertEqual(r_session.id, self.session_id)

        # Resolve session children (using id string)
        result = fw.resolve('{0}/{1}/<id:{2}>/<id:{3}>'.format(
            group_id, r_project.label, self.subject_id, self.session_id))
        self.assertEqual(len(result.path), 4)
        self.assertEqual(result.path[0], r_group)
        self.assertEqual(result.path[1], r_project)
        self.assertEqual(result.path[2], r_subject)
        self.assertEqual(result.path[3], r_session)

        self.assertEqual(len(result.children), 1)
        r_acquisition = result.children[0]
        self.assertEqual(r_acquisition.session, self.session_id)
        self.assertEqual(r_acquisition.id, self.acquisition_id)

        # Finally, resolve acquisition files
        result = fw.resolve([
            group_id, r_project.label, r_subject.label, r_session.label,
            r_acquisition.label
        ])
        self.assertEqual(len(result.path), 5)
        self.assertEqual(result.path[0], r_group)
        self.assertEqual(result.path[1], r_project)
        self.assertEqual(result.path[2], r_subject)
        self.assertEqual(result.path[3], r_session)
        self.assertEqual(result.path[4], r_acquisition)

        self.assertEqual(len(result.children), 1)
        r_file = result.children[0]
        self.assertEqual(r_file.name, 'yeats.txt')
        self.assertEqual(r_file.size, len(poem))

        # TODO: Test Analyses

        # Test resolve gears
        result = fw.resolve('gears')
        self.assertEmpty(result.path)
        self.assertGreaterEqual(len(result.children), 1)
        found = False
        for child in result.children:
            if child.id == self.gear_id:
                found = True
                break
        self.assertTrue(found)
Esempio n. 19
0
    def test_lookup(self):
        fw = self.fw
        group_id = self.group_id

        # Get labels for everything
        result = fw.resolve([
            group_id,
            idz(self.project_id),
            idz(self.subject_id),
            idz(self.session_id)
        ])
        self.assertEqual(4, len(result.path))
        self.assertEqual(1, len(result.children))

        group = result.path[0]
        project = result.path[1]
        subject = result.path[2]
        session = result.path[3]
        acquisition = result.children[0]

        # Create test gear
        self.gear_id = create_test_gear()
        gear = self.fw.get_gear(self.gear_id)
        self.assertIsNotNone(gear)

        # Upload file acquisition
        poem = 'The Second Coming! Hardly are those words out'
        fw.upload_file_to_acquisition(self.acquisition_id,
                                      flywheel.FileSpec('yeats.txt', poem))

        # Resolve group
        r_group = fw.lookup([group_id])
        self.assertEqual(r_group.id, group_id)
        self.assertIsNotNone(r_group.label)
        self.assertNotEmpty(r_group.permissions)

        # Resolve project
        r_project = fw.lookup('{0}/{1}'.format(group_id, project.label))
        self.assertEqual(r_project.id, self.project_id)

        # Resolve subject
        r_subject = fw.lookup('{0}/{1}/<id:{2}>'.format(
            group_id, project.label, self.subject_id))
        self.assertEqual(r_subject.id, self.subject_id)

        # Resolve session
        r_session = fw.lookup('{0}/{1}/<id:{2}>/<id:{3}>'.format(
            group_id, project.label, self.subject_id, self.session_id))
        self.assertEqual(r_session.id, self.session_id)

        # Resolve acquisition
        r_acquisition = fw.lookup([
            group_id, project.label, subject.label, session.label,
            acquisition.label
        ])
        self.assertEqual(r_acquisition.id, self.acquisition_id)

        # Resolve acquisition file
        r_file = fw.lookup([
            group_id, project.label, subject.label, session.label,
            acquisition.label, 'files', 'yeats.txt'
        ])
        self.assertEqual(r_file.name, 'yeats.txt')
        self.assertEqual(r_file.size, len(poem))

        # Test not found
        try:
            fw.lookup('NOT-A-GROUP/NOT-A-PROJECT')
            self.fail('Expected ApiException!')
        except flywheel.ApiException as e:
            self.assertEqual(e.status, 404)

        # TODO: Test Analyses

        # Test resolve gears
        r_gear = fw.lookup(['gears', gear.gear.name])
        self.assertEqual(r_gear.gear, gear.gear)
Esempio n. 20
0
    def test_packfile(self):
        fw = self.fw

        session = fw.get_session(self.session_id)
        self.assertNotEmpty(session.label)

        acquisitions = fw.get_session_acquisitions(self.session_id)
        self.assertEmpty(acquisitions)

        poem1 = 'Surely some revelation is at hand;'
        poem2 = 'Surely the Second Coming is at hand.'

        token = fw.start_project_packfile_upload(self.project_id)
        self.assertNotEmpty(token)

        files = [
            flywheel.FileSpec('yeats1.txt', poem1),
            flywheel.FileSpec('yeats2.txt', poem2)
        ]

        fw.project_packfile_upload(self.project_id, token, files)

        acquisition_label = self.rand_string()

        metadata = {
            'project': {
                '_id': self.project_id
            },
            'session': {
                'label': session.label
            },
            'acquisition': {
                'label': acquisition_label
            },
            'packfile': {
                'type': 'text'
            }
        }
        metastr = json.dumps(metadata)

        resp = fw.end_project_packfile_upload(self.project_id,
                                              token,
                                              metastr,
                                              _preload_content=False)
        self.assertEqual(resp.status_code, 200)

        for line in resp.iter_lines():
            if six.PY3:
                line = line.decode('utf-8')
            print('response line: ' + line)

        acquisitions = fw.get_session_acquisitions(self.session_id)
        self.assertEqual(len(acquisitions), 1)

        self.assertEqual(acquisitions[0].label, acquisition_label)
        self.assertEqual(len(acquisitions[0].files), 1)

        self.assertEqual(acquisitions[0].files[0].name,
                         acquisition_label + '.zip')

        zip_data = fw.download_file_from_acquisition_as_data(
            acquisitions[0].id, acquisition_label + '.zip')
        zip_file = zipfile.ZipFile(six.BytesIO(zip_data))

        names = zip_file.namelist()
        self.assertIn(acquisition_label + '/yeats1.txt', names)
        self.assertIn(acquisition_label + '/yeats2.txt', names)

        with zip_file.open(acquisition_label + '/yeats1.txt') as f:
            data = f.read()
            if six.PY3:
                data = data.decode('utf-8')
            self.assertEqual(data, poem1)
        with zip_file.open(acquisition_label + '/yeats2.txt') as f:
            data = f.read()
            if six.PY3:
                data = data.decode('utf-8')
            self.assertEqual(data, poem2)
Esempio n. 21
0
def upload_attachment(client,
                      target_object,
                      level,
                      attachment_dict,
                      subject_rename=None,
                      session_rename=None,
                      folders=['anat', 'dwi', 'func', 'fmap', 'perf'],
                      dry_run=True):
    '''processes and uploads the attachment
    '''

    bids = {"Filename": None, "Folder": None, "Path": None}

    if level == 'project':
        bids.update({"Filename": attachment_dict['name'], "Path": '.'})
    else:

        # manipulate sub and ses labels
        subj_replace = none_replace if subject_rename is None else subject_rename
        subj_label = subj_replace(
            force_label_format(target_object.subject.label))

        ses_replace = none_replace if session_rename is None else session_rename
        sess_label = ses_replace(force_label_format(target_object.label))

        attachment_dict['name'] = force_template_format(
            attachment_dict['name'])
        attachment_dict['name'] = attachment_dict['name'].format(
            subject=subj_label, session=sess_label)

        # get the dir/folder/path
        dirs = Path(attachment_dict['name']).parts
        folder = [x for x in dirs if x in folders]
        if not folder:
            folder = None
        else:
            folder = folder[0]

        path = str(Path(attachment_dict['name']).parent)

        # get filename
        attachment_dict['name'] = str(Path(attachment_dict['name']).name)

        # get BIDS ready
        bids.update({
            "Filename": str(Path(attachment_dict['name']).name),
            "Folder": folder,
            "Path": path
        })
    logger.debug(
        "Attachment details:\n\tFilename: {}\n\tData: {}\n\tMIMEType: {}".
        format(attachment_dict['name'], attachment_dict['data'],
               attachment_dict['type']))
    logger.debug("Updating BIDS: \n\t{}".format(bids))

    verify_name, verify_data, verify_type = verify_attachment(
        attachment_dict['name'], attachment_dict['data'],
        attachment_dict['type'])

    if not all([verify_name, verify_data, verify_type]):

        logger.warning("Attachments may not be valid for upload!")
        logger.debug(
            "\tFilename valid: {}\n\tData valid: {}\n\tMIMEType valid: {}".
            format(verify_name, verify_data, verify_type))

    if not dry_run:
        file_spec = flywheel.FileSpec(attachment_dict['name'],
                                      attachment_dict['data'],
                                      attachment_dict['type'])
        target_object.upload_file(file_spec)
        target_object = target_object.reload()
        target_object.update_file_info(attachment_dict['name'], {'BIDS': bids})
        logger.info("Attachment uploaded!")
Esempio n. 22
0
    def test_batch_with_jobs(self):
        fw = self.fw_device

        gear = fw.get_gear(self.gear_id)
        self.assertIsNotNone(gear)

        # Make a couple jobs
        poem = 'Mere anarchy is loosed upon the world,'
        fw.upload_file_to_acquisition(self.acquisition_id,
                                      flywheel.FileSpec('yeats.txt', poem))
        inputs = {
            'any-file':
            flywheel.FileReference(id=self.acquisition_id,
                                   type='acquisition',
                                   name='yeats.txt')
        }
        destination = flywheel.JobDestination(id=self.acquisition_id,
                                              type='acquisition')
        tag = self.rand_string()

        jobs = [
            flywheel.Job(gear_id=self.gear_id,
                         destination=destination,
                         inputs=inputs,
                         tags=[tag]),
            flywheel.Job(gear_id=self.gear_id,
                         destination=destination,
                         inputs=inputs,
                         tags=[tag])
        ]

        # Propose batch jobs
        proposal = fw.create_batch_job_from_jobs(
            flywheel.BatchJobsProposalInput(jobs=jobs))

        self.assertIsNotNone(proposal)

        self.assertNotEmpty(proposal.id)
        # Gear Id should be none, each job already knows its gear
        self.assertIsNone(proposal.gear_id)
        self.assertIsNotNone(proposal.origin)
        self.assertEqual(proposal.origin.type, 'device')
        self.assertNotEmpty(proposal.origin.id)

        self.assertTimestampBeforeNow(proposal.created)
        self.assertGreaterEqual(proposal.modified, proposal.created)

        # Get
        r_batch = fw.get_batch(proposal.id)
        self.assertIsNotNone(r_batch)
        # Gear Id should be none, each job already knows its gear
        self.assertIsNone(proposal.gear_id)
        self.assertEqual(r_batch.state, 'pending')

        # Get all
        batches = fw.get_all_batches()
        self.assertIn(r_batch, batches)

        # Start
        jobs = fw.start_batch(proposal.id)
        self.assertEqual(len(jobs), 2)

        # Get again
        r_batch2 = fw.get_batch(proposal.id)
        self.assertEqual(r_batch2.state, 'running')
        self.assertTimestampAfter(r_batch2.modified, r_batch.modified)

        # Cancel
        cancelled = fw.cancel_batch(proposal.id)
        self.assertEqual(cancelled, 2)
Esempio n. 23
0
    def test_job_queue(self):
        fw = self.fw

        poem = 'The blood-dimmed tide is loosed, and everywhere'
        fw.upload_file_to_acquisition(self.acquisition_id,
                                      flywheel.FileSpec('yeats.txt', poem))

        tag = self.rand_string()
        job = flywheel.Job(gear_id=self.gear_id,
                           destination=flywheel.JobDestination(
                               id=self.acquisition_id, type='acquisition'),
                           inputs={
                               'any-file':
                               flywheel.FileReference(id=self.acquisition_id,
                                                      type='acquisition',
                                                      name='yeats.txt')
                           },
                           tags=[tag])

        # Add
        job_id = fw.add_job(job)
        self.assertNotEmpty(job_id)

        # Check
        r_job = fw.get_job(job_id)
        self.assertEqual(r_job.state, 'pending')

        # Run
        r_job = fw.get_next_job(tags=[tag])
        self.assertIsNotNone(r_job)
        self.assertEqual(r_job.id, job_id)
        self.assertIsNotNone(r_job.request)
        self.assertIn('dir', r_job.request.target)
        self.assertEqual(r_job.request.target['dir'], '/flywheel/v0')

        # Next fetch should not find any jobs
        try:
            fw.get_next_job(tags=[tag])
            self.fail('Expected an error retrieving next job')
        except flywheel.ApiException as e:
            self.assertEqual(e.status, 400)

        # Heartbeat
        fw.modify_job(job_id, {})
        r_job2 = fw.get_job(job_id)
        self.assertTimestampAfter(r_job2.modified, r_job.modified)

        # Add logs
        log1 = [flywheel.JobLogStatement(fd=-1, msg='System message')]
        log2 = [
            flywheel.JobLogStatement(fd=1, msg='Standard out'),
            flywheel.JobLogStatement(fd=2, msg='Standard err')
        ]
        fw.add_job_logs(job_id, log1)
        fw.add_job_logs(job_id, log2)

        # Finish
        r_job.change_state('complete')

        r_job3 = fw.get_job(job_id)
        self.assertEqual(r_job3.state, 'complete')
        self.assertTimestampAfter(r_job3.modified, r_job2.modified)

        logs = fw.get_job_logs(job_id)
        self.assertEqual(len(logs.logs), 4)
        self.assertEqual(logs.logs[1], log1[0])
        self.assertEqual(logs.logs[2], log2[0])
        self.assertEqual(logs.logs[3], log2[1])
Esempio n. 24
0
    def test_subject_files(self):
        fw = self.fw

        subject = flywheel.Subject(code=self.rand_string(), project=self.project_id)
        subject_id = fw.add_subject(subject)

        # Upload a file
        poem = 'The best lack all conviction, while the worst'
        fw.upload_file_to_subject(subject_id, flywheel.FileSpec('yeats.txt', poem))

        # Check that the file was added to the subject
        r_subject = fw.get_subject(subject_id)
        self.assertEqual(len(r_subject.files), 1)
        self.assertEqual(r_subject.files[0].name, 'yeats.txt')
        self.assertEqual(r_subject.files[0].size, 45)
        self.assertEqual(r_subject.files[0].mimetype, 'text/plain')

        # Download the file and check content
        self.assertDownloadFileTextEquals(fw.download_file_from_subject_as_data, subject_id, 'yeats.txt', poem)

        # Test unauthorized download with ticket for the file
        self.assertDownloadFileTextEqualsWithTicket(fw.get_subject_download_url, subject_id, 'yeats.txt', poem)

        # Test file attributes
        self.assertEqual(r_subject.files[0].modality, None)
        self.assertEmpty(r_subject.files[0].classification)
        self.assertEqual(r_subject.files[0].type, 'text')

        resp = r_subject.files[0].update(type='type', modality='modality')

        # Check that no jobs were triggered, and attrs were modified
        self.assertEqual(resp.jobs_spawned, 0)

        r_subject = fw.get_subject(subject_id)
        self.assertEqual(r_subject.files[0].modality, "modality")
        self.assertEmpty(r_subject.files[0].classification)
        self.assertEqual(r_subject.files[0].type, 'type')

        # Test classifications
        resp = fw.replace_subject_file_classification(subject_id, 'yeats.txt', {
            'Custom': ['measurement1', 'measurement2'],
        })
        self.assertEqual(resp.modified, 1)
        self.assertEqual(resp.jobs_spawned, 0)

        r_subject = fw.get_subject(subject_id)
        self.assertEqual(r_subject.files[0].classification, {
            'Custom': ['measurement1', 'measurement2']
        });

        resp = fw.modify_subject_file_classification(subject_id, 'yeats.txt', {
            'add': {
                'Custom': ['HelloWorld'],
            },
            'delete': {
                'Custom': ['measurement2']
            }
        })
        self.assertEqual(resp.modified, 1)
        self.assertEqual(resp.jobs_spawned, 0)

        r_subject = fw.get_subject(subject_id)
        self.assertEqual(r_subject.files[0].classification, {
            'Custom': ['measurement1', 'HelloWorld'],
        });

        # Test file info
        self.assertEmpty(r_subject.files[0].info)
        fw.replace_subject_file_info(subject_id, 'yeats.txt', {
            'a': 1,
            'b': 2,
            'c': 3,
            'd': 4
        })

        fw.set_subject_file_info(subject_id, 'yeats.txt', {
            'c': 5
        })

        r_subject = fw.get_subject(subject_id)
        self.assertEqual(r_subject.files[0].info['a'], 1)
        self.assertEqual(r_subject.files[0].info['b'], 2)
        self.assertEqual(r_subject.files[0].info['c'], 5)
        self.assertEqual(r_subject.files[0].info['d'], 4)

        fw.delete_subject_file_info_fields(subject_id, 'yeats.txt', ['c', 'd'])
        r_subject = fw.get_subject(subject_id)
        self.assertEqual(r_subject.files[0].info['a'], 1)
        self.assertEqual(r_subject.files[0].info['b'], 2)
        self.assertNotIn('c', r_subject.files[0].info)
        self.assertNotIn('d', r_subject.files[0].info)

        fw.replace_subject_file_info(subject_id, 'yeats.txt', {})
        r_subject = fw.get_subject(subject_id)
        self.assertEmpty(r_subject.files[0].info)

        # Delete file
        fw.delete_subject_file(subject_id, 'yeats.txt')
        r_subject = fw.get_subject(subject_id)
        self.assertEmpty(r_subject.files)

        # Delete subject
        fw.delete_subject(subject_id)