Python in Modo
This guide intends to introduce the Modo users to the new Python API introduced in Modo 701.
It does assume that you have a minimum knowledge of Python and Modo GUI and Tools.
Even when it contains small introductions to them when is considered necessary.
The new Python API is composed of several modules, and allows the creation of Tools, Commands and other types of plug-ins explained a bit later.
Unlike the old Scripting API that created fire and forget scripts.This unleash new powerful ways to expand Modo.
The Python API Modules will be further explained, don't worry.
Note: You can create your own Python packages and modules to be used with the new API.
Kits were introduced in Modo 501 and are described here, have a read to that page first, and don't feel daunted by it. We will review some of those concepts here.
- The index.cfg files for kits are written in the same way for the Python API or C++ plug-ins.
Modo's Python Interpreter Version
Modo includes an embedded Python interpreter.
This table resume the different versions of Modo and their Python interpreters:
|Modo Version||Python Version|
Modo's Python interpreter resets the Python Path and points it to it's own Scripts directories.
There are several ways you can add your own modules and Python packages:
PYTHONPATH on a kit
As we've seen a kit in Modo is a directory inside the user scripts directory, containing an index.cfg file and other resources like images, plug-ins, etc.. .
You can access to this directory from Modo's menu System > Open User Scripts Folder.
You can create a directory there with the name of your kit and inside that directory an index.cfg file that will contain xml code.
Really the index.cfg is a xml file with the extension changed to .cfg.
Inside that file you can add directives for your forms, plug-ins, etc..
- Open your User Scripts Folder from Modo's menu System > Open User Scripts Folder.
- Create a directory called mynewkit.
- Inside that directory create an index.cfg file and open it on you favourite text editor.
- Copy and paste this xml code on it:
<?xml version="1.0" encoding="UTF-8"?> <!-- Kit name and version number --> <configuration kit="mynewkit" version="1.0"> <!-- This auto-imports all the contents on the kits directory --> <import>kit_mynewkit:</import> <!-- This imports a specific module inside of a directory of the kit --> <import>directory_name/module.py</import> </configuration>
PYTHONPATH on a Python Module
In a module living on the user scripts directory add to the top part of your module.py file:
import sys # Substitute [USER_NAME] for your user name # Substitute [DIR]with the name of the directory containing your module.py sys.path.append('C:/Users/[USER_NAME]/AppData/Roaming/Luxology/Scripts/[DIR]/')
PYTHONPATH on a Python File
- Create a python script file that appends to sys.path and import that file at the top of your script:
addtosysp.py: import sys # Substitute [USER_NAME] for your user name # Substitute [DIR] with the name of the directory containing your module.py sys.path.append('C:/Users/[USER_NAME]/AppData/Roaming/Luxology/Scripts/[DIR]/')
otherfile.py: import addtosysp
PYTHONPATH on a site-packages Directory
- Modo treats the user scripts directory as a site-packages folder. It even correctly processes .pth files contained there at start-up.
- It means is that you can install packages/modules into your system python & have them added to modo by adding a .pth file pointing at the system site-packages folder.
Note: For that your External Python version must be exactly the same one as the one used by modo internally.
Packages in Modo's Python
To create a Package in Python you create a directory and inside that directory a file called __init__.py.
1. For example in your user scripts directory create a directory called mypackage.
2. Inside that directory create a file called __init__.py with this content:
#!/usr/bin/env python # -*- coding: utf-8 -*- """ Initialization file of mypackage. """
3. Other modules can go in the same directory of the __init__ file.
4. To use the package in other modules you can use absolute imports:
import mypackage.mymodule # Calling a function inside mymodule of mypackage mypackage.mymodule.myfunction()
5. Or relative imports:
from mypackage import mymodule # Calling a function inside mymodule of mypackage mymodule.myfunction()