Spaces:
Runtime error
Runtime error
Update app.py
Browse files
app.py
CHANGED
|
@@ -7,11 +7,11 @@ import time
|
|
| 7 |
|
| 8 |
# Configure OpenAI API settings
|
| 9 |
API_URL = "https://api.openai.com/v1/chat/completions"
|
| 10 |
-
MODEL_NAME = "gpt-4o" #
|
| 11 |
|
| 12 |
# Set API key from Hugging Face secrets
|
| 13 |
try:
|
| 14 |
-
API_KEY = st.secrets["
|
| 15 |
except:
|
| 16 |
API_KEY = "" # Will be prompted to enter API key if not in secrets
|
| 17 |
|
|
@@ -21,31 +21,6 @@ if "uploaded_images" not in st.session_state:
|
|
| 21 |
if "api_key" not in st.session_state:
|
| 22 |
st.session_state["api_key"] = API_KEY
|
| 23 |
|
| 24 |
-
# Custom styles for the app
|
| 25 |
-
st.markdown("""
|
| 26 |
-
<style>
|
| 27 |
-
.main .block-container {
|
| 28 |
-
padding-bottom: 5rem !important;
|
| 29 |
-
max-width: 100% !important;
|
| 30 |
-
}
|
| 31 |
-
|
| 32 |
-
@media (max-width: 640px) {
|
| 33 |
-
.main .block-container {
|
| 34 |
-
padding: 1rem 0.5rem !important;
|
| 35 |
-
}
|
| 36 |
-
|
| 37 |
-
h1 { font-size: 1.5rem !important; }
|
| 38 |
-
h2, h3 { font-size: 1.2rem !important; }
|
| 39 |
-
|
| 40 |
-
.stButton button {
|
| 41 |
-
width: 100% !important;
|
| 42 |
-
height: 3rem !important;
|
| 43 |
-
margin: 0.5rem 0 !important;
|
| 44 |
-
}
|
| 45 |
-
}
|
| 46 |
-
</style>
|
| 47 |
-
""", unsafe_allow_html=True)
|
| 48 |
-
|
| 49 |
# Function to encode image to base64
|
| 50 |
def encode_image(image):
|
| 51 |
# Convert RGBA to RGB if needed
|
|
@@ -73,13 +48,14 @@ def analyze_home_photos(images, property_type, price_range, timeframe, additiona
|
|
| 73 |
{"type": "text", "text": f"Analyze these home photos and recommend improvements to maximize value for a {property_type} in the {price_range} range. The owner plans to sell within {timeframe}. {additional_details}"}
|
| 74 |
]
|
| 75 |
|
| 76 |
-
# Add images to the message
|
| 77 |
for img in images:
|
| 78 |
base64_img = encode_image(img)
|
| 79 |
content.append({
|
| 80 |
"type": "image_url",
|
| 81 |
"image_url": {
|
| 82 |
-
"url": f"data:image/jpeg;base64,{base64_img}"
|
|
|
|
| 83 |
}
|
| 84 |
})
|
| 85 |
|
|
@@ -100,6 +76,9 @@ def analyze_home_photos(images, property_type, price_range, timeframe, additiona
|
|
| 100 |
For each recommendation, explain the potential value impact and approximate ROI.
|
| 101 |
Be specific based on what you can see in the photos.
|
| 102 |
Avoid generic advice - focus on what's visible in the images provided.
|
|
|
|
|
|
|
|
|
|
| 103 |
"""
|
| 104 |
},
|
| 105 |
{
|
|
@@ -115,13 +94,24 @@ def analyze_home_photos(images, property_type, price_range, timeframe, additiona
|
|
| 115 |
status.write("Sending images to AI service...")
|
| 116 |
response = requests.post(API_URL, headers=headers, json=payload, timeout=60)
|
| 117 |
|
|
|
|
|
|
|
|
|
|
| 118 |
if response.status_code == 200:
|
| 119 |
status.update(label="Analysis complete!", state="complete")
|
| 120 |
return response.json()["choices"][0]["message"]["content"]
|
| 121 |
else:
|
| 122 |
status.update(label="Error in analysis", state="error")
|
| 123 |
-
|
| 124 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 125 |
except Exception as e:
|
| 126 |
st.error(f"Error: {str(e)}")
|
| 127 |
return f"Error: {str(e)}"
|
|
@@ -129,6 +119,19 @@ def analyze_home_photos(images, property_type, price_range, timeframe, additiona
|
|
| 129 |
# Main application
|
| 130 |
st.title("Home Value Maximizer 🏡")
|
| 131 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 132 |
# API Key input if not in secrets
|
| 133 |
if not st.session_state["api_key"]:
|
| 134 |
st.session_state["api_key"] = st.text_input("Enter your OpenAI API Key", type="password")
|
|
|
|
| 7 |
|
| 8 |
# Configure OpenAI API settings
|
| 9 |
API_URL = "https://api.openai.com/v1/chat/completions"
|
| 10 |
+
MODEL_NAME = "gpt-4o" # Use the latest model with vision capabilities
|
| 11 |
|
| 12 |
# Set API key from Hugging Face secrets
|
| 13 |
try:
|
| 14 |
+
API_KEY = st.secrets["OPENAI_API_KEY"]
|
| 15 |
except:
|
| 16 |
API_KEY = "" # Will be prompted to enter API key if not in secrets
|
| 17 |
|
|
|
|
| 21 |
if "api_key" not in st.session_state:
|
| 22 |
st.session_state["api_key"] = API_KEY
|
| 23 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 24 |
# Function to encode image to base64
|
| 25 |
def encode_image(image):
|
| 26 |
# Convert RGBA to RGB if needed
|
|
|
|
| 48 |
{"type": "text", "text": f"Analyze these home photos and recommend improvements to maximize value for a {property_type} in the {price_range} range. The owner plans to sell within {timeframe}. {additional_details}"}
|
| 49 |
]
|
| 50 |
|
| 51 |
+
# Add images to the message with proper format for GPT-4o
|
| 52 |
for img in images:
|
| 53 |
base64_img = encode_image(img)
|
| 54 |
content.append({
|
| 55 |
"type": "image_url",
|
| 56 |
"image_url": {
|
| 57 |
+
"url": f"data:image/jpeg;base64,{base64_img}",
|
| 58 |
+
"detail": "low" # Use low detail to reduce token usage
|
| 59 |
}
|
| 60 |
})
|
| 61 |
|
|
|
|
| 76 |
For each recommendation, explain the potential value impact and approximate ROI.
|
| 77 |
Be specific based on what you can see in the photos.
|
| 78 |
Avoid generic advice - focus on what's visible in the images provided.
|
| 79 |
+
|
| 80 |
+
Always add the following text to the beginning of your response:
|
| 81 |
+
'Here are your personalized home improvement recommendations! If you found this tool helpful, visit www.myeverydayai.com to see more AI tools like this that can help with your real estate needs!'
|
| 82 |
"""
|
| 83 |
},
|
| 84 |
{
|
|
|
|
| 94 |
status.write("Sending images to AI service...")
|
| 95 |
response = requests.post(API_URL, headers=headers, json=payload, timeout=60)
|
| 96 |
|
| 97 |
+
# Debug information
|
| 98 |
+
st.write(f"Status code: {response.status_code}")
|
| 99 |
+
|
| 100 |
if response.status_code == 200:
|
| 101 |
status.update(label="Analysis complete!", state="complete")
|
| 102 |
return response.json()["choices"][0]["message"]["content"]
|
| 103 |
else:
|
| 104 |
status.update(label="Error in analysis", state="error")
|
| 105 |
+
error_text = f"API Error: {response.status_code}"
|
| 106 |
+
if response.text:
|
| 107 |
+
try:
|
| 108 |
+
error_json = response.json()
|
| 109 |
+
if "error" in error_json:
|
| 110 |
+
error_text += f" - {error_json['error']['message']}"
|
| 111 |
+
except:
|
| 112 |
+
error_text += f" - {response.text[:200]}"
|
| 113 |
+
st.error(error_text)
|
| 114 |
+
return f"Error: {error_text}. Please check your API key and try again."
|
| 115 |
except Exception as e:
|
| 116 |
st.error(f"Error: {str(e)}")
|
| 117 |
return f"Error: {str(e)}"
|
|
|
|
| 119 |
# Main application
|
| 120 |
st.title("Home Value Maximizer 🏡")
|
| 121 |
|
| 122 |
+
# Custom CSS for better appearance
|
| 123 |
+
st.markdown("""
|
| 124 |
+
<style>
|
| 125 |
+
.main .block-container {padding-bottom: 5rem !important; max-width: 100% !important;}
|
| 126 |
+
@media (max-width: 640px) {
|
| 127 |
+
.main .block-container {padding: 1rem 0.5rem !important;}
|
| 128 |
+
h1 {font-size: 1.5rem !important;}
|
| 129 |
+
h2, h3 {font-size: 1.2rem !important;}
|
| 130 |
+
.stButton button {width: 100% !important; height: 3rem !important;}
|
| 131 |
+
}
|
| 132 |
+
</style>
|
| 133 |
+
""", unsafe_allow_html=True)
|
| 134 |
+
|
| 135 |
# API Key input if not in secrets
|
| 136 |
if not st.session_state["api_key"]:
|
| 137 |
st.session_state["api_key"] = st.text_input("Enter your OpenAI API Key", type="password")
|