Working with an ankideck using python

I want to do some programmatic stuff with one of my decks but have been seriously struggling with representing an .apkg file in python. I simply want to do something like:

decks = load('decks.apkg')
decks['deck']['note']['field'] = 'content'
decks.write('new.apkg')

ergo:
How do I load an .apkg file into a python environment?

This is probably a wrong paradigm, I know that. I tried:

import aqt
import anki
from anki.importing.apkg import AnkiPackageImporter
import os
col_name = "collect/decks"
if os.path.exists(col_name):
    os.remove(col_name)
    
col = anki.collection.Collection(col_name)

decks = AnkiPackageImporter(col, "decks.apkg")
decks.run()

There are several errors:

import aqt

reports:

macos_helper:
dlopen(/usr/local/anaconda3/lib/python3.11/site-packages/_aqt/data/lib/libankihelper.dylib, 0x0006): tried:
'/usr/local/anaconda3/lib/python3.11/site-packages/_aqt/data/lib/libankihelper.dylib' (no such file),
'/System/Volumes/Preboot/Cryptexes/OS/usr/local/anaconda3/lib/python3.11/site-packages/_aqt/data/lib/libankihelper.dylib' (no such file),
'/usr/local/anaconda3/lib/python3.11/site-packages/_aqt/data/lib/libankihelper.dylib' (no such file)

The main problem arises here though:

---------------------------------------------------------------------------
AttributeError                            Traceback (most recent call last)
Cell In[13], line 9
      7 # Not the actual data structures
      8 decks = AnkiPackageImporter(col, "decks.apkg")
----> 9 decks.run()

File /usr/local/anaconda3/lib/python3.11/site-packages/anki/importing/apkg.py:50, in AnkiPackageImporter.run(self)
     48     self.nameToNum[unicodedata.normalize("NFC", v)] = k
     49 # run anki2 importer
---> 50 Anki2Importer.run(self, importing_v2=suffix == ".anki21")
     51 # import static media
     52 for file, c in list(self.nameToNum.items()):

File /usr/local/anaconda3/lib/python3.11/site-packages/anki/importing/anki2.py:53, in Anki2Importer.run(self, media, importing_v2)
     51     self.src.media._dir = media
     52 try:
---> 53     self._import()
     54 finally:
     55     self.src.close(downgrade=False)

File /usr/local/anaconda3/lib/python3.11/site-packages/anki/importing/anki2.py:77, in Anki2Importer._import(self)
     75 self._prepareTS()
     76 self._prepareModels()
---> 77 self._importNotes()
     78 self._importCards()
     79 self._importStaticMedia()

File /usr/local/anaconda3/lib/python3.11/site-packages/anki/importing/anki2.py:180, in Anki2Importer._importNotes(self)
    178 if add:
    179     for row in add:
--> 180         self._logNoteRow(self.dst.tr.adding_added(), row)
    181 if dupesIdentical:
    182     for row in dupesIdentical:

File /usr/local/anaconda3/lib/python3.11/site-packages/anki/importing/anki2.py:88, in Anki2Importer._logNoteRow(self, action, noteRow)
     86 def _logNoteRow(self, action: str, noteRow: list[str]) -> None:
     87     self.log.append(
---> 88         "[{}] {}".format(action, strip_html_media(noteRow[6].replace("\x1f", ", ")))
     89     )

File /usr/local/anaconda3/lib/python3.11/site-packages/anki/utils.py:65, in strip_html_media(txt)
     62 import anki.lang
     63 from anki.collection import StripHtmlMode
---> 65 return anki.lang.current_i18n.strip_html(
     66     text=txt, mode=StripHtmlMode.PRESERVE_MEDIA_FILENAMES
     67 )

AttributeError: 'NoneType' object has no attribute 'strip_html'

I am on a Mac M2 chipset, might have to do with it.
The .apkg was created using anki:
Version ⁨2.1.65 (aa9a734f)⁩
Python 3.9.15 Qt 6.5.0 PyQt 6.5.0

Versions:
python v3.11.5
aqt 23.10.1
anki 23.10.1

Tried reinstalling aqt and anki.

How do I load an .apkg file into a python environment? Am I tackling this the right way? Is it possible?

Adding a call to anki.lang.set_lang() before .run() seems to work:

from anki.lang import set_lang

set_lang("en_US")
1 Like

That’s the legacy importer, which will be removed in the future. The following code should be used instead, though it will only work if you run for git or wait until the next beta build.

        from anki.collection import ImportAnkiPackageOptions, ImportAnkiPackageRequest

        col.import_anki_package(
            ImportAnkiPackageRequest(
                package_path="/path/foo.apkg",
                options=ImportAnkiPackageOptions(
                    with_scheduling=True, with_deck_configs=True
                ),
            )
        )
1 Like

This topic was automatically closed 30 days after the last reply. New replies are no longer allowed.