Package: genanki
genanki: A Library for Generating Anki Decksgenankiallows you to programatically generate decks in Python 3 for Anki, a popular spaced-repetition flashcard
program. Please see below for concepts and usage.This library and its author(s) are not affiliated/associated with the main Anki project in any way.NotesThe basic unit in Anki is theNote, which contains a fact to memorize.Notes correspond to one or moreCards.Here's how you create aNote:my_note=genanki.Note(model=my_model,fields=['Capital of Argentina','Buenos Aires'])You pass in aModel, discussed below, and a set offields(encoded as HTML).ModelsAModeldefines the fields and cards for a type ofNote. For example:my_model=genanki.Model(1607392319,'Simple Model',fields=[{'name':'Question'},{'name':'Answer'},],templates=[{'name':'Card 1','qfmt':'{{Question}}','afmt':'{{FrontSide}}<hr id="answer">{{Answer}}',},])This note-type has two fields and one card. The card displays theQuestionfield on the front and theQuestionandAnswerfields on the back, separated by a<hr>. You can also pass acssargument toModel()to supply custom
CSS.You need to pass amodel_idso that Anki can keep track of your model. It's important that you use a uniquemodel_idfor eachModelyou define. Useimport random; random.randrange(1 << 30, 1 << 31)to generate a suitable model_id, and hardcode it
into yourModeldefinition.Generating a Deck/PackageTo import your notes into Anki, you need to add them to aDeck:my_deck=genanki.Deck(2059400110,'Country Capitals')my_deck.add_note(my_note)Once again, you need a uniquedeck_idthat you should generate once and then hardcode into your.pyfile.Then, create aPackagefor yourDeckand write it to a file:genanki.Package(my_deck).write_to_file('output.apkg')You can then loadoutput.apkginto Anki using File -> Import...Media FilesTo add sounds or images, set themedia_filesattribute on yourPackage:my_package=genanki.Package(my_deck)my_package.media_files=['sound.mp3','images/image.jpg']media_filesshould have the path (relative or absolute) to each file. To use them in notes, first add a field to your model, and reference that field in your template:my_model=genanki.Model(1091735104,'Simple Model with Media',fields=[{'name':'Question'},{'name':'Answer'},{'name':'MyMedia'},# ADD THIS],templates=[{'name':'Card 1','qfmt':'{{Question}}<br>{{MyMedia}}',# AND THIS'afmt':'{{FrontSide}}<hr id="answer">{{Answer}}',},])Then, set theMyMediafield on your card to[sound:sound.mp3]for audio and<img src="image.jpg">for images.Youcannotput<img src="{MyMedia}">in the template andimage.jpgin the field. See these sections in the Anki manual for more information:Importing MediaandMedia & LaTeX.You should only put the filename (aka basename) and not the full path in the field;<img src="images/image.jpg">willnotwork. Media files should have unique filenames.Note GUIDsNotes have aguidproperty that uniquely identifies the note. If you import a new note that has the same GUID as an
existing note, the new note will overwrite the old one (as long as their models have the same fields).This is an important feature if you want to be able to tweak the design/content of your notes, regenerate your deck, and
import the updated version into Anki. Your notes need to have stable GUIDs in order for the new note to replace the
existing one.By default, the GUID is a hash of all the field values. This may not be desirable if, for example, you add a new field
with additional info that doesn't change the identity of the note. You can create a custom GUID implementation to hash
only the fields that identify the note:classMyNote(genanki.Note):@propertydefguid(self):returngenanki.guid_for(self.fields[0],self.fields[1])sort_fieldAnki has a value for eachNotecalled thesort_field. Anki uses this value to sort the cards in the Browse
interface. Anki also is happier if you avoid having two notes with the samesort_field, although this isn't strictly
necessary. By default, thesort_fieldis the first field, but you can change it by passingsort_field=toNote()or implementingsort_fieldas a property in a subclass (similar toguid).You can also passsort_field_index=toModel()to change the sort field.0means the first field in the Note,1means the second, etc.YAML for Templates (and Fields)You can create your template definitions in the YAML format and pass them as astrtoModel(). You can also do this
for fields.Using genanki inside an Anki addongenankisupports adding generated notes to the local collection when running inside an Anki 2.1 addon (Anki 2.0
may work but has not been tested). See the.write_to_collection_from_addon() method.CLOZE_MODEL DeprecationWarningDue to a mistake, in genanki versions before 0.13.0,builtin_models.CLOZE_MODELonly had a single field, whereas the real Cloze model that is built into Anki has two fields. If you get aDeprecationWarningwhen usingCLOZE_MODEL, simply add another field (it can be an empty string) when creating yourNote, e.g.my_note=genanki.Note(model=genanki.CLOZE_MODEL,fields=['{{c1::Rome}} is the capital of {{c2::Italy}}',''])FAQMy field data is getting garbledIf fields in your notes contain literal<,>, or&characters, you need to HTML-encode them: field data is HTML, not plain text. You can use thehtml.escapefunction.For example, you should writefields=['AT&amp;T was originally called', 'Bell Telephone Company']orfields=[html.escape(f) for f in ['AT&T was originally called', 'Bell Telephone Company']]This applies even if the content is LaTeX; for example, you should writefields=['Piketty calls this the "central contradiction of capitalism".', '[latex]r &gt; g[/latex]']Publishing to PyPIIf your name is Kerrick, you can publish thegenankipackage to PyPI by running these commands from the root of thegenankirepo:rm -rf dist/*
python3 setup.py sdist bdist_wheel
python3 -m twine upload dist/*Note that this directly uploads to prod PyPI and skips uploading to test PyPI.