Mongoosetross's picture
Fast deploy (index 51f60c37cb32)
4d4cb57 verified
Raw
History Blame Contribute Delete
2.97 kB
from __future__ import annotations
from typing import Literal
from pydantic import BaseModel, Field
RelName = str
Quantifier = Literal["any", "all", "none", "exactly"]
ColorBy = Literal["relation", "family", "confidence", "depth", "macroarea"]
ViewName = Literal["tree", "radial", "map", "table", "stats"]
class WalsClause(BaseModel):
feature_id: str
values: list[int] = Field(default_factory=list)
class NodePredicate(BaseModel):
languages: list[str] = Field(default_factory=list)
families: list[str] = Field(default_factory=list)
macroareas: list[str] = Field(default_factory=list)
statuses: list[str] = Field(default_factory=list)
term_contains: str = ""
term_regex: str | None = None
require_coords: bool = False
min_lat: float | None = None
max_lat: float | None = None
min_lon: float | None = None
max_lon: float | None = None
wals: list[WalsClause] = Field(default_factory=list)
phonemes_have: list[str] = Field(default_factory=list)
phonemes_lack: list[str] = Field(default_factory=list)
require_tone: bool | None = None
# Popularity within language (modern lects). Zipf ~3 rare … ~7 very common.
min_zipf: float | None = Field(default=None, ge=0.0, le=8.0)
# Keep leaves whose corpus rank is <= N (1 = most frequent). Orders of magnitude presets in UI.
max_rank: int | None = Field(default=None, ge=1, le=5_000_000)
keep_unknown: bool = False
class EdgeFilter(BaseModel):
relations: list[str] = Field(default_factory=list)
min_confidence: float = 0.7
max_depth: int = Field(default=3, ge=1, le=8)
max_visit: int = Field(default=50_000, ge=100, le=200_000)
# Also walk toward etymons (forward CSR) and place them opposite descendants.
include_ancestors: bool = True
max_ancestor_depth: int = Field(default=4, ge=0, le=8)
class PathFilter(BaseModel):
node: NodePredicate = Field(default_factory=NodePredicate)
quantifier: Quantifier = "any"
exactly_k: int = 1
relations_any: list[str] = Field(default_factory=list)
relations_none: list[str] = Field(default_factory=list)
apply_to_root: bool = False
class TreeQuery(BaseModel):
term: str
lang: str
# Editorial etymology id / etymology_number key; omit to auto-resolve.
ety: str | None = None
edges: EdgeFilter = Field(default_factory=EdgeFilter)
leaf: NodePredicate = Field(default_factory=NodePredicate)
path: PathFilter = Field(default_factory=PathFilter)
expand: list[str] = Field(default_factory=list)
# High default = do not collapse children into cluster stubs.
cluster_threshold: int = Field(default=1_000_000, ge=1, le=1_000_000)
max_payload: int = Field(default=50_000, ge=50, le=100_000)
color_by: ColorBy = "relation"
class SuggestHit(BaseModel):
term: str
lang: str
ety: str = ""
lang_display: str | None = None
family_name: str | None = None
child_count: int = 0
id: int