This file provides guidance for AI assistants working with the pyRevit codebase.
pyRevit is a Rapid Application Development (RAD) environment for Autodesk Revit. It allows users to create automation tools and add-ins using Python (IronPython 2.7.12 default, CPython 3.12.3, or IronPython 3.4.0), C#, or VB.NET. The project includes a CLI utility for deployment and a telemetry server for usage tracking.
bin/- Pre-built binaries (DLLs) and Python engines (IPY2712PR, IPY342, CPY3123)dev/- C# source code, build scripts, and solution filesdocs/- Documentation source for the website (mkdocs)extensions/- pyRevit extensions (tools visible in Revit ribbon)extras/- Additional resources (icons, dark mode generator)licenses/- Third-party library licensespyrevitlib/- Python libraries for Revit API developmentrelease/- Build artifacts and installer configurationssite-packages/- Third-party Python packages (must be IronPython 2.7.12 compatible)
- Python: IronPython 2.7.12 (default), CPython 3.12.3, IronPython 3.4.0
- C#: .NET Framework 4.8 (Revit 2017-2024), .NET 8.0 (Revit 2025+)
- Go: pyRevit autocomplete application (
dev/pyRevitLabs/pyRevitCLIAutoComplete) - Build Tools: Visual Studio 2022, pipenv, MSBuild, Inno Setup
All build commands use pipenv. Run from the repository root:
# Setup environment
pipenv install
pipenv run pyrevit check # Verify build environment
# Build commands
pipenv run pyrevit build products # Build all C# DLLs (Release mode)
pipenv run pyrevit build products Debug # Build in Debug mode
pipenv run pyrevit build labs # Build main project only
pipenv run pyrevit build engines # Build Python engines
pipenv run pyrevit build installers # Create Inno Setup installers
# Cleaning
pipenv run pyrevit clean labs # Clean build artifacts
# Version management
pipenv run pyrevit set version <ver> # Set version number
pipenv run pyrevit set build wip # Set as work-in-progress
pipenv run pyrevit set build release # Set as release build- Main website: https://pyrevitlabs.io/
- Technical docs: https://docs.pyrevitlabs.io/ (mkdocs, built from
docs/folder)
pipenv run docs # Build documentation (mkdocs)
pipenv run check-docstrings # Lint docstrings with ruffTo test in Revit:
pyrevit clones add dev <path-to-repo>
pyrevit attach dev default --installed- Fork and clone the repository
- Checkout
developbranch (active development) - Initialize submodules:
git submodule update --init --recursive - Install dependencies:
pipenv install - Build:
pipenv run pyrevit build products Debug - Test in Revit by attaching the clone
For debugging C# code:
- Build in Debug mode
- Open the appropriate
.slnfile in Visual Studio - Attach debugger to
revit.exeprocess
- Revit reads
.addinmanifest from Addins folder - Manifest points to
pyRevitLoader.dll(C#) - Loader launches
pyrevitloader.pyin IronPython - Python script calls
pyrevit.loader.sessionmgr.load_session() - Extensions are discovered and UI is built
- pyRevitLoader (
dev/pyRevitLoader/): Revit add-in entry point - PyRevit.Runtime (
dev/pyRevitLabs/pyRevitLabs.PyRevit.Runtime/): Command execution - pyrevitlib (
pyrevitlib/pyrevit/): Python API for scripts - CLI (
dev/pyRevitLabs/pyRevitLabs.PyRevit/): Command-line management
Located in dev/pyRevitLabs/pyRevitLabs.PyRevit.Runtime/:
IronPythonEngine.cs- Default Python engineCPythonEngine.cs- Modern Python (3.12)CLREngine.cs- C#/VB.NET executionDynamoBIMEngine.cs- Dynamo graphsGrasshopperEngine.cs- Grasshopper definitions
Extensions follow this hierarchy:
MyExtension.extension/
MyTab.tab/
MyPanel.panel/
MyButton.pushbutton/
bundle.yaml # Button configuration
script.py # Python script
icon.png # Button icon
Supported bundle types: pushbutton, smartbutton, pulldown, splitbutton, panelbutton
Pipfile- Python dependencies (requires Python 3.10)pyRevitfile- Engine definitions and deployment profilespyproject.toml- Ruff linting config (Google docstring convention)mkdocs.yml- Documentation generation.gitmodules- Git submodules for dependencies
- Python: Google docstring convention, formatted with black, linted with ruff
- C#: Standard .NET conventions
When writing or suggesting code comments, document what the code does and why, never how.
Implementation details are already visible in the code itself. Restating them in a comment adds noise and creates drift: when the implementation changes, comments that describe it become misleading if not updated at the same time.
Avoid comments that:
- Restate what the next line of code literally does (
# increment counter,# call the loader,# return the list). - Name specific internal functions, classes, or modules that the code depends on.
- Describe the sequence of steps the implementation follows.
- Reference implementation choices that could change (e.g. which engine, which data structure, which library). Prefer comments that:
- Explain the purpose or intent of a block (
# ensure the session is clean before loading extensions). - Capture non-obvious why reasoning that cannot be inferred from the code (
# Revit does not allow re-entrant API calls during this event). - Warn about known constraints or side effects that a future editor needs to be aware of.
- Describe what a function or class is responsible for, not how it achieves it. Example — what to avoid:
# Call get_ext_root_dirs to retrieve the list of extension paths from user config,
# then pass each path to extensionmgr to scan for UI extension manifests.
extensions = get_all_extensions()Example — what to write instead:
# Collect all installed extensions visible to the current user before building the UI.
extensions = get_all_extensions()The same rule applies to docstrings, inline comments, and any documentation generated alongside code.
2017-2027, with separate builds per version:
- Revit 2017-2024: .NET Framework 4.7.2/4.8
- Revit 2025-2026: .NET 8.0
- Revit 2027+: .NET 10.0
developbranch: Active development (always start here)masterbranch: Release material onlydocsbranch: Documentation website- Feature branches from
develop, PRs back todevelop - Run
git submodule updateafter switching branches