Python is a popular scripting language for implementing computer vision applications. While Python’s performance isn’t nearly good enough for the low-level number crunching required by vision algorithms, its expressive power makes it handy for writing the high-level logic of complex algorithms whose low-level parts are implemented in native code.
The VisionAppster platform comes with a built-in Python interpreter. Due to its size and runtime overhead, the interpreter isn’t enabled by default and must be manually turned on by installing the Python extension from the VisionAppster Store:
va-pkg install com.visionappster.extensions.python
One of the things that has made Python popular is the large set of packages it provides via PyPI (the Python package index). Unfortunately, Python does not support package versioning. This means that two different versions of a package cannot coexists in a Python installation. This has made Python to introduce “virtual environments” that isolate Python applications from each other.
Virtual environments however solve only part of the problem. If packages A and B depend on different versions of package C, Python cannot run A and B in the same program. This can be worked around by renaming either or the different versions of C and changing the affected code in either A or B, but this is often not a viable option. Our advice is to minimize the number of dependencies.
The embedded Python interpreter in the VisionAppster runtime is isolated
from the system’s default Python installation and existing virtual
environments. That means you cannot (by default) use NumPy in your tool
implementations even if you installed it with
pip install numpy. To
install Python packages to the VisionAppster “virtual environment” use
the va-pkg command-line tool. For example:
va-pkg install python:numpy python:opencv-python
If you want to experiment with Python and use the packages in your existing Python installation, put the following three lines code at the top of your Python tool plugin:
import sys import site sys.path.append(site.getusersitepackages())
Note that this will void your warranty and may cause random crashes due to incompatible extensions. It is not allowed in components you distribute through the VisionAppster store.
Reloading Python code🔗
Python does not support module unloading and even reloading Python modules at run time is not safe. The best that can be done is to re-evaluate the source code of a module in the context of the existing module. This means definitions can be added and modified but not removed. This may hide bugs if the new code uses definitions that existed in an old version but were removed.
Nevertheless, the VisionAppster runtime does its best at live-updating
Python code. Python modules installed in the component database using
va-pkg or the web interface will be automatically reloaded. User
$HOME/VisionAppster/plugins/tool can also be reloaded,
but only on user request. The tool box in the Builder has a button for
this. Note however that updating a Python module does not affect
existing instances of Python tools. You need to replace existing tools
in the graph with newly created ones to apply the changes.
Reloading native Python extensions is not possible. As a consequence, the VisionAppster runtime does not even try to reload packages installed from PyPI. You need to restart the Builder or the Engine before updates to such Python packages come into effect.
Python was designed neither embedding nor multi-threading in mind, yet we are doing both. This has consequences.
Python’s design dictates one interpreter per process 1. The execution of Python code must be serialized to a single interpreter, which may become a bottleneck if many tools use the Python interface simultaneously. Note however that some extensions allow Python code to be executed in a parallel thread while waiting for results from a native call.
We haven’t found a way to safely interrupt the Python interpreter when multiple threads are involved. If your tool code runs into an eternal loop or locks up otherwise, it will hang the whole process (Builder or Engine). There seems to be a partial remedy to this problem in the most recent version of the CPython interpreter, but the fix did not make it to our release.
Python has no garbage collector and can leak memory due to reference cycles. This may be unexpected of a scripting language and must be taken into account if the code is targeted at a production system.
CPython does have “sub-interpreters”, which provide almost separated environments for executing Python code in parallel. They however break some native extensions and cannot thus be safely used in a generic fashion.