Anki’s new uv launcher uses a python executable file, so it seems to me that it is possible to get the python path from sys.executable and execute a code with it. (I already mentioned this a bit in another thread. [Wiki] Bundling Python modules with add-ons - #22 by Shigeyuki)
There are various things to keep in mind during development (e.g. it’s probably better not to import aqt, and there is a risk of the laptop crashing if an infinite loop occurs). But I thought that this might not be the intended use of Python, so it might be prohibited or strongly discouraged by the official Anki in the first place.(e.g. increased security risk)
Is it possible to call Python executable files from add-ons and execute code(for now)?
Minimal code example is like this:
# __init__.py
from .sample_addon import run_uv_python
run_uv_python()
# sample_addon.py
import os
import sys
import subprocess
def run_uv_python():
py_script_path = os.path.abspath(__file__)
uv_python_path = sys.executable
creationflags = 0
if sys.platform == "win32":
creationflags = (
subprocess.CREATE_NEW_PROCESS_GROUP | subprocess.DETACHED_PROCESS
)
subprocess.Popen(
[uv_python_path, py_script_path],
start_new_session=True,
stdin=subprocess.DEVNULL,
stdout=subprocess.DEVNULL,
stderr=subprocess.DEVNULL,
creationflags=creationflags,
)
if __name__ == "__main__":
from PyQt6.QtWidgets import QApplication, QWidget
app = QApplication(sys.argv)
window = QWidget()
window.setWindowTitle("sample")
window.resize(300, 100)
window.show()
app.exec()
I think these are advantages:
- It is possible to develop add-ons that run after Anki is closed. (e.g. AnkiRestart, like AnkiConnect that works even after Anki is closed, auto launch Anki at a specified time)
- Separate the UI event loop: e.g. Custom console. When displaying a window within Anki, the add-on UI also freezes when Anki’s UI is loading. This problem does not occur when creating a window with a Python executable file and communicating via a socket. (I am currently developing a prototype of this.)
- It is also possible to prevent Anki from freezing due to add-ons. Calculations can be run in the background, but UI processing cannot be run in the background, so if an add-on processes a lot of UI, Anki will freeze. (e.g. Leaderboard)
- File size: e.g. if I build AnkiRestart for Win, MacOS, and Linux using PyInstaller and incorporate it into an add-on it will be 18 MB in size using only Python. The actual code required is only 3 KB, so this method is compact and can also use PyQt.
- Code signing: Apps built with PyInstaller often get blocked from running if they don’t have code signing. With this way code signing probably isn’t needed, so development costs are lower.
and disadvantages:
- not sure if it works cross platform.
- not sure if sys.executable will reliably return the Python path.
- Perhaps this is not the intended use of Anki or UV, so unexpected problems may occur. (it looks the same to me as using normal Python)
- If this works without code signing it seems likely that there will be high security risks. (e.g. the program may continue to run in the background after the user closes Anki. but I think existing add-ns also have almost the same risk when Anki is running.)
- If an unexpected error occurs users may not be able to close the program.