Accessing Anki collection models from Python
For one-off projects that target Anki collections, I often use Python in a standalone application rather than an Anki add-on. Since I’m not going to distribute these little creations that are specific to my own needs, there’s no reason to create an add-on. These are just a few notes - nothing comprehensive - on the process.
One thing to be aware of is that there must be a perfect match between the Anki major and minor version numbers for the Python anki
module to work. If you are running Anki 2.1.48 on your desktop application but have the Python module built for 2.1.49, it will not work. This is a huge irritation and there’s no backwards compatibility; the versions must match precisely.
Anyway, here’s a little application to illustrate the simple process of finding all of the moderls (also know as note types.)
#!/usr/bin/env python3
import os
from anki.collection import Collection
from anki.models import ModelManager
import anki.errors
COLLECTION_PATH = os.environ.get('ANKI_RU_COL_PATH')
def anki_utf8_tr(ustr: str) -> str:
try:
return ustr.encode('latin1').decode('utf8')
except UnicodeEncodeError:
return ustr
if __name__ == "__main__":
try:
col = Collection(COLLECTION_PATH)
except anki.errors.DBError:
print("ERROR: Anki should be closed")
quit()
model_mgr = ModelManager(col)
for m in model_mgr.all_names_and_ids():
m_id = m.id
m_name = anki_utf8_tr(m.name)
print(f'{m_id} - {m_name}')
An interesting caveat in reading the model names: if you’ve used names with character sets other than Latin, then the output of the model.name
looks a little strnge, e.g. name: "\320\240\321\203\321\201\321\201\320\272\320\270\320\271 enhanced"
which took a bit of time to figure out. It’s actually just decimal UTF-8 codes. The function anki_utf8_tr
function is meant to provide the translation to the original representation. I’ve written more about this previously.