Skip to content

Built-in Help

mixpanel_headless.help() prints reference text for any public name. mixpanel_headless.reference returns the same information as structured, frozen dataclasses. Both work offline: no network call, no config file, no Workspace. See the Built-in Help guide for the query grammar, the three output formats, the JSON shape, the exit codes, and the mp help CLI command.

import mixpanel_headless as mp
from mixpanel_headless import reference as ref

mp.help("Workspace.query")                       # prints text, returns None
entry = ref.describe("Workspace.query_funnel")   # HelpEntry
hits = ref.search("retention")                   # SearchResult
print(ref.render(entry, "markdown"))

Import with an alias

from mixpanel_headless import help shadows the Python builtin in that namespace. Prefer import mixpanel_headless as mp and mp.help(...).

mixpanel_headless.reference

mixpanel_headless.reference

Built-in API reference: help(), describe(), search(), render().

This module is the public face of the offline help system. It introspects the installed mixpanel_headless package and answers questions about its own surface — signatures, fields, enum values, Literal aliases, exception trees, Workspace domains — without a network call, without a config file, and without building a Workspace.

Three ways to use it:

import mixpanel_headless as mp

mp.help("Workspace.query")                  # print reference text
entry = mp.reference.describe("Filter")     # structured HelpEntry
hits = mp.reference.search("cohort")        # structured SearchResult

The CLI twin is mp help QUERY... (also python3 -m mixpanel_headless help QUERY...).

Importing this module is cheap: the introspection machinery loads lazily on the first call, so import mixpanel_headless does not pay for it.

HelpFormat module-attribute

HelpFormat = Literal['text', 'markdown', 'json']

Output format accepted by the renderers and the CLI --format option.

HelpKind module-attribute

HelpKind = Literal[MemberKind, 'overview', 'listing', 'parameter']

Classification of a help entry (what kind of object the query resolved to).

Every MemberKind plus the three kinds that only exist as whole entries: the package overview, a listing (Workspace, types, exceptions), and a single parameter of a callable. A search result is a SearchResult, not a HelpEntry, and has no kind.

DocSections dataclass

DocSections(
    summary: str = "",
    body: str = "",
    args: tuple[tuple[str, str], ...] = (),
    returns: str = "",
    raises: tuple[tuple[str, str], ...] = (),
    example: str = "",
    notes: str = "",
)

Parsed Google-style docstring.

ATTRIBUTE DESCRIPTION
summary

First paragraph before the first section header, lines joined with single spaces.

TYPE: str

body

Everything before the first section header, dedented, newlines kept.

TYPE: str

args

(name, description) pairs from Args:.

TYPE: tuple[tuple[str, str], ...]

returns

Text of Returns: (and Yields:).

TYPE: str

raises

(exception_name, description) pairs from Raises:.

TYPE: tuple[tuple[str, str], ...]

example

Text of Example: / Examples:, dedented, fences kept.

TYPE: str

notes

Text of Note: / Notes:.

TYPE: str

to_dict

to_dict() -> dict[str, object]

Convert to a JSON-serializable dict.

RETURNS DESCRIPTION
dict[str, object]

A dict with args and raises as lists of two-item lists.

Source code in src/mixpanel_headless/_internal/help/models.py
def to_dict(self) -> dict[str, object]:
    """Convert to a JSON-serializable dict.

    Returns:
        A dict with ``args`` and ``raises`` as lists of two-item lists.
    """
    return {
        "summary": self.summary,
        "body": self.body,
        "args": _pairs_to_lists(self.args),
        "returns": self.returns,
        "raises": _pairs_to_lists(self.raises),
        "example": self.example,
        "notes": self.notes,
    }

FieldDoc dataclass

FieldDoc(
    name: str,
    annotation: str,
    default: str | None = None,
    required: bool = False,
    constraints: tuple[str, ...] = (),
    alias: str | None = None,
    values: tuple[str, ...] = (),
    description: str = "",
)

One public field of a dataclass or Pydantic model.

ATTRIBUTE DESCRIPTION
name

Python attribute name.

TYPE: str

annotation

Display form of the annotation.

TYPE: str

default

Display form of the default (repr or <factory name>), or None.

TYPE: str | None

required

True when the field has no default.

TYPE: bool

constraints

Pydantic constraints such as "max_length=255".

TYPE: tuple[str, ...]

alias

JSON alias when it differs from name, else None.

TYPE: str | None

values

Enum member names or literal values accepted by the field, if any.

TYPE: tuple[str, ...]

description

Field description from Field(description=...) or the docstring.

TYPE: str

__post_init__

__post_init__() -> None

Reject a required field that also carries a default.

RAISES DESCRIPTION
ValueError

When required is True and default is not None; a field with a default is by definition optional.

Source code in src/mixpanel_headless/_internal/help/models.py
def __post_init__(self) -> None:
    """Reject a required field that also carries a default.

    Raises:
        ValueError: When ``required`` is ``True`` and ``default`` is not
            ``None``; a field with a default is by definition optional.
    """
    if self.required and self.default is not None:
        raise ValueError(
            f"FieldDoc {self.name!r} is required but has default {self.default!r}"
        )

to_dict

to_dict() -> dict[str, object]

Convert to a JSON-serializable dict.

RETURNS DESCRIPTION
dict[str, object]

A dict with every field; tuples become lists.

Source code in src/mixpanel_headless/_internal/help/models.py
def to_dict(self) -> dict[str, object]:
    """Convert to a JSON-serializable dict.

    Returns:
        A dict with every field; tuples become lists.
    """
    return {
        "name": self.name,
        "annotation": self.annotation,
        "default": self.default,
        "required": self.required,
        "constraints": list(self.constraints),
        "alias": self.alias,
        "values": list(self.values),
        "description": self.description,
    }

Group dataclass

Group(title: str, items: tuple[MemberDoc, ...])

A titled group of members, used for Workspace domain grouping.

ATTRIBUTE DESCRIPTION
title

Group title, for example "Discovery".

TYPE: str

items

Members in the group.

TYPE: tuple[MemberDoc, ...]

to_dict

to_dict() -> dict[str, object]

Convert to a JSON-serializable dict.

RETURNS DESCRIPTION
dict[str, object]

{"title": ..., "items": [member dicts]}.

Source code in src/mixpanel_headless/_internal/help/models.py
def to_dict(self) -> dict[str, object]:
    """Convert to a JSON-serializable dict.

    Returns:
        ``{"title": ..., "items": [member dicts]}``.
    """
    return {"title": self.title, "items": [item.to_dict() for item in self.items]}

HelpEntry dataclass

HelpEntry(
    kind: HelpKind,
    name: str,
    qualname: str,
    summary: str,
    doc: DocSections,
    signature: SignatureDoc | None = None,
    bases: tuple[str, ...] = (),
    config: tuple[tuple[str, str], ...] = (),
    construction: tuple[MemberDoc, ...] = (),
    fields: tuple[FieldDoc, ...] = (),
    properties: tuple[MemberDoc, ...] = (),
    methods: tuple[MemberDoc, ...] = (),
    values: tuple[str, ...] = (),
    value: str | None = None,
    groups: tuple[Group, ...] = (),
    referenced_types: tuple[tuple[str, str], ...] = (),
    used_by: tuple[UsageDoc, ...] = (),
    domain: str | None = None,
    see_also: tuple[str, ...] = (),
    hints: tuple[Hint, ...] = (),
)

Structured description of one resolved help query.

kind, name, qualname, summary, and doc are required. Every collection defaults to an empty tuple and every scalar extra to None, so builders can construct partial entries for kinds that lack a section. Which fields a kind populates is fixed by the conventions below; reference.describe() follows them and the renderers rely on them. A consumer of to_dict() can too.

Per-kind field conventions:

  • method / function: signature holds the callable and name is the display name (Workspace.query, accounts.add). referenced_types lists the library types in the signature. For a Workspace method, domain is the registry domain title and see_also names the other Workspace methods of that domain; both are empty for every other callable. groups is unused.
  • property: signature has no params; its returns is the property type or None.
  • parameter: signature.params holds exactly one ParamDoc and signature.name is the owning callable's bare name; values repeats the parameter's allowed values; summary and doc carry the parameter description.
  • class / model / dataclass: bases, config (models only), construction, fields (models and dataclasses), properties, methods, and used_by map one-to-one to the rendered sections.
  • enum: values holds the member names in definition order and fields reuses FieldDoc for the members: name is the member name, annotation the type name of the member value, default its repr, required always False. bases lists the enum's bases.
  • literal: values holds the allowed values in declaration order.
  • alias: values holds the member display names of the union and referenced_types the (name, summary) rows for the members that are library types.
  • exception: bases[0] is the direct base. groups is empty for a leaf or one group titled Subclasses whose items carry their nesting in MemberDoc.depth (a direct subclass is depth 0). used_by lists the Workspace methods whose Raises: names it.
  • module: one group titled Members with every __all__ name.
  • constant: value is the repr of the value and bases holds one name, the value's type (the enum class for an enum member such as FeatureFlagStatus.ENABLED). values is unused.
  • listing: groups carries the rows (Workspace domains, the types kinds, or the one Exceptions tree whose items carry depth). summary is a count line or the facade's summary.
  • overview: summary is the package version and doc.body the query grammar; groups is empty.
ATTRIBUTE DESCRIPTION
kind

What the query resolved to.

TYPE: HelpKind

name

Display name, for example "Workspace.query" or "Filter".

TYPE: str

qualname

Canonical help query for this entry, for example "Workspace.query" or "Filter"; passing it back to describe() returns the same entry. Not an import path.

TYPE: str

summary

First docstring line (or generated summary for aliases).

TYPE: str

doc

Parsed docstring sections.

TYPE: DocSections

signature

Signature for callables, else None.

TYPE: SignatureDoc | None

bases

Names of public base classes (the value's type for a constant).

TYPE: tuple[str, ...]

config

Non-default Pydantic model config as (key, value) pairs.

TYPE: tuple[tuple[str, str], ...]

construction

Public constructors and factory classmethods.

TYPE: tuple[MemberDoc, ...]

fields

Public dataclass or model fields; enum members for an enum.

TYPE: tuple[FieldDoc, ...]

properties

Public properties.

TYPE: tuple[MemberDoc, ...]

methods

Public methods (instance, class, static).

TYPE: tuple[MemberDoc, ...]

values

Enum member names, literal values, or alias member names.

TYPE: tuple[str, ...]

value

Display form of a constant's value (repr), else None.

TYPE: str | None

groups

Titled member groups for listings, modules, and exception trees.

TYPE: tuple[Group, ...]

referenced_types

(type_name, summary) pairs referenced by a callable.

TYPE: tuple[tuple[str, str], ...]

used_by

Workspace methods that accept (or raise) this type.

TYPE: tuple[UsageDoc, ...]

domain

Registry domain title of a Workspace method, else None.

TYPE: str | None

see_also

Other Workspace methods in the same registry domain.

TYPE: tuple[str, ...]

hints

Hosted-documentation pointers.

TYPE: tuple[Hint, ...]

to_dict

to_dict() -> dict[str, object]

Convert to a JSON-serializable dict.

Nested models convert recursively; tuples become lists; pair tuples become two-item lists. Keys follow the dataclass field order.

RETURNS DESCRIPTION
dict[str, object]

A dict suitable for json.dumps.

Source code in src/mixpanel_headless/_internal/help/models.py
def to_dict(self) -> dict[str, object]:
    """Convert to a JSON-serializable dict.

    Nested models convert recursively; tuples become lists; pair tuples
    become two-item lists. Keys follow the dataclass field order.

    Returns:
        A dict suitable for ``json.dumps``.
    """
    return {
        "kind": self.kind,
        "name": self.name,
        "qualname": self.qualname,
        "summary": self.summary,
        "doc": self.doc.to_dict(),
        "signature": None if self.signature is None else self.signature.to_dict(),
        "bases": list(self.bases),
        "config": _pairs_to_lists(self.config),
        "construction": [member.to_dict() for member in self.construction],
        "fields": [field.to_dict() for field in self.fields],
        "properties": [member.to_dict() for member in self.properties],
        "methods": [member.to_dict() for member in self.methods],
        "values": list(self.values),
        "value": self.value,
        "groups": [group.to_dict() for group in self.groups],
        "referenced_types": _pairs_to_lists(self.referenced_types),
        "used_by": [usage.to_dict() for usage in self.used_by],
        "domain": self.domain,
        "see_also": list(self.see_also),
        "hints": [hint.to_dict() for hint in self.hints],
    }

Hint dataclass

Hint(title: str, url: str)

Pointer to a hosted documentation page.

ATTRIBUTE DESCRIPTION
title

Short human-readable label, for example "Entity management guide".

TYPE: str

url

Absolute URL of the page.

TYPE: str

to_dict

to_dict() -> dict[str, object]

Convert to a JSON-serializable dict.

RETURNS DESCRIPTION
dict[str, object]

{"title": ..., "url": ...}.

Source code in src/mixpanel_headless/_internal/help/models.py
def to_dict(self) -> dict[str, object]:
    """Convert to a JSON-serializable dict.

    Returns:
        ``{"title": ..., "url": ...}``.
    """
    return {"title": self.title, "url": self.url}

MemberDoc dataclass

MemberDoc(
    name: str,
    kind: MemberKind,
    summary: str = "",
    signature: SignatureDoc | None = None,
    depth: int = 0,
)

One member in a listing (method, property, classmethod, module export).

ATTRIBUTE DESCRIPTION
name

Member name, never indented; nesting is carried by depth.

TYPE: str

kind

Member classification, one of MEMBER_KINDS.

TYPE: MemberKind

summary

First docstring line, or "".

TYPE: str

signature

Signature for method / function members (always present for those kinds), None for every other kind.

TYPE: SignatureDoc | None

depth

Nesting level inside a tree-shaped group, 0 for a flat row. The exception tree uses it: each level is one subclass step below the group's root. The text renderer indents two spaces per level; markdown and JSON keep the bare name and expose depth.

TYPE: int

__post_init__

__post_init__() -> None

Validate the kind, its agreement with signature, and depth.

RAISES DESCRIPTION
ValueError

When kind is not one of MEMBER_KINDS, when a method / function member has no signature, when any other kind carries one, or when depth is negative.

Source code in src/mixpanel_headless/_internal/help/models.py
def __post_init__(self) -> None:
    """Validate the kind, its agreement with ``signature``, and ``depth``.

    Raises:
        ValueError: When ``kind`` is not one of ``MEMBER_KINDS``, when a
            ``method`` / ``function`` member has no signature, when any
            other kind carries one, or when ``depth`` is negative.
    """
    if self.depth < 0:
        raise ValueError(f"MemberDoc depth must be >= 0, got {self.depth}")
    if self.kind not in MEMBER_KINDS:
        allowed = ", ".join(MEMBER_KINDS)
        raise ValueError(
            f"Unknown member kind {self.kind!r}; expected one of: {allowed}"
        )
    callable_kind = self.kind in _CALLABLE_MEMBER_KINDS
    if callable_kind and self.signature is None:
        raise ValueError(
            f"MemberDoc {self.name!r} of kind {self.kind!r} requires a signature"
        )
    if not callable_kind and self.signature is not None:
        raise ValueError(
            f"MemberDoc {self.name!r} of kind {self.kind!r} "
            "must not carry a signature"
        )

to_dict

to_dict() -> dict[str, object]

Convert to a JSON-serializable dict.

RETURNS DESCRIPTION
dict[str, object]

A dict with signature converted recursively or None, and

dict[str, object]

depth as an integer.

Source code in src/mixpanel_headless/_internal/help/models.py
def to_dict(self) -> dict[str, object]:
    """Convert to a JSON-serializable dict.

    Returns:
        A dict with ``signature`` converted recursively or ``None``, and
        ``depth`` as an integer.
    """
    return {
        "name": self.name,
        "kind": self.kind,
        "summary": self.summary,
        "signature": None if self.signature is None else self.signature.to_dict(),
        "depth": self.depth,
    }

ParamDoc dataclass

ParamDoc(
    name: str,
    annotation: str | None = None,
    default: str | None = None,
    description: str = "",
    values: tuple[str, ...] = (),
    kind: ParamKind = "positional_or_keyword",
)

One parameter of a callable signature.

ATTRIBUTE DESCRIPTION
name

Parameter name without self; *args and **kwargs keep their prefixes.

TYPE: str

annotation

Display form of the annotation (already cleaned), or None when the parameter has none (as SignatureDoc.returns).

TYPE: str | None

default

repr of the default, or None when the parameter is required.

TYPE: str | None

description

Description from the Args: docstring section, or "".

TYPE: str

values

Literal or enum member values accepted by the parameter, if any.

TYPE: tuple[str, ...]

kind

How the parameter may be passed. Renderers print a bare * before the first keyword_only parameter (unless a var_positional one precedes it) and a / after the last positional_only parameter.

TYPE: ParamKind

to_dict

to_dict() -> dict[str, object]

Convert to a JSON-serializable dict.

RETURNS DESCRIPTION
dict[str, object]

A dict with every field; values becomes a list.

Source code in src/mixpanel_headless/_internal/help/models.py
def to_dict(self) -> dict[str, object]:
    """Convert to a JSON-serializable dict.

    Returns:
        A dict with every field; ``values`` becomes a list.
    """
    return {
        "name": self.name,
        "annotation": self.annotation,
        "default": self.default,
        "description": self.description,
        "values": list(self.values),
        "kind": self.kind,
    }

SearchHit dataclass

SearchHit(category: MemberKind, name: str, summary: str, matched_on: MatchedOn)

One search result row.

ATTRIBUTE DESCRIPTION
category

Display category: the ExportKind of an export or module member (exception, enum, model, dataclass, class, literal, alias, function, module, constant), or method / property for Workspace members.

TYPE: MemberKind

name

Matched name, qualified for Workspace members.

TYPE: str

summary

First docstring line, or "".

TYPE: str

matched_on

Which part of the entry matched the term.

TYPE: MatchedOn

to_dict

to_dict() -> dict[str, object]

Convert to a JSON-serializable dict.

RETURNS DESCRIPTION
dict[str, object]

A dict with the four scalar fields.

Source code in src/mixpanel_headless/_internal/help/models.py
def to_dict(self) -> dict[str, object]:
    """Convert to a JSON-serializable dict.

    Returns:
        A dict with the four scalar fields.
    """
    return {
        "category": self.category,
        "name": self.name,
        "summary": self.summary,
        "matched_on": self.matched_on,
    }

SearchResult dataclass

SearchResult(
    term: str,
    hits: tuple[SearchHit, ...] = (),
    suggestions: tuple[str, ...] = (),
)

Result of reference.search(term).

ATTRIBUTE DESCRIPTION
term

The search term as given.

TYPE: str

hits

Matching entries in display order, duplicates removed.

TYPE: tuple[SearchHit, ...]

suggestions

"Did you mean?" names when there are no hits.

TYPE: tuple[str, ...]

to_dict

to_dict() -> dict[str, object]

Convert to a JSON-serializable dict.

RETURNS DESCRIPTION
dict[str, object]

{"term": ..., "hits": [hit dicts], "suggestions": [...]}.

Source code in src/mixpanel_headless/_internal/help/models.py
def to_dict(self) -> dict[str, object]:
    """Convert to a JSON-serializable dict.

    Returns:
        ``{"term": ..., "hits": [hit dicts], "suggestions": [...]}``.
    """
    return {
        "term": self.term,
        "hits": [hit.to_dict() for hit in self.hits],
        "suggestions": list(self.suggestions),
    }

SignatureDoc dataclass

SignatureDoc(
    name: str, params: tuple[ParamDoc, ...] = (), returns: str | None = None
)

A callable signature with per-parameter documentation.

ATTRIBUTE DESCRIPTION
name

Callable name (unqualified).

TYPE: str

params

Parameters in declaration order.

TYPE: tuple[ParamDoc, ...]

returns

Display form of the return annotation, or None when absent.

TYPE: str | None

to_dict

to_dict() -> dict[str, object]

Convert to a JSON-serializable dict.

RETURNS DESCRIPTION
dict[str, object]

A dict with params converted recursively.

Source code in src/mixpanel_headless/_internal/help/models.py
def to_dict(self) -> dict[str, object]:
    """Convert to a JSON-serializable dict.

    Returns:
        A dict with ``params`` converted recursively.
    """
    return {
        "name": self.name,
        "params": [param.to_dict() for param in self.params],
        "returns": self.returns,
    }

UsageDoc dataclass

UsageDoc(method: str, params: tuple[str, ...])

One Workspace method that accepts a given type ("Used by Workspace").

ATTRIBUTE DESCRIPTION
method

Method name on Workspace.

TYPE: str

params

Names of the parameters whose annotation references the type.

TYPE: tuple[str, ...]

to_dict

to_dict() -> dict[str, object]

Convert to a JSON-serializable dict.

RETURNS DESCRIPTION
dict[str, object]

{"method": ..., "params": [...]}.

Source code in src/mixpanel_headless/_internal/help/models.py
def to_dict(self) -> dict[str, object]:
    """Convert to a JSON-serializable dict.

    Returns:
        ``{"method": ..., "params": [...]}``.
    """
    return {"method": self.method, "params": list(self.params)}

HelpLookupError

HelpLookupError(
    query: str,
    *,
    suggestions: Sequence[str] = (),
    hits: Sequence[SearchHit] = (),
)

Bases: MixpanelHeadlessError

A mixpanel_headless.help() / reference.describe() query matched nothing.

Raised by :func:mixpanel_headless.reference.describe (and re-raised by :func:mixpanel_headless.reference.search for an empty term) when the query names no export, no Workspace member, and no parameter. The lookup is fully offline, so this is never an HTTP failure and the base is :class:MixpanelHeadlessError, not :class:APIError. The CLI maps it to ExitCode.NOT_FOUND (4).

The instance carries the structured recovery data the plain-text help() wrapper prints: close-name suggestions (difflib) and the first search hits for the same term.

ATTRIBUTE DESCRIPTION
query

The query string as the caller gave it.

TYPE: str

suggestions

Close names in difflib order; () when none.

TYPE: tuple[str, ...]

hits

Search hits (SearchHit records) for the query; () when none.

TYPE: tuple[SearchHit, ...]

Example
from mixpanel_headless import HelpLookupError, reference

try:
    reference.describe("Filtr")
except HelpLookupError as exc:
    print(exc.query)
    # Filtr
    print(exc.suggestions)
    # ('Filter', 'DropFilter', 'FilterOperator', 'FilterDateUnit', 'FrequencyFilter')
    print(exc.hits)
    # ()

Initialize a help lookup miss.

PARAMETER DESCRIPTION
query

The query string that matched nothing.

TYPE: str

suggestions

Close names to offer, most similar first. Stored as a tuple. Rendered as Did you mean: a, b, c? when non-empty.

TYPE: Sequence[str] DEFAULT: ()

hits

Search hits for the same term. Stored as a tuple and kept out of the message; the help() wrapper prints them. details["hits"] carries their to_dict() form.

TYPE: Sequence[SearchHit] DEFAULT: ()

Source code in src/mixpanel_headless/exceptions.py
def __init__(
    self,
    query: str,
    *,
    suggestions: Sequence[str] = (),
    hits: Sequence[SearchHit] = (),
) -> None:
    """Initialize a help lookup miss.

    Args:
        query: The query string that matched nothing.
        suggestions: Close names to offer, most similar first. Stored as
            a tuple. Rendered as ``Did you mean: a, b, c?`` when non-empty.
        hits: Search hits for the same term. Stored as a tuple and kept
            out of the message; the ``help()`` wrapper prints them.
            ``details["hits"]`` carries their ``to_dict()`` form.
    """
    self.query: str = query
    self.suggestions: tuple[str, ...] = tuple(suggestions)
    self.hits: tuple[SearchHit, ...] = tuple(hits)
    message = f"No help entry for '{query}'."
    if self.suggestions:
        message += f" Did you mean: {', '.join(self.suggestions)}?"
    super().__init__(
        message,
        code="HELP_NOT_FOUND",
        details={
            "query": query,
            "suggestions": list(self.suggestions),
            "hits": [hit.to_dict() for hit in self.hits],
        },
    )

help

help(
    query: str | object | None = None,
    *,
    format: HelpFormat = "text",
    file: TextIO | None = None,
    hints: bool = True,
    domain: str | None = None,
) -> None

Print reference help for the library, a type, a method, or a search.

Works offline: no credentials, no network, no config file. The text is plain (no Rich markup) so it is safe to paste into a prompt or a file.

Query grammar (tokens are split on whitespace, so "search cohort" and "search cohort" are equal):

Query Result kind Notes
None or "" overview Version, import line, entry points, domain table, grammar summary, llms.txt link.
Workspace listing Methods grouped by domain; properties first. domain= filters to one group (case-insensitive, unique prefix accepted).
Workspace.<method> method Signature, docstring, referenced types, see also, hint.
Workspace.<property> property Return annotation and docstring.
Workspace.<method>.<param> parameter Annotation, default, allowed values, description.
<Model> (Pydantic) model Bases, config, construction, fields, properties, methods, used by, hint.
<Dataclass> dataclass Same, with dataclass field rules.
<Enum> enum Member table and used by.
<LiteralAlias> literal Allowed values, one-line description, used by with parameter names.
<UnionAlias> / Account alias Expanded members, each with its first doc line.
<Exception> exception Base, docstring, subclasses, Workspace methods that raise it.
<Class>.<member> method / property Any public class, not only Workspace.
<function> function login_unified, validate_bookmark, label helpers.
accounts / session / targets module __all__ members with first doc lines and compact signatures.
<constant> constant Value and type.
types listing Public types grouped by kind. No hints.
exceptions listing Indented tree from MixpanelHeadlessError. No hints.
search <term> search Case-insensitive substring search.
help function This table.
miss (printed) No help entry ..., Did you mean? suggestions, first five search hits.

Objects are accepted too: help(mp.Filter), help(ws.query), help(mp.accounts).

PARAMETER DESCRIPTION
query

Query text, a public object, or None for the overview.

TYPE: str | object | None DEFAULT: None

format

"text" (default), "markdown", or "json".

TYPE: HelpFormat DEFAULT: 'text'

file

Destination stream; defaults to sys.stdout.

TYPE: TextIO | None DEFAULT: None

hints

Print the hosted-documentation Tip: block when one applies.

TYPE: bool DEFAULT: True

domain

Restrict the Workspace listing to one domain title. Any other query with domain set raises HelpDomainError.

TYPE: str | None DEFAULT: None

RETURNS DESCRIPTION
None

None. The rendered text is written to file.

RAISES DESCRIPTION
ValueError

When format is not text, markdown, or json.

HelpDomainError

When domain names no registered domain, several domains (ambiguous prefix), or is given for a query other than Workspace. A plain lookup miss does not raise; it prints the message and suggestions instead, even when domain is set.

Example
import mixpanel_headless as mp

mp.help()                                # overview
mp.help("Workspace", domain="funnel query")
mp.help("Workspace.query.events")        # one parameter
mp.help("MathType")                      # Literal alias values
mp.help("search cohort")                 # search
mp.help("Filter", format="json")         # machine-readable
Source code in src/mixpanel_headless/reference.py
def help(
    query: str | object | None = None,
    *,
    format: HelpFormat = "text",
    file: TextIO | None = None,
    hints: bool = True,
    domain: str | None = None,
) -> None:
    """Print reference help for the library, a type, a method, or a search.

    Works offline: no credentials, no network, no config file. The text is
    plain (no Rich markup) so it is safe to paste into a prompt or a file.

    Query grammar (tokens are split on whitespace, so ``"search cohort"``
    and ``"search   cohort"`` are equal):

    | Query | Result kind | Notes |
    | --- | --- | --- |
    | ``None`` or ``""`` | ``overview`` | Version, import line, entry points, domain table, grammar summary, ``llms.txt`` link. |
    | ``Workspace`` | ``listing`` | Methods grouped by domain; properties first. ``domain=`` filters to one group (case-insensitive, unique prefix accepted). |
    | ``Workspace.<method>`` | ``method`` | Signature, docstring, referenced types, see also, hint. |
    | ``Workspace.<property>`` | ``property`` | Return annotation and docstring. |
    | ``Workspace.<method>.<param>`` | ``parameter`` | Annotation, default, allowed values, description. |
    | ``<Model>`` (Pydantic) | ``model`` | Bases, config, construction, fields, properties, methods, used by, hint. |
    | ``<Dataclass>`` | ``dataclass`` | Same, with dataclass field rules. |
    | ``<Enum>`` | ``enum`` | Member table and used by. |
    | ``<LiteralAlias>`` | ``literal`` | Allowed values, one-line description, used by with parameter names. |
    | ``<UnionAlias>`` / ``Account`` | ``alias`` | Expanded members, each with its first doc line. |
    | ``<Exception>`` | ``exception`` | Base, docstring, subclasses, ``Workspace`` methods that raise it. |
    | ``<Class>.<member>`` | ``method`` / ``property`` | Any public class, not only ``Workspace``. |
    | ``<function>`` | ``function`` | ``login_unified``, ``validate_bookmark``, label helpers. |
    | ``accounts`` / ``session`` / ``targets`` | ``module`` | ``__all__`` members with first doc lines and compact signatures. |
    | ``<constant>`` | ``constant`` | Value and type. |
    | ``types`` | ``listing`` | Public types grouped by kind. No hints. |
    | ``exceptions`` | ``listing`` | Indented tree from ``MixpanelHeadlessError``. No hints. |
    | ``search <term>`` | ``search`` | Case-insensitive substring search. |
    | ``help`` | ``function`` | This table. |
    | miss | (printed) | ``No help entry ...``, ``Did you mean?`` suggestions, first five search hits. |

    Objects are accepted too: ``help(mp.Filter)``, ``help(ws.query)``,
    ``help(mp.accounts)``.

    Args:
        query: Query text, a public object, or ``None`` for the overview.
        format: ``"text"`` (default), ``"markdown"``, or ``"json"``.
        file: Destination stream; defaults to ``sys.stdout``.
        hints: Print the hosted-documentation ``Tip:`` block when one applies.
        domain: Restrict the ``Workspace`` listing to one domain title. Any
            other query with ``domain`` set raises ``HelpDomainError``.

    Returns:
        ``None``. The rendered text is written to ``file``.

    Raises:
        ValueError: When ``format`` is not ``text``, ``markdown``, or ``json``.
        HelpDomainError: When ``domain`` names no registered domain, several
            domains (ambiguous prefix), or is given for a query other than
            ``Workspace``. A plain lookup miss does **not** raise; it prints
            the message and suggestions instead, even when ``domain`` is set.

    Example:
        ```python
        import mixpanel_headless as mp

        mp.help()                                # overview
        mp.help("Workspace", domain="funnel query")
        mp.help("Workspace.query.events")        # one parameter
        mp.help("MathType")                      # Literal alias values
        mp.help("search cohort")                 # search
        mp.help("Filter", format="json")         # machine-readable
        ```
    """
    if format not in HELP_FORMATS:
        allowed = ", ".join(HELP_FORMATS)
        raise ValueError(f"Unknown help format {format!r}; expected one of: {allowed}")
    out = file if file is not None else sys.stdout
    if isinstance(query, str) and not isinstance(query, enum.Enum):
        from mixpanel_headless._internal.help.resolve import parse_query

        mode, payload = parse_query(query)
        if mode == "search":
            if not payload:
                print(_search_usage(format), file=out)
                return
            print(render(search(payload), format), file=out)
            return
        query = None if mode == "overview" else payload
    try:
        entry = describe(query, hints=hints, domain=domain)
    except HelpDomainError:
        raise
    except HelpLookupError as exc:
        print(render_miss(exc, format), file=out)
        return
    print(render(entry, format), file=out)

describe

describe(
    query: str | object, *, hints: bool = True, domain: str | None = None
) -> HelpEntry

Resolve a query and assemble its structured HelpEntry.

This is the assembler behind :func:help. It resolves the query (a dotted string from the package root or a public object), then builds one entry per HelpKind from signatures, docstrings, fields, relations, and hints.

PARAMETER DESCRIPTION
query

Dotted query text ("Workspace.query", "Filter", "types"), a public object (mp.Filter, ws.query, mp.accounts), or None / "" for the overview.

TYPE: str | object

hints

Include hosted-documentation hints. False yields hints=() on every entry.

TYPE: bool DEFAULT: True

domain

Restrict the Workspace listing to one domain title (case-insensitive; a unique prefix is accepted).

TYPE: str | None DEFAULT: None

RETURNS DESCRIPTION
HelpEntry

The assembled entry.

RAISES DESCRIPTION
HelpLookupError

When the query matches nothing. The error carries suggestions and the first five search hits. Raised for a name miss even when domain is set.

HelpDomainError

When the query resolved but domain was rejected: it is given for a query other than Workspace (reason not_workspace), names no registered domain (unknown; the error carries every title in domains), or matches several titles (ambiguous; the candidates are in domains).

Example
entry = describe("Workspace.query_funnel")
entry.signature.params[0].name     # "steps"
entry.to_dict()["kind"]            # "method"
Source code in src/mixpanel_headless/reference.py
def describe(
    query: str | object,
    *,
    hints: bool = True,
    domain: str | None = None,
) -> HelpEntry:
    """Resolve a query and assemble its structured ``HelpEntry``.

    This is the assembler behind :func:`help`. It resolves the query (a dotted
    string from the package root or a public object), then builds one entry
    per ``HelpKind`` from signatures, docstrings, fields, relations, and hints.

    Args:
        query: Dotted query text (``"Workspace.query"``, ``"Filter"``,
            ``"types"``), a public object (``mp.Filter``, ``ws.query``,
            ``mp.accounts``), or ``None`` / ``""`` for the overview.
        hints: Include hosted-documentation hints. ``False`` yields
            ``hints=()`` on every entry.
        domain: Restrict the ``Workspace`` listing to one domain title
            (case-insensitive; a unique prefix is accepted).

    Returns:
        The assembled entry.

    Raises:
        HelpLookupError: When the query matches nothing. The error carries
            ``suggestions`` and the first five search ``hits``. Raised for
            a name miss even when ``domain`` is set.
        HelpDomainError: When the query resolved but ``domain`` was rejected:
            it is given for a query other than ``Workspace`` (``reason``
            ``not_workspace``), names no registered domain (``unknown``; the
            error carries every title in ``domains``), or matches several
            titles (``ambiguous``; the candidates are in ``domains``).

    Example:
        ```python
        entry = describe("Workspace.query_funnel")
        entry.signature.params[0].name     # "steps"
        entry.to_dict()["kind"]            # "method"
        ```
    """
    from mixpanel_headless._internal.help.resolve import resolve

    query_text = query if isinstance(query, str) else None
    try:
        target = resolve(query)
    except HelpLookupError as exc:
        raise _with_hits(exc) from None
    if domain is not None and not _is_workspace_class(target):
        raise HelpDomainError(
            query_text if query_text is not None else target.qualname,
            domain=domain,
            reason="not_workspace",
        )
    entry = _assemble(target, domain=domain)
    return entry if hints else _without_hints(entry)

search

search(term: str, *, limit: int | None = None) -> SearchResult

Search the public surface for a case-insensitive substring.

Matches names first, then first docstring lines, then enum members and Literal values. Hits are ordered by tier, then by (category, name).

PARAMETER DESCRIPTION
term

Text to look for.

TYPE: str

limit

Keep at most this many hits; None keeps all.

TYPE: int | None DEFAULT: None

RETURNS DESCRIPTION
SearchResult

The search result. On a miss hits is empty and suggestions

SearchResult

holds close names.

RAISES DESCRIPTION
HelpLookupError

When term is empty or whitespace only.

ValueError

When limit is negative.

Example
search("retention").hits[0].name     # "RetentionCohortData"
search("Filtr").suggestions          # ("Filter", ...)
Source code in src/mixpanel_headless/reference.py
def search(term: str, *, limit: int | None = None) -> SearchResult:
    """Search the public surface for a case-insensitive substring.

    Matches names first, then first docstring lines, then enum members and
    Literal values. Hits are ordered by tier, then by ``(category, name)``.

    Args:
        term: Text to look for.
        limit: Keep at most this many hits; ``None`` keeps all.

    Returns:
        The search result. On a miss ``hits`` is empty and ``suggestions``
        holds close names.

    Raises:
        HelpLookupError: When ``term`` is empty or whitespace only.
        ValueError: When ``limit`` is negative.

    Example:
        ```python
        search("retention").hits[0].name     # "RetentionCohortData"
        search("Filtr").suggestions          # ("Filter", ...)
        ```
    """
    from mixpanel_headless._internal.help.search import search as _search

    return _search(term, limit=limit)

render

render(entry: HelpEntry | SearchResult, format: HelpFormat = 'text') -> str

Render an entry or a search result as text, markdown, or JSON.

PARAMETER DESCRIPTION
entry

A HelpEntry from :func:describe or a SearchResult from :func:search.

TYPE: HelpEntry | SearchResult

format

"text" (default), "markdown", or "json".

TYPE: HelpFormat DEFAULT: 'text'

RETURNS DESCRIPTION
str

The rendered string without a trailing newline.

RAISES DESCRIPTION
ValueError

When format is not one of the three formats.

Example
print(render(describe("MathType"), "markdown"))
Source code in src/mixpanel_headless/reference.py
def render(entry: HelpEntry | SearchResult, format: HelpFormat = "text") -> str:
    """Render an entry or a search result as text, markdown, or JSON.

    Args:
        entry: A ``HelpEntry`` from :func:`describe` or a ``SearchResult``
            from :func:`search`.
        format: ``"text"`` (default), ``"markdown"``, or ``"json"``.

    Returns:
        The rendered string without a trailing newline.

    Raises:
        ValueError: When ``format`` is not one of the three formats.

    Example:
        ```python
        print(render(describe("MathType"), "markdown"))
        ```
    """
    from mixpanel_headless._internal.help.render import render as _render

    return _render(entry, format)

clear_cache

clear_cache() -> None

Drop every per-process help cache.

Clears the inventory, resolved type hints, relations (used by, raised by, exception map), and the search index. The next call rebuilds them from the live package.

Source code in src/mixpanel_headless/reference.py
def clear_cache() -> None:
    """Drop every per-process help cache.

    Clears the inventory, resolved type hints, relations (used by, raised
    by, exception map), and the search index. The next call rebuilds them
    from the live package.
    """
    from mixpanel_headless._internal.help import (
        introspect,
        inventory,
        relations,
    )
    from mixpanel_headless._internal.help import (
        search as search_module,
    )

    search_module.clear_cache()
    relations.clear_cache()
    introspect.clear_cache()
    inventory.clear_cache()

render_miss

render_miss(exc: HelpLookupError, format: HelpFormat) -> str

Render a lookup miss: the error message, then the first search hits.

Shared by :func:help and the mp help command so both print the same text for the same miss. Not part of __all__; the public entry points are :func:help (prints it) and :func:describe (raises the error it renders).

PARAMETER DESCRIPTION
exc

The lookup error raised by :func:describe. exc.message already carries the Did you mean: a, b? tail when there are suggestions.

TYPE: HelpLookupError

format

The requested output format.

TYPE: HelpFormat

RETURNS DESCRIPTION
str

For json an object with error (the message), query,

str

suggestions, and hits; otherwise the message followed, when

str

there are hits, by the search view of the first five.

Example
from mixpanel_headless import HelpLookupError, reference

try:
    reference.describe("zzqq")
except HelpLookupError as exc:
    print(reference.render_miss(exc, "text"))
    # No help entry for 'zzqq'.
Source code in src/mixpanel_headless/reference.py
def render_miss(exc: HelpLookupError, format: HelpFormat) -> str:
    """Render a lookup miss: the error message, then the first search hits.

    Shared by :func:`help` and the ``mp help`` command so both print the
    same text for the same miss. Not part of ``__all__``; the public entry
    points are :func:`help` (prints it) and :func:`describe` (raises the
    error it renders).

    Args:
        exc: The lookup error raised by :func:`describe`. ``exc.message``
            already carries the ``Did you mean: a, b?`` tail when there
            are suggestions.
        format: The requested output format.

    Returns:
        For ``json`` an object with ``error`` (the message), ``query``,
        ``suggestions``, and ``hits``; otherwise the message followed, when
        there are hits, by the search view of the first five.

    Example:
        ```python
        from mixpanel_headless import HelpLookupError, reference

        try:
            reference.describe("zzqq")
        except HelpLookupError as exc:
            print(reference.render_miss(exc, "text"))
            # No help entry for 'zzqq'.
        ```
    """
    hits = exc.hits[:_MISS_HITS]
    if format == "json":
        payload = {
            "error": exc.message,
            "query": exc.query,
            "suggestions": list(exc.suggestions),
            "hits": [hit.to_dict() for hit in hits],
        }
        return json.dumps(payload, indent=2)
    blocks: list[str] = [exc.message]
    if hits:
        blocks.append(render(SearchResult(term=exc.query, hits=hits), format))
    return "\n\n".join(blocks)

Result types

describe() returns a HelpEntry; search() returns a SearchResult. Every result type is a frozen slots=True dataclass with a recursive to_dict(), and every one is a root export, so mp.HelpEntry, mp.ParamDoc, and the rest work as type hints and as help queries (mp help HelpEntry).

Type Role
HelpEntry One resolved query. Its docstring lists which fields each kind fills; domain holds the registry domain title of a Workspace method and value the repr of a constant.
DocSections Parsed Google-style docstring: summary, body, args, returns, raises, example, notes.
SignatureDoc / ParamDoc Callable signature. ParamDoc.kind is one of positional_only, positional_or_keyword, var_positional, keyword_only, var_keyword; annotation is None when the source has none.
FieldDoc One model or dataclass field (also reused for enum members).
MemberDoc One row of a class section or group; depth is the nesting level in an exception subclass tree.
Group A titled list of MemberDoc rows (a Workspace domain, a types kind, a module's members).
UsageDoc One Workspace method that accepts or raises the described type.
Hint One hosted-documentation pointer (title, url).
SearchResult / SearchHit Search output; SearchHit.category is a MemberKind and matched_on is name, doc, or member.

Three Literal kind families describe the surface. ExportKind names what an export can be (module, exception, enum, model, dataclass, class, literal, alias, function, constant). MemberKind adds method and property. HelpKind adds overview, listing, and parameter and is the type of HelpEntry.kind.

mixpanel_headless.HelpEntry dataclass

HelpEntry(
    kind: HelpKind,
    name: str,
    qualname: str,
    summary: str,
    doc: DocSections,
    signature: SignatureDoc | None = None,
    bases: tuple[str, ...] = (),
    config: tuple[tuple[str, str], ...] = (),
    construction: tuple[MemberDoc, ...] = (),
    fields: tuple[FieldDoc, ...] = (),
    properties: tuple[MemberDoc, ...] = (),
    methods: tuple[MemberDoc, ...] = (),
    values: tuple[str, ...] = (),
    value: str | None = None,
    groups: tuple[Group, ...] = (),
    referenced_types: tuple[tuple[str, str], ...] = (),
    used_by: tuple[UsageDoc, ...] = (),
    domain: str | None = None,
    see_also: tuple[str, ...] = (),
    hints: tuple[Hint, ...] = (),
)

Structured description of one resolved help query.

kind, name, qualname, summary, and doc are required. Every collection defaults to an empty tuple and every scalar extra to None, so builders can construct partial entries for kinds that lack a section. Which fields a kind populates is fixed by the conventions below; reference.describe() follows them and the renderers rely on them. A consumer of to_dict() can too.

Per-kind field conventions:

  • method / function: signature holds the callable and name is the display name (Workspace.query, accounts.add). referenced_types lists the library types in the signature. For a Workspace method, domain is the registry domain title and see_also names the other Workspace methods of that domain; both are empty for every other callable. groups is unused.
  • property: signature has no params; its returns is the property type or None.
  • parameter: signature.params holds exactly one ParamDoc and signature.name is the owning callable's bare name; values repeats the parameter's allowed values; summary and doc carry the parameter description.
  • class / model / dataclass: bases, config (models only), construction, fields (models and dataclasses), properties, methods, and used_by map one-to-one to the rendered sections.
  • enum: values holds the member names in definition order and fields reuses FieldDoc for the members: name is the member name, annotation the type name of the member value, default its repr, required always False. bases lists the enum's bases.
  • literal: values holds the allowed values in declaration order.
  • alias: values holds the member display names of the union and referenced_types the (name, summary) rows for the members that are library types.
  • exception: bases[0] is the direct base. groups is empty for a leaf or one group titled Subclasses whose items carry their nesting in MemberDoc.depth (a direct subclass is depth 0). used_by lists the Workspace methods whose Raises: names it.
  • module: one group titled Members with every __all__ name.
  • constant: value is the repr of the value and bases holds one name, the value's type (the enum class for an enum member such as FeatureFlagStatus.ENABLED). values is unused.
  • listing: groups carries the rows (Workspace domains, the types kinds, or the one Exceptions tree whose items carry depth). summary is a count line or the facade's summary.
  • overview: summary is the package version and doc.body the query grammar; groups is empty.
ATTRIBUTE DESCRIPTION
kind

What the query resolved to.

TYPE: HelpKind

name

Display name, for example "Workspace.query" or "Filter".

TYPE: str

qualname

Canonical help query for this entry, for example "Workspace.query" or "Filter"; passing it back to describe() returns the same entry. Not an import path.

TYPE: str

summary

First docstring line (or generated summary for aliases).

TYPE: str

doc

Parsed docstring sections.

TYPE: DocSections

signature

Signature for callables, else None.

TYPE: SignatureDoc | None

bases

Names of public base classes (the value's type for a constant).

TYPE: tuple[str, ...]

config

Non-default Pydantic model config as (key, value) pairs.

TYPE: tuple[tuple[str, str], ...]

construction

Public constructors and factory classmethods.

TYPE: tuple[MemberDoc, ...]

fields

Public dataclass or model fields; enum members for an enum.

TYPE: tuple[FieldDoc, ...]

properties

Public properties.

TYPE: tuple[MemberDoc, ...]

methods

Public methods (instance, class, static).

TYPE: tuple[MemberDoc, ...]

values

Enum member names, literal values, or alias member names.

TYPE: tuple[str, ...]

value

Display form of a constant's value (repr), else None.

TYPE: str | None

groups

Titled member groups for listings, modules, and exception trees.

TYPE: tuple[Group, ...]

referenced_types

(type_name, summary) pairs referenced by a callable.

TYPE: tuple[tuple[str, str], ...]

used_by

Workspace methods that accept (or raise) this type.

TYPE: tuple[UsageDoc, ...]

domain

Registry domain title of a Workspace method, else None.

TYPE: str | None

see_also

Other Workspace methods in the same registry domain.

TYPE: tuple[str, ...]

hints

Hosted-documentation pointers.

TYPE: tuple[Hint, ...]

to_dict

to_dict() -> dict[str, object]

Convert to a JSON-serializable dict.

Nested models convert recursively; tuples become lists; pair tuples become two-item lists. Keys follow the dataclass field order.

RETURNS DESCRIPTION
dict[str, object]

A dict suitable for json.dumps.

Source code in src/mixpanel_headless/_internal/help/models.py
def to_dict(self) -> dict[str, object]:
    """Convert to a JSON-serializable dict.

    Nested models convert recursively; tuples become lists; pair tuples
    become two-item lists. Keys follow the dataclass field order.

    Returns:
        A dict suitable for ``json.dumps``.
    """
    return {
        "kind": self.kind,
        "name": self.name,
        "qualname": self.qualname,
        "summary": self.summary,
        "doc": self.doc.to_dict(),
        "signature": None if self.signature is None else self.signature.to_dict(),
        "bases": list(self.bases),
        "config": _pairs_to_lists(self.config),
        "construction": [member.to_dict() for member in self.construction],
        "fields": [field.to_dict() for field in self.fields],
        "properties": [member.to_dict() for member in self.properties],
        "methods": [member.to_dict() for member in self.methods],
        "values": list(self.values),
        "value": self.value,
        "groups": [group.to_dict() for group in self.groups],
        "referenced_types": _pairs_to_lists(self.referenced_types),
        "used_by": [usage.to_dict() for usage in self.used_by],
        "domain": self.domain,
        "see_also": list(self.see_also),
        "hints": [hint.to_dict() for hint in self.hints],
    }

mixpanel_headless.DocSections dataclass

DocSections(
    summary: str = "",
    body: str = "",
    args: tuple[tuple[str, str], ...] = (),
    returns: str = "",
    raises: tuple[tuple[str, str], ...] = (),
    example: str = "",
    notes: str = "",
)

Parsed Google-style docstring.

ATTRIBUTE DESCRIPTION
summary

First paragraph before the first section header, lines joined with single spaces.

TYPE: str

body

Everything before the first section header, dedented, newlines kept.

TYPE: str

args

(name, description) pairs from Args:.

TYPE: tuple[tuple[str, str], ...]

returns

Text of Returns: (and Yields:).

TYPE: str

raises

(exception_name, description) pairs from Raises:.

TYPE: tuple[tuple[str, str], ...]

example

Text of Example: / Examples:, dedented, fences kept.

TYPE: str

notes

Text of Note: / Notes:.

TYPE: str

to_dict

to_dict() -> dict[str, object]

Convert to a JSON-serializable dict.

RETURNS DESCRIPTION
dict[str, object]

A dict with args and raises as lists of two-item lists.

Source code in src/mixpanel_headless/_internal/help/models.py
def to_dict(self) -> dict[str, object]:
    """Convert to a JSON-serializable dict.

    Returns:
        A dict with ``args`` and ``raises`` as lists of two-item lists.
    """
    return {
        "summary": self.summary,
        "body": self.body,
        "args": _pairs_to_lists(self.args),
        "returns": self.returns,
        "raises": _pairs_to_lists(self.raises),
        "example": self.example,
        "notes": self.notes,
    }

mixpanel_headless.SignatureDoc dataclass

SignatureDoc(
    name: str, params: tuple[ParamDoc, ...] = (), returns: str | None = None
)

A callable signature with per-parameter documentation.

ATTRIBUTE DESCRIPTION
name

Callable name (unqualified).

TYPE: str

params

Parameters in declaration order.

TYPE: tuple[ParamDoc, ...]

returns

Display form of the return annotation, or None when absent.

TYPE: str | None

to_dict

to_dict() -> dict[str, object]

Convert to a JSON-serializable dict.

RETURNS DESCRIPTION
dict[str, object]

A dict with params converted recursively.

Source code in src/mixpanel_headless/_internal/help/models.py
def to_dict(self) -> dict[str, object]:
    """Convert to a JSON-serializable dict.

    Returns:
        A dict with ``params`` converted recursively.
    """
    return {
        "name": self.name,
        "params": [param.to_dict() for param in self.params],
        "returns": self.returns,
    }

mixpanel_headless.ParamDoc dataclass

ParamDoc(
    name: str,
    annotation: str | None = None,
    default: str | None = None,
    description: str = "",
    values: tuple[str, ...] = (),
    kind: ParamKind = "positional_or_keyword",
)

One parameter of a callable signature.

ATTRIBUTE DESCRIPTION
name

Parameter name without self; *args and **kwargs keep their prefixes.

TYPE: str

annotation

Display form of the annotation (already cleaned), or None when the parameter has none (as SignatureDoc.returns).

TYPE: str | None

default

repr of the default, or None when the parameter is required.

TYPE: str | None

description

Description from the Args: docstring section, or "".

TYPE: str

values

Literal or enum member values accepted by the parameter, if any.

TYPE: tuple[str, ...]

kind

How the parameter may be passed. Renderers print a bare * before the first keyword_only parameter (unless a var_positional one precedes it) and a / after the last positional_only parameter.

TYPE: ParamKind

to_dict

to_dict() -> dict[str, object]

Convert to a JSON-serializable dict.

RETURNS DESCRIPTION
dict[str, object]

A dict with every field; values becomes a list.

Source code in src/mixpanel_headless/_internal/help/models.py
def to_dict(self) -> dict[str, object]:
    """Convert to a JSON-serializable dict.

    Returns:
        A dict with every field; ``values`` becomes a list.
    """
    return {
        "name": self.name,
        "annotation": self.annotation,
        "default": self.default,
        "description": self.description,
        "values": list(self.values),
        "kind": self.kind,
    }

mixpanel_headless.FieldDoc dataclass

FieldDoc(
    name: str,
    annotation: str,
    default: str | None = None,
    required: bool = False,
    constraints: tuple[str, ...] = (),
    alias: str | None = None,
    values: tuple[str, ...] = (),
    description: str = "",
)

One public field of a dataclass or Pydantic model.

ATTRIBUTE DESCRIPTION
name

Python attribute name.

TYPE: str

annotation

Display form of the annotation.

TYPE: str

default

Display form of the default (repr or <factory name>), or None.

TYPE: str | None

required

True when the field has no default.

TYPE: bool

constraints

Pydantic constraints such as "max_length=255".

TYPE: tuple[str, ...]

alias

JSON alias when it differs from name, else None.

TYPE: str | None

values

Enum member names or literal values accepted by the field, if any.

TYPE: tuple[str, ...]

description

Field description from Field(description=...) or the docstring.

TYPE: str

__post_init__

__post_init__() -> None

Reject a required field that also carries a default.

RAISES DESCRIPTION
ValueError

When required is True and default is not None; a field with a default is by definition optional.

Source code in src/mixpanel_headless/_internal/help/models.py
def __post_init__(self) -> None:
    """Reject a required field that also carries a default.

    Raises:
        ValueError: When ``required`` is ``True`` and ``default`` is not
            ``None``; a field with a default is by definition optional.
    """
    if self.required and self.default is not None:
        raise ValueError(
            f"FieldDoc {self.name!r} is required but has default {self.default!r}"
        )

to_dict

to_dict() -> dict[str, object]

Convert to a JSON-serializable dict.

RETURNS DESCRIPTION
dict[str, object]

A dict with every field; tuples become lists.

Source code in src/mixpanel_headless/_internal/help/models.py
def to_dict(self) -> dict[str, object]:
    """Convert to a JSON-serializable dict.

    Returns:
        A dict with every field; tuples become lists.
    """
    return {
        "name": self.name,
        "annotation": self.annotation,
        "default": self.default,
        "required": self.required,
        "constraints": list(self.constraints),
        "alias": self.alias,
        "values": list(self.values),
        "description": self.description,
    }

mixpanel_headless.MemberDoc dataclass

MemberDoc(
    name: str,
    kind: MemberKind,
    summary: str = "",
    signature: SignatureDoc | None = None,
    depth: int = 0,
)

One member in a listing (method, property, classmethod, module export).

ATTRIBUTE DESCRIPTION
name

Member name, never indented; nesting is carried by depth.

TYPE: str

kind

Member classification, one of MEMBER_KINDS.

TYPE: MemberKind

summary

First docstring line, or "".

TYPE: str

signature

Signature for method / function members (always present for those kinds), None for every other kind.

TYPE: SignatureDoc | None

depth

Nesting level inside a tree-shaped group, 0 for a flat row. The exception tree uses it: each level is one subclass step below the group's root. The text renderer indents two spaces per level; markdown and JSON keep the bare name and expose depth.

TYPE: int

__post_init__

__post_init__() -> None

Validate the kind, its agreement with signature, and depth.

RAISES DESCRIPTION
ValueError

When kind is not one of MEMBER_KINDS, when a method / function member has no signature, when any other kind carries one, or when depth is negative.

Source code in src/mixpanel_headless/_internal/help/models.py
def __post_init__(self) -> None:
    """Validate the kind, its agreement with ``signature``, and ``depth``.

    Raises:
        ValueError: When ``kind`` is not one of ``MEMBER_KINDS``, when a
            ``method`` / ``function`` member has no signature, when any
            other kind carries one, or when ``depth`` is negative.
    """
    if self.depth < 0:
        raise ValueError(f"MemberDoc depth must be >= 0, got {self.depth}")
    if self.kind not in MEMBER_KINDS:
        allowed = ", ".join(MEMBER_KINDS)
        raise ValueError(
            f"Unknown member kind {self.kind!r}; expected one of: {allowed}"
        )
    callable_kind = self.kind in _CALLABLE_MEMBER_KINDS
    if callable_kind and self.signature is None:
        raise ValueError(
            f"MemberDoc {self.name!r} of kind {self.kind!r} requires a signature"
        )
    if not callable_kind and self.signature is not None:
        raise ValueError(
            f"MemberDoc {self.name!r} of kind {self.kind!r} "
            "must not carry a signature"
        )

to_dict

to_dict() -> dict[str, object]

Convert to a JSON-serializable dict.

RETURNS DESCRIPTION
dict[str, object]

A dict with signature converted recursively or None, and

dict[str, object]

depth as an integer.

Source code in src/mixpanel_headless/_internal/help/models.py
def to_dict(self) -> dict[str, object]:
    """Convert to a JSON-serializable dict.

    Returns:
        A dict with ``signature`` converted recursively or ``None``, and
        ``depth`` as an integer.
    """
    return {
        "name": self.name,
        "kind": self.kind,
        "summary": self.summary,
        "signature": None if self.signature is None else self.signature.to_dict(),
        "depth": self.depth,
    }

mixpanel_headless.Group dataclass

Group(title: str, items: tuple[MemberDoc, ...])

A titled group of members, used for Workspace domain grouping.

ATTRIBUTE DESCRIPTION
title

Group title, for example "Discovery".

TYPE: str

items

Members in the group.

TYPE: tuple[MemberDoc, ...]

to_dict

to_dict() -> dict[str, object]

Convert to a JSON-serializable dict.

RETURNS DESCRIPTION
dict[str, object]

{"title": ..., "items": [member dicts]}.

Source code in src/mixpanel_headless/_internal/help/models.py
def to_dict(self) -> dict[str, object]:
    """Convert to a JSON-serializable dict.

    Returns:
        ``{"title": ..., "items": [member dicts]}``.
    """
    return {"title": self.title, "items": [item.to_dict() for item in self.items]}

mixpanel_headless.UsageDoc dataclass

UsageDoc(method: str, params: tuple[str, ...])

One Workspace method that accepts a given type ("Used by Workspace").

ATTRIBUTE DESCRIPTION
method

Method name on Workspace.

TYPE: str

params

Names of the parameters whose annotation references the type.

TYPE: tuple[str, ...]

to_dict

to_dict() -> dict[str, object]

Convert to a JSON-serializable dict.

RETURNS DESCRIPTION
dict[str, object]

{"method": ..., "params": [...]}.

Source code in src/mixpanel_headless/_internal/help/models.py
def to_dict(self) -> dict[str, object]:
    """Convert to a JSON-serializable dict.

    Returns:
        ``{"method": ..., "params": [...]}``.
    """
    return {"method": self.method, "params": list(self.params)}

mixpanel_headless.Hint dataclass

Hint(title: str, url: str)

Pointer to a hosted documentation page.

ATTRIBUTE DESCRIPTION
title

Short human-readable label, for example "Entity management guide".

TYPE: str

url

Absolute URL of the page.

TYPE: str

to_dict

to_dict() -> dict[str, object]

Convert to a JSON-serializable dict.

RETURNS DESCRIPTION
dict[str, object]

{"title": ..., "url": ...}.

Source code in src/mixpanel_headless/_internal/help/models.py
def to_dict(self) -> dict[str, object]:
    """Convert to a JSON-serializable dict.

    Returns:
        ``{"title": ..., "url": ...}``.
    """
    return {"title": self.title, "url": self.url}

mixpanel_headless.SearchResult dataclass

SearchResult(
    term: str,
    hits: tuple[SearchHit, ...] = (),
    suggestions: tuple[str, ...] = (),
)

Result of reference.search(term).

ATTRIBUTE DESCRIPTION
term

The search term as given.

TYPE: str

hits

Matching entries in display order, duplicates removed.

TYPE: tuple[SearchHit, ...]

suggestions

"Did you mean?" names when there are no hits.

TYPE: tuple[str, ...]

to_dict

to_dict() -> dict[str, object]

Convert to a JSON-serializable dict.

RETURNS DESCRIPTION
dict[str, object]

{"term": ..., "hits": [hit dicts], "suggestions": [...]}.

Source code in src/mixpanel_headless/_internal/help/models.py
def to_dict(self) -> dict[str, object]:
    """Convert to a JSON-serializable dict.

    Returns:
        ``{"term": ..., "hits": [hit dicts], "suggestions": [...]}``.
    """
    return {
        "term": self.term,
        "hits": [hit.to_dict() for hit in self.hits],
        "suggestions": list(self.suggestions),
    }

mixpanel_headless.SearchHit dataclass

SearchHit(category: MemberKind, name: str, summary: str, matched_on: MatchedOn)

One search result row.

ATTRIBUTE DESCRIPTION
category

Display category: the ExportKind of an export or module member (exception, enum, model, dataclass, class, literal, alias, function, module, constant), or method / property for Workspace members.

TYPE: MemberKind

name

Matched name, qualified for Workspace members.

TYPE: str

summary

First docstring line, or "".

TYPE: str

matched_on

Which part of the entry matched the term.

TYPE: MatchedOn

to_dict

to_dict() -> dict[str, object]

Convert to a JSON-serializable dict.

RETURNS DESCRIPTION
dict[str, object]

A dict with the four scalar fields.

Source code in src/mixpanel_headless/_internal/help/models.py
def to_dict(self) -> dict[str, object]:
    """Convert to a JSON-serializable dict.

    Returns:
        A dict with the four scalar fields.
    """
    return {
        "category": self.category,
        "name": self.name,
        "summary": self.summary,
        "matched_on": self.matched_on,
    }

Errors

describe() raises HelpLookupError on a miss and HelpDomainError (a HelpLookupError subclass) when domain= names no registered domain, matches several titles, or is given with a query other than Workspace. search() raises HelpLookupError for an empty term. help() catches a plain miss and prints the suggestions and the first search hits; it re-raises HelpDomainError. Both exceptions are listed with the rest of the hierarchy under Exceptions.

HelpLookupError

Carries query, suggestions, and hits; details (and so to_dict()) includes the hits as dicts. The CLI prints the miss on stdout and exits 4.

mixpanel_headless.HelpLookupError

HelpLookupError(
    query: str,
    *,
    suggestions: Sequence[str] = (),
    hits: Sequence[SearchHit] = (),
)

Bases: MixpanelHeadlessError

A mixpanel_headless.help() / reference.describe() query matched nothing.

Raised by :func:mixpanel_headless.reference.describe (and re-raised by :func:mixpanel_headless.reference.search for an empty term) when the query names no export, no Workspace member, and no parameter. The lookup is fully offline, so this is never an HTTP failure and the base is :class:MixpanelHeadlessError, not :class:APIError. The CLI maps it to ExitCode.NOT_FOUND (4).

The instance carries the structured recovery data the plain-text help() wrapper prints: close-name suggestions (difflib) and the first search hits for the same term.

ATTRIBUTE DESCRIPTION
query

The query string as the caller gave it.

TYPE: str

suggestions

Close names in difflib order; () when none.

TYPE: tuple[str, ...]

hits

Search hits (SearchHit records) for the query; () when none.

TYPE: tuple[SearchHit, ...]

Example
from mixpanel_headless import HelpLookupError, reference

try:
    reference.describe("Filtr")
except HelpLookupError as exc:
    print(exc.query)
    # Filtr
    print(exc.suggestions)
    # ('Filter', 'DropFilter', 'FilterOperator', 'FilterDateUnit', 'FrequencyFilter')
    print(exc.hits)
    # ()

Initialize a help lookup miss.

PARAMETER DESCRIPTION
query

The query string that matched nothing.

TYPE: str

suggestions

Close names to offer, most similar first. Stored as a tuple. Rendered as Did you mean: a, b, c? when non-empty.

TYPE: Sequence[str] DEFAULT: ()

hits

Search hits for the same term. Stored as a tuple and kept out of the message; the help() wrapper prints them. details["hits"] carries their to_dict() form.

TYPE: Sequence[SearchHit] DEFAULT: ()

Source code in src/mixpanel_headless/exceptions.py
def __init__(
    self,
    query: str,
    *,
    suggestions: Sequence[str] = (),
    hits: Sequence[SearchHit] = (),
) -> None:
    """Initialize a help lookup miss.

    Args:
        query: The query string that matched nothing.
        suggestions: Close names to offer, most similar first. Stored as
            a tuple. Rendered as ``Did you mean: a, b, c?`` when non-empty.
        hits: Search hits for the same term. Stored as a tuple and kept
            out of the message; the ``help()`` wrapper prints them.
            ``details["hits"]`` carries their ``to_dict()`` form.
    """
    self.query: str = query
    self.suggestions: tuple[str, ...] = tuple(suggestions)
    self.hits: tuple[SearchHit, ...] = tuple(hits)
    message = f"No help entry for '{query}'."
    if self.suggestions:
        message += f" Did you mean: {', '.join(self.suggestions)}?"
    super().__init__(
        message,
        code="HELP_NOT_FOUND",
        details={
            "query": query,
            "suggestions": list(self.suggestions),
            "hits": [hit.to_dict() for hit in self.hits],
        },
    )

HelpDomainError

Carries query (the help query, never the domain), domain, domains (the titles to offer), and reason (unknown, ambiguous, or not_workspace; the HelpDomainReason literal). Error code HELP_BAD_DOMAIN. The CLI prints the message and one Domains: line on stderr and exits 3.

mixpanel_headless.HelpDomainError

HelpDomainError(
    query: str,
    *,
    domain: str,
    domains: Sequence[str] = (),
    reason: HelpDomainReason = "unknown",
)

Bases: HelpLookupError

The domain= filter of a help query was rejected.

Raised by :func:mixpanel_headless.reference.describe when domain matches no registered Workspace domain title, matches several titles (an ambiguous prefix), or is given with a query other than the Workspace listing. The query itself resolved fine, so this is not a lookup miss: :func:mixpanel_headless.reference.help re-raises it instead of printing suggestions, and the CLI maps it to ExitCode.INVALID_ARGS (3) instead of NOT_FOUND (4).

It subclasses :class:HelpLookupError so an except HelpLookupError still catches it; suggestions mirrors domains and hits is always empty.

ATTRIBUTE DESCRIPTION
query

The help query text ("Workspace", "Filter"), never the domain. An empty string is the overview, and the not_workspace message names it as such.

domain

The domain= value as the caller gave it.

TYPE: str

domains

Every registered title for an unknown domain, the candidate titles for an ambiguous prefix, () for a non-Workspace query.

TYPE: tuple[str, ...]

reason

"unknown", "ambiguous", or "not_workspace".

TYPE: HelpDomainReason

Example
from mixpanel_headless import HelpDomainError, reference

try:
    reference.describe("Workspace", domain="se")
except HelpDomainError as exc:
    print(exc)
    # Ambiguous domain 'se': session and switching, session replay.
    print(exc.reason, exc.domains)
    # ambiguous ('session and switching', 'session replay')

Initialize a rejected domain filter.

PARAMETER DESCRIPTION
query

The help query text the filter was applied to.

TYPE: str

domain

The rejected domain= value.

TYPE: str

domains

Titles to offer: all of them for unknown, the candidates for ambiguous, nothing for not_workspace. Stored as a tuple and mirrored into suggestions.

TYPE: Sequence[str] DEFAULT: ()

reason

Which check failed; picks the message.

TYPE: HelpDomainReason DEFAULT: 'unknown'

Source code in src/mixpanel_headless/exceptions.py
def __init__(
    self,
    query: str,
    *,
    domain: str,
    domains: Sequence[str] = (),
    reason: HelpDomainReason = "unknown",
) -> None:
    """Initialize a rejected domain filter.

    Args:
        query: The help query text the filter was applied to.
        domain: The rejected ``domain=`` value.
        domains: Titles to offer: all of them for ``unknown``, the
            candidates for ``ambiguous``, nothing for ``not_workspace``.
            Stored as a tuple and mirrored into ``suggestions``.
        reason: Which check failed; picks the message.
    """
    self.query = query
    self.domain: str = domain
    self.domains: tuple[str, ...] = tuple(domains)
    self.reason: HelpDomainReason = reason
    self.suggestions = self.domains
    self.hits = ()
    if reason == "ambiguous":
        message = f"Ambiguous domain '{domain}': {', '.join(self.domains)}."
    elif reason == "not_workspace":
        subject = f"'{query}'" if query else "the overview"
        message = (
            "--domain applies only to the Workspace listing; "
            f"{subject} is not the Workspace class."
        )
    else:
        message = f"Unknown domain '{domain}'."
    MixpanelHeadlessError.__init__(
        self,
        message,
        code="HELP_BAD_DOMAIN",
        details={
            "query": query,
            "domain": domain,
            "domains": list(self.domains),
            "suggestions": list(self.domains),
            "hits": [],
        },
    )