Skip to content

julien-sobczak/anki-cli

Repository files navigation

Anki CLI

CLI 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

$ pip3 install aqt==2.1.44 # Must be compatible with your Anki desktop installation
$ pip3 install anki-cli-unofficial

Usage

The CLI supports a single command load.

$ anki-cli-unofficial load -h
usage: anki-cli-unofficial load [-h] [--anki-dir ANKI_DIR] [--media-dir MEDIA_DIR] [--deck DECK] input_file output_file

positional arguments:
  input_file            YAML file containing the flashcards to create
  output_file           Anki generated archive filepath

optional arguments:
  -h, --help            show this help message and exit
  --anki-dir ANKI_DIR
                        Anki directory (Default to a temp directory)
  --media-dir MEDIA_DIR
                        local directory containing medias referenced in input_file
  --deck DECK
                        deck name in which to create flashcards

By 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-dir but I 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 command load expects 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 tags
  fields: # The ordered list of fields for the selected note type (ex: Basic notes require two fields: Front & Back)
    Front: Bonjour
    Back: Hello

The command load also 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-unofficial load cards.yaml archive.apkg

📂 Opening Anki collection...
🔍 Loading 'cards.yaml' into the deck 'Default'...
💾 Saving Anki collection...
👍 Done
👉 Anki collection can be opened using the following command:
        open /Applications/Anki.app --args -b /var/folders/5f/9sp_9nk17jjdtw7y9t9rydr80000gn/T/tmpn8rl4l2w
👉 Anki Archive is available here: ./archive.apkg

After 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 Uses

Multilingual Support

The 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 ankdir

Medias

Medias 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: Basic
  fields:
    Front: '<img src="car.jpg" />'
    Back: '[sound:voiture.mp3] Une voiture'
# 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-unofficial load --media-dir ~/anki-images cards.yaml
# Where ~/anki-images contains the files car.jpg and voiture.mp3

Custom Note Types

The 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%\Anki2
  • MacOS: ~/Library/Application Support/Anki2
  • Linux: ~/.local/share/Anki2

The CLI expects a user directory (~/Library/Application Support/Anki2/User 1 is 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.apkg

When 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 menu Browser and select the newly created cards (using a special tag, for example).
  • Right-click and select Export.

Examples

You will find additional examples in the directory examples/.

Development

Test locally

$ cd anki-cli/
$ python3 setup.py install # The binary anki-cli-unofficial is now present in $PATH
$ anki-cli-unofficial load --media-dir ./examples ./examples/french.yaml archive.apkg

Upload to PyPI

  1. Create an API Token from the Web UI. (Edit your ~/.pypirc with the generated token.)
  2. Install Twine
$ python3 -m pip install --user --upgrade twine
  1. Upload the bundle
$ python3 -m twine upload dist/*

Note: The upload to PyPI is currently assured by GitHub Actions.

Release

  1. Increase the version number in setup.py.
  2. Commit and push.
  3. Create a new tag in GitHub to trigger the CI pipeline.