Imports¶
chronicle.imports bulk-loads external research-report PDFs into an organization's library as deduped, org-scoped assets.
These are never personal uploads — organization scope is mandatory, and the server refuses an import without one. Pass organization_id= or configure a client default org; otherwise the call raises ChronicleConfigError.
Importing a batch¶
chronicle.imports.research_reports(...) takes a single path, a list of paths, or a directory. Directories expand to their *.pdf files (non-recursive). An explicitly-named non-PDF file raises — imports are PDF-only.
summary = chronicle.imports.research_reports(
"./arxiv-pdfs/", # a directory of PDFs → every *.pdf in it
organization_id="org_7Qk",
collection="lit-review-2026", # id or slug; added at finalize
)
print(f"imported {len(summary.imported)}, "
f"duplicates {len(summary.duplicates)}, "
f"failed {len(summary.failed)}")
Per file the SDK registers an imported_report asset (sha256 + size provenance), PUTs it via a presigned URL, then makes one /assets/bulk-finalize call over the batch — verifying the uploads, flipping them ready, and enqueueing the server-side text-extraction job.
Re-running a batch is safe
Bytes already present in the org come back as duplicates (server 409) — success-shaped, nothing re-uploaded. Re-run a partially-failed import without producing copies.
Targeting collections¶
collection and collections are fluent — pass either or both. Each entry is a collection id or slug; every report that reaches ready is added as a member at finalize. The server resolves slugs within the org and requires Write on each collection, so an unresolvable slug or a missing grant fails the finalize call. See the collections guide.
summary = chronicle.imports.research_reports(
["./a.pdf", "./b.pdf"],
collections=["lit-review-2026", "col_xy9"], # list or a lone string
)
A report that couldn't be added to a collection (e.g. Write lost mid-batch) lands in collection_warnings — never failing the batch.
Skipping finalize¶
Pass finalize=False to register and upload without finalizing — no extraction job runs, collection targets are ignored, and extraction_job_id stays None. Use it when you want to finalize the batch yourself later.
ImportSummary¶
The returned ImportSummary — counts always add up to the inputs:
| Field | Type | Meaning |
|---|---|---|
organization_id |
str |
Org the batch imported into |
imported |
list[ImportedReport] |
Successfully registered + uploaded files |
duplicates |
list[str] |
Filenames already in the org — nothing re-uploaded |
failed |
list[tuple[str, str]] |
(filename, reason) for everything else |
extraction_job_id |
str \| None |
The batch's pdf_extraction job (None if nothing finalized) |
collection_warnings |
list[dict] |
Per-asset {asset_id, collection_id, reason} add-skips |
ImportedReport¶
Each entry in summary.imported:
| Field | Type | Meaning |
|---|---|---|
asset_id |
str |
The created org-scoped asset |
name |
str |
Asset name (the file stem) |
path |
Path |
Source file on disk |
sha256 |
str |
Content digest used for provenance + dedup |
The full signature and result types are in the client reference under methodic.imports.ImportsAPI.