Created a Docker Image to Call FBX SDK Python from Node.js
This article is a translated version of my original post on Qiita. Original (Japanese): https://qiita.com/segur/items/5d068661b12a1e7717d2
Created a Docker Image to Call FBX SDK Python from Node.js
Due to certain requirements, I needed to call FBX SDK Python from Node.js, so I created a Docker image.
The Docker image I created is published at the following link: https://hub.docker.com/r/seguropus/fbx-sdk-python-nodejs
Sample Code
The sample code is available here: https://github.com/segurvita/docker-fbx-sdk-python-nodejs
How to Use the Sample Code
# Build the Docker image
docker-compose build
# Start the Docker container
docker-compose up
If the following display appears, it indicates success:
fbx-sdk-python-nodejs | # FBX SDK can read the following formats.
fbx-sdk-python-nodejs | 00 FBX (*.fbx)
fbx-sdk-python-nodejs | 01 AutoCAD DXF (*.dxf)
fbx-sdk-python-nodejs | 02 Alias OBJ (*.obj)
fbx-sdk-python-nodejs | 03 3D Studio 3DS (*.3ds)
fbx-sdk-python-nodejs | 04 Collada DAE (*.dae)
fbx-sdk-python-nodejs | 05 Alembic ABC (*.abc)
fbx-sdk-python-nodejs | 06 Biovision BVH (*.bvh)
fbx-sdk-python-nodejs | 07 Motion Analysis HTR (*.htr)
fbx-sdk-python-nodejs | 08 Motion Analysis TRC (*.trc)
fbx-sdk-python-nodejs | 09 Acclaim ASF (*.asf)
fbx-sdk-python-nodejs | 10 Acclaim AMC (*.amc)
fbx-sdk-python-nodejs | 11 Vicon C3D (*.c3d)
fbx-sdk-python-nodejs | 12 Adaptive Optics AOA (*.aoa)
fbx-sdk-python-nodejs | 13 Superfluo MCD (*.mcd)
fbx-sdk-python-nodejs | 14 (*.zip)
fbx-sdk-python-nodejs exited with code 0
The listed formats are those that FBX SDK can read.
This indicates that you're successfully accessing FBX SDK Python.
What Happens Behind the Scenes?
First, when you run docker-compose up, the Docker container starts.
Once up, the Docker container executes the Node.js code in index.js.
The index.js script calls the Python code main.py.
The main.py script retrieves and displays the supported formats list from FBX SDK Python.
Dockerfile
I based the Dockerfile on a Docker image that already integrates Python and Node.js.
# Alpine with Python 2.7 and Node.js 12
FROM nikolaik/python-nodejs:python2.7-nodejs12-alpine
# Update libraries using apk
RUN apk update && \
apk add \
curl \
libxml2 \
libstdc++
# Download FBX SDK
RUN curl -L \
https://damassets.autodesk.net/content/dam/autodesk/www/adn/fbx/20195/fbx20195_fbxpythonsdk_linux.tar.gz \
-o /tmp/fbx20195_fbxpythonsdk_linux.tar.gz
# Create installation directory
RUN mkdir -p /python-fbx/install
# Extract FBX SDK
RUN tar -zxvf \
/tmp/fbx20195_fbxpythonsdk_linux.tar.gz \
-C /python-fbx && \
printf "yes\nn" | \
/python-fbx/fbx20195_fbxpythonsdk_linux \
/python-fbx/install
# Install FBX SDK
RUN cp /python-fbx/install/lib/Python27_ucs4_x64/* \
/usr/local/lib/python2.7/site-packages/
# Install python-shell
RUN npm install -g python-shell
# Remove temporary files
RUN rm -r /python-fbx
RUN rm /tmp/fbx20195_fbxpythonsdk_linux.tar.gz
# Set NODE_PATH environment variable
ENV NODE_PATH /usr/local/lib/node_modules
python-shell is a library used to call Python from Node.js.
It's installed globally, so the NODE_PATH environment variable is set to make it accessible to index.js.
docker-compose.yml
The docker-compose.yml file is structured as follows:
version: '3'
services:
fbx-sdk-python-nodejs:
image: 'seguropus/fbx-sdk-python-nodejs'
container_name: 'fbx-sdk-python-nodejs'
build:
context: ./
dockerfile: ./Dockerfile
volumes:
- .:/src
working_dir: /src
command: node index.js
The command index.js is executed upon starting the Docker container.
index.js
The index.js script looks like this:
const pythonShell = require('python-shell');
// Options for python-shell
const pyOption = {
mode: 'text',
pythonPath: '/usr/local/bin/python',
pythonOptions: ['-u'],
scriptPath: '/src',
}
// Execute main.py
const pyShell = new pythonShell.PythonShell('main.py', pyOption);
// Show Python's standard output
pyShell.on('message', (message) => {
console.log(message);
});
// Handle exit
pyShell.end(function (err, code, signal) {
if (err) {
console.error(err);
}
console.log('The exit code was: ' + code);
});
This script uses python-shell to invoke main.py.
main.py
Here's the main.py script:
from fbx import *
def list_reader_format(manager):
print('# FBX SDK can read the following formats.')
for formatIndex in range(manager.GetIOPluginRegistry().GetReaderFormatCount()):
description = manager.GetIOPluginRegistry().GetReaderFormatDescription(formatIndex)
print(formatIndex, description)
def main():
# Create
manager = FbxManager.Create()
scene = FbxScene.Create(manager, "fbxScene")
# List
list_reader_format(manager)
# Destroy
scene.Destroy()
manager.Destroy()
if __name__ == '__main__':
main()
This script imports FBX SDK Python with from fbx import * and lists all file formats that FBX SDK Python can read using the function list_reader_format().
Successfully, I was able to create a Docker image that allows Node.js to call FBX SDK Python!
Publishing on Docker Hub
Since I went through the effort, I published it on Docker Hub.
# Log in
docker login
# Push the Docker image
docker push seguropus/fbx-sdk-python-nodejs
It is published here: https://hub.docker.com/r/seguropus/fbx-sdk-python-nodejs
In Conclusion
In creating this article, I referred to the following pages. Thank you for your valuable resources:
- https://hub.docker.com/r/lerignoux/python-fbx
- https://hub.docker.com/r/nikolaik/python-nodejs
- Using
python-shellto Call Python Code from Node.js - List of File Formats Supported by FBX SDK Python
- Got Stuck with Global Installation of Node.js