Skip to content

_aux_task_group_disambiguation

FUNCTION DESCRIPTION
get_task_group_owner_email

Find and return the user's email associated to a TaskGroupV2 instance.

remove_duplicate_task_groups

Extract an item for each version from a sorted task-group list.

serialize_task_group

Serialize a TaskGroupV2 (including its tasks) into a dict.

Attributes

Classes

Functions:

_disambiguate_task_groups(*, matching_task_groups, user_id, default_group_id, db) async

Find ownership-based top-priority task group, if any.

PARAMETER DESCRIPTION

matching_task_groups

TYPE: list[TaskGroupV2]

user_id

TYPE: int

default_group_id

TYPE: int | None

db

TYPE: AsyncSession

RETURNS DESCRIPTION
TaskGroupV2 | None

The task group or None.

Source code in fractal_server/app/routes/api/v2/_aux_task_group_disambiguation.py
async def _disambiguate_task_groups(
    *,
    matching_task_groups: list[TaskGroupV2],
    user_id: int,
    default_group_id: int | None,
    db: AsyncSession,
) -> TaskGroupV2 | None:
    """
    Find ownership-based top-priority task group, if any.

    Args:
        matching_task_groups:
        user_id:
        default_group_id:
        db:

    Returns:
        The task group or `None`.
    """

    # Highest priority: task groups created by user
    list_user_ids = [tg.user_id for tg in matching_task_groups]
    try:
        ind_user_id = list_user_ids.index(user_id)
        task_group = matching_task_groups[ind_user_id]
        logger.debug(
            "[_disambiguate_task_groups] "
            f"Found task group {task_group.id} with {user_id=}, return."
        )
        return task_group
    except ValueError:
        logger.debug(
            "[_disambiguate_task_groups] "
            f"No task group with {user_id=}, continue."
        )

    # Medium priority: task groups owned by default user group
    settings = Inject(get_settings)
    list_user_group_ids = [tg.user_group_id for tg in matching_task_groups]
    if settings.FRACTAL_DEFAULT_GROUP_NAME is not None:
        try:
            ind_user_group_id = list_user_group_ids.index(default_group_id)
            task_group = matching_task_groups[ind_user_group_id]
            logger.debug(
                "[_disambiguate_task_groups] "
                f"Found task group {task_group.id} with {user_id=}, return."
            )
            return task_group
        except ValueError:
            logger.debug(
                "[_disambiguate_task_groups] "
                "No task group with user_group_id="
                f"{default_group_id}, continue."
            )

    # Lowest priority: task groups owned by other groups, sorted
    # according to age of the user/usergroup link
    logger.debug(
        "[_disambiguate_task_groups] "
        "Sort remaining task groups by oldest-user-link."
    )
    stm = (
        select(LinkUserGroup.group_id)
        .where(LinkUserGroup.user_id == user_id)
        .where(LinkUserGroup.group_id.in_(list_user_group_ids))
        .order_by(LinkUserGroup.timestamp_created.asc())
    )
    res = await db.execute(stm)
    oldest_user_group_id = res.scalars().first()
    logger.debug(
        f"[_disambiguate_task_groups] Result: {oldest_user_group_id=}."
    )
    task_group = next(
        iter(
            task_group
            for task_group in matching_task_groups
            if task_group.user_group_id == oldest_user_group_id
        ),
        None,
    )
    return task_group

_disambiguate_task_groups_not_none(*, matching_task_groups, user_id, default_group_id, db) async

Find ownership-based top-priority task group, and fail otherwise.

PARAMETER DESCRIPTION

matching_task_groups

TYPE: list[TaskGroupV2]

user_id

TYPE: int

default_group_id

TYPE: int | None

db

TYPE: AsyncSession

RETURNS DESCRIPTION
TaskGroupV2

The top-priority task group.

Source code in fractal_server/app/routes/api/v2/_aux_task_group_disambiguation.py
async def _disambiguate_task_groups_not_none(
    *,
    matching_task_groups: list[TaskGroupV2],
    user_id: int,
    default_group_id: int | None,
    db: AsyncSession,
) -> TaskGroupV2:
    """
    Find ownership-based top-priority task group, and fail otherwise.

    Args:
        matching_task_groups:
        user_id:
        default_group_id:
        db:

    Returns:
        The top-priority task group.
    """
    task_group = await _disambiguate_task_groups(
        matching_task_groups=matching_task_groups,
        user_id=user_id,
        default_group_id=default_group_id,
        db=db,
    )
    if task_group is None:
        error_msg = (
            "[_disambiguate_task_groups_not_none] Could not find a task "
            f"group ({user_id=}, {default_group_id=})."
        )
        logger.error(f"UnreachableBranchError {error_msg}")
        raise UnreachableBranchError(error_msg)
    else:
        return task_group

get_task_group_owner_email(*, task_group, db) async

Find and return the user's email associated to a TaskGroupV2 instance.

Source code in fractal_server/app/routes/api/v2/_aux_task_group_disambiguation.py
async def get_task_group_owner_email(
    *,
    task_group: TaskGroupV2,
    db: AsyncSession,
) -> str:
    """
    Find and return the user's email associated to a TaskGroupV2 instance.
    """
    res = await db.execute(
        select(UserOAuth.email)
        .join(TaskGroupV2, TaskGroupV2.user_id == UserOAuth.id)
        .where(TaskGroupV2.id == task_group.id)
    )
    user_email = res.scalar_one()
    return user_email

remove_duplicate_task_groups(*, task_groups, user_id, default_group_id, db) async

Extract an item for each version from a sorted task-group list.

PARAMETER DESCRIPTION

task_groups

A list of task groups with identical pkg_name

TYPE: list[TaskGroupV2]

user_id

User ID

TYPE: int

RETURNS DESCRIPTION
list[TaskGroupV2]

New list of task groups with no duplicate (pkg_name,version) entries

Source code in fractal_server/app/routes/api/v2/_aux_task_group_disambiguation.py
async def remove_duplicate_task_groups(
    *,
    task_groups: list[TaskGroupV2],
    user_id: int,
    default_group_id: int | None,
    db: AsyncSession,
) -> list[TaskGroupV2]:
    """
    Extract an item for each `version` from a *sorted* task-group list.

    Args:
        task_groups: A list of task groups with identical `pkg_name`
        user_id: User ID

    Returns:
        New list of task groups with no duplicate `(pkg_name,version)` entries
    """

    new_task_groups = [
        (
            await _disambiguate_task_groups_not_none(
                matching_task_groups=list(groups),
                user_id=user_id,
                default_group_id=default_group_id,
                db=db,
            )
        )
        for version, groups in itertools.groupby(
            task_groups, key=lambda tg: tg.version
        )
    ]
    return new_task_groups

serialize_task_group(*, task_group, user_email=None, in_use=None)

Serialize a TaskGroupV2 (including its tasks) into a dict. Optionally include user_email and in_use if provided.

Source code in fractal_server/app/routes/api/v2/_aux_task_group_disambiguation.py
def serialize_task_group(
    *,
    task_group: TaskGroupV2,
    user_email: str | None = None,
    in_use: bool | None = None,
) -> dict[str, Any]:
    """
    Serialize a TaskGroupV2 (including its tasks) into a dict.
    Optionally include `user_email` and `in_use` if provided.
    """
    serialized_task_group = dict(
        task_list=[orm_model_to_dict(task) for task in task_group.task_list],
        **orm_model_to_dict(task_group),
    )
    if user_email is not None:
        serialized_task_group["user_email"] = user_email
    if in_use is not None:
        serialized_task_group["in_use"] = in_use

    return serialized_task_group