Source code for q2_smart.ts_endpoints.models.trait_list

from dataclasses import asdict, dataclass

from q2_smart.exceptions import Q2SmartInternalError


[docs] @dataclass class TraitMetadata: """Visible trait metadata. ``users_count`` and ``total_users`` are snapshots from daily trait coverage processing, not live counts. They may be older when processing is delayed. """ id: str display_name: str description: str type: str source: str | None users_count: int total_users: int
[docs] def to_dict(self) -> dict: return asdict(self)
[docs] @dataclass class TraitList: traits: list[TraitMetadata]
[docs] @classmethod def from_response(cls, payload: object) -> "TraitList": if not isinstance(payload, dict) or not isinstance(payload.get("traits"), list): raise Q2SmartInternalError( "Invalid GET traits response: 'traits' must be a list" ) traits = [] text_fields = ("id", "display_name", "description", "type", "source") count_fields = ("users_count", "total_users") required = (*text_fields, *count_fields) for index, trait in enumerate(payload["traits"]): if not isinstance(trait, dict): raise Q2SmartInternalError( f"Invalid GET traits response: trait at index {index} must be an object" ) if "hidden" not in trait: raise Q2SmartInternalError( f"Invalid GET traits response: trait at index {index} is missing hidden" ) if not isinstance(trait["hidden"], bool): raise Q2SmartInternalError( f"Invalid GET traits response: trait at index {index} has non-boolean hidden" ) if trait["hidden"]: continue missing = [field for field in required if field not in trait] if missing: raise Q2SmartInternalError( f"Invalid GET traits response: trait at index {index} is missing {', '.join(missing)}" ) for field in text_fields: value = trait[field] if not isinstance(value, str) and not ( field == "source" and value is None ): raise Q2SmartInternalError( f"Invalid GET traits response: trait at index {index} has invalid {field}" ) for field in count_fields: if type(trait[field]) is not int or trait[field] < 0: raise Q2SmartInternalError( f"Invalid GET traits response: trait at index {index} has invalid {field}" ) traits.append(TraitMetadata(**{field: trait[field] for field in required})) return cls(traits)
[docs] def to_json(self) -> dict: return {"traits": [trait.to_dict() for trait in self.traits]}