Using Hooks to get the Family Name being loaded

I am a bit new to using hooks in pyrevit. so please excuse me if there is an obvious answer to this.

I am trying to create a hook that returns the name of the Family each time a family is loaded into a project.
Below is the code i have done so far:

import clr
import pyrevit
from Autodesk.Revit.DB import *
from pyrevit import revit, DB, UI
clr.AddReference('RevitAPI')
clr.AddReference('RevitAPIUI')
from Autodesk.Revit.DB import *
from Autodesk.Revit.UI import *
from Autodesk.Revit.DB.Events import *
from System import EventHandler
from pyrevit import revit, forms, script

uidoc = __revit__.ActiveUIDocument
doc = __revit__.ActiveUIDocument.Document
app = __revit__.Application

def element_added_handler(sender, args):
    # Check all added elements
    for added_element_id in args.GetAddedElementIds():
        # Get the element
        element = sender.GetElement(added_element_id)
        # Only proceed if the added element is a Family
        if isinstance(element, Family):
            # Get the name of the family
            family_name = element.Symbol.Family.Name
            # Display an alert
            forms.alert("Family instance placed: ",
                        family_name,
                        title="New Family Instance",
                        footer="bimco Hooks")

# Attach the handler to the active document
doc.DocumentChanged += EventHandler[DocumentChangedEventArgs](element_added_handler)

running this code returns the below warning:

 File "...\family-loaded.py", line 13, in <module>
AttributeError: 'Application' object has no attribute 'ActiveUIDocument'

Hi @THEfonz,
welcome to the forum!

Did you read the documentation about hook scripts?

Create Your First Hook
Anatomy od Hook Scripts
Extension hooks - list of all avaliable hooks

  • First, you should name your script doc-changed.py and drop the last line, pyrevit already registers the script for you
  • To get the event arguments, you need to from pyrevit import EXEC_PARAMS and then you can access them via EXEC_PARAMS.event_args; The same applies to the sender
  • Your imports are a bit messy, and you don’t really need them; you can greatly simplify the script like this:
from pyrevit import EXEC_PARAMS, forms

args = EXEC_PARAMS.event_args
sender = EXEC_PARAMS.event_sender
# Check all added elements
for added_element_id in args.GetAddedElementIds():
    # Get the element
    element = sender.GetElement(added_element_id)
    # Only proceed if the added element is a Family
    if isinstance(element, Family):
        # Get the name of the family
        family_name = element.Symbol.Family.Name
        # Display an alert
        forms.alert("Family instance placed: ",
            family_name,
            title="New Family Instance",
            footer="bimco Hooks"
        )

Note that this is not tested, so it may contain errors, but I hope it points you in the right direction!

Thank you for the warm welcome.

i did indeed read through that documentation.
i do struggle a bit understanding the “Anatomy of a Hook Script”, which is probably what lead me here :slight_smile:

I am currently using family-loaded.py as my script name.

I tried running my own code with the script renamed to doc-changed.py and i tried your code with both naming as well.

Is there somewhere where i can see all available attributes of Events? This could help me troubleshoot my warnings.

You’re right that the family-loaded.py hook is more appropriate! I was mislead by the last line of your script.

I assume that the error you got is different, since we got rid f the line that triggered the previous one.

Anyway, the Extension Hooks page states that the Revit Event Type for that hook is Application.FamilyLoadedIntoDocument.
You can get more info about Revit APIs from the wonderful site revitapidocs.com.
This is the page of the FamilyLoadedIntoDocument events; you can click on the FamilyLoadedIntoDocumentEventArgs to browse to that class and inspect its members.
There you can see that you can access Document, FamilyName and FamilyPath directly:

from pyrevit import EXEC_PARAMS, forms

forms.alert(
    "Family instance placed: {}".format(EXEC_PARAMS.args.FamilyName),
    title="New Family Instance",
    footer="bimco Hooks"
)

Thanks you so much.
I used that website so often, but it somehow never clicked in my head that you can click on stuff to go to that section. Such a rookie mistake.

Here is the final working code for future reference:

from pyrevit import EXEC_PARAMS, forms

forms.alert(
    "Family instance placed: {}".format(EXEC_PARAMS.event_args.FamilyName),
    title="New Family Instance",
    footer="bimco Hooks"
)
1 Like