Spaces:
Sleeping
Sleeping
Update app.py
Browse files
app.py
CHANGED
@@ -1,17 +1,15 @@
|
|
1 |
# === IMPORTS ===
|
|
|
2 |
import streamlit as st
|
3 |
from PIL import Image
|
4 |
-
import
|
5 |
from pathlib import Path
|
6 |
import io
|
7 |
|
8 |
-
# β
1. Page Configuration
|
9 |
st.set_page_config(page_title="AI Architecture Assistant", layout="centered")
|
10 |
|
11 |
-
# β
2.
|
12 |
-
openai.api_key = st.secrets["OPENAI_API_KEY"]
|
13 |
-
|
14 |
-
# β
3. Inline custom CSS with Poppins font and olive green theme
|
15 |
st.markdown("""
|
16 |
<style>
|
17 |
@import url('https://fonts.googleapis.com/css2?family=Poppins:wght@300;500;700&display=swap');
|
@@ -21,6 +19,7 @@ st.markdown("""
|
|
21 |
color: #1e1e1e;
|
22 |
padding: 1rem;
|
23 |
}
|
|
|
24 |
h1 {
|
25 |
font-family: 'Poppins', sans-serif;
|
26 |
color: #3a5a40 !important;
|
@@ -33,6 +32,7 @@ h2, h3 {
|
|
33 |
font-weight: 600;
|
34 |
font-size: 1.4rem;
|
35 |
}
|
|
|
36 |
.stTextInput input, .stTextArea textarea {
|
37 |
background-color: #ffffff !important;
|
38 |
color: #1e1e1e !important;
|
@@ -42,6 +42,7 @@ h2, h3 {
|
|
42 |
font-size: 1rem;
|
43 |
font-family: 'Poppins', sans-serif;
|
44 |
}
|
|
|
45 |
.stButton > button {
|
46 |
background-color: #588157;
|
47 |
color: white;
|
@@ -58,6 +59,7 @@ h2, h3 {
|
|
58 |
background-color: #3a5a40;
|
59 |
box-shadow: 0 4px 10px rgba(0,0,0,0.15);
|
60 |
}
|
|
|
61 |
a {
|
62 |
color: #3a5a40;
|
63 |
font-family: 'Poppins', sans-serif;
|
@@ -71,17 +73,25 @@ a:hover {
|
|
71 |
</style>
|
72 |
""", unsafe_allow_html=True)
|
73 |
|
74 |
-
|
|
|
75 |
try:
|
76 |
logo = Image.open("ThinkTiny.jpg")
|
77 |
st.image(logo, width=300)
|
78 |
except FileNotFoundError:
|
79 |
st.warning("Logo not found. Please ensure 'ThinkTiny.jpg' is in the same folder as app.py.")
|
80 |
|
|
|
|
|
|
|
|
|
|
|
81 |
# β
5. Session Setup
|
82 |
if "prompt" not in st.session_state:
|
83 |
st.session_state.prompt = ""
|
84 |
|
|
|
|
|
85 |
sample_prompt = (
|
86 |
"A highly detailed, realistic architectural floor plan for a modern tiny home. "
|
87 |
"The design features an open-concept layout with a multi-functional living space "
|
@@ -91,10 +101,13 @@ sample_prompt = (
|
|
91 |
"with subtle accents. Annotate key dimensions and furniture placements. Professional architectural rendering style."
|
92 |
)
|
93 |
|
94 |
-
|
|
|
|
|
95 |
st.caption("Design smarter. Visualize faster. Build better.")
|
96 |
|
97 |
-
|
|
|
98 |
st.text_area("Prompt", key="prompt_input", value=st.session_state.prompt, height=200)
|
99 |
|
100 |
col1, col2 = st.columns(2)
|
@@ -104,22 +117,24 @@ with col1:
|
|
104 |
st.rerun()
|
105 |
|
106 |
st.session_state.prompt = st.session_state.prompt_input
|
|
|
107 |
st.text_area("Current Prompt Being Used", st.session_state.prompt, height=200, disabled=True)
|
108 |
|
109 |
-
|
|
|
110 |
|
111 |
if st.button("Generate Image"):
|
112 |
if st.session_state.prompt.strip():
|
113 |
with st.spinner("Generating image..."):
|
114 |
try:
|
115 |
-
response =
|
116 |
model="dall-e-3",
|
117 |
prompt=st.session_state.prompt,
|
118 |
size="1024x1024",
|
119 |
quality="standard",
|
120 |
n=1
|
121 |
)
|
122 |
-
image_url = response
|
123 |
st.image(image_url, caption="Generated Floor Plan", use_column_width=True)
|
124 |
st.markdown(f"[Download Image]({image_url})", unsafe_allow_html=True)
|
125 |
except Exception as e:
|
@@ -127,7 +142,8 @@ if st.button("Generate Image"):
|
|
127 |
else:
|
128 |
st.warning("Please enter a valid prompt.")
|
129 |
|
130 |
-
|
|
|
131 |
|
132 |
if st.button("Get Material Recommendations"):
|
133 |
if st.session_state.prompt.strip():
|
@@ -138,7 +154,8 @@ if st.button("Get Material Recommendations"):
|
|
138 |
"return a list of 5 to 10 building materials implied by the layout or concept. "
|
139 |
"Respond in clear, plain English using bullet points. Do not return JSON."
|
140 |
)
|
141 |
-
|
|
|
142 |
model="gpt-4",
|
143 |
messages=[
|
144 |
{"role": "system", "content": system_instruction},
|
@@ -147,13 +164,12 @@ if st.button("Get Material Recommendations"):
|
|
147 |
temperature=0.7
|
148 |
)
|
149 |
return response.choices[0].message.content.strip()
|
|
|
150 |
result = generate_material_recommendations(st.session_state.prompt)
|
151 |
st.markdown(result)
|
152 |
else:
|
153 |
st.warning("Please enter a prompt first.")
|
154 |
|
155 |
-
# More code continues below for costs, code comparison, etc. (unchanged structure, just update API calls as shown)
|
156 |
-
|
157 |
|
158 |
|
159 |
|
|
|
1 |
# === IMPORTS ===
|
2 |
+
|
3 |
import streamlit as st
|
4 |
from PIL import Image
|
5 |
+
from openai import OpenAI
|
6 |
from pathlib import Path
|
7 |
import io
|
8 |
|
9 |
+
# β
1. Page Configuration β MUST be first Streamlit command
|
10 |
st.set_page_config(page_title="AI Architecture Assistant", layout="centered")
|
11 |
|
12 |
+
# β
2. Inline custom CSS with Poppins font and olive green theme
|
|
|
|
|
|
|
13 |
st.markdown("""
|
14 |
<style>
|
15 |
@import url('https://fonts.googleapis.com/css2?family=Poppins:wght@300;500;700&display=swap');
|
|
|
19 |
color: #1e1e1e;
|
20 |
padding: 1rem;
|
21 |
}
|
22 |
+
/* Headings */
|
23 |
h1 {
|
24 |
font-family: 'Poppins', sans-serif;
|
25 |
color: #3a5a40 !important;
|
|
|
32 |
font-weight: 600;
|
33 |
font-size: 1.4rem;
|
34 |
}
|
35 |
+
/* Inputs */
|
36 |
.stTextInput input, .stTextArea textarea {
|
37 |
background-color: #ffffff !important;
|
38 |
color: #1e1e1e !important;
|
|
|
42 |
font-size: 1rem;
|
43 |
font-family: 'Poppins', sans-serif;
|
44 |
}
|
45 |
+
/* Buttons */
|
46 |
.stButton > button {
|
47 |
background-color: #588157;
|
48 |
color: white;
|
|
|
59 |
background-color: #3a5a40;
|
60 |
box-shadow: 0 4px 10px rgba(0,0,0,0.15);
|
61 |
}
|
62 |
+
/* Links */
|
63 |
a {
|
64 |
color: #3a5a40;
|
65 |
font-family: 'Poppins', sans-serif;
|
|
|
73 |
</style>
|
74 |
""", unsafe_allow_html=True)
|
75 |
|
76 |
+
|
77 |
+
# β
3. Logo Display (must come after styling)
|
78 |
try:
|
79 |
logo = Image.open("ThinkTiny.jpg")
|
80 |
st.image(logo, width=300)
|
81 |
except FileNotFoundError:
|
82 |
st.warning("Logo not found. Please ensure 'ThinkTiny.jpg' is in the same folder as app.py.")
|
83 |
|
84 |
+
|
85 |
+
# β
4. Connect to OpenAI
|
86 |
+
client = OpenAI(api_key=st.secrets["OPENAI_API_KEY"])
|
87 |
+
|
88 |
+
|
89 |
# β
5. Session Setup
|
90 |
if "prompt" not in st.session_state:
|
91 |
st.session_state.prompt = ""
|
92 |
|
93 |
+
|
94 |
+
# β
6. Sample Prompt
|
95 |
sample_prompt = (
|
96 |
"A highly detailed, realistic architectural floor plan for a modern tiny home. "
|
97 |
"The design features an open-concept layout with a multi-functional living space "
|
|
|
101 |
"with subtle accents. Annotate key dimensions and furniture placements. Professional architectural rendering style."
|
102 |
)
|
103 |
|
104 |
+
|
105 |
+
# === UI START ===
|
106 |
+
st.title("π AI Architecture Assistant")
|
107 |
st.caption("Design smarter. Visualize faster. Build better.")
|
108 |
|
109 |
+
# === 1. Prompt Input ===
|
110 |
+
st.markdown("### βοΈ Enter Your Floor Plan Prompt")
|
111 |
st.text_area("Prompt", key="prompt_input", value=st.session_state.prompt, height=200)
|
112 |
|
113 |
col1, col2 = st.columns(2)
|
|
|
117 |
st.rerun()
|
118 |
|
119 |
st.session_state.prompt = st.session_state.prompt_input
|
120 |
+
|
121 |
st.text_area("Current Prompt Being Used", st.session_state.prompt, height=200, disabled=True)
|
122 |
|
123 |
+
# === 2. Generate Image ===
|
124 |
+
st.markdown("### πΌοΈ Generate a Floor Plan Image")
|
125 |
|
126 |
if st.button("Generate Image"):
|
127 |
if st.session_state.prompt.strip():
|
128 |
with st.spinner("Generating image..."):
|
129 |
try:
|
130 |
+
response = client.images.generate(
|
131 |
model="dall-e-3",
|
132 |
prompt=st.session_state.prompt,
|
133 |
size="1024x1024",
|
134 |
quality="standard",
|
135 |
n=1
|
136 |
)
|
137 |
+
image_url = response.data[0].url
|
138 |
st.image(image_url, caption="Generated Floor Plan", use_column_width=True)
|
139 |
st.markdown(f"[Download Image]({image_url})", unsafe_allow_html=True)
|
140 |
except Exception as e:
|
|
|
142 |
else:
|
143 |
st.warning("Please enter a valid prompt.")
|
144 |
|
145 |
+
# === 3. Recommend Materials ===
|
146 |
+
st.markdown("### π§± Recommended Building Materials")
|
147 |
|
148 |
if st.button("Get Material Recommendations"):
|
149 |
if st.session_state.prompt.strip():
|
|
|
154 |
"return a list of 5 to 10 building materials implied by the layout or concept. "
|
155 |
"Respond in clear, plain English using bullet points. Do not return JSON."
|
156 |
)
|
157 |
+
|
158 |
+
response = client.chat.completions.create(
|
159 |
model="gpt-4",
|
160 |
messages=[
|
161 |
{"role": "system", "content": system_instruction},
|
|
|
164 |
temperature=0.7
|
165 |
)
|
166 |
return response.choices[0].message.content.strip()
|
167 |
+
|
168 |
result = generate_material_recommendations(st.session_state.prompt)
|
169 |
st.markdown(result)
|
170 |
else:
|
171 |
st.warning("Please enter a prompt first.")
|
172 |
|
|
|
|
|
173 |
|
174 |
|
175 |
|