Skip to content

onconova.terminology.controllers

TerminologyController

Bases: ControllerBase

Api controller for handling terminology-related endpoints.

get_terminology_concepts(terminologyName, query)

Retrieves terminology concepts from the specified terminology, applying optional filters and search criteria.

Source code in onconova/terminology/controllers.py
@route.get(
    path="/{terminologyName}/concepts",
    response={200: Paginated[CodedConceptSchema], **COMMON_HTTP_ERRORS},  # type: ignore
    operation_id="getTerminologyConcepts",
)
@paginate()
def get_terminology_concepts(
    self, terminologyName: str, query: Query[TerminologyFilters]
):
    """        
    Retrieves terminology concepts from the specified terminology, applying optional filters and search criteria.
    """
    queryset = getattr(terminologies, terminologyName).objects.all()
    if query.search_term:
        # Prepare the search term
        search_term = query.search_term.strip()
        # Query matching criteria
        match_code = Q(code__icontains=search_term)
        match_display = Q(display__icontains=search_term)
        match_synonyms = Q(synonym_match=True)
        # Prepare the filtered queryset
        queryset = (
            queryset.annotate(
                # Aggreagate the matching of the search term against all synonyms in the array
                synonym_match=RawSQL(
                    """
                EXISTS (
                    SELECT 1
                    FROM unnest(synonyms) AS synonym
                    WHERE synonym ILIKE %s
                )
                """,
                    params=[f"%{search_term}%"],
                )
            )
            .filter(match_code | match_display | match_synonyms)
            .distinct()
            .annotate(
                matching_score=(
                    get_matching_score_expression(match_code, 10)
                    + get_matching_score_expression(match_display, 5)
                    + get_matching_score_expression(match_synonyms, 1)
                    - Cast(StrIndex("display", Value(search_term)), IntegerField())
                    - Cast(Length("display"), IntegerField())
                ),
            )
            .order_by("-matching_score")
        )

    if query.codes:
        queryset = queryset.filter(code__in=query.codes).distinct()
    return queryset

TerminologyFilters

Bases: Schema

Schema for filtering terminology queries.

Attributes:

Name Type Description
search_term str | None

Optional search term to filter results. Mapped from the "query" field in input.

codes List[str] | None

Optional list of codes to filter results. Mapped from the "codes" field in input.

codes class-attribute instance-attribute

search_term class-attribute instance-attribute

get_matching_score_expression(query, score)

Generates a Django Case expression that assigns a specified score when a condition is met.

Parameters:

Name Type Description Default

query

Any

A Django Q object or condition to evaluate.

required

score

int

The score to assign if the condition is true.

required

Returns:

Name Type Description
Case Expression

A Django Case expression that returns score when query is true, otherwise returns 0.

Source code in onconova/terminology/controllers.py
def get_matching_score_expression(query: any, score):
    """
    Generates a Django Case expression that assigns a specified score when a condition is met.

    Args:
        query (Any): A Django Q object or condition to evaluate.
        score (int): The score to assign if the condition is true.

    Returns:
        Case (Expression): A Django Case expression that returns `score` when `query` is true, otherwise returns 0.
    """
    return Case(
        When(query, then=Value(score)),
        default=Value(0),
        output_field=IntegerField(),
    )
runner