The Bundle Price Increases in
04d 21h 10m 03s
Join Today with 30% OFF.
Jan 7, 2025
Create AI Assistant for Revit | pyRevit Hacker Podcast #1
Learn how to integrade Open AI by using pyRevit by listening to the first episode of pyRevit Hackers Podcast
Code from Podcast:
The code below was kindly provided by Ashish Ranjan after he has attended to pyRevit Hackers Podcase #1.
📁Openai_Server/chatgpt_service.py
import openai
import sys
import json
# Replace 'your_openai_api_key' with your actual OpenAI API key
openai.api_key = 'OpenAI API key'
def ask_openai(question):
try:
# Use ChatCompletion endpoint to get a response from ChatGPT
response = openai.ChatCompletion.create(
model="gpt-3.5-turbo", # Use "gpt-4" if you have access
messages=[{"role": "user", "content": question}],
max_tokens=100,
temperature=0.7
)
# Extract and return the response content
return response.choices[0].message['content'].strip()
except Exception as e:
return f"Error: {str(e)}"
if __name__ == "__main__":
# Check if the question is provided as a command-line argument
if len(sys.argv) < 2:
print("Error: No question provided.")
sys.exit(1)
# Get the question from the command-line argument
question = sys.argv[1]
# Get the response from OpenAI
response_text = ask_openai(question)
# Print the response to be captured by script.py
print(response_text)
📁AskRev.pushbutton
ChatGPTForm.xaml
<Window xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
Title="AskRev – Get Answers, Gain Insight" Height="400" Width="450" WindowStartupLocation="CenterScreen">
<Grid Margin="10">
<Grid.RowDefinitions>
<RowDefinition Height="*"/>
<RowDefinition Height="Auto"/>
<RowDefinition Height="Auto"/>
</Grid.RowDefinitions>
<!-- Conversation History RichTextBox -->
<RichTextBox x:Name="ConversationHistory" Grid.Row="0" Margin="0,0,0,10"
HorizontalAlignment="Stretch" VerticalAlignment="Stretch"
Background="LightGray" IsReadOnly="True" VerticalScrollBarVisibility="Auto"
FontSize="15" />
<!-- TextBox for New Question Input -->
<TextBox x:Name="QuestionInput" Grid.Row="1" Margin="0,0,0,10" Height="30"
HorizontalAlignment="Stretch" VerticalAlignment="Top"/>
<!-- Send Button -->
<Button x:Name="SendButton" Content="Send" Width="80" Height="30"
HorizontalAlignment="Center" Grid.Row="2" Background="LightGreen" Margin="0,0,0,10"/>
</Grid>
</Window>
script.py
from pyrevit import forms
import subprocess
import os
from System.Windows.Documents import Run, Paragraph
from System.Windows.Media import Brushes
# Define the function to send a question to ChatGPT
def ask_chatgpt(question):
try:
# Run chatgpt_service.py with the user's question as a command-line argument
result = subprocess.check_output(
[
r"....", # Full path to Python executable
r"....", # Full path to chatgpt_service.py
question
],
stderr=subprocess.STDOUT,
universal_newlines=True
)
return result.strip()
except subprocess.CalledProcessError as e:
return "Error from chatgpt_service.py: " + e.output.strip()
except Exception as e:
return "An unexpected error occurred: " + str(e)
# Define the main form class
class ChatGPTForm(forms.WPFWindow):
def __init__(self):
# Load the XAML file
xaml_path = os.path.join(os.path.dirname(__file__), "ChatGPTForm.xaml")
forms.WPFWindow.__init__(self, xaml_path)
# Attach the Send button click event
self.SendButton.Click += self.send_button_click
def send_button_click(self, sender, args):
# Get the user's question from the QuestionInput TextBox
user_question = self.QuestionInput.Text.strip()
if user_question == "":
return
# Add the user's question in red to the ConversationHistory RichTextBox
user_paragraph = Paragraph()
user_run = Run("User: {}\n".format(user_question))
user_run.Foreground = Brushes.Red
user_paragraph.Inlines.Add(user_run)
self.ConversationHistory.Document.Blocks.Add(user_paragraph)
# Get response from ChatGPT
response_text = ask_chatgpt(user_question)
# Add ChatGPT's response in green to the ConversationHistory RichTextBox
bot_paragraph = Paragraph()
bot_run = Run("AskRev: {}\n\n".format(response_text))
bot_run.Foreground = Brushes.Green
bot_paragraph.Inlines.Add(bot_run)
self.ConversationHistory.Document.Blocks.Add(bot_paragraph)
# Clear the QuestionInput TextBox
self.QuestionInput.Text = ""
# Scroll to the bottom of the ConversationHistory RichTextBox
self.ConversationHistory.ScrollToEnd()
# Show the dialog window
try:
ChatGPTForm().ShowDialog()
except Exception as e:
print("An error occurred while displaying the form:", e)
📁ModelMind.pushbutton
ModelChatForm.xaml
<Window xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
Title="ModelMind-Your Model’s Knowledge, Unlocked" Height="400" Width="450" WindowStartupLocation="CenterScreen">
<Grid Margin="10">
<Grid.RowDefinitions>
<RowDefinition Height="*"/>
<RowDefinition Height="Auto"/>
<RowDefinition Height="Auto"/>
</Grid.RowDefinitions>
<!-- Conversation History RichTextBox -->
<RichTextBox x:Name="ConversationHistory" Grid.Row="0" Margin="0,0,0,10"
HorizontalAlignment="Stretch" VerticalAlignment="Stretch"
Background="LightGray" IsReadOnly="True" VerticalScrollBarVisibility="Auto"
FontSize="15" />
<!-- TextBox for New Question Input -->
<TextBox x:Name="QuestionInput" Grid.Row="1" Margin="0,0,0,10" Height="30"
HorizontalAlignment="Stretch" VerticalAlignment="Top"/>
<!-- Send Button -->
<Button x:Name="SendButton" Content="Send" Width="80" Height="30"
HorizontalAlignment="Center" Grid.Row="2" Background="LightGreen" Margin="0,0,0,10"/>
</Grid>
</Window>
script.py
import clr
import json
import os
import sys
import subprocess
from pyrevit import forms
from System.Windows.Documents import Run, Paragraph
from System.Windows.Media import Brushes
from Autodesk.Revit.UI import UIApplication
from Autodesk.Revit.DB import FilteredElementCollector, BuiltInParameter
# Define paths to the external Python interpreter and main.py script
python_exe_path = r"" # Full path to Python executable
main_script_path = r"" # Full path to chatgpt_service.py
# Access the Revit document using UIApplication
uiapp = __revit__ # Get the Revit application from pyRevit's __revit__ variable
doc = uiapp.ActiveUIDocument.Document
# Path to the extracted data JSON file
data_path = os.path.join(os.path.expanduser("~"), "RevitModelData.json")
# Function to extract model data and save to JSON
def extract_model_data():
elements = FilteredElementCollector(doc).WhereElementIsNotElementType().ToElements()
all_data = []
for el in elements:
data = {
"Id": el.Id.IntegerValue,
"Category": el.Category.Name if el.Category else "N/A",
"Name": el.Name if hasattr(el, "Name") else "Unnamed Element",
"Volume": el.LookupParameter("Volume").AsDouble() if el.LookupParameter("Volume") else None,
"Area": el.LookupParameter("Area").AsDouble() if el.LookupParameter("Area") else None,
"Material": el.LookupParameter("Material").AsString() if el.LookupParameter("Material") else "Not Specified"
}
all_data.append(data)
# Save extracted data to JSON
with open(data_path, 'w') as f:
json.dump(all_data, f, indent=4)
return all_data
# Load data from file if available, otherwise extract it
if os.path.exists(data_path):
with open(data_path, 'r') as f:
model_data = json.load(f)
else:
model_data = extract_model_data()
# Define query function to call OpenAI via subprocess
def query_data(question, model_data):
input_data = json.dumps({
"question": question,
"model_data": model_data
})
# Run main.py with the question and model data as input
try:
process = subprocess.Popen(
[python_exe_path, main_script_path],
stdin=subprocess.PIPE, stdout=subprocess.PIPE, stderr=subprocess.PIPE,
universal_newlines=True
)
stdout, stderr = process.communicate(input=input_data)
if process.returncode != 0:
return "Error: " + stderr.strip()
return stdout.strip()
except Exception as e:
return "An error occurred: " + str(e)
# Main chat interface
class ModelChatForm(forms.WPFWindow):
def __init__(self):
xaml_path = os.path.join(os.path.dirname(__file__), "ModelChatForm.xaml")
forms.WPFWindow.__init__(self, xaml_path)
self.SendButton.Click += self.send_button_click
def send_button_click(self, sender, args):
user_question = self.QuestionInput.Text.strip()
if user_question == "":
return
# Display user question in red
user_paragraph = Paragraph()
user_run = Run("User: {}\n".format(user_question))
user_run.Foreground = Brushes.Red
user_paragraph.Inlines.Add(user_run)
self.ConversationHistory.Document.Blocks.Add(user_paragraph)
# Get response from OpenAI's API via subprocess
response_text = query_data(user_question, model_data)
# Display response in green
bot_paragraph = Paragraph()
bot_run = Run("ModelMind: {}\n\n".format(response_text))
bot_run.Foreground = Brushes.Green
bot_paragraph.Inlines.Add(bot_run)
self.ConversationHistory.Document.Blocks.Add(bot_paragraph)
# Clear input and scroll to bottom
self.QuestionInput.Text = ""
self.ConversationHistory.ScrollToEnd()
try:
ModelChatForm().ShowDialog()
except Exception as e:
print("An error occurred:", e)
Join Newsletter
📩 You will be added to Revit API Newsletter
Join Us!
which is already read by 7500+ people!
Ready to become Revit Hero for your office? Learn Revit API!
Join this comprehensive course that will guide you step by step on how to create your dream tools for Revit that save time.