Over the course of the year we’ll be featuring a series of articles by Christopher Welch on emerging and interesting trends in digital architecture, complementing and expanding on topics explored in talks given around New Zealand.

I’m going to open this document with a short story: Recently, a contract had us producing a set of Revit families for a client. The final output for this work ended up being 107 family types across 11 families. Each of these types had to be set up on it’s own named sheet with 6 orthographic views, and then exported out as both .dwg and .pdf files.

For each sheet, this generally took between 3-5 minutes (depending on how long the computer decided to hang for on each export). With human error, and double checking, I ended up completing the work in just over a day, with a couple of hours cleaning up files the next morning. It wasn’t the most particularly engaging work, but it was difficult to justify the added effort of exploring alternate work-flows in order to only save a couple of hours of effort.

The next Revit contract came in with over 800 family types. After some brief mental algebra I was suddenly gripped by a deep curiosity of how to automate Revit tasks.

After a couple of days of trawling the internet and some infuriating trial and error I managed to write a python script that automatically generated the sheet generation and exporting process. What would have been a week long process was turned into a single button push, the files ready by the time I got back from lunch.

Python2As well as saving time in the short term (spending two days to automate an otherwise week long process), this process can save time over the lifetime of your firm – if a client asks that the work be revisited, or if similar work needs to be undertaken for another client, the same code can be used to regenerate the work with only minor tweaking. Michael Kilkelly over at Arch Smarter tells a similar story about the benefit of working in this way, saving an estimated 20 hours over a month with an initial 6 hour investment.

Coming in as an absolute beginner and trying to get a handle on how these things work, I found that while the information was out there, it was scatter-shot and assumed a certain amount of knowledge that an absolute beginner might give up before even starting. Luckily, industry research is a part of my role and I can justify the exertion.

What you’ll find below is a beginners guide as to how I started writing python scripts in Revit. This is not written as a best-practices guide, and it is probably not the best way, but for those with the interest and aptitude but without the time to research, hopefully it will put you on the path towards producing useful programs in a short time frame.

First up, how do you learn to program in the first place?

Actually sitting down and learning to program can be a challenge. For those of us who have little exposure to the underlying concepts, it can have a shallow learning curve. But once you get past the initial hurdles, code can be satisfying and rewarding in it’s own right.

At the suggestion of my thesis supervisor, I started teaching myself Python over at Codecademy. After practising around an hour a day for a couple of weeks I found that I had enough understanding of the underlying concepts to begin writing my own code with some degree of confidence.

This website isn’t perfect by any means – some of the early tutorials are rubbish, and feel a bit like struggling through high school algebra then teaching you logic. But after about 1/3 of the course, the pace picks up. There are plenty of other ways to learn python, and this is the way that worked for me.

Unfortunately, you WILL need to have these basic skills down before you will make any headway within Revit. As someone who’s tried to skip and learn this stuff the quick and dirty way, I can tell you that sometimes, these things just take time and effort to learn the fundamentals before you get stuck in.

Why Python?

Revit has native support for C#, Visual Basic and Visual C++, and if you know one of those languages, then, well, you probably know more than me and shouldn’t be reading this blog post.

I’ve used a little C# and a little JavaScript and the reason I would recommend Python for a beginner is that it lets you explore a lot of the fundamentals of scripting without the structures and syntax that can exacerbate the learning curve when you are just trying to get simple things done.

So how do I start programming in Revit?

The first thing that you need to do before you even get into Revit is to install all the tools that you’ll need. I found a lot of this information through Nathan Miller’s The Proving Ground, which I would recommend if you want further advice or another point of view.

Step 1: Install IronPython

Fairly self-explanatory; In order for the computer to interpret your code, you need the language installed somewhere. It’s worth noting that IronPython is identical to regular Python – you can read about the differences here.

Step 2: Install RevitPythonShell

This is the plug-in for Revit that will allow Python to communicate with Revit.

Step 3: Open Revit and hook up the IronPython library.

In your Revit plug-ins tab, you should see a drop down menu labeled ‘Interactive Python Shell.’

In the drop down menu, select ‘Configure…’ and then navigate to the ‘Search Paths’ tab in the pop up window. Add a new search path that points at your IronPython library (e.g C:\Program Files (x86)\IronPython 2.7\Lib).

Step 4: Download and install the Revit Software Development Kit.

(It’s at the very bottom of the page under ‘tools.’)

Installing this kit (Mine helpfully installed itself at C/Revit 2014 SDK) gives you access to the Revit API. Learning how to successfully navigate an API was one of the initial hurdles I had when I first started learning to code, so I will attempt to explain it succinctly below;

The Revit API is a comprehensive tome of everything that you are able to program Revit to do; everything from creating points and drawing geometry, to creating and naming views.


For example, searching for ‘Drafting View’ in the API reveals a class called ViewDrafting. Clicking on the ‘Members’ of this class will reveal all of the functions that can be run by that class. Trawling through these can reveal interesting opportunities. For example, “ViewDrafting.HideElementsTemporary” can automatically set multiple elements to be temporarily hidden in a view. Sounds useful!

Step 5: Set yourself up a template to write your code.

Revit is a complicated beast to get working but luckily Nathan Miller has provided us with a fantastic template to work from over at The Proving Ground, so I recommend going over to that and reading through his example.

This is a very well documented template and hats off to Nathan for making it. There are only a couple of things I want to add to his explanation. First note the second section of his code:

[code language=”python”]
#set the active Revit application and document
app = __revit__.Application
doc = __revit__.ActiveUIDocument.Document

Here, ‘doc’ refers to the active document and you’ll use ‘doc ‘to refer to everything you do inside Revit – for example, setting up a drafting view would be achieved via:

[code language=”python”]
myview = doc.Create.NewViewDrafting()

Secondly, it’s worth noting that t.Start() and t.Commit() can be a bit of a pain. If you run a script with an error, your transaction will start but not finish, and you’ll need to manually write t.Commit() into the console before you can keep testing your code.

Step 6: Start making tools.

Now that you’re all set up, the best way to learn is to start building your own tools!

Your best bet is to find examples, intuit your way through it and slowly build up a picture of exactly what you can do within the API. I stumbled my way through this phase by working from examples and writing your own code, and desperately googling.

The Proving Ground was a fantastic reference for design focused programming, while Arch Smarter was a great resource for more pragmatic concepts.Here at the bottom of this article I’ve also included one of my first short python scripts that will hopefully aid in your understanding.

Hopefully some of you will find this article helpful in expanding your capacity to save time and be creative within the context of your work by using this article. If anyone has any questions of comments relating to this article, please sing out in the comments.

If you are interested in a digital design consultation or require professionally created 2D and 3D CAD BIM content, feel free to contact one of our BIM Specialists here at Productspec.

Read: The Tangible Benefits of the BIM Revolution

[code language=”python”]
#import libraries and reference the RevitAPI and RevitAPIUI
import clr
import math

from Autodesk.Revit.DB import *

#set the active Revit application and document
app = __revit__.Application
doc = __revit__.ActiveUIDocument.Document

#define a transaction variable and describe the transaction
t = Transaction(doc, ‘This is my new transaction’)

#start a transaction in the Revit database

#perform some action here…

#opens a .txt file with a list of filenames

viewname_list = open(‘C:\Users\User1\Documents\CAD\Viewnames.txt’, ‘r’)

#collects all drafting views in the document and puts them into a document

collector = FilteredElementCollector(doc)
viewscollector = collector.OfClass(ViewDrafting)
views = list(viewscollector)
filelist = []

#checks to see if there are any existing views in the document, skips them if they do, cleans up and adds them to a list if they dont

for line in viewname_list:

namestring = str(line)
trimmed_name = namestring[:-5]
dup_counter = 0

for v in views:
if trimmed_name == v.ViewName:
dup_counter = dup_counter+1
if dup_counter == 0:

#iterates through the view names and creates new views, importing and placing the relevant .dwgs.

for name in filelist:

newview = doc.Create.NewViewDrafting()
newview.Scale = 10
newview.ViewName = name

import_settings = DWGImportOptions()
dwg_name = (‘C:\Users\User1\Documents\CAD\\’ + name + ‘.dwg’)


#commit the transaction to the Revit database

#close the script window