Getting parameters of element in Cpython

I’ve been trying to get the parameters of an element. However, I have noticed that the below code runs only in IronPython when I remove the - #!python3 tag. However, the code doesn’t run with the #!python3 tag. I am unable to use get_parameter to get any parameter of BuiltInParameter in CPython. Is there any fix for this because I need to access the parameters and I am using pandas to store the retrieved parameters in a dataframe but am unable to extract the parameters in CPython

#!python3

collector = FilteredElementCollector(doc).WhereElementIsNotElementType()

BIPs = [
     BuiltInParameter.STAIRS_BASE_LEVEL_PARAM,
    BuiltInParameter.INSTANCE_REFERENCE_LEVEL_PARAM,
]


for element in collector:
    if element.Category and element.Category.HasMaterialQuantities:
            if element.LevelId.Equals(ElementId.InvalidElementId):
                for BIP in BIPs:
                    param = element.get_Parameter(BIP)

                    # exec("param = %s" % BIP)

                    # param = element.get_Parameter(BuiltInParameter.STAIRS_BASE_LEVEL_PARAM)

                    if param:
                        param_elem_id = param.AsElementId()
                        print(param_elem_id)
                        if param_elem_id.Compare(ElementId.InvalidElementId) == 1:
                            elem_level = param_elem_id
                            break
                else:
                    elem_level = element.LevelId
            else:
                elem_level = elem_level.Name

@adarsh.bim ,

i have on top at any script:

# -*- coding: utf-8 -*-

Gives me the same error. No change.

@adarsh.bim ,

your code runs…

i did just a slidly change to the collector

# 🏓 get all elements
collector = FilteredElementCollector(doc).WhereElementIsNotElementType().ToElements()

2024-05-06_12h32_50

Are you running the code with #!python3 tag on top?
Without the tag, the code runs in IronPython, but with the tag it doesn’t run in CPython. Even with the ToElements(), it throws an error.
The exact error is -

TypeError : No method matches given arguments for get_Parameter: (<class 'int'>)

no without this comment, when i add this comment it does not work i only use

# -*- coding: utf-8 -*-

Since I am using Pandas I have to use this - #!python3

Since get_parameter and BuiltInParameter doesn’t work in CPython apparently, I used python subprocess to separate the code with IronPython handling all the BuiltInParameters and the python subprocess handing pandas.

2 Likes

@adarsh.bim there is also a workaround for this in cpython,
without the ironpython/cpython split - but it is surely not the prettiest:

hopefully there will be a better way for this in future pyrevit cpython. :pray:

1 Like

Does this work for CPython? From query.py in pyrevitlib

def get_builtinparameter(element, param_name, doc=None):
    doc = doc or DOCS.doc
    eparam = element.LookupParameter(param_name)
    if eparam:
        for biparam in DB.BuiltInParameter.GetValues(DB.BuiltInParameter):
            if int(biparam) == eparam.Definition.Id.IntegerValue:
                return biparam

I wasn’t aware of this before but will check it out thanks!
I might stick with the python subprocess as it is fairly straightforward and works perfectly since now I can divide my IronPython codes from my python3 codes without worrying about running into any future problems.

@jpitts the downside with element.LookupParameter("parameter_name") for BuiltInParameters is:
it is not UI-language agnostic (Revit assigns different names to the same BuiltInParameters depending on the Revit UI language).
in case if you have users of your pyRevit scripts with different Revit language settings, via LookupParameter it will only work for the ones with matching language setting but not for others.
whereas the element.get_Parameter(Bip.BuiltInParameterName) access works for any Revit language setting.