Good day!
Sorry, but I have one more question. 🙂
Is there something special to install python modules for Fusion?
I used pip to install numpy 1.9.2 and pycollada 0.4.1 (module to work with COLLADA files). In addin's code I write "import collada" and then I get access to all functions and objects of pycollada using "pycollada.[object]". However, when I run code, import error rises:
>>> Traceback (most recent call last): File "D:/Projects/2-ExportModel/2/CAD to Earth Fusion 360. Python/CAD to Earth Fusion 360.py", line 13, in <module> import collada File "C:\Users\Anton\AppData\Local\Autodesk\webdeploy\production\d823d7c932fe4a7e4d638cb6af4b3845addcfe7d\Python\lib\collada\__init__.py", line 30, in <module> from collada import animation ImportError: cannot import name animation
The file "__init__.py" does exist in directory C:\Users\Anton\AppData\Local\Autodesk\webdeploy\production\d823d7c932fe4a7e4d638cb6af4b3845addcfe7d\Python\lib\collada\ .
And when I check installed packages with command "pip list" in command prompt, it shows:
numpy (1.9.2) pip (7.1.0) pycollada (0.4.1) python-dateutil (2.4.2) setuptools (18.1) six (1.9.0) wheel (0.24.0)
The author of module pycollada doesn't know the reason of mistake and think that something is wrong with the PYTHONPATH in Fusion.
Best Regards,
Anton.
Solved! Go to Solution.
Solved by KrisKaplan. Go to Solution.
The issue was resolved in other way, without using pycollada.
But may be it will be useful for other developers.
I'm not sure why that did not work. The Python/lib folder is set to the system path on Fusion startup, so any packages located there should be found when imported from any script.
However, I definitely would not recomend installing packages into this Python/lib folder for your scripts. One reason is that the specific webdepoly path will be abandoned every time the application is updated (every few weeks or so). You would have to continuously apply your modifications to those locations.
The other reason is that the Python environment in Fusion is a shared environment for all loaded scripts and addins. Different scripts could be dependent on different versions of libraries. Plus there is no (as of yet) setup/install phase for scripts. A 'copy to deploy' model is desired. For these reasons, the recomendation would be to include all of your dependent libraries in your script folder and use relative imports ('from .packages import collada' and copy (or virtual environment install) the libraries into 'YourScript/packages'). Most packages include their own dependencies and use relative imports, but some (such as collada) assume a shared install of numpy exists. In that case, you would either need to change the collada code to do package (your script's package) relative imports of numpy (or any other external dependencies not in our distro), or use an absolute import.
Now using script relative libraries gives this isolation, but it can increase redundancy. This normally wouldn't be a problem with publicly shared or published scripts. But if you use a large library (say numpy) in a lot of your own local scripts, this would grow to be a problem. In that case, you could create a shared library location and do an absolute import after modifying the sys.path list to include your shared library folder. I would put this shared library folder out in the user API folder so it survives across updates (or any location convenient to you, but using a location relative to your scripts would make it more portable if you ever shared your scripts).
Kris
Could you explain this a little bit more? I use Fusion 360 on a Mac at home and on Windows at work and I'd like to be able to install python modules and use them within Fusion 360. It appears that Fusion 360 uses Python 3.3. Does this mean that if I install the Python 3.3 version of a module outside of Fusion that within Fusion that module will be available to me? Specifically I'm trying to import Scipy and NumPy into a script as I am used to them but I'm not sure how to go about doing it.
Fusion currently uses version 3.3.5 of Python located in the Fusion install (webdeploy) folder. Just as you can install multiple separate versions of Python on your machine and packages installed in one are not visible to the other. The same is true for the version of Python used by Fusion. Even if it is the same version as another version of Python on your system, packages installed on one are not visible to the other.
This is all controlled by the standard package resolution rules in Python. Packages are searched for relative to the current running module's __file__ path, then in some standard locations relative to the Python runtime location (e.g. site_packages), and then the paths enumerated by sys.path. So in order to use a package in your Fusion script, it needs to be in one of these locations. As mentioned above, you should avoid trying to add the packages directly to Fusion's Python folder, because this is in the webdepoloy folder that is recreated on every update and all scripts run in this shared environment, so there can be version problems between scripts. Unfortunately, this would normally be the standard way to install packages. So this leaves either relying on the module relative import mechanism (preferred), or modifying sys.path to point to the absolute path where these packages are located.
Unfortunately, the scientific packages (like numpy) make this harder with their extensive use of binary extensions. And because numpy is so large, other packages like scipy normally assume numpy is available in the system path, and does not do a relative import (like other smaller packages tend to do). This makes copying something like scipy into your script's folder and referencing it with a relative import a little more difficult (as it would require editing some of their files to perform relative imports). So the easiest way forward would probably be to have your script append the path to these packages onto sys.path before importing these modules. This has the downside of affecting the module search order for all scripts run in Fusion, so it would be best to revert the sys.path as soon as you are done (and ideally remove these absolute imported modules from sys.modules). To do this, I might use virtualenv to create a virtual environment from a 64bit Python 3.3.5 (from Fusion's install directory or one you setup), and setup the desired packages (scipy, numpy), and add the path to this virtual environment's site-packages folder to sys.path in your script (if not already present). Even better, you could copy the relevant module's from the virtual environment into a folder relative to your script (or common to all of your scripts if referenced by several) and add that folder to sys.path. (Doing this prevents the other modules in the virtual environment's site-packages from being visible in the path.)
Another thing to be aware of is that because Python is running embedded in the Fusion process, and the Fusion process is a 64bit process, the Python version is also a 64bit version. And because the scientific packages use binary extensions, you have to ensure that you get the 64bit versions of these packages (numpy, etc...) or they will not import in a script run in Fusion.
Kris
Thank you for such a detailed reply. That is extremely helpful. I'll try a few things out and most likely will be back with more questions 🙂
I am sorry, but this is not a solution, this is a workaround.
Pip is available in the webdeploy version of Python included with Fusion and it is not working. If my module wants to install a pip module at runtime, say with something like
pip.main(['install', 'MyModule']) import MyModule
and I don't care about waiting for it to do so, this should be possible -since it is a much easier solution - however it runs into a "FileNotFoundError: [WinError 2] The system cannot find the file specified" error.
I believe that OP is correct and the setup of webdeploy for pip is incorrect and should be fixed.
I'm currently facing the same problem. I'd like to use numpy and some other modules that are already installed with anaconda on my PC. Shouldn't it work to just do the following at the beginning of my script, because it does not.
import os, sys
sys.path.append("C:\...\anaconda3\Lib\site-packages")
import numpy
Thanks in advance!
Have you solved this? If so, could you provide the code you used to import the packages? I’ve been at this for a while and nothing seems to work. Thanks in advanced!
Thank you for providing a solution, and keeping this form up, but I must complain a little about the nature of the solution.
I am working on this add in: lpurdy01/Fusion-360-Camera-Control: A Fusion 360 script that allows for gamepad / controller input t... (Don't bother trying to run it if you don't have an os3m mouse, I haven't updated the gamepad input to work again yet.)
To do hid input, have a debug/config view, and manipulate the camera I am using modules numpy, pygame, pywinusb, and scipy. These are all heavy packages that require complied binaries.
I have found the following to work:
- Creating a venv in the same directory as my Add-In
- Installing the packages using the pip in that venv
Then including this code in my run function:
# Get the path of the current script
script_path = os.path.abspath(__file__)
# Get the parent directory of the script
parent_directory = os.path.dirname(script_path)
# Construct the path to the 'site-packages' directory
venv_site_packages = os.path.join(parent_directory, 'venv', 'Lib', 'site-packages')
# Save the original sys.path
original_sys_path = sys.path.copy()
# Add the new path to sys.path
sys.path.append(venv_site_packages)
# Do my real import stuff...
# ...
# Reset sys.path to its original state
sys.path = original_sys_path.copy()
# Do my Add-In stuff
I fear forcing devs to include installed versions of packages will case software licensing issues. I would really appreciate it if Autodesk would consider investing the time to develop a more thought out solution. Possibly a wrapper for pip that could allow Script or Add-In developers to declare what packages they need and have fusion install them?
Can't find what you're looking for? Ask the community or share your knowledge.