Skip to content

Model Registry

The ModelRegistry provides programmatic access to the bundled model catalog, including availability metadata.

Model

perplexity_webui_scraper.models.types.Model

Bases: BaseModel

Immutable metadata for a single Perplexity AI model.

ATTRIBUTE DESCRIPTION
id

Canonical string key used to select this model (e.g. "perplexity/best").

TYPE: str

name

Human-readable display name shown in the UI.

TYPE: str

description

Short description of the model's characteristics.

TYPE: str

identifier

Internal Perplexity model identifier sent in the API payload.

TYPE: str

identifier_by_tier

Optional identifier overrides selected by account tier.

TYPE: dict[ModelTier, str]

tool_name

MCP tool name used when registering this model as an MCP tool.

TYPE: str

provider

Provider slug used for catalog grouping.

TYPE: str

is_official

Whether Perplexity currently lists the model in its official WebUI.

TYPE: bool

min_tier

Minimum Perplexity subscription, or None when unknown.

TYPE: ModelTier | None

mode

API request mode sent in the payload (e.g. "copilot", "search", "research").

TYPE: ModelMode

mode_by_tier

Optional mode overrides selected by account tier.

TYPE: dict[ModelTier, ModelMode]

status

Observed availability state. Unknown models require explicit risk acknowledgement and are the default until a live test is recorded.

TYPE: ModelStatus

last_tested_at

UTC timestamp of the test that supports the current status, or None when the model has not been tested.

TYPE: datetime | None


ModelRegistry

perplexity_webui_scraper.models.registry.ModelRegistry

ModelRegistry(
    raw_models: list[dict[str, object]] | None = None,
)

Registry of all available Perplexity AI models.

The registry is populated at instantiation time by reading models.json from the _static package directory via importlib.resources. The singleton MODELS instance is created at module import time.

Usage::

from perplexity_webui_scraper.models import MODELS

model = MODELS.resolve("perplexity/best")
all_models = MODELS.list_all()

Load models from the bundled models.json static asset.

Source code in src/perplexity_webui_scraper/models/registry.py
def __init__(self, raw_models: list[dict[str, object]] | None = None) -> None:
    """Load models from the bundled ``models.json`` static asset."""
    self._models = self._load(raw_models if raw_models is not None else self._read_static_models())

Methods:

resolve

resolve(model_id: str) -> Model

Look up a model by its canonical string ID.

PARAMETER DESCRIPTION
model_id

The model identifier, e.g. "perplexity/best".

TYPE: str

RETURNS DESCRIPTION
Model

The matching :class:Model instance.

RAISES DESCRIPTION
ValueError

If model_id is not registered.

Source code in src/perplexity_webui_scraper/models/registry.py
def resolve(self, model_id: str) -> Model:
    """Look up a model by its canonical string ID.

    Args:
        model_id: The model identifier, e.g. ``"perplexity/best"``.

    Returns:
        The matching :class:`Model` instance.

    Raises:
        ValueError: If ``model_id`` is not registered.
    """
    if model_id in self._models:
        return self._models[model_id]

    available = ", ".join(f'"{m}"' for m in self._models)
    raise ValueError(f"Unknown model {model_id!r}. Available models: {available}")

list_all

list_all() -> list[Model]

Return all registered :class:Model instances in definition order.

RETURNS DESCRIPTION
list[Model]

List of all models loaded from models.json.

Source code in src/perplexity_webui_scraper/models/registry.py
def list_all(self) -> list[Model]:
    """Return all registered :class:`Model` instances in definition order.

    Returns:
        List of all models loaded from ``models.json``.
    """
    return list(self._models.values())

resolve_for_use

resolve_for_use(
    model_id: str,
    *,
    allow_risky_model: bool = False,
    custom_model_mode: ModelMode = "copilot",
) -> Model

Resolve a model and enforce explicit acknowledgement of risky states.

Source code in src/perplexity_webui_scraper/models/registry.py
def resolve_for_use(
    self,
    model_id: str,
    *,
    allow_risky_model: bool = False,
    custom_model_mode: ModelMode = "copilot",
) -> Model:
    """Resolve a model and enforce explicit acknowledgement of risky states."""
    if model_id.startswith(_CUSTOM_PREFIX):
        identifier = model_id.removeprefix(_CUSTOM_PREFIX)
        if not fullmatch(_CUSTOM_IDENTIFIER_PATTERN, identifier):
            raise ValueError(
                "Custom model identifiers must contain 1-128 letters, digits, dots, colons, underscores, or hyphens"
            )

        model = Model(
            id=model_id,
            name=f"Custom model ({identifier})",
            description="User-supplied Perplexity internal model identifier.",
            identifier=identifier,
            tool_name="pplx_custom",
            provider="custom",
            min_tier=None,
            mode=custom_model_mode,
            status="unknown",
        )
    else:
        model = self.resolve(model_id)

    if model.status != "available" and not allow_risky_model:
        raise ModelStatusError(model.id, model.status, MODEL_STATUS_DESCRIPTIONS[model.status])

    if model.status != "available":
        warn(MODEL_STATUS_DESCRIPTIONS[model.status], ModelRiskWarning, stacklevel=2)

    return model