Skip to content

Python module

Erik Smistad edited this page Mar 4, 2017 · 16 revisions

FAST has also support for Python. It is a separate module which have to be enabled with the FAST_MODULE_Python cmake flag. The module works with both python 2 and 3, but have to be compiled separately. The Python wrapper is generated using SWIG and a set of interface files (.i) found throughout the repository. In order to expose a specific FAST class in the Python wrappers, you need to create an interface file. Instructions on how to do this can be found below.

Building the Python wrappers

To build the Python wrappers you will need to install SWIG on your system. For Ubuntu linux you can install the swig3.0 package:

sudo apt-get install swig3.0

For Windows you should download SWIG binaries from the SWIG homepage.

CMake will try to automatically find SWIG on your system, and if it's found it will build the Python wrappers automatically. If CMake can't find SWIG after you installed it, set the SWIG_EXECUTABLE variable manually. On Ubuntu the executable is installed at /usr/bin/swig3.0.

You also need python libs installed. For instance if you use python 3:

sudo apt-get install libpython3.5-dev

The python module is integrated with numpy, thus requiring numpy to be installed:

pip install numpy

Troubleshoot

For windows, you might get the error that numpy/arrayobject.h was not found. To fix this, create a symlink to the numpy include folder in the include folder of your python installation. To do this, open the command prompt with administration rights and type the following (assuming python is installed at C:\Python27):

mklink /D C:\Python27\include\numpy C:\Python27\Lib\site-packages\numpy\core\include\numpy

If you get several link errors like: "error LNK2019: unresolved external symbol __imp_PyType_IsSubtype referenced in function ...". Make sure you have downloaded the 64 bit version of python (see https://www.python.org/downloads/windows/).

On windows the Python paths in CMake also have to be set manually:

PYTHON_DEBUG_LIBRARY="C:\Python27\libs\python27.lib" 
PYTHON_LIBRARY="C:\Python27\libs\python27.lib" 
PYTHON_INCLUDE_DIR="C:\Python27\include" 

Using the Python wrappers

After building the Python wrappers, a _fast.so/pyd library file and a fast.py Python file will appear in the lib folder of your build directory. These two files constitutes the Python wrappers for FAST. In order to use the fast Python module you need to make sure Python can find it. This can be done by appending the path to the system path as follows.

import sys
sys.path.append('/path/to/fast/build/lib')

This path can also be added to the environment variable PYTHONPATH:

export PYTHONPATH=/path/to/fast/build/lib

Since all FAST objects are encapsulated in smart pointers you need to create each object using the static New method:

import fast
importer = fast.ImageFileImporter.New()
importer.setFilename(fast.TEST_DATA_DIR + 'US-2D.jpg')

You can find more Python examples at the example page.

If you get the following error: ImportError: dynamic module does not define init function (init_fast) You have most likely built FAST using a different version of python libs (e.g. python 3) than the one you are trying to use it from (e.g. python 2). To fix this, set the correct version of python libs with CMake, see the cmake group python.

Writing interface files

Generally you should create one interface file for each class you want to expose in Python. This file should have the postfix .i and be added in the closest CMakeLists.txt using the fast_add_python_interfaces macro:

fast_add_python_interfaces(
	ImageFileImporter.i
)

The interface file should have the following structure

  • Include (%include) any other interface files which the interface files depends on. For instance if your class extends other classes you should include the interface files for those classes.
  • If your class is encapsulated in a shared pointer, declare this using the %shared_ptr macro.
  • Declare the class as you would when creating a C++ header file. Only add the methods you want to expose in the Python wrapper. There is no need to include private or protected methods. However, you should add the private constructor to indicate that SWIG should not create a default constructor.
  • Add the %template macro to indicate that the class is an instance of the SharedPointer<> FAST template.

Here is an example of an interface file.

// This adds support for converting std::string into python strings
%include "std_string.i"

// Since ImageFileImporter extends ProcessObject, we need to include the interface file for it as well.
%include "FAST/ProcessObject.i"

// Declare that ImageFileImporter is a shared pointer
%shared_ptr(fast::ImageFileImporter)

// Declare the class and the exposed methods
namespace fast {

class ImageFileImporter : public ProcessObject {
    public:
    	static SharedPointer<ImageFileImporter> New();
        void setFilename(std::string filename);
    private:
    	ImageFileImporter();
};

// Add a template declaration for the class.
%template(ImageFileImporterPtr) SharedPointer<ImageFileImporter>;

} // end namespace fast
Clone this wiki locally