LearnRevitAPI

Nov 28, 2022

pyRevit Script Anatomy

"Computers are good at following instructions, but not at reading your mind. " Donald Knuth

Let's go through basic instructions that pyRevit needs to execute your code and display all the given information correctly.

πŸ”½ .pushbutton

Before I dive into pyRevit script Anatomy, I want to let you know that pyRevit is capable of running not just python scripts! 

πŸ“ File Types

When we create a pushbutton with pyRevit we don't necessary have to use python. pyRevit supports many different types:

  • IronPython / CPython 

  • Dynamo / Grasshopper

  • C# / VB .NET 

πŸ“ƒ Docs - Supported Files

This might be useful to easily convert your Dynamo scripts into a button in your new extension, but you might encounter issues with GUI if you use Dynamo packages for that.

I primaraly focus on python!
so Let's have a look at its structure

🐍 python Script

Script Structure

πŸ‘ˆ When i think about my python scripts, I imagine structure like this.

πŸ”ΆMeta: special variables that tell pyRevit more about your button

πŸ”ΆImports: Obviously we need to import Revit API and sometimes .NET and pyRevit classes

πŸ”ΆVariables: There are variables repeated across all scripts such as doc that RevitAPI needs.

πŸ”Ά Main: Here goes your functions, classes, and all the logic necessary for the script. That's where all the juice is!

πŸ’ͺ Let's break it down

πŸ”… pyRevit Meta

There are 2 ways of defining meta information about a button.
1️⃣ Simply define them on the top of your script, that's how I generally do it.

2️⃣ Alternatively you can create an extension.yaml file and write it there. You don't have to connect python and yaml files, pyRevit does it automatically if they are placed in the same folder.

There will be differences in syntax because of different file formats, but you can always have a look at other extensions to get an idea about them.

These are the main Meta variables you might want to use.
There are a few more that you can read more about in
Dev Docs

πŸ‘‡

__title__ πŸ‘ˆ This is the name of the button

__doc__ πŸ‘ˆ Description of the button (Shown when hover over the button)

 __author__ πŸ‘ˆ Name of the author  

__helpurl__ πŸ‘ˆ Provide URL or a path that can be opened with F1 when you hover over the button

__highlight__ πŸ‘ˆ It will highligh button in UI. ('new' / 'updated')

__min_revit_ver__ πŸ‘ˆ Limit button to certain Revit Version Min

__max_revit_ver πŸ‘ˆ Limit button to certain Revit Version Max

__context__ πŸ‘ˆ If you want your script to be accessible only if user has certain elements selected or certain view activated, you can specify it. It will be grayed out until it meets requirements. Read more about context

__beta__ πŸ‘ˆ You can hide a tool that you are working on in the interface from other users.

➑️ Imports

Imports are straight-forward, but I will still mention them, because even here we have some features that pyRevit offers.

Revit API Imports

We pretty much always need to import something from Revit API, but we don't need to reference Revit API libraries every time. pyRevit has them included by default. Just Import them straight in your code.

from Autodesk.Revit.DB import *

.NET Imports

When working with Revit API you will see that many methods take ICollection<t> or IList<t> as an argument, and python list will not be enough. </t></t>

Just refference System module and import List[T] so you can convert your python list into a List of elements that will work with Revit API.

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

pyRevit Imports

pyRevit is full of classes and functions that we can reuse in our scripts, and to learn more about them you need to spend some time in pyRevit dev docs and read some source code. You will learn a lot from other examples. 

I mainly import forms, revit and sometimes output modules. Just be curious how pyRevit can help you, and you might get surprised!

Custom Imports (lib)

After a while you will need to start collecting your code and make it more reusable. 

You can create a lib folder in the root of your extension, and you can simply import your reusable functions, classes and variables. I will dive into that topic deeper in the future. 

Remember: 'Good programmer code, great programmers reuse code.'

πŸ“¦ Variables

Most Used Variables

For some reason I get my doc, uidoc and app in the following way:

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

But we can also import them from pyRevit

from pyrevit.revit import doc, uidoc, app

It takes less space, but I developed a habit using it the first way I use, so it's up to you. 

πŸ‘‡ Get My FREE Template

I can't explain a lot on this topic in a single email, but I think you can learn even more just by looking at templates that I prepared.

There is a lot of code that will be used in all your scripts, so you better make a template that you can reuse to quickly make new ones. Or use mine and over time you will adjust it to suit your own needs

πŸ“ GitHub: python Template

🎦 Video Tutorial

If you want to understand it even more,
Check out this tutorial where I explain pyRevit Script Anatomy
πŸ‘‡

Create your first Extension for Revit

I explain pyRevit folder structure so you can create and orginize your extension. I will also show you how to work with lib folder so you can start reusing your code as soon as possible!
πŸ‘€ Watch it

Enjoyed Newsletter?

Leave a Testimonial Here.

⌨️ Happy Coding!
Erik Frits

Join Newsletter

πŸ“© You will be added to Revit API Newsletter

Join Us!

which is already read by 6700+ people!