Textbooks¶
A textbook is a long structured document. Alongside its metadata it carries a structure tree (its table of contents — chapters, sections) and a set of passages (the extracted text, addressable by page). Textbooks are URN-backed; passages are UUID-backed and always belong to a textbook.
What they are¶
Textbook |
TextbookPassage |
|
|---|---|---|
Entity class |
|
|
Collection |
|
|
Endpoint |
|
|
Identifier |
URN ( |
UUID ( |
Belongs to |
— |
a textbook ( |
Important
Structure-tree and passage operations require the textbook to have exactly one
associated artifact (the source file). With zero or several artifacts, those operations
raise a ValueError telling you so.
Quick example¶
import os
from wisefood import DataClient, Credentials
client = DataClient(
os.environ["WISEFOOD_API_URL"],
Credentials(username=os.environ["WISEFOOD_USERNAME"],
password=os.environ["WISEFOOD_PASSWORD"]),
)
tb = client.textbooks["nutrition-science-3e"]
print(tb.title, "·", tb.publisher, tb.edition)
for passage in tb.page[37]: # passages on page 37
print(passage.sequence_no, passage.text[:80])
Field reference — Textbook¶
Field |
Type |
Notes |
|---|---|---|
|
|
Read-only. |
|
|
|
|
|
|
|
|
Defaults to |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
Defaults to |
|
|
Defaults to |
|
|
Defaults to |
|
|
|
|
|
|
|
|
|
|
tree helper |
See below. |
|
|
|
|
|
Read-only. |
Field reference — TextbookPassage¶
Field |
Type |
Notes |
|---|---|---|
|
|
Read-only. |
|
|
Read-only. |
|
|
Read-only. |
|
|
|
|
|
The passage text. |
|
|
Offsets within the page/document. |
|
|
Read-only — the tree node this passage sits under. |
|
|
Read-only — path from the root. |
|
|
Provenance of the extraction. |
|
|
Read-only. |
The structure tree¶
textbook.structure_tree is a live helper for building and navigating the table of
contents. Constructing nodes automatically fills in the textbook’s single artifact_id,
and (with sync=True) each change is saved back to the API.
Building it¶
tb = client.textbooks["nutrition-science-3e"]
tree = tb.structure_tree
# Add a top-level chapter
ch1 = tree.add_chapter(id="ch1", title="Macronutrients", page_start=1, page_end=40)
# Nest sections under it
ch1.add_section(id="ch1-1", title="Carbohydrates", page_start=1, page_end=11)
ch1.add_section(id="ch1-2", title="Proteins", page_start=12, page_end=25)
# add_root / set_root let you control roots explicitly (set_root clears first)
root = tree.set_root(id="book", title="Nutrition Science", kind="book", page_start=1)
root.add_chapter(id="ch1", title="Macronutrients", page_start=1, page_end=40)
add_child(...) is the general form; add_chapter / add_section are convenience
wrappers that set kind for you.
Replacing it wholesale¶
tb.structure_tree = {
"roots": [
{"id": "ch1", "title": "Macronutrients", "kind": "chapter",
"page_start": 1, "page_end": 40, "children": []},
]
}
Passages¶
textbook.passages is a textbook-scoped collection (it queries
textbook-passages/by-textbook/<urn>).
tb.passages.search("glycemic index") # scoped full-text search
tb.passages.by_page(37) # all passages on page 37
tb.page[37] # same thing, index syntax
tb.passages["<passage-uuid>"] # direct lookup, validated against this textbook
Bulk replace¶
Replace a textbook’s passages (and optionally its structure tree and page count) in one call — useful right after a fresh extraction:
tb.passages.bulk_replace(
page_count=420,
structure_tree=tb.structure_tree.to_dict(),
passages=[
{"page_no": 1, "sequence_no": 0, "text": "Chapter 1. Macronutrients ..."},
{"page_no": 1, "sequence_no": 1, "text": "Carbohydrates are ..."},
],
extractor_name="pdf-extractor",
extractor_run_id="run-2024-001",
)
The artifact_id is resolved from the textbook automatically when the proxy is bound to
a loaded textbook; pass it explicitly otherwise.
Gotchas¶
No top-level passage browsing.
client.textbook_passages.search(...)and listing raiseNotImplementedError— passages only exist within a textbook. Usetb.passages...orclient.textbook_passages.by_textbook(urn).Structure/passage operations need exactly one associated artifact; otherwise you get a clear
ValueError.typeis immutable;textbook_urn,artifact_id,structure_node_id, andstructure_pathon passages are read-only.by_page(n)requiresn >= 1.