Skip to content

author_index

src.models.author_index

Author index schema.

Generated by generate_author_index.pyauthor_index.json.

AffiliationHistoryEntry

Bases: BaseModel

A previous affiliation with date, tracking institution moves.

Source code in src/models/author_index.py
13
14
15
16
17
18
class AffiliationHistoryEntry(BaseModel):
    """A previous affiliation with date, tracking institution moves."""

    affiliation: str = Field(description="Previous institution name.")
    source: str = Field(description="Enrichment source that set this affiliation.")
    date: str = Field(description="ISO 8601 date when this affiliation was recorded.")

ExternalIds

Bases: BaseModel

Optional identifiers from external databases.

Source code in src/models/author_index.py
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
class ExternalIds(BaseModel):
    """Optional identifiers from external databases."""

    dblp_pid: str | None = Field(
        default=None,
        description="DBLP person identifier (e.g., 'homepages/c/HaiboChen0001').",
    )
    orcid: str | None = Field(
        default=None,
        pattern=r"^\d{4}-\d{4}-\d{4}-\d{3}[\dX]$",
        description="ORCID identifier (e.g., '0000-0001-2345-6789').",
    )
    openalex_id: str | None = Field(
        default=None,
        description="OpenAlex author ID (e.g., 'A1234567890').",
    )

    model_config = {"extra": "forbid"}

AuthorIndexEntry

Bases: BaseModel

Canonical record for a single author.

Single source of truth for author metadata. Generated by generate_author_index.py, updated by enrichment pipeline.

Source code in src/models/author_index.py
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
class AuthorIndexEntry(BaseModel):
    """Canonical record for a single author.

    Single source of truth for author metadata. Generated by
    ``generate_author_index.py``, updated by enrichment pipeline.
    """

    id: int = Field(ge=1, description="Stable integer identifier. Assigned once, never reused or changed.")
    name: str = Field(
        description=(
            "Full name in DBLP format. Includes disambiguation suffix "
            "when present (e.g., 'Haibo Chen 0001'). Unique across all authors."
        ),
    )
    display_name: str = Field(description="Human-readable name without DBLP disambiguation suffix.")
    affiliation: str = Field(description="Normalized institution affiliation. Empty string if unknown.")
    affiliation_source: Literal["csrankings", "dblp", "openalex", "crossref", "manual", ""] = Field(
        default="",
        description="Which enrichment layer last set the affiliation.",
    )
    affiliation_updated: str = Field(
        default="",
        pattern=r"^(\d{4}-\d{2}-\d{2})?$",
        description="ISO 8601 date when affiliation was last updated.",
    )
    affiliation_history: list[AffiliationHistoryEntry] = Field(
        default_factory=list,
        description="Previous affiliations with dates, tracking institution moves.",
    )
    external_ids: ExternalIds = Field(
        default_factory=ExternalIds,
        description="Optional identifiers from external databases.",
    )
    category: Literal["systems", "security", "both"] = Field(
        default="systems",
        description="Primary research area.",
    )

    model_config = {"extra": "forbid"}