Source code for veupath_chatbot.integrations.veupathdb.strategy_api.records

"""Record type info, single record, and column distribution methods.

Provides :class:`RecordsMixin` with methods for record type metadata,
individual record retrieval, and column value distributions.
"""

from typing import cast

from veupath_chatbot.integrations.veupathdb.strategy_api.base import StrategyAPIBase
from veupath_chatbot.platform.errors import WDKError
from veupath_chatbot.platform.logging import get_logger
from veupath_chatbot.platform.types import JSONObject, JSONValue

logger = get_logger(__name__)


[docs] class RecordsMixin(StrategyAPIBase): """Mixin providing record type info, single record, and distribution methods."""
[docs] async def get_record_type_info(self, record_type: str) -> JSONObject: """Get expanded record type info including attributes and tables. :param record_type: WDK record type (e.g. "gene"). :returns: Record type metadata with attribute fields. """ await self._ensure_session() return cast( JSONObject, await self.client.get( f"/record-types/{record_type}", params={"format": "expanded"}, ), )
[docs] async def get_single_record( self, record_type: str, primary_key: list[JSONObject], attributes: list[str] | None = None, tables: list[str] | None = None, ) -> JSONObject: """Fetch a single record by its primary key. WDK's ``POST /record-types/{type}/records`` requires ``primaryKey``, ``attributes``, and ``tables`` arrays in the request body. When ``attributes`` or ``tables`` are not provided we send empty arrays which tells WDK to return the default set. :param record_type: WDK record type. :param primary_key: List of ``{name, value}`` primary key parts. :param attributes: Attribute names to include (empty = default set). :param tables: Table names to include (empty = none). :returns: Full record with requested attributes/tables. """ payload: JSONObject = { "primaryKey": cast(JSONValue, primary_key), "attributes": cast(JSONValue, attributes or []), "tables": cast(JSONValue, tables or []), } await self._ensure_session() return cast( JSONObject, await self.client.post( f"/record-types/{record_type}/records", json=payload, ), )
[docs] async def get_column_distribution( self, step_id: int, column_name: str ) -> JSONObject: """Get distribution data for a column using the byValue column reporter. Uses ``POST .../columns/{col}/reports/byValue`` which returns a ``histogram`` array and ``statistics`` object. This replaces the deprecated ``filter-summary`` endpoint. Not all columns support the byValue reporter (e.g. overview or composite columns). When WDK returns an error, an empty result is returned so the frontend can show a friendly message. :param step_id: WDK step ID (must be part of a strategy). :param column_name: Attribute/column name. :returns: ``{histogram: [...], statistics: {...}}`` """ await self._ensure_session() try: result = await self.client.post( f"/users/{self.user_id}/steps/{step_id}" f"/columns/{column_name}/reports/byValue", json={"reportConfig": {}}, ) return result if isinstance(result, dict) else {} except WDKError: logger.warning( "Column reporter unavailable", step_id=step_id, column_name=column_name, ) return {"histogram": [], "statistics": {}}