Package: anki-cli-unofficial
Anki CLICLI to automate Anki notes/flashcards creation.This project is not part of the official Anki project.Note: The code was tested using Python 3.8 and Anki 2.1.35.Installation$pip3installaqt==2.1.44# Must be compatible with your Anki desktop installation$pip3installanki-cli-unofficialUsageThe CLI supports a single commandload.$anki-cli-unofficialload-h
usage:anki-cli-unofficialload[-h][--anki-dirANKI_DIR][--media-dirMEDIA_DIR][--deckDECK]input_fileoutput_file

positionalarguments:input_fileYAMLfilecontainingtheflashcardstocreateoutput_fileAnkigeneratedarchivefilepath

optionalarguments:-h,--helpshowthishelpmessageandexit--anki-dirANKI_DIRAnkidirectory(Defaulttoatempdirectory)--media-dirMEDIA_DIRlocaldirectorycontainingmediasreferencedininput_file--deckDECKdecknameinwhichtocreateflashcardsBy default, the CLI will create a sandbox Anki environment. This temporary directory will be deleted by your OS after a few days. You can specify an existing Anki directory using the option--anki-dirbutI strongly recommend that you don't run this program on your main Anki directory. This code may become outdated, and I don't want bugs to damage your precious flashcards.The commandloadexpects a YAML file as input. This file must use this format:# File cards.yaml# An array of documents-type:Basic# The type of the node to create ("Basic", "Basic (with reverse card)", etc.). Also known as the model.tags:[tag1,tag2]# An optional list of tagsfields:# The ordered list of fields for the selected note type (ex: Basic notes require two fields: Front & Back)Front:BonjourBack:HelloThe commandloadalso expects the filename of the generated Anki package (usually ends with.apkg). The file doesn't have to exist. The CLI will create it in your current directory.To generate the flashcards:$anki-cli-unofficialloadcards.yamlarchive.apkg

📂OpeningAnkicollection...
🔍Loading'cards.yaml'intothedeck'Default'...
💾SavingAnkicollection...
👍Done
👉Ankicollectioncanbeopenedusingthefollowingcommand:open/Applications/Anki.app--args-b/var/folders/5f/9sp_9nk17jjdtw7y9t9rydr80000gn/T/tmpn8rl4l2w
👉AnkiArchiveisavailablehere:./archive.apkgAfter the completion, you have the option to visualize the generated flashcard by opening Anki on the sandbox directory. The command differs depending on your OS and is therefore displayed by the CLI. If everything looks fine, you can close Anki and reopen it without any option like usual to import the packaged Anki deck generated by the CLI. That's it!Advanced UsesMultilingual SupportThe CLI was tested using the English locale. You may still use it with a different locale but minor adjustement are required.Ex: (French)# Create a Anki home with the French locale
$ anki -l fr -b ./ankidir

# Make sure your input file follows the locale naming conventions
$ echo cards.yml
- type: Basique  # "Basic" translation in French
  tags: [idiom]
  fields:        # Field names must be translated:
    Recto: 'Avoir la banane! <small>idiom</small>'
    Verso: 'To feel great. (literally: <em>to have the banana<em>)'

# Use the option --deck to override the default deck name
$ anki-cli-unofficial load cards.yaml \
      --deck="Par défaut" \
      --anki-dir="./ankidir/Utilisateur 1/" \
      archive.apkg

# Open Anki to check generated cards
$ anki -b ankdirMediasMedias are supported using the usual Anki syntax:Include[sound:file.mp3]inside a field to add sounds to your flashcard.Include<img src="file.jpg">inside a field to add images to your flashcard.Ex:-type:Basicfields:Front:'<imgsrc="car.jpg"/>'Back:'[sound:voiture.mp3]Unevoiture'# This card will show the picture of a card and print the translation# with the pronunciation when the back card is revealed.You must specify the local directory containing the media files. The CLI will copy these files in the Anki medias database (missing files are ignored).$anki-cli-unofficialload--media-dir~/anki-imagescards.yaml# Where ~/anki-images contains the files car.jpg and voiture.mp3Custom Note TypesThe CLI creates a fresh Anki directory to generate the flashcards (for safety reasons). Therefore, only default card types are supported. If you have custom note types, you may decide to launch the CLI directly on your Anki directory using the option--anki-dir. That would be a bad idea. Bugs happen. I don't want to damage your flashcards. A better alternative is to create a copy of your current directory.Note: The Anki directory differs according your OS (check the official documentation):Windows:%APPDATA%\Anki2MacOS:~/Library/Application Support/Anki2Linux:~/.local/share/Anki2The CLI expects a user directory (~/Library/Application Support/Anki2/User 1is valid but~/Library/Application Support/Anki2/is not).Before running the CLI, make sure to back up this directory!(Create a zip archive using the file explorer or using the terminal.) Anki Desktop creates automatic backups by default, but they don't include medias.Then, run the CLI on the copy of your Anki directory. Example (on MacOS):$ mkdir $TMPDIR/Anki2
$ cp -R ~/Library/Application Support/Anki2/User\ 1 $TMPDIR/Anki2
$ anki-cli-unofficial load --anki-dir $TMPDIR/Anki2/User\ 1 cards.yaml archive.apkgWhen running on an existing Anki directory, the CLI doesn't create the package file (to avoid exporting all of your flashcards). Therefore, you have to create the archive yourself:Open Anki on the clone directory (the command is displayed in the output).Use the menuBrowserand select the newly created cards (using a special tag, for example).Right-click and selectExport.ExamplesYou will find additional examples in the directoryexamples/.DevelopmentTest locally$cdanki-cli/
$python3setup.pyinstall# The binary anki-cli-unofficial is now present in $PATH$anki-cli-unofficialload--media-dir./examples./examples/french.yamlarchive.apkgUpload to PyPICreate an API Token from the Web UI. (Edit your~/.pypircwith the generated token.)Install Twine$python3-mpipinstall--user--upgradetwineUpload the bundle$python3-mtwineuploaddist/*Note: The upload to PyPI is currently assured by GitHub Actions.ReleaseIncrease the version number insetup.py.Commit and push.Create a new tag in GitHub to trigger the CI pipeline.