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/- Generated product binaries (DLLs, engines, CLI). Built locally viadotnet run -- cior downloaded anonymously from public CI Release assets bypyrevit clone. Not tracked in git. Static sources:release/bin-assets/,release/cengines/,release/pyrevit-hosts.json.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: .NET 10, ModularPipelines, Visual Studio 2022, MSBuild, Inno Setup
The build is driven by the C# ModularPipelines project under build/. Run from build/:
# Default unsigned local build (Channel=none)
dotnet run -c Release -- ci
# Debug build (attach the Visual Studio debugger to revit.exe)
dotnet run -c Debug -- ci
# WIP-style stamping + product build (mirrors develop push on the main repo)
$env:Build__Channel = 'wip'
dotnet run -c Release -- ci
# Release-style stamping + product build (mirrors master / tag CI on the main repo)
$env:Build__Channel = 'release'
$env:DOTNET_ENVIRONMENT = 'Production'
dotnet run -c Release -- ciOther pipeline modes: pack, sign, publish, winget, notify. See build/README.md for the full list, Build__Channel semantics, and CI gating.
- 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:
cd build && dotnet run -c Debug -- ci && cd .. - 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#) PyRevitLoaderApplication.OnStartupcalls the C# session manager directly (no IronPython bootstrap)SessionManagerService.LoadSessionrunssession_preload.py, builds extension assemblies and UI in C#, then runssession_postload.py- The preload/postload scripts drive the residual Python session services (telemetry, routes, output window, hooks framework) through the runtime engine
Reload re-enters the same C# orchestrator via PyRevitLoaderApplication.LoadSession. The legacy pure-Python loader has been removed; the C# loader requires Revit 2021+.
- 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