Extensible Storage Dynamo Python 2024, ForgeTypeId?

Revit 2024 Dynamo Python3 see my error below. Thank you for taking the time to help!

My error:
Node Name: Python Script.
Package: Core.Scripting
Dynamo Version: 2.18.1.5096
Host: Dynamo Revit
Messages: TypeError : No method matches given arguments for Set: (<class ‘Autodesk.Revit.DB.ExtensibleStorage.Field’>, <class ‘str’>) [’ File “”, line 72, in \n’, ’ File “”, line 52, in attachSchemaToElements\n’]
State: Warning

This leads me to the following lines below:

    # Add a simple field of string data type to the schema
    fieldBuilder = schemaBuilder.AddSimpleField("MyField", SpecTypeId.String.Text)
    #PreviousTry
    #fieldBuilder = schemaBuilder.AddSimpleField("MyField", String)

or

        # Set the value for the schema field
        ent.Set(field, fieldValue, SpecTypeId.String.Text)
        #PreviousTry
        #ent.Set(field, fieldValue)

What have I referenced:

Full Code Below:

# Import required libraries
import clr
clr.AddReference('ProtoGeometry')  # Geometry library
clr.AddReference('RevitServices')  # Revit Services library
clr.AddReference('RevitAPI')  # Autodesk Revit API
clr.AddReference('RevitNodes')  # Revit Node library
clr.AddReference('RevitAPIUI')  # Autodesk Revit UI
clr.AddReference('System')  # System library
from Autodesk.Revit.DB import *
from Autodesk.Revit.DB.ExtensibleStorage import *
from RevitServices.Persistence import DocumentManager
from RevitServices.Transactions import TransactionManager
from System import Guid, String

# Close any open transactions
TransactionManager.Instance.ForceCloseTransaction()

# Initialize variables
doc = DocumentManager.Instance.CurrentDBDocument  # Current Revit Document

# Function to attach a schema to multiple Revit elements
def attachSchemaToElements(elems, schemaName, myGuid, fieldValue):
    # Create Schema Builder
    schemaBuilder = SchemaBuilder(Guid(myGuid))
    schemaBuilder.SetReadAccessLevel(AccessLevel.Public)  # Public read access
    schemaBuilder.SetWriteAccessLevel(AccessLevel.Public)  # Public write access
    schemaBuilder.SetSchemaName(schemaName)  # Set schema name
    schemaBuilder.SetVendorId("myVID")  # Set Vendor ID
    
    # Add a simple field of string data type to the schema
    fieldBuilder = schemaBuilder.AddSimpleField("MyField", SpecTypeId.String.Text)
    fieldBuilder.SetDocumentation("This is a sample field.")
    
    # Finalize schema
    schema = schemaBuilder.Finish()
    
    # Initialize list to store elements that had schema set
    modified_elems = []
    
    # Start a new transaction
    t = Transaction(doc, "Attach Schema")
    t.Start()
    
    # Loop through each element and attach the schema
    for elem in elems:
        # Create a new entity based on the schema
        ent = Entity(schema)
        # Retrieve the field from the schema
        field = schema.GetField("MyField")
        # Set the value for the schema field
        ent.Set(field, fieldValue, SpecTypeId.String.Text)
        
        # Attach schema entity to the Revit element
        elem.SetEntity(ent)
        # Append element to the list
        modified_elems.append(elem)
    
    # Commit the transaction
    t.Commit()
    TransactionManager.Instance.TransactionTaskDone()
    
    return modified_elems

# Sample inputs (replace these with actual inputs from Dynamo)
elems = IN[0]  # List of Revit elements from Dynamo
schemaName = "MySchema" #IN[1]  # Schema name from Dynamo
myGuid = "720080CB-DA99-40DC-9415-E53F280AA1F0" #IN[2]  # GUID for the schema from Dynamo
fieldValue = "SampleValue" #IN[3]  # Field value from Dynamo


# Call the function and attach the schema to elements
OUT = attachSchemaToElements(elems, schemaName, myGuid, fieldValue)

AddSimpleField() needs a string and a System Type, however I think you are supplying a string and a ForgeTypeId try schemaBuilder.AddSimpleField("MyField", String)

Here the fieldValue is a string where the API docs note that this should be a FieldType however the main issue here is that the API is looking for a C# generic - see Pythonnet docs here and API docs here so for Set<FieldType>(Field, FieldType, ForgeTypeId) you can use in python ent.Set[String](field, String, SpecTypeId.String.Text)

1 Like

@Mike.Buttery Thank you! I replaced what you provided blindly and no joy. I will have to read your references and will repost results soon. Thanks again.

Hi,
for info, (in addition to overloading resolution issues) methods with template Parameters doesn’t work with PythonNet 2.5.x (seem fixed in PythonNet 3.x.x)

you can use IronPython (2 or 3) instead

1 Like

Thank you both for the assistance. I feel like I am fighting this alot and thinking perhaps C# is the path this time. Unless I have missed something here, Link.

1 Like

you can download it via the package manager

Thanks Cyril, spent a bit of time trying to get around the bug today - didn’t work :expressionless: once you add the generic to Set all attributes and methods are not accessible

1 Like