import streamlit as st import requests import pandas as pd # ---------------------- App Title ---------------------- st.title("🏗️ BuildSmart Estimator") st.markdown("Estimate construction materials using a Mistral-powered model via Hugging Face.") # ---------------------- User Inputs ---------------------- st.header("📋 Project Details") area = st.number_input("Total Area (in square feet)", min_value=100, max_value=100000, step=100) floors = st.number_input("Number of Floors", min_value=1, max_value=100, step=1) structure_type = st.selectbox("Structure Type", ["Residential", "Commercial", "Industrial"]) material_preference = st.selectbox("Material Preference", ["Cement & Bricks", "Steel & Concrete"]) location = st.text_input("Location") # ---------------------- Hugging Face Config ---------------------- HUGGINGFACE_API_TOKEN = st.secrets["api_token"] HUGGINGFACE_API_URL = "https://api-inference.huggingface.co/models/mistralai/Mistral-7B-Instruct-v0.2" headers = { "Authorization": f"Bearer {MISTRAL_API}", "Content-Type": "application/json" } # ---------------------- Build Prompt ---------------------- def build_prompt(area, floors, structure_type, material_pref, location): return ( f"[INST] Estimate construction materials for the following project:\n" f"- Area: {area} sqft\n" f"- Floors: {floors}\n" f"- Structure type: {structure_type}\n" f"- Material preference: {material_pref}\n" f"- Location: {location}\n\n" f"Return in this format:\n" f"Cement (bags), Sand (cubic feet), Bricks (units), Steel (kg), Crush (cubic feet), Rori (cubic feet). [/INST]" ) # ---------------------- Call API ---------------------- def query_mistral(prompt): response = requests.post( HUGGINGFACE_API_URL, headers=headers, json={"inputs": prompt} ) if response.status_code == 200: return response.json()[0]["generated_text"] else: return f"❌ API Error {response.status_code}: {response.text}" # ---------------------- Submit Button ---------------------- if st.button("Estimate Materials"): if not location: st.warning("Please enter a location before submitting.") else: with st.spinner("Estimating materials using Mistral..."): prompt = build_prompt(area, floors, structure_type, material_preference, location) result_text = query_mistral(prompt) st.subheader("📦 Estimated Materials") st.text(result_text) try: lines = result_text.strip().split(",") data = [] for line in lines: if ":" in line: key, value = line.split(":", 1) else: parts = line.strip().split() key = " ".join(parts[:-1]) value = parts[-1] data.append([key.strip(), value.strip()]) df = pd.DataFrame(data, columns=["Material", "Estimated Quantity"]) st.dataframe(df) csv = df.to_csv(index=False) st.download_button("📥 Download as CSV", csv, "material_estimate.csv", "text/csv") except Exception as e: st.error("❗ Could not parse the model output.") st.exception(e) st.markdown("---") st.caption("Powered by Mistral via Hugging Face Inference API")