Set PYTHONPATH environment

Dear supporters,

I am creating a specific gateway script which needs a specific module called pydim, which I have defined in a not usual placement. The gateway script includes the following:

#!/usr/bin/env python3
import os
os.environ[“DIM_DNS_NODE”] = “cs-ccr-mpdds1”
os.environ[“PYTHONPATH”] = “/home/pmendez/workspace/DIM/pydim3-3.0.2/lib/lib64/python3.6”
import sys
import time
import pydim

However, pydim is not found:

Traceback (most recent call last):
File “<TimerScript:NP04_Cryostat/DIM-Connection @5,000ms >”, line 9, in
ImportError: No module named pydim

8.0.12 (b2020042115)
Azul Systems, Inc. 11.0.6

So I would like to know:

– First, how to declare PYTHONPATH within the code
– Second, how to ensure that I am really executing the code with python3
Thanks so much,
Patricia

Hi Patricia,

Unfortunately, the Python used in Ignition is actually Jython 2.7 (for Ignition v8.0).

That means you cannot run a Python library that’s written for python 3, and you cannot run a Python library that needs C(++) bindings. So you will not be able to use the pydim library directly.

Your two options are:

  • Use pyDIM as an external program, and communicate via the OS (i.e. https://stackabuse.com/executing-shell-commands-with-python/). This is probably the faster way to implement, but quite hacky so probably slow and unreliable.
  • Use the Java bindings, and create your own Ignition module. This is probably more stable, but also more work to implement.
1 Like

Thanks a lot for the answer. when is it planned to support to python3?

It’s not, really. If a stable Jython 3 release ever happens we’ll evaluate whether or not we can even upgrade while preserving backwards compatibility, but it’s not something we’re prioritizing or has a timeline.

I took a brief look at DIM. Python3 support won’t help you: Jython3, whenever it shows up, will still have the limitations on C/C++ bindings. As @Sanderd17 notes, DIM has java bindings that could be loaded via an Ignition 3rd-party module. That is complicated a bit by DIM’s LGPL license, so you couldn’t actually including those java bindings directly. They’d have to be dynamically loaded instead. Possible, but not simple (it is what I do with OpenCV, for the same reason). Thanks to Ignition’s tools for modules to expose functionality in jython, you can probably make DIM’s java interface appear almost seamlessly as if from pydim.

Thanks so much for taking so much implication in my question. I take all your advices

Dear supporters,
I come back to this issue and I reopen the discussion because I am afraid the problem has nothing to do with the fact I am using a specific pydim package, but with the fact I cannot export any environment in Ignition. The same problem I had with pydim I reproduce it with any other python module not installed in the default area. So I have taken a very simple pymodule: pytz, which only has dependencies with python itself. In my Linux machine, I built it, I installed it and just after I open the python console:

$ python
Python 2.7.5 (default, Apr 2 2020, 13:16:51)
[GCC 4.8.5 20150623 (Red Hat 4.8.5-39)] on linux2
Type "help", "copyright", "credits" or "license" for more information.

import os
os.environ['PYTHONPATH']="/home/pmendez/pytz-install/lib/python2.7/site-packages"
import pytz

Perfect, from my linux machine, the module is perfectly found. Now I try the same from the Designer: Tools--> Script console. And here it cannot find the module (just check the screenshot I am attaching).

-- 2nd try: Same code from a gateway script, same result. Module not found
-- 3rd try: Export of the PYTHONPATH variable from a local file and source from /etc/init.d/ignition under:

List of files to source prior to executing any commands. Use ';' as delimiter.

For example:

FILES_TO_SOURCE=" /home/user/ .bashrc;anotherfile;../file3"

FILES_TO_SOURCE=" /home/pmendez/ .bash_ignition"
and ignition service restarted. Same result, module not found.

So I am wondering how can I export the PYTHONPATH variable and any other Env variable from any code included in Ignition, because this is a basic and daily coding operation and the exporting of the external modules and the exporting of the environment should be a very easy operation within Ignition.

Thanks a lot
PAtricia

Be sure to use Jython and not Python, as has already been stated.

What do you mean by dynamically loading it? As far as I understand it, LGPL allows the default way to use Java libraries: by including their JAR and linking to it. This is also how Ignition distributes modules.

It's different from GPL, which generally has the purpose that it cannot be used as a library without open-sourcing the rest (unless you can separate it to a degree that allows your app to be partially functional without the library).

https://www.gnu.org/licenses/lgpl-java.en.html

Part of the LGPL requires you to allow your users to replace the library you supply with one they compile themselves or otherwise obtain themselves. As long as the replacement library implements the same API (that’s on them), it enables users to run with features that are only legal/available in that way, and enables them to replace buggy or security-compromised versions.

Ignition’s module signing system doesn’t permit this, even for free modules, so including LGPL in your .modl file is not allowed.

Hmm, LGPL doesn’t require you to let the user get it signed back under the same key though. That would void the entire signing process, as signing is meant to ensure the origin of the file is known and not tampered with.

But if a module user can

  1. Unpack the modl file
  2. Replace the library jar with something that implements the same interface
  3. Zip and sign the module with a new key

it should be fine to include an LGPL library I think.

Hmm. Maybe. I'm not gonna test that idea.

IMHO all this should be hidden for the user. We are talking here about a very basic action: set a pythonpath variable and the user has all the rights to install modules all over the machine. If this is a licence matter, take into account that basically all modules available in pypi are excluded here and this is a show-stop for any development, moreover when we are talking about a product based in python language from the user perspective.
Take into account that the inductive university does not even foresee the user knows python because it even includes a 1st lecture of what it is python and how even to make a simply print statement within Ignition.
This is great, but the course is supposed to put people to the level of using ignition but people cannot do it because the simplest and more meanful action of python, import a module, cannot be done from the script console provided in default by ignition. And this is not good, because then there is a enormous gap between what the course claims and what Ignition in reality requires in order to be use. And this is not my case, because I knew python before.
Users should not know whether they use python or jpython… users know what the designer provides them with and the designer provides a script console (claimed at the course to be a python console) and that script console does not allow the exporting of a python module. And this is a enormous show-stop.
If we start from a python print statement level in a course then we cannot come to: distinctions between python and jpython (Ignition designer does not give you this chance and the course does not even mention it), licences matters… for something so basic as exporting a module.

Unless I am passing something and I am not realizing any important point, but the most basic actions require the most basic setups.

So if I want to use the pytz module or any other pypi available module in an easy way what Ignition proposes me?.
If this line that any python user writes in their codes:

os.environ[“PYTHONPATH”] = “bla/bla/bla/lib/lib64/python2.7/site-packages”

requires more than a line of code in Ignition or more than a 20seconds video in the Inductive university then we have a big problem, right?

This topic went off the rails. PYTHONPATH and what would be its equivalent, JYTHONPATH are not used, and when embedded as a script runtime Jython does not look at these.

It does look at python.path, set on the engine, which Ignition uses and sets to its external script dir: $IGNITION_INSTALL/user-lib/pylib.

If you add libraries to this location on the gateway they will be automatically synced down to clients as well. https://docs.inductiveautomation.com/display/DOC80/Libraries#Libraries-Importing3rdPartyLibraries

@Sanderd17 and I were on a non-relevant tangent, sorry.

As to your problem, Ignition can't support what you want because it has to distribute packages to clients and designers. Place your python add-ons in the site-packages folder as documented. Period.

… beat me to it. /: