Ejemplo n.º 1
0
def get_by_id(call: APICall, company_id, req_model: TaskRequest):
    task = TaskBLL.get_task_with_access(req_model.task,
                                        company_id=company_id,
                                        allow_public=True)
    task_dict = task.to_proper_dict()
    unprepare_from_saved(call, task_dict)
    call.result.data = {"task": task_dict}
Ejemplo n.º 2
0
def get_by_id(call: APICall, company_id, req_model: TaskRequest):
    task = TaskBLL.get_task_with_access(req_model.task,
                                        company_id=company_id,
                                        allow_public=True)
    task_dict = task.to_proper_dict()
    conform_output_tags(call, task_dict)
    call.result.data = {"task": task_dict}
Ejemplo n.º 3
0
def delete(call: APICall, company_id, req_model: DeleteRequest):
    task = TaskBLL.get_task_with_access(req_model.task,
                                        company_id=company_id,
                                        requires_write_access=True)

    move_to_trash = req_model.move_to_trash
    force = req_model.force

    if task.status != TaskStatus.created and not force:
        raise errors.bad_request.TaskCannotBeDeleted(
            "due to status, use force=True",
            task=task.id,
            expected=TaskStatus.created,
            current=task.status,
        )

    with translate_errors_context():
        result = cleanup_task(task, force)

        if move_to_trash:
            collection_name = task._get_collection_name()
            archived_collection = "{}__trash".format(collection_name)
            task.switch_collection(archived_collection)
            try:
                # A simple save() won't do due to mongoengine caching (nothing will be saved), so we have to force
                # an insert. However, if for some reason such an ID exists, let's make sure we'll keep going.
                with TimingContext("mongo", "save_task"):
                    task.save(force_insert=True)
            except Exception:
                pass
            task.switch_collection(collection_name)

        task.delete()
        org_bll.update_org_tags(company_id, reset=True)
        call.result.data = dict(deleted=True, **attr.asdict(result))
Ejemplo n.º 4
0
def dequeue(call: APICall, company_id, req_model: UpdateRequest):
    task = TaskBLL.get_task_with_access(
        req_model.task,
        company_id=company_id,
        only=("id", "execution", "status", "project"),
        requires_write_access=True,
    )
    if task.status not in (TaskStatus.queued,):
        raise errors.bad_request.InvalidTaskId(
            status=task.status, expected=TaskStatus.queued
        )

    _dequeue(task, company_id)

    status_message = req_model.status_message
    status_reason = req_model.status_reason
    res = DequeueResponse(
        **ChangeStatusRequest(
            task=task,
            new_status=TaskStatus.created,
            status_reason=status_reason,
            status_message=status_message,
        ).execute(unset__execution__queue=1)
    )
    res.dequeued = 1

    call.result.data_model = res
Ejemplo n.º 5
0
def reset(call: APICall, company_id, req_model: UpdateRequest):
    task = TaskBLL.get_task_with_access(req_model.task,
                                        company_id=company_id,
                                        requires_write_access=True)

    force = req_model.force

    if not force and task.status == TaskStatus.published:
        raise errors.bad_request.InvalidTaskStatus(task_id=task.id,
                                                   status=task.status)

    api_results = {}
    updates = {}

    try:
        dequeued = _dequeue(task, company_id, silent_fail=True)
    except APIError:
        # dequeue may fail if the task was not enqueued
        pass
    else:
        if dequeued:
            api_results.update(dequeued=dequeued)
        updates.update(unset__execution__queue=1)

    cleaned_up = cleanup_task(task, force)
    api_results.update(attr.asdict(cleaned_up))

    updates.update(
        set__last_iteration=DEFAULT_LAST_ITERATION,
        set__last_metrics={},
        unset__output__result=1,
        unset__output__model=1,
        __raw__={"$pull": {
            "execution.artifacts": {
                "mode": {
                    "$ne": "input"
                }
            }
        }},
    )

    res = ResetResponse(**ChangeStatusRequest(
        task=task,
        new_status=TaskStatus.created,
        force=force,
        status_reason="reset",
        status_message="reset",
    ).execute(started=None, completed=None, published=None, **updates))

    for key, value in api_results.items():
        setattr(res, key, value)

    call.result.data_model = res
Ejemplo n.º 6
0
def set_requirements(call: APICall, company_id, req_model: SetRequirementsRequest):
    requirements = req_model.requirements
    with translate_errors_context():
        task = TaskBLL.get_task_with_access(
            req_model.task,
            company_id=company_id,
            only=("status", "script"),
            requires_write_access=True,
        )
        if not task.script:
            raise errors.bad_request.MissingTaskFields(
                "Task has no script field", task=task.id
            )
        res = task.update(
            script__requirements=requirements, last_update=datetime.utcnow()
        )
        call.result.data_model = UpdateResponse(updated=res)
        if res:
            call.result.data_model.fields = {"script.requirements": requirements}
Ejemplo n.º 7
0
def set_task_status_from_call(request: UpdateRequest,
                              company_id,
                              new_status=None,
                              **kwargs) -> dict:
    task = TaskBLL.get_task_with_access(
        request.task,
        company_id=company_id,
        only=("status", "project"),
        requires_write_access=True,
    )
    status_reason = request.status_reason
    status_message = request.status_message
    force = request.force
    return ChangeStatusRequest(
        task=task,
        new_status=new_status or task.status,
        status_reason=status_reason,
        status_message=status_message,
        force=force,
    ).execute(**kwargs)
Ejemplo n.º 8
0
def set_task_status_from_call(
    request: UpdateRequest, company_id, new_status=None, **set_fields
) -> dict:
    fields_resolver = SetFieldsResolver(set_fields)
    task = TaskBLL.get_task_with_access(
        request.task,
        company_id=company_id,
        only=tuple({"status", "project"} | fields_resolver.get_names()),
        requires_write_access=True,
    )

    status_reason = request.status_reason
    status_message = request.status_message
    force = request.force
    return ChangeStatusRequest(
        task=task,
        new_status=new_status or task.status,
        status_reason=status_reason,
        status_message=status_message,
        force=force,
    ).execute(**fields_resolver.get_fields(task))
Ejemplo n.º 9
0
def reset(call: APICall, company_id, req_model: UpdateRequest):
    task = TaskBLL.get_task_with_access(req_model.task,
                                        company_id=company_id,
                                        requires_write_access=True)

    force = req_model.force

    if not force and task.status == TaskStatus.published:
        raise errors.bad_request.InvalidTaskStatus(task_id=task.id,
                                                   status=task.status)

    api_results = {}
    updates = {}

    cleaned_up = cleanup_task(task, force)
    api_results.update(attr.asdict(cleaned_up))

    updates.update(
        unset__script__requirements=1,
        set__last_iteration=DEFAULT_LAST_ITERATION,
        set__last_metrics={},
        unset__output__result=1,
        unset__output__model=1,
    )

    res = ResetResponse(**ChangeStatusRequest(
        task=task,
        new_status=TaskStatus.created,
        force=force,
        status_reason="reset",
        status_message="reset",
    ).execute(started=None, completed=None, published=None, **updates))

    for key, value in api_results.items():
        setattr(res, key, value)

    call.result.data_model = res
Ejemplo n.º 10
0
def set_task_status_from_call(request: UpdateRequest,
                              company_id,
                              new_status=None,
                              **set_fields) -> dict:
    fields_resolver = SetFieldsResolver(set_fields)
    task = TaskBLL.get_task_with_access(
        request.task,
        company_id=company_id,
        only=tuple({"status", "project", "started", "duration"}
                   | fields_resolver.get_names()),
        requires_write_access=True,
    )

    if "duration" not in fields_resolver.get_names():
        if new_status == Task.started:
            fields_resolver.add_fields(
                min__duration=max(0, task.duration or 0))
        elif new_status in (
                TaskStatus.completed,
                TaskStatus.failed,
                TaskStatus.stopped,
        ):
            fields_resolver.add_fields(
                duration=int((task.started -
                              datetime.utcnow()).total_seconds()))

    status_reason = request.status_reason
    status_message = request.status_message
    force = request.force
    return ChangeStatusRequest(
        task=task,
        new_status=new_status or task.status,
        status_reason=status_reason,
        status_message=status_message,
        force=force,
    ).execute(**fields_resolver.get_fields(task))