Exemplo n.º 1
0
def get_job(id, **kwargs):
    """
    Query for job and task-level metadata for a specified job

    :param id: Job ID
    :type id: str

    :rtype: JobMetadataResponse
    """

    url = '{cromwell_url}/{id}/metadata?{query}'.format(
        cromwell_url=_get_base_url(),
        id=id,
        query='includeKey=' + '&includeKey='.join(job_include_keys))
    response = requests.get(url,
                            auth=kwargs.get('auth'),
                            headers=kwargs.get('auth_headers'))

    if response.status_code != 200:
        handle_error(response)

    job = response.json()

    failures = [
        format_task_failure(name, m)
        for name, metadata in job.get('calls', {}).items() for m in metadata
        if m.get('failures') is not None
    ]

    # if there are no tasks/subworkflows but there are errors, get them
    if not len(failures) and job.get('failures'):
        failures = [format_workflow_failure(f) for f in job.get('failures')]

    tasks = [
        format_task(task_name, task_metadata)
        for task_name, task_metadata in job.get('calls', {}).items()
    ]

    sorted_tasks = sorted(tasks, key=lambda t: t.start)
    start = _parse_datetime(job.get('start'))
    submission = _parse_datetime(job.get('submission'))
    if submission is None:
        # Submission is required by the common jobs API. Submission may be missing
        # for subworkflows in which case we fallback to the workflow start time
        # or, if not started, the current time. This fallback logic may be
        # removed if/when Cromwell changes behavior per https://github.com/broadinstitute/cromwell/issues/2968.
        submission = start or datetime.utcnow()
    return JobMetadataResponse(
        id=id,
        name=job.get('workflowName'),
        status=job_statuses.cromwell_workflow_status_to_api(job.get('status')),
        submission=submission,
        start=start,
        end=_parse_datetime(job.get('end')),
        inputs=update_key_names(job.get('inputs', {})),
        outputs=update_key_names(job.get('outputs', {})),
        labels=job.get('labels'),
        failures=failures,
        extensions=ExtendedFields(tasks=sorted_tasks,
                                  parent_job_id=job.get('parentWorkflowId')))
Exemplo n.º 2
0
def _metadata_response(id, job):
    return JobMetadataResponse(id=id,
                               status=job_statuses.dsub_to_api(job),
                               submission=job['create-time'],
                               name=job['job-name'],
                               start=job.get('start-time'),
                               end=job['end-time'],
                               inputs=job['inputs'],
                               outputs=job['outputs'],
                               labels=labels.dsub_to_api(job),
                               failures=failures.get_failures(job),
                               extensions=extensions.get_extensions(job))
Exemplo n.º 3
0
def get_job(id, **kwargs):
    """
    Query for job and task-level metadata for a specified job

    :param id: Job ID
    :type id: str

    :rtype: JobMetadataResponse
    """
    url = '{cromwell_url}/{id}/metadata'.format(cromwell_url=_get_base_url(),
                                                id=id)
    response = requests.get(url,
                            auth=kwargs.get('auth'),
                            headers=kwargs.get('auth_headers'))
    job = response.json()
    if response.status_code == BadRequest.code:
        raise BadRequest(job.get('message'))
    elif response.status_code == NotFound.code:
        raise NotFound(job.get('message'))
    elif response.status_code == InternalServerError.code:
        raise InternalServerError(job.get('message'))

    failures = None
    if job.get('failures'):
        failures = [
            FailureMessage(failure=f['message']) for f in job['failures']
        ]
    # Get the most recent run of each task in task_metadata
    tasks = [
        format_task(task_name, task_metadata[-1])
        for task_name, task_metadata in job.get('calls', {}).items()
    ]
    sorted_tasks = sorted(tasks, key=lambda t: t.start)
    start = _parse_datetime(job.get('start'))
    submission = _parse_datetime(job.get('submission'))
    if submission is None:
        # Submission is required by the common jobs API. Submission may be missing
        # for subworkflows in which case we fallback to the workflow start time
        # or, if not started, the current time. This fallback logic may be
        # removed if/when Cromwell changes behavior per https://github.com/broadinstitute/cromwell/issues/2968.
        submission = start or datetime.utcnow()
    return JobMetadataResponse(id=id,
                               name=job.get('workflowName'),
                               status=job.get('status'),
                               submission=submission,
                               start=start,
                               end=_parse_datetime(job.get('end')),
                               inputs=update_key_names(job.get('inputs', {})),
                               outputs=update_key_names(job.get('outputs',
                                                                {})),
                               labels=job.get('labels'),
                               failures=failures,
                               extensions=ExtendedFields(tasks=sorted_tasks))
Exemplo n.º 4
0
 def must_get_job(self, job_id):
     resp = self.client.open('/jobs/{}'.format(job_id), method='GET')
     self.assert_status(resp, 200)
     return JobMetadataResponse.from_dict(resp.json)