Uneedbest's picture
Update app.py
a884c6c verified
# app.py - Ultra-reliable, simplified version
import os
import gradio as gr
import time
import traceback
from openai import OpenAI
# Check if API key is in environment variable
DEFAULT_API_KEY = os.environ.get("OPENAI_API_KEY", "")
# Create our material knowledge base (simplified version)
MATERIAL_KNOWLEDGE = """
# Material Selection Guide for Chemical Processing
## Caustic Soda (NaOH)
For concentrations up to 50% and temperatures up to 90°C:
- Stainless Steel 316L: Excellent corrosion resistance, suitable for most applications
- Nickel Alloy 400 (Monel): Superior for high-concentration applications
- Alloy 20: Excellent for mixed acid/caustic environments
- PTFE-lined carbon steel: Cost-effective option with excellent chemical resistance
- FRP (Fiber Reinforced Plastic): Good for lower temperatures and pressures
## Sulfuric Acid (H2SO4)
For concentrations up to 98%:
- Alloy 20: Excellent for sulfuric acid up to 80°C
- PTFE-lined carbon steel: Excellent chemical resistance across all concentrations
- High-silicon cast iron (14%+ Si): Excellent for concentrations above 80%
- FRP with vinyl ester resin: Good for concentrations below 70% at ambient temperature
- Carpenter 20Cb-3: Good for concentrations below 80% up to 60°C
## Hydrochloric Acid (HCl)
For concentrations up to 37%:
- Hastelloy C-276: Excellent resistance across all temperatures and concentrations
- Hastelloy B-3: Superior performance for HCl service
- PVDF (Polyvinylidene fluoride): Excellent for room temperature applications
- FRP with vinyl ester resin: Good for temperatures below 80°C
- Zirconium: Excellent but expensive option for high-temperature service
## Seawater Applications
For seawater and brackish water:
- Super Duplex Stainless Steel (UNS S32750): Excellent resistance to seawater corrosion
- Copper-Nickel Alloys (90/10 or 70/30): Traditional marine service materials
- Titanium Grade 2: Superior performance but higher cost
- 6% Molybdenum Stainless Steels: Excellent for critical seawater applications
- FRP with vinyl ester resin: Good for low-pressure applications
## High-Temperature Service
For temperatures above 200°C:
- Inconel 625: Excellent for temperatures up to 980°C
- Hastelloy X: Superior for high-temperature oxidizing environments
- Stainless Steel 310/310S: Good for temperatures up to 1100°C
- Monel 400: Good for reducing environments up to 540°C
- Incoloy 800H/800HT: Designed for high-temperature strength and carburization resistance
"""
# Extremely simplified material recommendation function
def get_material_recommendation(query, api_key):
# Basic error checking
try:
log_message = f"[DEBUG] Processing query: {query[:50]}..."
print(log_message)
# Format the AI prompt
messages = [
{"role": "system", "content": f"You are MatSelectAI, an expert materials engineer. Use this knowledge base:\n\n{MATERIAL_KNOWLEDGE}"},
{"role": "user", "content": f"Query: {query}\n\nProvide material recommendations with specific grades, properties, limitations, and alternatives."}
]
# Simple OpenAI call with timeout
try:
# Initialize the client
print("[DEBUG] Initializing OpenAI client...")
client = OpenAI(api_key=api_key, timeout=60.0)
# Call the API
print("[DEBUG] Calling OpenAI API...")
response = client.chat.completions.create(
model="gpt-3.5-turbo",
messages=messages,
temperature=0.3,
max_tokens=800
)
# Extract and return the response
print("[DEBUG] Successfully received response from OpenAI")
answer = response.choices[0].message.content
return answer
except Exception as e:
# Get detailed error information
error_trace = traceback.format_exc()
print(f"[ERROR] OpenAI API error: {str(e)}\n{error_trace}")
# Return a user-friendly error message
return f"❌ Error communicating with OpenAI API: {str(e)}\n\nPlease try again or check your API key."
except Exception as e:
# Catch-all for any other errors
error_trace = traceback.format_exc()
print(f"[ERROR] Unexpected error: {str(e)}\n{error_trace}")
return f"❌ Unexpected error: {str(e)}"
# Simple Gradio interface
with gr.Blocks(theme=gr.themes.Soft()) as demo:
gr.Markdown("# MatSelectAI - Material Selection Assistant")
gr.Markdown("Get recommendations for piping and equipment materials based on fluid types")
with gr.Row():
with gr.Column():
# API key input
api_key_input = gr.Textbox(
label="OpenAI API Key",
placeholder="Enter your OpenAI API key (sk-...)",
type="password",
value=DEFAULT_API_KEY
)
# Query input
query_input = gr.Textbox(
label="Material Selection Query",
placeholder="e.g., What materials are suitable for piping carrying 50% NaOH at 80°C?",
lines=3
)
# Buttons
with gr.Row():
submit_btn = gr.Button("Get Recommendation", variant="primary")
clear_btn = gr.Button("Clear")
# Diagnostic info
with gr.Accordion("Diagnostics", open=False):
status_info = gr.Markdown("Status: Ready")
# Output area
output_area = gr.Markdown(label="Material Recommendation")
# Example queries
gr.Examples(
examples=[
"What materials are suitable for piping carrying 50% NaOH at 80°C?",
"Recommend materials for a heat exchanger with seawater",
"Best corrosion-resistant materials for sulfuric acid storage tanks",
"What piping material should I use for HCl at room temperature?",
"Material options for a vessel containing caustic soda"
],
inputs=query_input
)
# Function to get recommendation
def process_query(query, api_key):
# Update status
status = "Processing query..."
# Validate API key
if not api_key or not api_key.startswith("sk-"):
return (
f"⚠️ Please enter a valid OpenAI API key (should start with 'sk-')",
"Status: ❌ Missing or invalid API key"
)
try:
# Update status and get recommendation
status = f"Sending request to OpenAI API..."
result = get_material_recommendation(query, api_key)
status = "Status: ✅ Response received"
return result, status
except Exception as e:
error_trace = traceback.format_exc()
print(f"[ERROR] Error in process_query: {str(e)}\n{error_trace}")
return f"❌ Error: {str(e)}", f"Status: ❌ Error: {str(e)}"
# Function to clear inputs
def clear_inputs():
return "", "Status: Ready"
# Connect the buttons
submit_btn.click(
process_query,
inputs=[query_input, api_key_input],
outputs=[output_area, status_info]
)
clear_btn.click(
clear_inputs,
outputs=[query_input, status_info]
)
# Launch the app
if __name__ == "__main__":
demo.launch()