Import CSV files programmatically

I am trying to automatically import CSV files.
For this purpose, I am trying to use Anki’s built-in code as below.
But it causes an error.
What did I do wrong?

import anki
from anki.collection import ImportCsvRequest, ImportLogWithChanges
from anki.hooks import wrap
from aqt import gui_hooks, mw
from aqt.utils import getFile, showText


def import_csv_(self, request: ImportCsvRequest) -> ImportLogWithChanges:
    print(str("request"))
    log = self._backend.import_csv_raw(request.SerializeToString())
    return ImportLogWithChanges.FromString(log)

anki.collection.Collection.import_csv = wrap(anki.collection.Collection.import_csv, import_csv_)


def print_pb(*args):
    path= getFile(mw, "133", None)
    meta = mw.col.get_csv_metadata(path, None)
    request = ImportCsvRequest()
    request.path = path
    # request.metadata =meta
    log = mw.col.import_csv(request)
    showText(str(log))
print_pb()

error:

anki.errors.InvalidInput: deck oneof not set

You have to pass ImportCsvRequest’s fields to the constructor. This works for me:

def print_pb(*args):
    path = getFile(mw, "133", None)
    metadata = mw.col.get_csv_metadata(path, None)
    request = ImportCsvRequest(path=path, metadata=metadata)
    log = mw.col.import_csv(request)
    showText(str(log))
2 Likes

It works!
But only if I import the CSV file into my current collection.
I tried importing it into a temporary collection that I created programmatically and nothing changes. Unlike adding a new note, it does work. Only the CSV import does not.
(I’m trying to import a CSV file and control the deck and the notetype to which each note will be imported. Since I have no way to control this through Anki’s new import using a addon, I create a temporary collection as above and then import from it)

from anki.collection import ImportCsvRequest, ImportLogWithChanges, Collection
from aqt.utils import getFile, showText
from anki.utils import tmpdir
from aqt import mw
import os


short_col_name ="temp_for_import"
name = tmpdir() + "\\" + f"{short_col_name}"
colpath = name + "\collection.anki2"
try:
    os.mkdir(name)
except FileExistsError:
    pass
mw.temp_col = Collection(colpath)

model = mw.temp_col.models.current()
note = mw.temp_col.new_note(model)
mw.temp_col.add_note(note, mw.col.decks.selected())
path = getFile(mw, "getFile", None)
metadata = mw.temp_col.get_csv_metadata(path, None)
request = ImportCsvRequest(path=path, metadata=metadata)
print(len(mw.temp_col.find_notes("")))

Your code is missing this line: mw.temp_col.import_csv(request)

1 Like

still not working.
(Before, I tried with this line. I forgot to add it in the example :disappointed_relieved:.)

len() is returning 1 so it must have imported something? I just copied your code and run it. Not sure why that’s not working for you.

1 Like

I tried again now and it worked.
I will try to see when there is a problem.
Thanks for the help! :+1::+1::+1::+1:

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