| | |
| | import os |
| | import gradio as gr |
| | import time |
| | import traceback |
| | from openai import OpenAI |
| |
|
| | |
| | DEFAULT_API_KEY = os.environ.get("OPENAI_API_KEY", "") |
| |
|
| | |
| | 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 |
| | """ |
| |
|
| | |
| | def get_material_recommendation(query, api_key): |
| | |
| | try: |
| | log_message = f"[DEBUG] Processing query: {query[:50]}..." |
| | print(log_message) |
| | |
| | |
| | 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."} |
| | ] |
| | |
| | |
| | try: |
| | |
| | print("[DEBUG] Initializing OpenAI client...") |
| | client = OpenAI(api_key=api_key, timeout=60.0) |
| | |
| | |
| | print("[DEBUG] Calling OpenAI API...") |
| | response = client.chat.completions.create( |
| | model="gpt-3.5-turbo", |
| | messages=messages, |
| | temperature=0.3, |
| | max_tokens=800 |
| | ) |
| | |
| | |
| | print("[DEBUG] Successfully received response from OpenAI") |
| | answer = response.choices[0].message.content |
| | return answer |
| | |
| | except Exception as e: |
| | |
| | error_trace = traceback.format_exc() |
| | print(f"[ERROR] OpenAI API error: {str(e)}\n{error_trace}") |
| | |
| | |
| | return f"❌ Error communicating with OpenAI API: {str(e)}\n\nPlease try again or check your API key." |
| | |
| | except Exception as e: |
| | |
| | error_trace = traceback.format_exc() |
| | print(f"[ERROR] Unexpected error: {str(e)}\n{error_trace}") |
| | return f"❌ Unexpected error: {str(e)}" |
| |
|
| | |
| | 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 = gr.Textbox( |
| | label="OpenAI API Key", |
| | placeholder="Enter your OpenAI API key (sk-...)", |
| | type="password", |
| | value=DEFAULT_API_KEY |
| | ) |
| | |
| | |
| | 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 |
| | ) |
| | |
| | |
| | with gr.Row(): |
| | submit_btn = gr.Button("Get Recommendation", variant="primary") |
| | clear_btn = gr.Button("Clear") |
| | |
| | |
| | with gr.Accordion("Diagnostics", open=False): |
| | status_info = gr.Markdown("Status: Ready") |
| | |
| | |
| | output_area = gr.Markdown(label="Material Recommendation") |
| | |
| | |
| | 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 |
| | ) |
| | |
| | |
| | def process_query(query, api_key): |
| | |
| | status = "Processing query..." |
| | |
| | |
| | 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: |
| | |
| | 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)}" |
| | |
| | |
| | def clear_inputs(): |
| | return "", "Status: Ready" |
| | |
| | |
| | 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] |
| | ) |
| |
|
| | |
| | if __name__ == "__main__": |
| | demo.launch() |