FabricationPart.SaveAsFabricationJob() usage in Cpython3 (Dynamo, Revit 2025)

I am getting lost with this one. It should be not that difficult, however it bugs me that i Cant get it to work.

I took took the C# example as base and that should port to python… however it keeps throwing me back. It reaches the messagebox (1) and then throws the exception shown it the picture.

Can anyone point me in the right direction (as it is part of a much larger existion Dynamo script that is working correctly, i would hate to create a new C# version of that just to get passed this issue)?

It looks like I am not able to pass the correct parameters to the Revit API node from Python (Iset). I tried different paths to get a set that way but without any result. Resulst (error) in the picture added.

Code python script below. IN[0] holds Fabrication elements.

import clr
clr.AddReference('RevitServices')
from RevitServices.Persistence import DocumentManager
from RevitServices.Transactions import TransactionManager

clr.AddReference('RevitAPI')
from Autodesk.Revit.DB import *
from Autodesk.Revit.DB.Fabrication import *
clr.AddReference("System.Windows.Forms")
from System.Windows.Forms import MessageBox

from System.Collections.Generic import *

doc = DocumentManager.Instance.CurrentDBDocument
fabrication_parts = [UnwrapElement(part) for part in IN[0]] 
maj_file_path = r"C:\Temp\FabricationExport.maj"
option = FabricationSaveJobOptions(False)

TransactionManager.Instance.EnsureInTransaction(doc)

try:   
    MessageBox.Show("1")
    if len(fabrication_parts) > 0:
        export=FabricationPart.SaveAsFabricationJob(doc,fabrication_parts, maj_file_path,option)
        MessageBox.Show("2")
        TransactionManager.Instance.TransactionTaskDone()
        # Show MessageBox confirmation
        MessageBox.Show(f"Fabrication job saved successfully!\nFile Path: {maj_file_path}", "Export Complete")
        OUT = f"Exported to {maj_file_path}"
    else:
        raise Exception("No valid Fabrication Parts selected!")

except Exception as e:
    # Roll back transaction on error
    TransactionManager.Instance.ForceCloseTransaction()
    MessageBox.Show(f"Error exporting fabrication job:\n{str(e)}", "Export Failed")
    OUT = str(e)

I believe that the method you are using needs element IDs. You’re passing elements by the looks of it.

I don’t have a model with fabrication parts to test with either. Can you post something?

Thx for your reply.

Yes, yiou are correct. I think I did create a new list in a previous version but that was rejected also. But I will check that out as it might have been a stupid oversight on my part!

Unfortunately that did not do it. Added:

partlist=list()

for part in fabrication_parts:
        partlist.append(part.Id)

and replaced the partlist instead of the fabrication_parts.

Added project file in a github repository

https://github.com/jpfx1/fabDemo/edit/main/fabrication%20demo.rvt

Can you post your .dyn here or to that git as well? It’d save some time in the initial setup.

hi,

we need a Set of ElementId

import clr
import System
from System import Array
from System.Collections.Generic import List, IList, HashSet
clr.AddReference('RevitServices')
from RevitServices.Persistence import DocumentManager
from RevitServices.Transactions import TransactionManager

clr.AddReference('RevitAPI')
from Autodesk.Revit.DB import *
from Autodesk.Revit.DB.Fabrication import *
clr.AddReference("System.Windows.Forms")
from System.Windows.Forms import MessageBox

my_path = System.Environment.GetFolderPath(System.Environment.SpecialFolder.MyDocuments)

doc = DocumentManager.Instance.CurrentDBDocument
fabrication_parts = UnwrapElement(IN[0])
fabrication_partsIds = HashSet[ElementId]([x.Id for x in fabrication_parts])
maj_file_path = my_path + "\\FabricationExport.maj"
option = FabricationSaveJobOptions(False)


if len(fabrication_parts) > 0:
    export=FabricationPart.SaveAsFabricationJob(doc,fabrication_partsIds, maj_file_path ,option)
    MessageBox.Show(f"Fabrication job saved successfully!\nFile Path: {maj_file_path}", "Export Complete")
    OUT = f"Exported to {maj_file_path}"
else:
    raise Exception("No valid Fabrication Parts selected!")
1 Like

Hi c.poupin,

Thanks a lot. Yes, i did see it needing the ilist, but failed to convert it (tried multiple ways). Going back to the old code and comparing it, finaly showed me where i went wrong (must have been blind through the code, this is just a very small part). I made a hashset before, but from the elements instead of the id :see_no_evil_monkey: )

If you want I can post the full dyn there later, but it is pretty specific for our company so the CID’s used are not the default CID’s (default CID’s are equal the te Pattern ID’s) so it will not work genericly. It also will need some shared parametes added to the elements we use to track orders and the UI is in dutch.

No need - you’ve got it working again thanks to @c.poupin. If you get stuck again providing a dataset and a dyn that has a minimum reproducible solution.

1 Like