AnkiForge Python
The Python SDK calls the default public Rust API through a PyO3 extension. Project is the sole authoring container. Choose a stable namespace and a stable key for every note; display names and content can change independently.
The distribution name and import package are both ankiforge. Once the release
is available on PyPI, install it with python -m pip install ankiforge.
See the release status before choosing a version.
from ankiforge import Project, Note, BuildOptions
project = Project('biology-course', default_deck='Science::Biology')
project.add('cell', Note.basic('What is a cell?', 'A unit of life'))
output = project.build(BuildOptions.to('biology.apkg'))
print(output.artifact.path, output.report.counts.notes)
Strings always mean plain text. Use Content.html(...) for HTML, and Content.sequence(...) to combine text, HTML, images and sounds while retaining their dependencies.
from ankiforge import Media, Content
image = Media.file('cell.png')
project.add('cell-image', Note.basic(Content.sequence(['Cell: ', image.image()]), '细胞'))
Media owns a snapshot immediately; deleting the input file later is safe. Media.bytes(data, mime_type) accepts bytes with an explicit MIME type, including resources larger than 64 KiB. Both constructors accept limits=MediaLimits(max_bytes=...). To use a fixed filename, call media.with_export_name('cell.png') before creating content. Existing references retain the earlier name. Assets referenced by raw HTML, CSS or scripts must be declared using Project.add_asset(media) or NoteTypeBuilder.asset(media).
Custom models are completed and validated before creating notes:
from ankiforge import Field, Template, NoteType
model = (NoteType.builder('vocab').name('词汇')
.field(Field('front', name='正面'))
.field(Field('back', name='背面'))
.template(Template('recognition', '{{front}}', '{{FrontSide}}<hr>{{back}}', name='识别'))
.build())
project.add('word:cell', model.note().field('front', 'cell').field('back', '细胞'))
Field and template keys are explicit and are used in template expressions. Models, notes, content and media are immutable reusable values. Builder methods return updated values. Models are collected automatically when adding a note. NoteType.from_bundle(path, limits=MediaLimits(max_bytes=256 << 20)) loads the new template-bundle-v2 format and snapshots its assets. The per-asset budget may be lowered or raised before reading. Bundle errors expose typed budget and nested error observations in source_details.
For image occlusion, use Note.image_occlusion(media).mask(Mask.rect('nucleus', 2, 2, 4, 4)).build(). Mask keys are required and preserve card identity when masks are reordered. OcclusionMode.HIDE_ALL_GUESS_ONE is the default; HIDE_ONE_GUESS_ONE is also supported. Add header/back_extra/comments through normal Note.field calls after building the IO note.
Updates use the original prior distribution APKG, which contains complete identity evidence:
from ankiforge import CompareOptions
next_project = Project('biology-course', default_deck='Science::Biology')
next_project.add('cell', Note.basic('What is a cell?', 'The basic unit of life'))
comparison = next_project.compare(CompareOptions.against('biology.apkg'))
output = next_project.build(BuildOptions.to('biology-v2.apkg').update_from('biology.apkg'))
A complete comparison returns a ComparisonReport even if its policy blocks publication. Update builds raise BuildError on that same blocking policy. The default UpdatePolicy() blocks High and Critical findings. After reviewing a particular risk category, explicitly accept it with UpdatePolicy().allow('RISK.NOTE_REMOVED'); this preserves the original findings and evidence. Unknown codes and hard errors cannot be accepted. Apply a policy with .update_policy(policy) on BuildOptions or CompareOptions. Explicit update policies on Create requests are configuration errors. InspectLimits applies independently to each inspected baseline and candidate.
Successful builds always return BuildOutput.artifact. BuildReport contains observations only. output.snapshot(), output.report.snapshot() and BuildError.snapshot() return JSON-serializable copies that do not own files. With BuildOptions.temporary(), retain an artifact handle while using the file; close it or release all copies to delete the temporary output. artifact.persist_to(path) returns a new persistent handle. Failures preserve domain exception types, kind, code, source-chain text in causes, and publication facts where relevant.
Development: run maturin develop --manifest-path bindings/python/native/Cargo.toml, build the independent observer with cargo build -p anki_forge_python_native --example python_parity, then run python -m pytest bindings/python/tests and python -m mypy --config-file bindings/python/pyproject.toml bindings/python/src/ankiforge.
Native handles belong to their creating process. After os.fork(), inherited handles reject operations with BINDING.FORKED_OBJECT; dropping them cannot remove parent-owned snapshots. Create new values in the child for child-side work. Those new values retain normal cleanup.
Addition diagnostics
Projects have a stable namespace and optional default deck, with no title. Image and sound constructors remain infallible; adding a note checks retained MIME categories: image/* for images, audio/* or video/* for sound references. Other categories raise AddError with code NOTE.MEDIA_USAGE_INVALID. Raw HTML and explicit assets retain their existing behavior; category checking does not promise decodability. Build still performs its independent MIME/extension checks.
AddError.details is described by exported AddErrorDetails TypedDict, with
context and nullable detail, alongside error_kind, causes and
source_details. Context includes note_key, model_key and target; field
targets include field_key, content_path and byte_range.
Native metadata must report embedded contract 2.0.0, even when binding/core
versions both match 0.2.0.
A field path is null/None for the field, [] for root content, or zero-based
indices into the original sequences. Byte ranges use UTF-8 offsets in the
original text/HTML leaf. Nested source details preserve the same facts.
Metadata
Release files for ankiforge 0.2.0
For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.
Source distribution (sdist)
| File | Size | Uploaded | |
|---|---|---|---|
| ankiforge-0.2.0.tar.gz | 419.1 kB | Details |
Built distributions (wheels)
| File | Reset | |||
|---|---|---|---|---|
| ankiforge-0.2.0-cp311-abi3-win_amd64.whl | CPython 3.11 | abi3 | Windows x86-64 | Details |
| ankiforge-0.2.0-cp311-abi3-manylinux_2_17_x86_64.manylinux2014_x86_64.whl | CPython 3.11 | abi3 | Linux glibc 2.17+ x86-64 | Details |
| ankiforge-0.2.0-cp311-abi3-macosx_11_0_arm64.whl | CPython 3.11 | abi3 | macOS 11.0+ ARM64 | Details |
| ankiforge-0.2.0-cp311-abi3-macosx_10_12_x86_64.whl | CPython 3.11 | abi3 | macOS 10.12+ x86-64 | Details |
Total release size: 23.0 MB
Release files / ankiforge-0.2.0.tar.gz
| Download URL | ankiforge-0.2.0.tar.gz |
|---|---|
| Size | 419.1 kB |
| Tags | Source |
|
SHA-256 checksum How to use checksums |
dfe671760e77c359a4613ec3664a69666ead22815a6b4ff37242cf93e6938a4f
|
|
BLAKE2b-256 checksum How to use checksums |
63382fce9cad7f3683803f695b54d08b29d7bdbcf6673d5affee04ae8fecf192
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
Yes |
| Uploaded via |
twine/7.0.0 CPython/3.13.14
|
Provenance
Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.
PyPI Publish Attestation
PyPI verified that this artifact, at this checksum, originated from the publisher listed below.
Signed by GitHub Actions, verified by PyPI on Oct 2, 2026.
Transparency logRelease files / ankiforge-0.2.0-cp311-abi3-win_amd64.whl
| Download URL | ankiforge-0.2.0-cp311-abi3-win_amd64.whl |
|---|---|
| Size | 5.1 MB |
| Tags | CPython 3.11 Windows x86-64 abi3 |
|
SHA-256 checksum How to use checksums |
98bc3816c002756fe7dda263825711abe366277e498fdcf197c27e654db278c9
|
|
BLAKE2b-256 checksum How to use checksums |
d4ca14540892055aa635f705e5d285353a405eeeef6ba473bcbd0bf2c342e6f8
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
Yes |
| Uploaded via |
twine/7.0.0 CPython/3.13.14
|
Provenance
Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.
PyPI Publish Attestation
PyPI verified that this artifact, at this checksum, originated from the publisher listed below.
Signed by GitHub Actions, verified by PyPI on Oct 2, 2026.
Transparency logRelease files / ankiforge-0.2.0-cp311-abi3-manylinux_2_17_x86_64.manylinux2014_x86_64.whl
| Download URL | ankiforge-0.2.0-cp311-abi3-manylinux_2_17_x86_64.manylinux2014_x86_64.whl |
|---|---|
| Size | 6.8 MB |
| Tags | CPython 3.11 Linux glibc 2.17+ x86-64 abi3 |
|
SHA-256 checksum How to use checksums |
703116da6f410632616b494c49f4f8cd50adc001f7471ca40da8d18bd7442a2b
|
|
BLAKE2b-256 checksum How to use checksums |
300ae7f9f3b2e0920a8760d718e7d49188e1dfd253c35e7274f2a70f709450f4
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
Yes |
| Uploaded via |
twine/7.0.0 CPython/3.13.14
|
Provenance
Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.
PyPI Publish Attestation
PyPI verified that this artifact, at this checksum, originated from the publisher listed below.
Signed by GitHub Actions, verified by PyPI on Oct 2, 2026.
Transparency logRelease files / ankiforge-0.2.0-cp311-abi3-macosx_11_0_arm64.whl
| Download URL | ankiforge-0.2.0-cp311-abi3-macosx_11_0_arm64.whl |
|---|---|
| Size | 5.2 MB |
| Tags | CPython 3.11 abi3 macOS 11.0+ ARM64 |
|
SHA-256 checksum How to use checksums |
62c14d70bd4db7059b4f2f86d96b8d49da0f7783755a0d5a858338eef0ad33e1
|
|
BLAKE2b-256 checksum How to use checksums |
f5ddf07e578c09040b29b79af3337cb20c6594527f4b04546b86a87b2cb28f0d
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
Yes |
| Uploaded via |
twine/7.0.0 CPython/3.13.14
|
Provenance
Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.
PyPI Publish Attestation
PyPI verified that this artifact, at this checksum, originated from the publisher listed below.
Signed by GitHub Actions, verified by PyPI on Oct 2, 2026.
Transparency logRelease files / ankiforge-0.2.0-cp311-abi3-macosx_10_12_x86_64.whl
| Download URL | ankiforge-0.2.0-cp311-abi3-macosx_10_12_x86_64.whl |
|---|---|
| Size | 5.4 MB |
| Tags | CPython 3.11 abi3 macOS 10.12+ x86-64 |
|
SHA-256 checksum How to use checksums |
12f90bc0510cd24218bc78e64423537038a231bec3ff40c986472bfcbfdf84ee
|
|
BLAKE2b-256 checksum How to use checksums |
7effc56b19096735bf3b70a751e12a6d2fece5f310a64b104f8aa7491bfa5034
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
Yes |
| Uploaded via |
twine/7.0.0 CPython/3.13.14
|
Provenance
Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.
PyPI Publish Attestation
PyPI verified that this artifact, at this checksum, originated from the publisher listed below.
Signed by GitHub Actions, verified by PyPI on Oct 2, 2026.
Transparency log