pyRevit Anatomy - Create Script Template

You know how to create pyRevit extension buttons. But now let's explore what we can write inside of our python scripts to make it work.

pyRevit Anatomy - Create Script Template

You know how to create pyRevit extension buttons. But now let's explore what we can write inside of our python scripts to make it work.

Summary

Python Script for pyRevit

Soon we will start coding a lot of tools in this course. But before we do that, let's prepare a python template for pyRevit scripts.

First of all I want to show you pyRevit's features that are super easy to use and also you will have a file that you can use for you new tools, so you don't ever start with a blank page.

Let's break down everything we want to include in our template file.

UTF-8 Encoding

First of all it's good to always add utf-8 encoding to our scripts by using this very special syntax.

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

This is necessary to add if you use any unique letters from other languages or special symbols.

If you forget to add it and you have a special character in your script you will get an error like shown on the left, so it’s always worth to include it.

Button's Title and Description

Next we usually provide name and description for our button. We use __title__ and __doc__ variables so python can automatically detect them and display in Revit UI.

💡You can also get creative in your description. I like to separate it in multiple sections so it's much more readable and organized. Feel free to adjust to your own needs.

__title__ = 'EF-Template'   # Name of the button
__doc__   = """Version = 1.0
Date    = 20.04.2022
____________________________________________
Description:
This is a template file for pyRevit Scripts.
____________________________________________
How-to: (Example)
-> Click on the button
-> Change Settings(optional)
-> Make a change
___________________________________________
Last update:
- [12.06.2023] - 1.1 UPDATE - New Feature
- [12.06.2023] - 1.0 RELEASE
___________________________________________
To-Do:
- Check Revit 2021
- Add ... Feature
__________________________________________
Author: Erik Frits"""   # Description 
Other Meta Tags

There are also multiple meta tags available for pyRevit scripts that can provide additional functionality.

# 👇 pyRevit Extra MetaTags (optional)
__author__ = 'Erik Frits'                                      
__helpurl__ = 'https://www.youtube.com/watch?v=dQw4w9WgXcQ'    
__min_revit_ver__ = 2021                                       
__max_revit_ver__ = 2023                                       
__highlight__ = 'new'


  • __author__ / __authors__ - Show Author's name in the button's description. Personally I prefer to write it in my __doc__ variable to save some space.


  • __helpurl__ - We can provide any link to a website or path to a file and it will be opened when we hover over the button and click F1. Can be useful to provide additional documentation on how to use button.


  • Revit Versions - We can limit our script to certain Revit version using:
    __min_revit_ver__
    __max_revit_ver__

    It’s very useful when you use new Revit API classes and methods which are not available in older versions used differently.
    e.g. We couldn't create Ceilings before Revit 2022 with Revit API, so it's wise to restrict the button to Revit 2022+.


  • __beta__ - This one will hide your button from Revit UI, but you could still access it with shortcuts. I would recommend creating a separate extension for development and only bring complete tools to your actual toolbar. It will give you more space to keep buttons in development and test your code.

  • __highlight__ - We can highlight our buttons as 'new' or 'updated', it will look like screenshot below in Revit UI and can draw extra attention from your users.


  • __context__ - Context is great when your tools are made for specific views or certain elements have to be selected before you run the button.

    💡 It even has it’s own Bundle Context page, with more examples.

Imports

To be able to access Revit API classes, we will need to add a few imports. Add most used imports in your template, you can always remove them once your script is complete.

💡My example is a little overkill, so feel free to delete unused imports.

import os, sys, datetime         
from Autodesk.Revit.DB import *  
from Autodesk.Revit.UI import *  
from Autodesk.Revit.DB.Architecture import *

# pyRevit
from pyrevit import forms, revit, script    

# .NET Imports
import clr
clr.AddReference('System') 
from System.Collections.Generic import List
# List_example = List[ElementId]()

💡Check out pyRevit's site-packages to see what packages are available by default.

Variables

There are multiple variable that are needed in every script that we are going to write, so include all of them in your template so you don't have to worry about it.


doc   = __revit__.ActiveUIDocument.Document #type: Document
uidoc = __revit__.ActiveUIDocument          #type: UIDocument
app   = __revit__.Application               # Application class

active_view  = doc.ActiveView                   
active_level = active_view.GenLevel             
rvt_year     = int(app.VersionNumber)           
PATH_SCRIPT  = os.path.dirname(__file__)        

# GLOBAL VARIABLES

# Place global variables here...
Functions and Classes

To be honest, I don't think we need any Functions or Classes in our template file.

💡 If you think you need a function or a class that is going to be reused so often, it's much better to place it to a reusable library of snippets and then import it.

🎦 We will cover that in the next lesson.

Main

Lastly, we can prepare our main section if you think you need something.

# ⌨ START CODE HERE

# 🔓 Use Transaction to Modify Document 
# (Avoid placing inside of loops)
t = Transaction(doc, 'Change Name')

t.Start()                       #🔓 Start Transaction
# Changes Here...
t.Commit()                      #🔒 Commit Transaction

print('-'*50)
print('Script is finished')
print('Template has been developed by Erik Frits.')
Customize to Your Own Needs

My template is just an example. If you are new feel free to use it, but make sure you modify it to your own needs over time.

FigLET Plugin

When I code you will often notice comment blocks that I create for marking different sections of my code. I use FigLET plugin for creating these blocks.

👇 They Look like this

# ╦╔╦╗╔═╗╔═╗╦═╗╔╦╗╔═╗
# ║║║║╠═╝║ ║╠╦╝ ║ ╚═╗
# ╩╩ ╩╩  ╚═╝╩╚═ ╩ ╚═╝ IMPORTS
#==================================================

# ╦  ╦╔═╗╦═╗╦╔═╗╔╗ ╦  ╔═╗╔═╗
# ╚╗╔╝╠═╣╠╦╝║╠═╣╠╩╗║  ║╣ ╚═╗
#  ╚╝ ╩ ╩╩╚═╩╩ ╩╚═╝╩═╝╚═╝╚═╝ VARIABLES
#==================================================

# ╔╦╗╔═╗╦╔╗╔
# ║║║╠═╣║║║║
# ╩ ╩╩ ╩╩╝╚╝
#==================================================

💡 I haven't seen anyone else do that, it's just something that I started doing in the beginning to write more readable code for myself and others. You can decide yourself if they are helpful or not.

Install FigLET

To install the plguin you need to open pyCharm's plugins window.

File -> Settings -> Plugins -> Marketplace -> Search 'FIGlet'

💡When you install it, you might get the following Notice from JetBrains. There is nothing to worry, you can Accept it.

Use FIGlet Plugin

To use FIGlet, select text which you want to convert and click ALT + Instert and select ASCII Art…

I use Calvis S font to generate blocks you see in my videos. You can explore other fonts as well.

# TEST

# 👆 Select 'TEST' -> click ALT+Insert -> ASCII Art...
# 👇 Result

# ╔╦╗╔═╗╔═╗╔╦╗
#  ║ ║╣ ╚═╗ ║ 
#  ╩ ╚═╝╚═╝ ╩ 
Template from Video
# -*- coding: utf-8 -*-
__title__ = "EF Template"                           # Name of the button displayed in Revit UI
__doc__ = """Version = 1.0
Date    = 20.04.2022
_____________________________________________________________________
Description:
This is a template file for pyRevit Scripts.
_____________________________________________________________________
How-to:
-> Click on the button
-> Change Settings(optional)
-> Make a change
_____________________________________________________________________
Last update:
- [24.04.2022] - 1.0 RELEASE
_____________________________________________________________________
To-Do:
- 
_____________________________________________________________________
Author: Erik Frits"""                                           # Button Description shown in Revit UI

# EXTRA: You can remove them.
__author__ = "Erik Frits"                                       # Script's Author
__helpurl__ = "https://www.youtube.com/watch?v=YhL_iOKH-1M"     # Link that can be opened with F1 when hovered over the tool in Revit UI.
# __highlight__ = "new"                                           # Button will have an orange dot + Description in Revit UI
__min_revit_ver__ = 2019                                        # Limit your Scripts to certain Revit versions if it's not compatible due to RevitAPI Changes.
__max_revit_ver = 2022                                          # Limit your Scripts to certain Revit versions if it's not compatible due to RevitAPI Changes.
# __context__ = [ "selection", "active-section-view"]           # Make it available only if Active view is Section and something is Selected
# __context__     = ['Walls', 'Floors', 'Roofs']                # Make your button available only when certain categories are selected. Or Revit/View Types.

# ╦╔╦╗╔═╗╔═╗╦═╗╔╦╗╔═╗
# ║║║║╠═╝║ ║╠╦╝ ║ ╚═╗
# ╩╩ ╩╩  ╚═╝╩╚═ ╩ ╚═╝ IMPORTS
# ==================================================
# Regular + Autodesk
import os, sys, math, datetime, time                                    # Regular Imports
from Autodesk.Revit.DB import *                                         # Import everything from DB (Very good for beginners)
from Autodesk.Revit.DB import Transaction, FilteredElementCollector     # or Import only classes that are used.

# pyRevit
from pyrevit import revit, forms                                        # import pyRevit modules. (Lots of useful features)

# Custom Imports
from Snippets._selection import get_selected_elements                   # lib import
from Snippets._convert import convert_internal_to_m                     # lib import

# .NET Imports
import clr                                  # Common Language Runtime. Makes .NET libraries accessinble
clr.AddReference("System")                  # Refference System.dll for import.
from System.Collections.Generic import List # List<ElementType>() <- it's special type of list from .NET framework that RevitAPI requires
# List_example = List[ElementId]()          # use .Add() instead of append or put python list of ElementIds in parentesis.

# ╦  ╦╔═╗╦═╗╦╔═╗╔╗ ╦  ╔═╗╔═╗
# ╚╗╔╝╠═╣╠╦╝║╠═╣╠╩╗║  ║╣ ╚═╗
#  ╚╝ ╩ ╩╩╚═╩╩ ╩╚═╝╩═╝╚═╝╚═╝ VARIABLES
# ==================================================
doc   = __revit__.ActiveUIDocument.Document   # Document   class from RevitAPI that represents project. Used to Create, Delete, Modify and Query elements from the project.
uidoc = __revit__.ActiveUIDocument          # UIDocument class from RevitAPI that represents Revit project opened in the Revit UI.
app   = __revit__.Application                 # Represents the Autodesk Revit Application, providing access to documents, options and other application wide data and settings.
PATH_SCRIPT = os.path.dirname(__file__)     # Absolute path to the folder where script is placed.

# GLOBAL VARIABLES

# - Place global variables here.

# ╔═╗╦ ╦╔╗╔╔═╗╔╦╗╦╔═╗╔╗╔╔═╗
# ╠╣ ║ ║║║║║   ║ ║║ ║║║║╚═╗
# ╚  ╚═╝╝╚╝╚═╝ ╩ ╩╚═╝╝╚╝╚═╝ FUNCTIONS
# ==================================================

# - Place local functions here. If you might use any functions in other scripts, consider placing it in the lib folder.

# ╔═╗╦  ╔═╗╔═╗╔═╗╔═╗╔═╗
# ║  ║  ╠═╣╚═╗╚═╗║╣ ╚═╗
# ╚═╝╩═╝╩ ╩╚═╝╚═╝╚═╝╚═╝ CLASSES
# ==================================================

# - Place local classes here. If you might use any classes in other scripts, consider placing it in the lib folder.

# ╔╦╗╔═╗╦╔╗╔
# ║║║╠═╣║║║║
# ╩ ╩╩ ╩╩╝╚╝ MAIN
# ==================================================
if __name__ == '__main__':
    # START CODE HERE

    # AVOID  placing Transaction inside of your loops! It will drastically reduce perfomance of your script.
    t = Transaction(doc,__title__)  # Transactions are context-like objects that guard any changes made to a Revit model.

    # You need to use t.Start() and t.Commit() to make changes to a Project.
    t.Start()  # <- Transaction Start

    #- CHANGES TO REVIT PROJECT HERE

    t.Commit()  # <- Transaction End

    # Notify user that script is complete.
    print('-' * 50)
    print('Script is finished.')
    print('Template has been developed by Erik Frits.')
Template_min from Video
# -*- coding: utf-8 -*-
__title__ = "EF Template.min"
__doc__ = """Version = 1.0
Date    = 20.04.2022
_____________________________________________________________________
Description:
This is a template file for pyRevit Scripts.
_____________________________________________________________________
How-to:
-> Click on the button
-> Change Settings(optional)
-> Make a change
_____________________________________________________________________
Last update:
- [24.04.2022] - 1.0 RELEASE
_____________________________________________________________________
To-Do:
- 
_____________________________________________________________________
Author: Erik Frits"""

# ╦╔╦╗╔═╗╔═╗╦═╗╔╦╗╔═╗
# ║║║║╠═╝║ ║╠╦╝ ║ ╚═╗
# ╩╩ ╩╩  ╚═╝╩╚═ ╩ ╚═╝ IMPORTS
# ==================================================
# Regular + Autodesk
from Autodesk.Revit.DB import *

# pyRevit
from pyrevit import revit, forms

# .NET Imports
import clr
clr.AddReference("System")
from System.Collections.Generic import List

# ╦  ╦╔═╗╦═╗╦╔═╗╔╗ ╦  ╔═╗╔═╗
# ╚╗╔╝╠═╣╠╦╝║╠═╣╠╩╗║  ║╣ ╚═╗
#  ╚╝ ╩ ╩╩╚═╩╩ ╩╚═╝╩═╝╚═╝╚═╝ VARIABLES
# ==================================================
doc   = __revit__.ActiveUIDocument.Document
uidoc = __revit__.ActiveUIDocument
app   = __revit__.Application

# ╔╦╗╔═╗╦╔╗╔
# ║║║╠═╣║║║║
# ╩ ╩╩ ╩╩╝╚╝ MAIN
# ==================================================
if __name__ == '__main__':
    # START CODE HERE
    print('Template has been developed by Erik Frits.')

HomeWork

💡 Creating a pyRevit script Template is a very important step. You will use it to start all your new tools.

✅Follow the video to create pyRevit Template
✅Modify Template to your own needs if necessary

⌨️ Happy Coding!

Questions:

Should I make Template just like yours?

Should I make Template just like yours?