Whadup whadup whadup!

Worked really hard this passed two weeks to get pyRevit v4.5-beta ready for y’all. I’m only posting about it here though since this is a beta version and not everyone should install this since it’s a developer test release.

Watch this video here. I’ll take you through this long article in the video to make it simpler:

(Why) Do I need to install this?

The purpose of this release is to allow (you) developers to test the new pyRevit core (watch this). There are some changes that might affect your scripts if you have used any of the revitutils or scriptutils modules from pyRevit.

IF you have developed your own python scripts that run under pyRevit, you need to install this beta version and start modifying and adjusting your scripts.

ELSE IF you want to deploy pyRevit in your company DO NOT USE this version since it’s just a beta release. I’ll let you know when v4.5 final release is here.

ELSE you don’t develop scripts and want to use the pyRevit standard tools, I’d suggest waiting for the v4.5 final release, although you can install this and test it out. Just don’t get mad if something breaks.

What has changed?

Okay here is a quick list of the major changes. I’ll explain each one in detail:

  • pyRevit has a new Rocket mode. In this mode, pyRevit runs all the tools in an extension, using a single IronPython engine to increase performance. Currently this feature is experimental but will be the default pyRevit setting for version 4.6. You’ll have the rest of 2017 to revise and adjust your scripts (not many changes)

  • revitutils and scriptutils have been removed (Read this). There is a single module for pyRevit now and it’s pyrevit. The functionality of revitutils and scriptutils modules have been moved inside the main pyrevit module. This is related to the changes required to make the Rocket mode work correctly.

  • pyRevit has a new Dynamo compatibility mode. It runs everything under IronPython 2.3.0 which matches the Dynamo IronPython version. You need to test your tools under this mode as well if you want to use it. Everything should be fine but just in case. Watch for unicode changes specifically if you deal with unicode characters.

  • pyRevit does not run IronPython in FullFrame mode anymore. You need to set __fullframeengine__ = True in your script to request a FullFrame engine for your script. This is usually completely unnecessary unless you’re using complex modules like requests that require a FullFrame engine

  • requests is shipped with pyRevit now.

  • You can Win+Shift click on pyRevit tools now and it’ll display a context menu with some options. It’ll show useful information about the script and will let you open the help link for the tool (e.g. youtube videos) or copy information about the script to the clipboard.

  • This doesn’t affect you but it’s good to know: pyRevit used to include all the python standard library in its folder structure under pylib. Starting with version 4.5 they’ve been moved to a zip file that is attached to the executing IronPython engine and pylib doesn’t exist anymore. This has two benefits:
    • One is that it allows pyRevit to switch its IronPython engine easily (e.g. use 2.7.7 or 2.3.0 and include the correct standard library for each engine)
    • Removing all those files from the installation saves space.
  • This also doesn’t affect you but it’s good to know: lib folder inside pyRevit that include third-party modules that I ship with pyRevit, is now renamed to site_packages to match the standard python folder for third-party packages.

What’s Rocket mode?

Let’s talk more about Rocket mode though an example, and I’ll promise it’ll all make sense at the end.

Why do I need Rocket mode?

OMG it’s FAST!!!! And also uses less memory.

What do I have to change to make my tools work under Rocket mode?

Not much. Just don’t use doc or uidoc globally in your modules. I explain this in detail below. Your scripts are fine since the script.py in your pyRevit tool is still being executed every time you run the tool. It’s just that if you have modules that are shared between scripts, you need to make sure you’re not using any volatile objects in them globally. This is really a programming best practice and has less to do with the Rocket mode.

What happend to scriptutils

Let’s talk about the more widely used scriptutils module first.

For example, here is how you are using the linkify() method on the pyRevit output:

from scriptutils import this_script
this_script.output.linkify(some_element_id)

Rocket mode doesn’t like this. Why? Because this_script is a python object instance that’s defined globally inside the scriptutils module so you can import it in your script easily. this_script represents the currently running script. It provides functionality to support the script running in pyRevit environment like providing information about it or giving access to the output window.

But Rocket mode shares the IronPython engine with multiple tools and it will keep it in memory so it can run the other tools inside the same engine to speed them up. This means that this_script will always represent the first script that was executed under the Rocket mode engine and it’ll mess up the behaviour of other tools since it does not represent them!

The solution is to not have a globally defined instance. So each script needs to ask for an instance of this class, to be able to access the functionality.

Here is how you would modify the snippet above for the new pyRevit core:

from pyrevit import script

output = script.get_output()

output.linkify(some_element_id)

The output object is exactly as it was before. You can still use the same methods for making charts and adjust the window size and whatnot. The only thing that has changed is how you’d ask for this output object.

And here is how you need to import other objects from the new script module:

# script logger
# currently:
# 	from scriptutils import logger

# in v4.5:
from pyrevit import script
logger = script.get_logger()



# results object to report results for the usage logs
# currently:
# 	from scriptutils import this_script
# 	this_script.results.timesaved = 10

# in v4.5:
from pyrevit import script
results = script.get_results()
results.timesaved = 10



# script configuration
# currently:
# 	from scriptutils import this_script
# 	this_script.config.somesetting = somevalue
#	this_script.save_config()

# in v4.5:
from pyrevit import script
config = script.get_config()
config.somesetting = somevalue
script.save_config()



# getting script-only data files
# currently:
# 	this_script.get_universal_data_file()

# in v4.5:
from pyrevit import script
datafile = script.get_universal_data_file()



# opening a url in browser
# currently:
# 	from scriptutils import open_url
#	open_url(url)

# in v4.5:
from pyrevit import script
script.open_url(url)


# info about the script
from pyrevit import script
script_info = script.get_info()

See pyrevitlib/pyrevit/script.py for full functionality. I’m documenting all the core scripts for the v4.5 final release.

What happend to revitutils

Some of you noticed that I had been importing doc and uidoc from revitutils in my scripts. Well this has radically changed due to the exact same issues with the Rocket mode. I had a global doc object in revitutils module that would remain in memory under the new pyRevit core. This means that if the user closes the current document/model in Revit and opens another one, the doc object is still pointing to the same document that is closed now and it would break my scripts.

I have removed the revitutils and moved the functionality inside the pyrevit module. You should revise your scripts to use rpw instead of revitutils

GENERALLY DONT USE ANY PYREVIT MODULE OTHER THAN script. ALWAYS USE THE rpw module for anything you need since it’s designed to wrap the Revit API and is also included in pyRevit installation.

So change this:

from revitutils import doc, uidoc, DB, UI

to this:

from rpw import revit, DB, UI

revit.doc
revit.uidoc

What if I don’t want to use the Rocket mode:

You still have to do all the changes above since they’re module changes. If you don’t want to support the Rocket mode you’ve got two ways:

ONE: Add this to your script:

__cleanengine__ = True

This tells pyRevit to run your tool in a clean engine and not a reused engine.

TWO: Set your extension to not-compatible with Rocket mode in your extension.json file

"rocket_mode_compatible": "False"

This tells pyRevit that all the tools in this extension are not Rocket mode compatible and they all need to be running in a clean engine.

What’s the deal about the Win+Shift click?

Here is how to add a help/youtube link to your tools:

__helpurl__ = 'http://link.to.your.help.page.or.youtube.video'

Where is the installer?

Download the v4.5-beta installer from here