Hi everyone, I have a family that is already in a project and i want a dynamo script that will reload the same family into the project. Im unfamiliar with the file and directory nodes. Could someone please give me some help on this topic?
What have you tried so far? Have you searched the forum for similar topics? There should be more than a few that deal with loading families. I believe Orchid has nodes for loading you could try.
Crumple package has one.
Hi @GavinCrump. Im a big fan of your youtube channel, it has helped me learn dynamo!
Im still learning dynamo, can you show me an example graph of how to use the FamilyDoc.LoadPath node?
Yep there is a graph here:
Thank you for your help!
Hi Gavin, Whether this code for reload is python 3 Compatible?
Yes, I have updated all but the nodes under the IronPython section of my package to CPython3.
Thanks for the information.
I tried to use the familydoc load node in cpython3 engine but it is not working as Familyloadoptions throws error in cPython3, i think it needed to be fixed to work in cpython3 thanks
Ah yes unfortunately that uses an interface which is not supported in CP3⦠my mistake. PythonNet will be needed or the IronPython2.7 package for now until the team builds it in.
Have you seen this? PythonNet3: A New Python to Fix Everything - Dynamo BIM
If Iām reading that right, pythonnetās improvements come in the form of another dependency package - oof if so.
I feel like 50% of my troubleshooting for packages these days is āinstall ironpython packageā (even after i put my own package in cp3 - most other packages didnātā¦).
PythonNet3 will become the default engine
I think It is a good idea that it be as a package (temporarily) to report issues in the different host software (Revit, Civil, etc.) and correct them
Ah that makes more sense, try it as a package, integrate it later. Thanks!
That sounds very promising in that case. I miss interfaces⦠and easy enumsā¦
As @c.poupin indicated, this is the intended state for today, but in the future this will be the default. Previous python updates have suffered from:
- No one can use it until the team ships it - which resulted in issues as they canāt test what users do with it.
- There was no chance at backwards compatibility - which resulted in package authors having to issue a different code base between builds. A package can be updated as possible in the future giving you (and others) the option of writing it once and using it again.
- Users and authors had to live with what is in the initial deployment - the only way things got fixed is when Dynamo was updated, which means we have to live with things until the team had time to fork, update, build, test, and ship the fix, which is a minimum of 6 months for some integrations
- Beta testing doesnāt require a beta machine - by allowing some use in the wild we can get real project feedback (usually where the issues that have the most impact are found as the base datasets are shall we say imperfect) rather than what can be gained from interaction with a sample project
The alternatives to a package are ādo it as we did it beforeā (remember CPython was introduced in July of 2020 and many still havenāt updated so Iām not a huge fan of that), or provide it under a feature flag⦠and if you think downloading a package for end users is difficult imagine getting IT to sign off on āenabling a feature flag for an experimental code execution environmentā. This truly was the ābest pathā in my opinion.
Itās not that itās difficult for me, but it appears to be too difficult for the average Dynamo user to know to download a package, and before that actually read the instructions to ensure they donāt overshoot the version for their respective Revit build. This difficulty in turn leads on to repetitive lines of questioning/troubleshooting. Just feels like things are getting a bit⦠messy.
To clarify I think the team has done about as much as can be done in the UX to ensure users are aware of this dependency in the dependency manager interface. Itās just the nature of where weāre at I guess.
I honestly donāt mind the tabula rasa idea, the packages list needs a serious nuke, and a reset to PythonNet and beyond might be a good way to do it - albeit painful/confusing for users and package managers straddling whichever Revit build that could happen for. And potentially punishing for people who stuck with zero touch throughout the whole fiasco depending how a line in the sand could work.
Having moved on from pyRevit and running out of time to manage my own Python package, my skin in the game is limited, but the vast majority of depended upon packages utilize IP2 at this point it seems.
Personally I think we passed messy and moved into āforgot to put the lid on the blender before starting it right underneath the high power ceiling fanā about 5 years ago. Itās been a āclean upā effort ever since.
Bit of a minority stance here, but I really appreciate the thought behind it and in some ways would take a similar perspective if starting at a firm tomorrow. Sadly as soon as you say āwe are starting over without any upgrade pathā the people who buy the software (executives at the firm) get quite mad⦠If you were to tell your boss tomorrow that all of your current automations are going in the bin and youāre starting over in 2026 how do you think theyād react?
Not sure the statistics bear that out - could just be that the subset of Dynamo uses youāre after all have āeasyā solutions which are IP2 based, or it could be that the subset of Dynamo uses I see donāt touch IP2⦠Most stuff I see now though is C# based for better or worse. Could be worth doing a dig into how much there is in a narrow timeframe across the community (i.e. when looking at all package downloads from a one month span, what % of nodes have IP2 in them)ā¦
Yes in this case I should clarify that of the python based packages I deal with most, they tend to be IP2. If I delved back into packages again it would definitely be zero touch as Iām two feet in C# for the last 3 months. Maybe a stronger stance to push in the learning materials/pathway, as the easy entry level of Python can be a temptation to put off ZT/C# (I myself being guilty).
Thereās broader scope these days that I see with Civil and other packages, so Iāll try not to paint with too broad of a brush in futureā¦
Broad brush is fine - in fact your opinion with any brush is highly welcome in any context.
Doing so brings meaningful insight and inspiration to the community.
Iām actively looking at building a POC for an analysis tool to parse a userās Dynamo environment (all loaded packages and definitions) for IronPython2 dependencies and save the result to disc. Looks quite doable and shouldnāt take much (~8 hours) to turn it into a view extension to help people like you make informed decisions on the management of your environment(s).
For anyone interested I am pasting my findings below. Note that I havenāt entirely tested this, but it should suffice for something you can build a POC from. Runs fine for me in Dynamo Sandbox 3.4 and Dynamo for Revit 2.12 using the CPython engine.
The Python Code
########################################
__author__ = 'Jacob Small'
__version__ = '0.1.0'
__description__ = "Attempts to parse the Dynamo environemnt to pull all custom nodes (*.dyf files) and checks each to confirm if there is (0) an unsupported Python in use, (1) only supported Python engines in use, (2) no Python in use."
__DynamoBuilds__ = "3.4"
__ReleaseNotes__ = "Runs in the CPython3 engine in Dynamo. Not completely tested in all environments and configurations. Test thuroughly before implementing."
__Dependancies__ = "None."
__Copyright__ = "2025, Autodesk Inc."
__License__ = "Apache 2"
########################################
### configure the Python environment ###
########################################
import sys, clr, os, json #import sys, clr, os, and json modules into the Python environment
clr.AddReference("DynamoServices") #add DynamoServices to the CLR
from Dynamo.Events import ExecutionEvents #import the execution events class from the Dynamo.Events namespace
import traceback
########################################
#### get dyf files from environment ####
########################################
packagePaths = list(ExecutionEvents.ActiveSession.GetParameterValue("PackagePaths")) #get the package paths from the current Dynamo environment
userFolder = [i for i in packagePaths if "AppData\\Roaming\\" in i][0] #get the user folder - sequence can vary here, but this should be fairly robust; parsing from the Dynamo engine or a property of the workspace might be better but I don't have time to solve everything today
defsFolder = userFolder.replace("packages","definitions") #replace the user pacage folder with the definitions folder
packagePaths.append(defsFolder) #append the definitions folder to the package paths
dyfs = [] #empty list to hold all DYFs found
walk = [os.walk(path) for path in packagePaths] #walk the packag e paths to get all files and directories recursively
for step in walk: #for each step in the walk
for root, subdir, files in step: #for the root folder, subdir, and files in each step
[dyfs.append(os.path.join(root,file)) for file in files if file.endswith(".dyf")] #append any file paths to the dyfs directory if the file ends with .dyf
########################################
###### prepare the output strings ######
########################################
unsupportedFileVersion, unsupportedCustomNodes, supportedCustomNodes, noPythonCustomNodes = [], [], [], []
########################################
###### parse dyf for python nodes ######
########################################
for file in dyfs: #for each file
with open(file) as dyf: #open the file
dyfStr = dyf.read() #read the dyf as a string
if dyfStr[0]=="<": #if the first character is a "<" the dyf is in file version 1 and uncompatible by default
unsupportedFileVersion.append("\t"+file) #append anything older than dirt to the appropriate list
else:
data = json.loads(dyfStr) #read the JSON structure from the string
nodes = data["Nodes"] #get the nodes
pythonNodes = [node for node in nodes if "Python" in node["NodeType"]] #filter to only nodes which are Python type
if not pythonNodes: #if there is no Python node
noPythonCustomNodes.append("\t"+file) #append to the appropriate list
failing = [] #build a list for failing nodes
for pythonNode in pythonNodes: #for each python node
if not "Engine" in pythonNode.keys(): #if there is no engine tag the graph is really old and will try to default to IronPython2
failing.append([file, pythonNode["Id"]]) #append to the appropriate list
elif pythonNode["Engine"] == "IronPython2": #if the engine tag is IronPython2
failing.append([file, pythonNode["Id"]]) #append to the appropriate list
if failing: #if there is data in failing
nodes = "\n".join(["\t\t\t"+i[1] for i in failing]) #get the nodes formatted as a string with tripple indent and new lines between each
count = "\t\t"+str(len(failing)) + " python nodes with unsupported engine" #count the failing nodes and format as a string
root = [i for i in packagePaths if i in file][0]
shortPath = file.replace(root,"")
result = "\n".join(["\t"+shortPath,count,nodes]) #join the result as a string with line breaks
unsupportedCustomNodes.append(result) #append to the appropriate list
else: #otherwise
supportedCustomNodes.append("\t"+file) #append the indented title to the appropriate list
#########################################
##### Return the results to Dynamo ######
#########################################
report = {"Invalid or unsupported file format":unsupportedFileVersion, "Utilized Python Engine in unsupported": unsupportedCustomNodes, "Utilized Python Engine is supported": supportedCustomNodes, "No python in use": noPythonCustomNodes}
OUT = report #return the result to the Dynamo environment```
A quick test of the 8 most installed packages on the package manager in Revit 2022 gave me:
- 61 invalid files
- These are still Dynamo 1.0 formatted so they arenāt compatible with the new engine.
- They were entirely from
steam nodes
, which hasnāt been updated in over a 7 years so itās well and truly deprecated at this point.
- 220 used no Python
- These are custom nodes which just use OOTB nodes for execution.
- No worries here - youāve got bigger fish to fry.
- 1 using a supported Python version.
- Clockworkās
CustomNode.Propeorties.dyf
node takes the cake here.
- Clockworkās
- 834 using an unsupported Python version.
- 89 in
Archi-Lab
which are likely not supported based on statements from the package author over the years, where itās been indicated that there should not be any Python nodes in the package. - 293 in
Clockwork
. There is an effort underway to modernize on a CPython3 engine, but it is as of yet unreleased. Repository is here for anyone interested: ClockworkForDynamo/nodes/3.x at master Ā· andydandy74/ClockworkForDynamo Ā· GitHub - 349 in
Genius Loci
. I am not sure where this stands; last I it was firmly in camp ānot going to upgrade at this timeā. - 103 in
spring nodes
, which hasnāt been updated in nearly 5 years now, so also likely deprecated.
- 89 in
So not a very pretty picture for those looking for Revit automation packages at first glimpse. But itās important to keep that 834 in perspective - as of Dynamo for Revit 3.2 (what I have to test handy at the moment) youāve got 946 nodes in the core Dynamo library and another 776 in Dynamo for Revit. Add Rhythm (~276 nodes) and Archi-Labās C# nodes (499 C# nodes after removing the unsupported Python nodes) and youāre looking at 2586 nodes which donāt run into any issues with users configuration of their Python engine. The net result is a Dynamo environment with 3552 nodes, 3/4 of which work when the correct package version is installed (totaling 2718 nodes), and 1/4 of which require the proper version of the deprecated Python engine being installed (834).
Now that node count omits deprecated packages, and your library might look quite a bit different (i.e. installing Orchid or Sythesize would make more Python independent nodes, while installing Datashapes would increase the IronPython woes). But for a tool where office wide content management usually is best described as āwe alternate between applying duct tape and spraying with WD40 until it worksā Iād say thatās pretty good. But for ābetterā results itās less going to be about the end user education (what you pointed to above @GavinCrump) or the Dynamo team ālocking-inā current versioning (the clear slate method) or someone somehow supporting all previous code forever (the ideal state which never existed, but we all were ignorant to the reality of), and firms developing, maintaining, and sharing best practicesā¦