Example #1
0
def handler(event, context):
    '''
    this is to check if the task run is done:
    http://docs.sevenbridges.com/reference#get-task-execution-details
    '''
    # used to automatically determine the environment
    tibanna_settings = event.get('_tibanna', {})
    tibanna = Tibanna(**tibanna_settings)
    sbg = sbg_utils.create_sbg_workflow(token=tibanna.sbg_keys, **event.get('workflow'))
    ff_meta = ff_utils.create_ffmeta(sbg, **event.get('ff_meta'))

    # check status of workflow, error if not done
    status = sbg.check_task()
    LOG.info("status of sbg task is %s" % status)

    if not status['status'] in ['DONE', 'COMPLETED', 'FAILED']:
        data = {'workflow': sbg.as_dict(),
                'status': status}
        raise sbg_utils.SBGStillRunningException('Task not finished => %s' % data)

    if status['status'] == 'FAILED':
        ff_meta.run_status = 'error'
        ff_meta.description = 'SBG task %s reported FAILED status' % sbg.task_id
        ff_meta.post(key=tibanna.ff_keys)

    # TODO: handle only specific errors so this can terminate the rest of the workflow

    return {'workflow': sbg.as_dict(),
            'run_response': status,
            'ff_meta': ff_meta.as_dict(),
            'pf_meta': event.get('pf_meta'),
            '_tibanna': tibanna.as_dict(),
            }
Example #2
0
def handler(event, context):
    '''
    this is to check if the task run is done:
    http://docs.sevenbridges.com/reference#get-task-execution-details
    consider this format:
      {'data': event.get('workflow'), # actully in reverse
       'data_name': 'workflow', # how to get the data
       'conversion_routine': 'function to run, taking workflow as argument'
       }
       then put / patch data_name with data
    #
    '''
    # used to automatically determine the environment
    tibanna_settings = event.get('_tibanna', {})
    tibanna = utils.Tibanna(**tibanna_settings)
    sbg = sbg_utils.create_sbg_workflow(token=tibanna.sbg_keys,
                                        **event.get('workflow'))
    # run_response = event.get('run_response')
    ff_meta = ff_utils.create_ffmeta(sbg, **event.get('ff_meta'))
    key = event.get('ff_keys')
    ff_keys = utils.get_access_keys() if not key else key

    workflow_post_resp = ff_meta.post(key=ff_keys)

    return {
        "workflow": sbg.as_dict(),
        "res": workflow_post_resp,
        "ff_meta": ff_meta.as_dict(),
        "_tibanna": tibanna.as_dict()
    }
Example #3
0
def handler(event, context):
    '''
    this is to run the actual task
    '''
    # used to automatically determine the environment
    tibanna_settings = event.get('_tibanna', {})
    tibanna = utils.Tibanna(**tibanna_settings)
    sbg = sbg_utils.create_sbg_workflow(token=tibanna.sbg_keys, **event.get('workflow'))
    ff_meta = ff_utils.create_ffmeta(sbg, **event.get('ff_meta'))

    # TODO: check a whole bunch of stuff here maybe...
    if ff_meta.run_status == "output_file_transfer_finished":
        ff_meta.run_status = 'complete'
    else:
        ff_meta.run_status = 'error'
        ff_meta.description = ('set to error because status comming into finalize was not' +
                               ' output_file_transfer_finished as expected')

    # make all the file export meta-data stuff here
    # TODO: fix ff_meta mapping issue
    ff_meta.post(key=tibanna.ff_keys)

    return {'workflow': sbg.as_dict(),
            'ff_meta': ff_meta.as_dict(),
            "_tibanna": tibanna.as_dict(),
            }
Example #4
0
def handler(event, context):
    # get data
    input_file_args = event.get('input_file_args')
    parameter_dict = event.get('parameter_dict')

    # used to automatically determine the environment
    tibanna_settings = event.get('_tibanna', {})
    tibanna = utils.Tibanna(**tibanna_settings)
    sbg = sbg_utils.create_sbg_workflow(token=tibanna.sbg_keys, **event.get('workflow'))

    ff_meta = ff_utils.create_ffmeta(sbg, **event.get('ff_meta'))
    # import_ids = sbg.import_id_list
    pf_meta = event.get('pf_meta')

    # create Task for workflow run later
    task_name = sbg.app_name
    if tibanna.settings and tibanna.settings.get('run_name'):
        task_name = tibanna.settings.get('run_name')

    task_input = sbg_utils.SBGTaskInput(task_name,
                                        project=sbg.project_id,
                                        app=sbg.project_id + '/' + sbg.app_name,
                                        inputs=parameter_dict)

    for input_file in input_file_args:
        for import_id in input_file.get('import_ids', []):

            # this will handle checking if the import / file is on sbg, otherwise
            # it will throw an error
            res = sbg.check_import(import_id)

            # No idea why, but sometimes it comes back without
            # results as a sub object
            results = res.get('result', res)
            sbg_file_name = results.get('name')
            sbg_file_id = results.get('id')
            arg_name = input_file.get('workflow_argument_name')
            arg_uuids = input_file.get('uuid')
            # we need to know if this is a list so we can build proper task inputs for sbg
            is_list = isinstance(arg_uuids, (list, tuple))
            task_input.add_inputfile(sbg_file_name, sbg_file_id, arg_name, is_list)
            sbg.task_input = task_input

            # ff_meta.input_files.append({'workflow_argument_name': arg_name, 'value': arg_uuid})
            # Soo: This information was alreadyin ff_meta that was passed into this function.

    # make all the file export meta-data stuff here
    # TODO: fix ff_meta bugs with input / output files
    ff_meta.post(key=tibanna.ff_keys)

    return {'workflow': sbg.as_dict(),
            'ff_meta': ff_meta.as_dict(),
            'pf_meta': pf_meta,
            "_tibanna": tibanna.as_dict(),
            }
Example #5
0
def handler(event, context):
    '''
    this is to run the actual task
    '''
    # used to automatically determine the environment
    tibanna_settings = event.get('_tibanna', {})
    tibanna = utils.Tibanna(**tibanna_settings)
    sbg = sbg_utils.create_sbg_workflow(token=tibanna.sbg_keys,
                                        **event.get('workflow'))

    pf_meta = event.get('pf_meta')

    # create task on SBG
    LOG.info("sbg task input is %s" % sbg.task_input.__dict__)
    create_resp = sbg.create_task(sbg.task_input)
    LOG.info("create task response is %s" % create_resp)
    if create_resp['status'] != 'DRAFT':
        raise Exception("Failed to create draft task with input %s" %
                        sbg.task_input.__dict__)
    run_response = sbg.run_task()
    LOG.info("run task respons is %s" % run_response)
    if run_response.get('status', 0) == 400:
        raise Exception(
            "Failed to create task with input %s\n detailed info is %s" %
            (sbg.task_input.__dict__, run_response))

    ff_meta = ff_utils.create_ffmeta(sbg, **event.get('ff_meta'))
    ff_meta.run_status = 'running'
    ff_meta.sbg_task_id = run_response.get('id')

    # make all the file export meta-data stuff here
    # TODO: fix ff_meta mapping issue
    ff_meta.post(key=tibanna.ff_keys)

    return {
        'workflow': sbg.as_dict(),
        'run_response': run_response,
        'ff_meta': ff_meta.as_dict(),
        'pf_meta': pf_meta,
        "_tibanna": tibanna.as_dict(),
    }
Example #6
0
def handler(event, context):
    '''
    export output files from sbg to our s3
    '''

    # get data
    # used to automatically determine the environment
    tibanna_settings = event.get('_tibanna', {})
    tibanna = Tibanna(**tibanna_settings)
    sbg = sbg_utils.create_sbg_workflow(token=tibanna.sbg_keys,
                                        **event.get('workflow'))
    run_response = event.get('run_response')
    ff_meta = event.get('ff_meta')
    uuid = ff_meta['uuid']
    pf_meta = event.get('pf_meta')

    if run_response in ['FAILED', 'ABORTED']:
        raise Exception("workflow run failed or aborted")

    sbg.export_all_output_files(run_response, ff_meta, base_dir=uuid)
    # creating after we export will add output file info to ff_meta
    ff_meta = ff_utils.create_ffmeta(sbg, **event.get('ff_meta'))
    ff_meta.run_status = "output_files_transferring"
    ff_meta.post(key=tibanna.ff_keys)

    for pf in pf_meta:
        pf['status'] = "uploading"
    # we still need a code for patching.

    return {
        'workflow': sbg.as_dict(),
        'ff_meta': ff_meta.as_dict(),
        # 'pf_meta': [pf.as_dict() for pf in pf_meta]
        'pf_meta': pf_meta,
        '_tibanna': tibanna.as_dict()
    }
Example #7
0
def handler(event, context):
    '''
    this is generic function to run sbg workflow
    based on the data passed in

    workflow_uuid : for now, pass this on. Later we can add a code to automatically retrieve this from app_name.
    Note multiple workflow_uuids can be available for an app_name
    (different versions of the same app could have a different uuid)
    '''
    # get incomming data
    input_file_list = event.get('input_files')
    app_name = event.get('app_name')
    parameter_dict = event.get('parameters')
    workflow_uuid = event.get('workflow_uuid')
    output_bucket = event.get('output_bucket')
    tibanna_settings = event.get('_tibanna', {})
    # if they don't pass in env guess it from output_bucket
    env = tibanna_settings.get('env', '-'.join(output_bucket.split('-')[1:-1]))
    # tibanna provides access to keys based on env and stuff like that
    tibanna = Tibanna(env,
                      s3_keys=event.get('s3_keys'),
                      ff_keys=event.get('ff_keys'),
                      settings=tibanna_settings)

    LOG.info("input data is %s" % event)
    # represents the SBG info we need
    sbg = sbg_utils.create_sbg_workflow(app_name, tibanna.sbg_keys)
    LOG.info("sbg is %s" % sbg.__dict__)

    # represents the workflow metadata to be stored in fourfront
    parameters, _ = sbg_utils.to_sbg_workflow_args(parameter_dict,
                                                   vals_as_string=True)

    # get argument format & type info from workflow
    workflow_info = ff_utils.get_metadata(workflow_uuid, key=tibanna.ff_keys)
    LOG.info("workflow info  %s" % workflow_info)
    if 'error' in workflow_info.get('@type', []):
        raise Exception("FATAL, can't lookupt workflow info for % fourfront" %
                        workflow_uuid)

    # This dictionary has a key 'arguments' with a value
    # { 'workflow_argument_name': ..., 'argument_type': ..., 'argument_format': ... }

    # get format-extension map
    try:
        fp_schema = ff_utils.get_metadata("profiles/file_processed.json",
                                          key=tibanna.ff_keys)
        fe_map = fp_schema.get('file_format_file_extension')
    except Exception as e:
        LOG.error(
            "Can't get format-extension map from file_processed schema. %s\n" %
            e)

    # processed file metadata
    output_files = []
    try:
        if 'arguments' in workflow_info:
            pf_meta = []
            for arg in workflow_info.get('arguments'):
                if (arg.get('argument_type') in [
                        'Output processed file', 'Output report file',
                        'Output QC file'
                ]):

                    of = dict()
                    of['workflow_argument_name'] = arg.get(
                        'workflow_argument_name')
                    of['type'] = arg.get('argument_type')
                    if 'argument_format' in arg:
                        # These are not processed files but report or QC files.
                        pf = ff_utils.ProcessedFileMetadata(
                            file_format=arg.get('argument_format'))
                        try:
                            resp = pf.post(
                                key=tibanna.ff_keys
                            )  # actually post processed file metadata here
                            resp = resp.get('@graph')[0]
                            of['upload_key'] = resp.get('upload_key')
                            of['value'] = resp.get('uuid')
                        except Exception as e:
                            LOG.error(
                                "Failed to post Processed file metadata. %s\n"
                                % e)
                            LOG.error("resp" + str(resp) + "\n")
                            raise e
                        of['format'] = arg.get('argument_format')
                        of['extension'] = fe_map.get(
                            arg.get('argument_format'))
                        pf_meta.append(pf)
                    output_files.append(of)

    except Exception as e:
        LOG.error("output_files = " + str(output_files) + "\n")
        LOG.error("Can't prepare output_files information. %s\n" % e)
        raise e

    # create the ff_meta output info
    input_files = []
    for input_file in input_file_list:
        for idx, uuid in enumerate(ensure_list(input_file['uuid'])):
            input_files.append({
                'workflow_argument_name':
                input_file['workflow_argument_name'],
                'value':
                uuid,
                'ordinal':
                idx + 1
            })
    LOG.info("input_files is %s" % input_files)

    ff_meta = ff_utils.create_ffmeta(sbg,
                                     workflow_uuid,
                                     input_files,
                                     parameters,
                                     run_url=tibanna.settings.get('url', ''),
                                     output_files=output_files)
    LOG.info("ff_meta is %s" % ff_meta.__dict__)

    # store metadata so we know the run has started
    ff_meta.post(key=tibanna.ff_keys)

    # mount all input files to sbg this will also update sbg to store the import_ids
    for infile in input_file_list:
        imps = mount_on_sbg(infile, tibanna.s3_keys, sbg)
        infile['import_ids'] = imps

    # create a link to the output directory as well
    if output_bucket:
        sbg_volume = sbg_utils.create_sbg_volume_details()
        res = sbg.create_volumes(sbg_volume,
                                 output_bucket,
                                 public_key=tibanna.s3_keys['key'],
                                 secret_key=tibanna.s3_keys['secret'])
        vol_id = res.get('id')
        if not vol_id:
            # we got an error
            raise Exception("Unable to mount output volume, error is %s " %
                            res)
        sbg.output_volume_id = vol_id

    # let's not pass keys in plain text parameters
    return {
        "input_file_args": input_file_list,
        "workflow": sbg.as_dict(),
        "ff_meta": ff_meta.as_dict(),
        'pf_meta': [meta.as_dict() for meta in pf_meta],
        "_tibanna": tibanna.as_dict(),
        "parameter_dict": parameter_dict
    }
Example #8
0
def handler(event, context):
    '''
    this is to check if the task run is done:
    http://docs.sevenbridges.com/reference#get-task-execution-details
    '''
    # get data
    # used to automatically determine the environment
    tibanna_settings = event.get('_tibanna', {})
    tibanna = utils.Tibanna(**tibanna_settings)
    sbg = sbg_utils.create_sbg_workflow(token=tibanna.sbg_keys,
                                        **event.get('workflow'))
    ff_meta = ff_utils.create_ffmeta(sbg, **event.get('ff_meta'))
    pf_meta = event.get('pf_meta')
    # ensure this bad boy is always initialized
    patch_meta = False

    if len(sbg.export_report) != len(ff_meta.output_files):
        ff_meta.run_status = 'error'
        ff_meta.description = "no files output"
        ff_meta.post(key=tibanna.ff_keys)
        raise Exception(
            "Failing the workflow because sbg outputed files = %d and ffmeta = %d"
            % (len(sbg.export_report), len(ff_meta.output_files)))

    for idx, export in enumerate(sbg.export_report):
        upload_key = export['upload_key']
        export_id = export['export_id']
        export_res = sbg.check_export(export_id)
        print("export res is %s", export_res)
        status = export_res.get('state')
        sbg.export_report[idx]['status'] = status
        if status == 'COMPLETED':
            patch_meta = OUTFILE_UPDATERS[sbg.app_name]('uploaded', sbg,
                                                        ff_meta, tibanna)
            if pf_meta:
                pf_meta = update_processed_file_metadata(
                    'uploaded', pf_meta, tibanna)
        elif status in ['PENDING', 'RUNNING']:
            patch_meta = OUTFILE_UPDATERS[sbg.app_name]('uploading', sbg,
                                                        ff_meta, tibanna)
            raise sbg_utils.SBGStillRunningException(
                "Export of file %s is still running" % upload_key)
        elif status in ['FAILED']:
            patch_meta = OUTFILE_UPDATERS[sbg.app_name]('upload failed', sbg,
                                                        ff_meta, tibanna)
            ff_meta.run_status = 'error'
            ff_meta.post(key=tibanna.ff_keys)
            raise Exception("Failed to export file %s \n sbg result: %s" %
                            (upload_key, export_res))

    # if we got all the exports let's go ahead and update our ff_metadata object
    ff_meta.run_status = "output_file_transfer_finished"

    # allow for a simple way for updater to add appropriate meta_data
    if patch_meta:
        ff_meta.__dict__.update(patch_meta)

    # make all the file export meta-data stuff here
    # TODO: fix bugs with ff_meta mapping for output and input file
    ff_meta.post(key=tibanna.ff_keys)

    return {
        'workflow': sbg.as_dict(),
        'ff_meta': ff_meta.as_dict(),
        'pf_meta': pf_meta,
        '_tibanna': tibanna.as_dict()
    }