Issue with user-created python modules

Hi everyone,

Long ago I created a python module with some definitions that I needed to change these last couple of days. The issue arises when I change the definition(s) inside the python module (saving the module after changes) and use it with my main python script, since it looks like Dynamo doesn’t recognize the changes made.

The module and main python scripts are stored in the office network so that everyone can access it. The main python script is accessed in Dynamo through the Python Script From String node.
I also append the path where the module is to sys:

# Import TVA Python library
path = r'V:\Revit\09-dynamo scripts\08-python'
sys.path.append(path)
from TVA_modules import check_parameter_by_Guid, find_parameterGuid, \
                    copy_parameter_by_Guid, set_parameter_by_Guid, copy_parameter_by_Guid_string_to_integer

What I tried:

  • Copy the module under different name to my D: drive, append the path to sys, import the newly named module, change the definitions to force an exception. Run Dynamo and it was like I didn’t have changed the code. (didn’t work)
  • Close and restart Dynamo (didn’t work)
  • Use Dynamo Player (didn’t work)
  • Close and restart Revit (worked)

I also noticed that the first time I run this Dynamo graph, it takes a bit of time for it to run. After the first run it executes almost instantly. Is it possible that Dynamo only looks at the python module on the first graph execution and ignores changes afterwards?
Is there anything that I missing here, or that I should have done it differently? I cannot imagine that this is the expected default behaviour.

I am using:
Dynamo version v.2.18.1
Revit 2024.1.1
Visual Studio Code v1.70.2

Thank you in advance.

can you get a simple folder and script working like this

def hello():
    return "Hello, World!"

Updated Add __init__.py to the top folder with an __all__ list and you can import like this

__all__ = ["mypythonscript"]

image

Hi and thank you for your answer.

Yes I can but after I change the definition and save mypythonscript.py, when I run Dynamo again I don’t see the changes made.

You have to re-trigger the Python node for it to know that the module was updated; hitting ‘Run’ where you edit the code or adding a boolean input that you just swap should do the trick.

Also loading .py files from the server may require some additional infosec checks, depending on your policies; as a result you might want to consider moving the files to the user’s local disc (as an added bonus they’ll run faster as well).

Right, I forgot about that detail.

could you be more specific about this subject? Modules are not loading due too some IT infrastructure?

Thank you for all the input

For the execution first: Many orgs have a policy in place to prevent loading code from the network. Most of the time this is just .dll and .exe and similar formats, but it isn’t inconceivable that .py would be added to them. In my experience when such cases have been found either the directory or file needs to be white listed. The file often has to pass a scan (automated) or be reviewed before the authorization is added. An added kicker to this many smaller orgs will have these settings implemented without someone intentionally triggering it, as it’s frequently built into the default.

For the speed, reading a file that many people are touching is never going to be as fast as reading one which only you are interacting with. Add in server speed, network latency, data transfer validation, and all the other bits of mechanics between the user’s disc and the code and you’re into a situation where it can (and will) be noticeable.

My recommendation for deployment is to push stuff to the local disc 100% of the time. The .dyn, the packages, the .py, the settings… the whole kit. Many ways to do so, none of which are rocket science but all of which are ‘hard’ for someone who isn’t already familiar with how your org is managing your deployments, user accounts, server access, infosec, and other such tools. Basically your IT team can likely do all of the work in about the time it takes to get a pizza delivered if you communicate what is needed well; but someone from ‘outside’ the org will have to spend a day.

1 Like

Hi,
here some solutions

# SOLUTION 1 
# Del Previous Module in sys.modules
if "moduleName" in sys.modules:
    del sys.modules["moduleName"]

import moduleName

# SOLUTION 2 
# with importlib
import mymodule
import importlib
importlib.reload(mymodule)

a last solution is to reset the CPython engine

3 Likes

@c.poupin thank you for your solutions.
I ended up using solution 2 and now I just have to wait for less than 10sec after saving the module and then run Dynamo. Reload it made the trick :slight_smile:

1 Like

Thank you very much for taking the time to explain all of this.
We don’t have the issue with whitelisting the py. files. Fortunately, we are also not experiencing any issues with speed. I can believe, as you said, that on a bigger scale it would bring us problems.

I understand your point of view and I welcome the suggestions, but this just makes everything more cumbersome, since you need an extra person to distribute all the items you mentioned before.
Our short experience with this method shows that it doesn’t work flawlessly. We took therefore a more pragmatic approach to centralize everything and point Dynamo to that network folder, which is working well (but for the modules part which now is solved). :slight_smile:

Risking going off topic, this reminds me of why we changed our approach at the office. After a while developing Dynamo scripts, we started using mainly OOTB Dynamo nodes and the rest we coded in python, then we moved to only Python (to the extent our coding skills allow us to) and then to C#. The msi files are installed automatically to the user D: drive if she/he wants it to. No more copying files, updating packages etc.

Pushing to the local disc is definitely preferred, and can be done automatically without manual intervention for the full org by one automation that only takes someone with knowledge of your environment a few minutes to write. A few months back I watched a large org’s IT guy do this in less time than it took us to get lunch delivered - now any time someone updates the ‘home’ directory users get the update on their next log-in, every time, forever… Or until they get a new server which would require matching effort for any distribution tool.

That said if you’re a smaller org with minimal use of external packages and don’t mind taking on all the maintenance issues (every bit of Python has to be tested and many updated for each release) then your method if fine, just know it might have issues over time and plan for the annual maintenance of your (hopefully well documented and annotated) Python code.

I see, it sounds a no-brainer indeed.

That said if you’re a smaller org with minimal use of external packages and don’t mind taking on all the maintenance issues (every bit of Python has to be tested and many updated for each release) then your method if fine, just know it might have issues over time and plan for the annual maintenance of your (hopefully well documented and annotated) Python code.

Lets hope everything works as planned. Thank you very much for all your input.

1 Like

Yeah… I got the guy who’d be complaining about the difficulty for months in touch with a member of his IT team and his response was “why didn’t you just ask me the first time this came up?”

Many if not most orgs already do this type of stuff, so adding a few more files to copy is super simple for them, but most users developing Dynamo graphs aren’t even aware such things are happening. So while I know I come off like a broken record I always say “partner with your IT team first and foremost”.

3 Likes