Knowledge packs
KnowledgePack and its entry dataclasses, the bundled default pack, dict/JSON conversion, overlay merging.
A knowledge pack is JSON mapping "language-independent key → reading text and school attributes".
The core only judges facts; reading texts and the school-specific star attributes live here. For the
concept, the format and how to write an overlay, see the
knowledge pack guide; the full field reference is
knowledge/SCHEMA.md in the
repository.
from x_iztro import KnowledgePack
from x_iztro.enums import MajorStar
pack = KnowledgePack.builtin()
intro = pack.star_intro(MajorStar.ZIWEI)KnowledgePack is exported from the x_iztro top level; the entry dataclasses live in
x_iztro.knowledge. Every lookup takes a string, and the enums (MajorStar, PatternKey,
PalaceName, Mutagen …) are StrEnum, so you can pass them directly.
Types
KnowledgePack
Holds the raw pack object (a dict); the lookups return typed entries.
Metadata (read-only properties)
| Property | Type | Meaning |
|---|---|---|
schema | int | Format version, currently 1 |
id | str | Pack identifier; "iztro-docs" for the default pack |
version | str | Pack version; for the default pack, retrieval date + short source commit |
language | str | Language code of the texts |
extends | str | None | The pack this overlay overlays; None for a standalone pack |
source | Source | Origin and licence |
Methods
| Method | Meaning |
|---|---|
KnowledgePack.builtin(language="zh-CN") | The bundled default pack |
KnowledgePack.from_dict(d) | Build from a pack object (holds the reference, no copy) |
KnowledgePack.from_json(text) | Build from JSON text |
to_dict() | A deep copy of the pack object |
to_json(**kwargs) | JSON text; kwargs are passed through to json.dumps |
merged(*overlays) | Layer overlays on, returning a new pack |
star(key) / pattern(key) / palace(key) / mutagen(key) / concept(slug) | One entry, or None |
stars() / patterns() | All star / pattern entries |
star_intro(key) / pattern_intro(key) | The reading text directly |
Entry dataclasses
StarEntry, PatternEntry, TextEntry, ConceptEntry, StarAttributes and Source are all
frozen=True, slots=True dataclasses; absent fields are None.
StarEntry
| Field | Type | Meaning |
|---|---|---|
key | str | Star key |
name | str | None | Display name in this pack's language |
category | str | None | "major" / "minor" / "adjective" / "dec" / "flow" (a flowing star, a cross-reference entry pointing at its natal minor-star counterpart) |
group | str | None | Grouping: the adjective star's category, the decorative star's group |
attributes | StarAttributes | School attributes |
intro | str | None | Reading (Markdown) |
combinations | dict[str, str] | Reading for sharing a palace with another major star, keyed by that star |
StarAttributes: yin_yang (yin / yang), five_elements
(wood / fire / earth / metal / water), stem (jia…gui), five_elements_note,
dipper, chemistry, career, duty, aliases (list[str] | None), element_color,
energy_color.
PatternEntry: key, name, quotes (list[str] | None), conditions, intro.
TextEntry (palaces, transformations): key, name, intro.
ConceptEntry (glossary): slug, title, intro.
Source: name, url, commit, license, author, retrieved_at, adapted (adaptation note).
StarAttributes.five_elements and .yin_yang are what the pack's source says, and may differ from
the core star data, which is value-for-value identical to iztro's. The reason is in the
guide.
builtin
Purpose Get the bundled default knowledge pack.
Signature
@classmethod
def builtin(cls, language: LanguageType = "zh-CN") -> KnowledgePackParameters
| Parameter | Type | Required | Default | Meaning |
|---|---|---|---|---|
language | LanguageType | no | "zh-CN" | Text language |
Returns KnowledgePack.
Raises IztroError (with code invalid_argument) when there is no bundled pack for that
language. Only zh-CN has one today.
Example
from x_iztro import IztroError, KnowledgePack
pack = KnowledgePack.builtin()
print(pack)
print(pack.schema, pack.id, pack.version, pack.language, pack.extends)
print(pack.source.license, pack.source.author)
print(len(pack.stars()), len(pack.patterns()))
try:
KnowledgePack.builtin("en-US")
except IztroError as e:
print(e.code, e)Output
KnowledgePack(id='iztro-docs', version='2026-08-19+ec2d58b', language='zh-CN')
1 iztro-docs 2026-08-19+ec2d58b zh-CN None
MIT Sylar Long
162 64
invalid_argument no builtin knowledge pack for language 'en-US'from_dict / from_json / to_dict / to_json
Purpose Convert between your own pack and x-iztro.
Signature
@classmethod
def from_dict(cls, d: dict[str, Any]) -> KnowledgePack
@classmethod
def from_json(cls, text: str) -> KnowledgePack
def to_dict(self) -> dict[str, Any]
def to_json(self, **kwargs: Any) -> strNotes
from_dictholds the dict you pass without copying: mutating that dict afterwards changes the pack. To isolate them,copy.deepcopyfirst or go throughfrom_json.to_dictreturns a deep copy, so changing it never touches the pack.to_jsondefaultsensure_asciitoFalse(Chinese stays readable); the remainingkwargsgo straight tojson.dumps, e.g.pack.to_json(indent=2).- Both constructors validate the format version, with the same semantics as the Rust core's
parser: a non-object, a missing or zero
schema, or aschemanewer than this library supports raisesIztroError(invalid_argument). The structure is not deep-checked: an unrecognised field simply yields nothing.
Example my-school.json is an overlay pack; a complete sample is in the
knowledge pack guide:
from x_iztro import KnowledgePack
overlay = KnowledgePack.from_json(open("my-school.json", encoding="utf-8").read())
print(overlay.id, overlay.extends)
raw = overlay.to_dict()
raw["stars"]["ziweiMaj"]["intro"] = "changed again"
print(overlay.star_intro("ziweiMaj")) # to_dict is a deep copy; the pack is untouchedmerged
Purpose Layer overlay packs onto this one and return a new pack.
Signature
def merged(self, *overlays: KnowledgePack | dict[str, Any]) -> KnowledgePackParameters
| Parameter | Type | Meaning |
|---|---|---|
*overlays | KnowledgePack | dict | Overlays applied in argument order; later ones win |
Returns A new KnowledgePack; neither this pack nor the overlays change.
Raises IztroError (invalid_argument) when a pack does not fit the format, or its schema
is newer than this library supports.
The rules are in the guide: section by section,
key by key, an overlay's non-empty fields replace the same-keyed entry's fields, attributes and
combinations merge field by field, array fields are replaced wholesale. The merge itself runs in
the Rust core, so all three languages agree.
Example
from x_iztro import IztroError, KnowledgePack, PatternKey
from x_iztro.enums import MajorStar
pack = KnowledgePack.builtin()
overlay = KnowledgePack.from_dict({
"schema": 1, "id": "my-school", "version": "1", "language": "zh-CN", "extends": "iztro-docs",
"stars": {"ziweiMaj": {"intro": "我的紫微", "attributes": {"aliases": ["帝座"]}}},
"patterns": {"zi_fu_tong_gong": {"intro": "我的紫府同宫"}},
})
merged = pack.merged(overlay)
ziwei = merged.star(MajorStar.ZIWEI)
print(merged.id, ziwei.name, ziwei.attributes.aliases, ziwei.attributes.chemistry, ziwei.intro)
print(merged.pattern_intro(PatternKey.ZI_FU_TONG_GONG),
merged.pattern(PatternKey.ZI_FU_TONG_GONG).quotes)
print(pack.star_intro(MajorStar.ZIWEI)[:5])
try:
pack.merged({"schema": 99})
except IztroError as e:
print(e.code, e)Output
my-school 紫微 ['帝座'] 尊贵 我的紫微
我的紫府同宫 ['紫府同宫终身福厚。']
紫微星号称
invalid_argument knowledge pack schema 99 is newer than supported 1star / pattern / palace / mutagen / concept
Purpose Look up an entry by language-independent key.
Signature
def star(self, key: str) -> StarEntry | None
def pattern(self, key: str) -> PatternEntry | None
def palace(self, key: str) -> TextEntry | None
def mutagen(self, key: str) -> TextEntry | None
def concept(self, slug: str) -> ConceptEntry | NoneReturns None when the pack has no such entry.
Example
from x_iztro import KnowledgePack, Mutagen, PalaceName
from x_iztro.enums import MajorStar
pack = KnowledgePack.builtin()
ziwei = pack.star(MajorStar.ZIWEI)
print(ziwei.key, ziwei.name, ziwei.category, ziwei.attributes.dipper)
print(ziwei.attributes.aliases)
print(sorted(ziwei.combinations)[:5])
print(pack.palace(PalaceName.SOUL).name, pack.mutagen(Mutagen.LU).name)
print(pack.concept("tong-gong").title)
print(pack.star("nope"))Output
ziweiMaj 紫微 major 中天星系
['帝王星', '老板星', '俸禄星']
['pojunMaj', 'qishaMaj', 'tanlangMaj', 'tianfuMaj', 'tianxiangMaj']
命宫 化禄
遇、加、逢、同宫、同度
Nonestars / patterns
Purpose List every star / pattern entry in the pack.
Signature
def stars(self) -> list[StarEntry]
def patterns(self) -> list[PatternEntry]Returns Sorted by key, each entry carrying its own key. The default pack gives 162 and 64.
Use these when walking the whole pack — indexing, exporting, feeding an LLM — instead of digging
through to_dict().
star_intro / pattern_intro
Purpose Get the reading text directly.
Signature
def star_intro(self, key: str) -> str | None
def pattern_intro(self, key: str) -> str | NoneReturns None both when the entry is missing and when it exists without a reading.
Example List the natal patterns with their quotations:
from x_iztro import Astro, KnowledgePack
pack = KnowledgePack.builtin()
chart = Astro().by_solar("2000-8-16", 2, "female")
for hit in chart.patterns():
print(hit.name, "|", pack.pattern(hit.key).quotes[0])
print(pack.pattern_intro(hit.key)[:10])Output
府相朝垣 | 府相朝垣命必荣
“食禄千锺”的断语使