Accessing DynamoCore and DynamoRevit Assemblies and Namespaces in Python

@solamour Last question:
Why do I need the “DynamoRevitDS” ? I am not using anything of this library. It seems that I’m not getting the AddReference and import stuff right. For me it was always like this:

If I want to use e.g a dynamo core node inside of a python script I did the following:
I want to use List.Flatten so I look for it in github and find it in the “CoreNodes” library. From the Properties folder I search for the Assembly file and inside of it for the assembly title which is “DSCoreNodes”. After this I open the List.cs file inside of the library and look for the namespace of the Flatten method which is “DSCore”. Now I have everything to do the following:

clr.AddReference('DSCoreNodes')
import DSCore
from DSCore import *

For your example I cannot find the “Dynamo” namespace inside the “DynamoRevit” library. Could you please enlighten me? :innocent: :bulb:

@leonard.moelders you are not doing anything wrong, the mapping from .net to Python/IronPython is a bit confusing :frowning:

Bascially, clr.AddReference() is supposed to make IronPython aware of the assembly, and import imports the types into the Python scope. We do some imports and reference adding in the background, which adds a bit to the confusion.

We used to have autogenerated docs, but they never went beyond a single assembly so that was relatively useless. As per previous suggestions in this thread from @Michael_Kirschner2 we do like Fuget.org where you can search all of the Assemblies. Example below, covering a full case (and I know you know most of this already!).

Fuget Dynamo Revit Example:

Under the DynamoVisualProgramming.Revit nuget, you will find two Assemblies;

  1. RevitNodes.dll
  2. RevitServices.dll

In order to inform Python that these assemblies exist, you need to add a reference to them.

So, inside of Dynamo for Revit we will open up a Python node and add in this reference.

clr.AddReference('RevitNodes')

But if we use dir() (Exploring the current directory), we will notice that nothing has ostensibly changed inside of the Python window. Because while Python knows about the reference, it’s yet to pull things in. You can check the references that are “known” by querying the clr, which now shows Revit.

So you can simply now import Revit or from Revit import * depending on your flavour choice to import the namespace into the Python scope. You can also import sub-elements of the Revit namespace such as from Revit.Elements import * or from Revit.Transaction import *

import Revit example:

from Revit.Elements import * example:

Typically, getting granular is better as it has an impact on memory and execution time - so only import the things you need!

Fuget Dynamo Core Example:

Under the [DynamoVisualProgramming.Core nuget, you will find nine Assemblies;

  1. DesignScriptBuiltin.dll
  2. DSCpython.dll
  3. DynamoApplications.dll
  4. DynamoCore.dll
  5. DynamoInstallDetective.dll
  6. DynamoShapeManager.dll
  7. DynamoUtilities.dll
  8. ProtoCore.dll
  9. VMDataBridge.dll

Again, in order to inform Python that these assemblies exist, you need to add a reference to them.

So, inside of Dynamo for Revit we will open up a Python node and add in this reference.

clr.AddReference('DynamoCore')

Again, if we use dir() (Exploring the current directory), we will notice that nothing has ostensibly changed inside of the Python window. Because while Python knows about the reference, it’s yet to pull things in. You can again check the references that are “known” by querying the clr, which now shows Dynamo (As well as other, pre-loaded assemblies like Autodesk).

5 Likes

@leonard.moelders to specifically answer your question below, let’s take a journey into Github:

For your example I cannot find the “Dynamo” namespace inside the “DynamoRevit” library. Could you please enlighten me? :innocent: :bulb:

Inside of the DynamoRevit github repo, under src (Source code), you will find a tonne of stuff that can be a little overwhelming. But, if you search for DynamoRevitDS as per my example, you’ll find a file in DynamoRevit/src/DynamoRevit/Properties/ called AssemblyInfo.cs, and inside this file you’ll find the Assembly Title - which, voila, is “DynamoRevitDS”.

So, if you search for the assembly Title as follows;

[assembly: AssemblyTitle

You’ll find a bunch of different references, most of which you can reference and import inside of the Python node.

Once you have found the Assembly, you need to find the Namespace to import, and again you can do this with the dir(clr) approach, which surfaces Dynamo as your namespace. You’ll have to just get a feel for the other “already imported namespaces into the clr” unfortunately, but usually the Dynamo, Autodesk and Revit ones are obvious using keywords or derivatives of those three keys :slight_smile:

5 Likes

@solamour
I’m overwhelmed :heart:
Thank you very much! This made the whole Import/AddReference-Thing much clearer :slight_smile:
So if I got it right there are two import Dynamo options. One from DynamoCore and the other from DynamoRevitDS. How does python know which one I meant? From the last AddReference? Lets say if I do this:

import sys
import clr
clr.AddReference('DynamoCore')
import Dynamo
clr.AddReference('DynamoRevitDS')
import Dynamo

Is this state of the art, or should/need I use something like import Dynamo as DynCore to differentiate?

The dir() function to snoop the namespaces of an assembly is a really helpful hint :+1: :heart:

1 Like

Glad to hear it! :nerd_face:

In the example you have here, you have two options (Noting that, for performance reasons, you will want to only import the namespaces you actually need rather than the fully qualified parent namespace):

  1. You can use aliases/nicknames:
import sys
import clr

clr.AddReference('DynamoCore')
import Dynamo as dc
clr.AddReference('DynamoRevitDS')
import Dynamo as dr

OUT = dir(dr)

  1. Use the alternative import method of from:
import sys
import clr

clr.AddReference('DynamoCore')
from Dynamo import Core

clr.AddReference('DynamoRevitDS')
from Dynamo import Models

OUT = dir()

So yes, you should definitely use the alias if you need it! But I would recommend only importing the things you actually need - in the case of DSCoreNodes, this may be something like “List” or from ProtoGeometry in may be “Circle”.

2 Likes

I just found out that this method doesn’t work in Revit 2019. If I add “RevitNodes” to clr references it does not affect what is shown in dir(clr):

Is there a chance to explore the assembly in Revit 2019? I tried to explore it in VS Code but my vs code says, that he doesn’t know the clr module, eventhough my VS Code suggests clr when I type “import c”.

This is a coding issue because it does work in Revit 2019 if everything is coded correctly.

You need to make the following changes:

  • Your “dir(clr)” is checking the clr module and therefore will not show anything, change it to “dir()”. then you should see Revit.
  • You have only imported the reference and not actually imported the RevitNodes module, see below image.

1 Like

That is totally clear. I want to know what I can import from an assembly by exploring it. But unfortunately I can’t get it working like @solamour did in this picture:

With the picture above he shows, that we can use “import Revit”, because Revit is in the list.

Even with Revit 2022 I don’t have the “Revit” entry:

@leonard.moelders - It depends on your particular set-up, and what is already loaded into your Python environment.

As @Brendan_Cassidy said, you’ll need to either import Revit, but if you want to use the method above to search for what to Import, you can follow your nose in the CLR, as follows:

import sys
import clr
clr.AddReference('RevitNodes')

OUT = dir(clr.Autodesk)

This will give you what the CLR understands about the Autodesk reference, including the Revit key to import.

1 Like

Thanks for your answer, but unfortunately I can’t work it out:

and when I use “dir(clr)” the list I get does not contain the revit key and yes I want to know what I can import from the several references like. “DSCoreNodes”, “RevitNodes” etc.

Ah, strange. I’m using Revit 2023 / Dynamo 2.13.1 for mine and unfortunately I don’t have prior versions of Revit installed to test.

Any thoughts as to why this would be failing for Leonard @Aparajit_Pratap ?

1 Like

I’m not very strong at Python, maybe @Michael_Kirschner2 can talk to why dir() isn’t working, but I would use a tool like ILSpy to tell me what are the namespaces, types, and methods in a reference.

3 Likes

Curious, why do you want to know what is in CLR? Not everything there will transfer to the Python environment.

You’re working in a particular Python environment, so pulling what is available in that environment (sys.modules) might be more useful.

3 Likes

@jacob.small
I thougt that exploring with dir() is a more convenient way to know what to import from a reference. My current way is to look through the github repo and collect everything I need by hand. In @solamour post’s it looked like it would work out, but unfortunately it does not for me.

It’s unfortunate that it doesn’t work @leonard.moelders :frowning: But do try @jacob.small 's sys.modules suggestion, or @Aparajit_Pratap 's ILSpy suggestion and see if they work for you!

Assuming the search assembly / method is loaded in Dynamo environment (Domain)

search namespace

import sys
import clr
import System
clr.AddReference('ProtoGeometry')
from Autodesk.DesignScript.Geometry import *
def search_assemby_bymethod(methodName):
	s_name_space, s_methodName = methodName.split(".")
	for assembly in System.AppDomain.CurrentDomain.GetAssemblies():
		try:
			name_spaces = assembly.GetTypes()
		except:
			name_spaces = []
		for name_space in name_spaces:
			if s_name_space in name_space.Name:
				try:
					methods = name_space.GetMethods()
				except:
					methods = []
				for m in methods:
					if s_methodName in m.Name :
						return assembly, name_space

name_method = IN[0]
OUT = search_assemby_bymethod(name_method)
4 Likes

@c.poupin
Wow that’s really useful and exactly what I was looking for. Tank you very much!

To the rest:
Thanks for your several suggestions on solving my problem. I learned a lot again :slight_smile:

2 Likes