Skip to main content

AnkiSync 2

PyPI version shields.io PyPI license

*.apkg and *.anki2 file structure is very simple, but with some quirks of incompleteness.

*.apkg file structure is a zip of at least two files.

.
├── example
│   ├── example.anki2
│   ├── media
│   ├── 1  # Media files with the names masked as integers
│   ├── 2
│   ├── 3
|   └── ...
└── example.apkg

*.anki2 is a SQLite file with foreign key disabled, and the usage of some JSON schemas instead of some tables

Also, *.anki2 is used internally at os.path.join(appdirs.user_data_dir('Anki2'), 'User 1', 'collection.anki2'), so editing the SQLite there will also edit the database.

The media file is a text file of at least a string of {}, which is actually a dictionary of keys -- stringified int; and values -- filenames.

Usage

Some extra tables are created if not exists.

from ankisync2.apkg import Apkg, db

apkg = Apkg("example.apkg")  # Or Apkg("example/") also works, otherwise the folder named 'example' will be created.
db.database.execute_sql(SQL, PARAMS)
apkg.zip(output="example1.apkg")

I also support adding media.

apkg.add_media("path/to/media.jpg")

To find the wanted cards and media, iterate though the Apkg and Apkg.iter_media object.

iter_apkg = iter(apkg)
for i in range(5):
    print(next(iter_apkg))

Creating a new *.apkg

You can create a new *.apkg via Apkg with any custom filename (and *.anki2 via Anki2()). A folder required to create *.apkg needs to be created first.

from ankisync2.apkg import Apkg

apkg = Apkg("example")  # Create example folder

After that, the Apkg will require at least 1 card, which is connected to at least 1 note, 1 model, 1 template, and 1 deck; which should be created in this order.

  1. Model, Deck
  2. Template, Note
  3. Card
from ankisync2.apkg import db

m = db.Models.create(name="foo", flds=["field1", "field2"])
d = db.Decks.create(name="bar::baz")
t = [
    db.Templates.create(name="fwd", mid=m.id, qfmt="{{field1}}", afmt="{{field2}}"),
    db.Templates.create(name="bwd", mid=m.id, qfmt="{{field2}}", afmt="{{field1}}")
]
n = db.Notes.create(mid=m.id, flds=["data1", "<img src='media.jpg'>"], tags=["tag1", "tag2"])
c = [
    db.Cards.create(nid=n.id, did=d.id, ord=i)
    for i, _ in enumerate(t)
]

You can also add media, which is not related to the SQLite database.

apkg.add_media("path/to/media.jpg")

Finally, finalize with

apkg.zip(output="example1.apkg")
apkg.close()

Updating an *.apkg

This is also possible, by modifying db.Notes.data as sqlite_ext.JSONField, with peewee.signals.

It is now as simple as,

from ankisync2.apkg import Apkg, db

apkg = Apkg("example1.apkg")

for n in db.Notes.filter(db.Notes.data["field1"] == "data1"):
    n.data["field3"] = "data2"
    n.save()

apkg.close()

JSON schema of Col.models, Col.decks, Col.conf and Col.dconf

I have created dataclasses for this at /ankisync2/builder.py. To serialize it, use dataclasses.asdict or

from ankisync2.util import DataclassJSONEncoder
import json

json.dumps(dataclassObject, cls=DataclassJSONEncoder)

Editing user's collection.anki2

This can be found at ${ankiPath}/${user}/collection.anki2, but you might need ankisync2.anki21 package, depending on your Anki version. Of course, do this at your own risk. Always backup first.

from ankisync2.anki21 import db
from ankisync2.dir import get_anki_collection

db.database.init(get_anki_collection("User 1"))

Using peewee framework

This is based on peewee ORM framework. You can use Dataclasses and Lists directly, without converting them to string first.

Examples

Please see /examples, /scripts and /tests.

Installation

pip install ankisync2

Related projects

Metadata

Release files for ankisync2 0.3.0.1

For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.

Source distribution (sdist)

Source distribution for ankisync2 0.3.0.1
File Size Uploaded
ankisync2-0.3.0.1.tar.gz 11.9 kB Details

Built distribution (wheel)

Table of built distributions (wheels) for ankisync2 0.3.0.1
File Interpreter ABI Platform
ankisync2-0.3.0.1-py3-none-any.whl Python 3 none any Details

Total release size: 27.8 kB

Release files / ankisync2-0.3.0.1.tar.gz

Download URL ankisync2-0.3.0.1.tar.gz
Size 11.9 kB
Tags Source
SHA-256 checksum
How to use checksums
e4bff7f3774418773b865fbbf6edcab708ddb1121c762caacaa955d7e0f07389
BLAKE2b-256 checksum
How to use checksums
55bb0a9e17c2a45d5fbca08eb172636ebf5918e236bb81a3e35342a571048b38
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
No
Uploaded via poetry/1.1.4 CPython/3.8.6 Windows/10

Release files / ankisync2-0.3.0.1-py3-none-any.whl

Download URL ankisync2-0.3.0.1-py3-none-any.whl
Size 15.9 kB
Tags Python 3
SHA-256 checksum
How to use checksums
0e6a056f327f3f8b48e97a2f8df885e171032a5e4445ebb1bc8b31a3e6f2a255
BLAKE2b-256 checksum
How to use checksums
2424404eeed9cf87faa70f5af082185799e8b233406174294eb2a26df7329fb7
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
No
Uploaded via poetry/1.1.4 CPython/3.8.6 Windows/10

Release history Release notifications | RSS feed

0.3.4

2 release files

0.3.3

2 release files

0.3.2

2 release files

0.3.1

2 release files

This release

0.3.0.1 This release

2 release files

0.3.0

2 release files

0.2.4

2 release files

0.2.3

2 release files

0.2.2

2 release files

0.2.1

2 release files

0.2.0

2 release files

Anthropic, PBC Visionary sponsor Bloomberg Visionary sponsor Hudson River Trading Visionary sponsor Meta Visionary sponsor NVIDIA Visionary sponsor Microsoft Sustainability sponsor Depot Continuous Integration AWS Cloud computing and Security Sponsor Datadog Monitoring Fastly CDN Google Download Analytics Sentry Error logging StatusPage Status page