tamilprabaharan commited on
Commit
4ca3484
·
verified ·
1 Parent(s): df01b82

Create app.py

Browse files
Files changed (1) hide show
  1. app.py +316 -0
app.py ADDED
@@ -0,0 +1,316 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ import streamlit as st
2
+ import os
3
+ import re
4
+ from datetime import datetime
5
+ import json
6
+ from openai import AzureOpenAI
7
+ from dotenv import load_dotenv
8
+
9
+ # Load environment variables
10
+ load_dotenv()
11
+
12
+
13
+ # For Hugging Face Spaces
14
+ if 'AZURE_OPENAI_API_KEY' in os.environ:
15
+ api_key = os.environ['AZURE_OPENAI_API_KEY']
16
+ endpoint = os.environ['AZURE_OPENAI_ENDPOINT']
17
+ else:
18
+ # Fall back to dotenv for local development
19
+ from dotenv import load_dotenv
20
+ load_dotenv()
21
+ api_key = os.getenv("AZURE_OPENAI_API_KEY")
22
+ endpoint = os.getenv("AZURE_OPENAI_ENDPOINT")
23
+
24
+ # Configure Azure OpenAI client
25
+ client = AzureOpenAI(
26
+ api_key=api_key,
27
+ api_version="2024-02-15-preview",
28
+ azure_endpoint=endpoint
29
+ )
30
+
31
+ # Set page configuration
32
+ st.set_page_config(
33
+ page_title="CSR Initiative Portal",
34
+ page_icon="🌱",
35
+ layout="wide"
36
+ )
37
+
38
+ # CSS to improve UI
39
+ st.markdown("""
40
+ <style>
41
+ .main {
42
+ padding: 2rem;
43
+ }
44
+ .stButton>button {
45
+ width: 100%;
46
+ margin-top: 10px;
47
+ }
48
+ .title {
49
+ text-align: center;
50
+ margin-bottom: 30px;
51
+ }
52
+ .form-section {
53
+ background-color: #f8f9fa;
54
+ padding: 20px;
55
+ border-radius: 10px;
56
+ margin-bottom: 20px;
57
+ }
58
+ </style>
59
+ """, unsafe_allow_html=True)
60
+
61
+ # Title
62
+ st.markdown("<h1 class='title'>CSR Initiative Portal</h1>", unsafe_allow_html=True)
63
+
64
+ # List of beneficiary groups
65
+ beneficiary_groups = [
66
+ "Supporting next generation",
67
+ "Impact entrepreneurs",
68
+ "Environment sustainability",
69
+ "Disaster response"
70
+ ]
71
+
72
+ def extract_json_from_text(text):
73
+ """
74
+ Extracts JSON from text that might contain other content.
75
+ """
76
+ # Try to find JSON pattern with regex first
77
+ json_pattern = r'({[\s\S]*})'
78
+ matches = re.search(json_pattern, text)
79
+
80
+ if matches:
81
+ json_text = matches.group(1)
82
+ try:
83
+ return json.loads(json_text)
84
+ except:
85
+ pass
86
+
87
+ # If regex extraction fails, try cleaning the text directly
88
+ text = text.strip()
89
+
90
+ # If the text starts with markdown code block, remove it
91
+ if text.startswith('```json'):
92
+ text = text[7:]
93
+ elif text.startswith('```'):
94
+ text = text[3:]
95
+
96
+ # If the text ends with markdown code block, remove it
97
+ if text.endswith('```'):
98
+ text = text[:-3]
99
+
100
+ # Try to find the start of the JSON object if there's other text before it
101
+ if not text.startswith('{'):
102
+ try:
103
+ start_idx = text.index('{')
104
+ text = text[start_idx:]
105
+ except ValueError:
106
+ return None
107
+
108
+ # Try to find the end of the JSON object if there's other text after it
109
+ if not text.endswith('}'):
110
+ try:
111
+ end_idx = text.rindex('}')
112
+ text = text[:end_idx+1]
113
+ except ValueError:
114
+ return None
115
+
116
+ # Try to parse the cleaned text
117
+ try:
118
+ return json.loads(text)
119
+ except json.JSONDecodeError as e:
120
+ st.error(f"JSON parsing error: {str(e)}")
121
+ return None
122
+
123
+ def analyze_initiative_with_ai(description):
124
+ """
125
+ Use Azure OpenAI to analyze initiative description and extract fields
126
+ """
127
+ system_prompt = """
128
+ You are an AI assistant for a CSR portal. Analyze the initiative description and extract the following fields accurately:
129
+
130
+ 1. Initiative Name (create a concise, descriptive name)
131
+ 2. Date (extract start and end dates)
132
+ 3. Location (extract location)
133
+ 4. Who will be working with and who will the initiative help? (2-line description)
134
+ 5. What will the participant be doing? (2-line description)
135
+ 6. How does the initiative align with focus areas and how will it change lives? (2-line description)
136
+ 7. Role Name (extract or suggest an appropriate role)
137
+ 8. Role Description (2-line description)
138
+ 9. Start date (in format YYYY-MM-DD)
139
+ 10. End date (in format YYYY-MM-DD)
140
+ 11. Deadline date (in format YYYY-MM-DD)
141
+ 12. Beneficiary group (select ONE from: Supporting next generation, Impact entrepreneurs, Environment sustainability, Disaster response)
142
+
143
+ Format your response as JSON with exact keys corresponding to the field names above.
144
+ IMPORTANT: Provide ONLY the JSON object with no additional text before or after.
145
+ """
146
+
147
+ try:
148
+ # Using the new OpenAI API format
149
+ response = client.chat.completions.create(
150
+ model="gpt-4o-mini", # Adjust to your deployed model name
151
+ messages=[
152
+ {"role": "system", "content": system_prompt},
153
+ {"role": "user", "content": description}
154
+ ],
155
+ temperature=0.3,
156
+ max_tokens=1000,
157
+ response_format={"type": "json_object"} # Request JSON formatted response
158
+ )
159
+
160
+ # Extract the generated text
161
+ result = response.choices[0].message.content
162
+
163
+ # Parse the JSON with our robust function
164
+ parsed_result = extract_json_from_text(result)
165
+
166
+ if parsed_result:
167
+ return parsed_result
168
+ else:
169
+ st.error("Failed to parse AI response into a valid JSON format.")
170
+ return None
171
+ except Exception as e:
172
+ st.error(f"Error analyzing initiative: {str(e)}")
173
+ return None
174
+
175
+ # Initialize session state for form fields if they don't exist
176
+ if 'initiative_name' not in st.session_state:
177
+ st.session_state.initiative_name = ""
178
+ if 'date' not in st.session_state:
179
+ st.session_state.date = ""
180
+ if 'location' not in st.session_state:
181
+ st.session_state.location = ""
182
+ if 'owner' not in st.session_state:
183
+ st.session_state.owner = "Prabaharan S"
184
+ if 'working_with' not in st.session_state:
185
+ st.session_state.working_with = ""
186
+ if 'participant_doing' not in st.session_state:
187
+ st.session_state.participant_doing = ""
188
+ if 'alignment' not in st.session_state:
189
+ st.session_state.alignment = ""
190
+ if 'role_name' not in st.session_state:
191
+ st.session_state.role_name = ""
192
+ if 'role_description' not in st.session_state:
193
+ st.session_state.role_description = ""
194
+ if 'start_date' not in st.session_state:
195
+ st.session_state.start_date = None
196
+ if 'end_date' not in st.session_state:
197
+ st.session_state.end_date = None
198
+ if 'deadline_date' not in st.session_state:
199
+ st.session_state.deadline_date = None
200
+ if 'beneficiary_group' not in st.session_state:
201
+ st.session_state.beneficiary_group = beneficiary_groups[0]
202
+
203
+ # Create two columns for layout
204
+ col1, col2 = st.columns([1, 1])
205
+
206
+ with col1:
207
+ st.markdown("<div class='form-section'>", unsafe_allow_html=True)
208
+ st.subheader("Create with AI")
209
+
210
+ # Text area for the initiative description
211
+ initiative_description = st.text_area(
212
+ "Enter a detailed description of your initiative",
213
+ height=300,
214
+ placeholder="Describe your initiative in detail. Include information about dates, location, activities, beneficiaries, and goals."
215
+ )
216
+
217
+ # Button to trigger AI analysis
218
+ if st.button("Generate with AI", key="generate_button"):
219
+ if initiative_description:
220
+ with st.spinner("Analyzing your initiative..."):
221
+ result = analyze_initiative_with_ai(initiative_description)
222
+
223
+ if result:
224
+ # For debugging: Show raw JSON
225
+ st.write("Debug - Generated JSON:", result)
226
+
227
+ # Update the session state with AI-generated content
228
+ st.session_state.initiative_name = result.get("Initiative Name", "")
229
+ st.session_state.date = result.get("Date", "")
230
+ st.session_state.location = result.get("Location", "")
231
+ st.session_state.working_with = result.get("Who will be working with and who will the initiative help?", "")
232
+ st.session_state.participant_doing = result.get("What will the participant be doing?", "")
233
+ st.session_state.alignment = result.get("How does the initiative align with focus areas and how will it change lives?", "")
234
+ st.session_state.role_name = result.get("Role Name", "")
235
+ st.session_state.role_description = result.get("Role Description", "")
236
+
237
+ # Handle dates
238
+ try:
239
+ start_date_str = result.get("Start date", "")
240
+ if start_date_str:
241
+ st.session_state.start_date = datetime.strptime(start_date_str, "%Y-%m-%d").date()
242
+ except Exception as e:
243
+ st.warning(f"Could not parse start date: {start_date_str}. Error: {str(e)}")
244
+
245
+ try:
246
+ end_date_str = result.get("End date", "")
247
+ if end_date_str:
248
+ st.session_state.end_date = datetime.strptime(end_date_str, "%Y-%m-%d").date()
249
+ except Exception as e:
250
+ st.warning(f"Could not parse end date: {end_date_str}. Error: {str(e)}")
251
+
252
+ try:
253
+ deadline_date_str = result.get("Deadline date", "")
254
+ if deadline_date_str:
255
+ st.session_state.deadline_date = datetime.strptime(deadline_date_str, "%Y-%m-%d").date()
256
+ except Exception as e:
257
+ st.warning(f"Could not parse deadline date: {deadline_date_str}. Error: {str(e)}")
258
+
259
+ # Handle beneficiary group
260
+ predicted_beneficiary = result.get("Beneficiary group", "")
261
+ if predicted_beneficiary in beneficiary_groups:
262
+ st.session_state.beneficiary_group = predicted_beneficiary
263
+
264
+ # Display success message
265
+ st.success("Initiative details generated successfully!")
266
+ st.rerun() # Rerun the app to update the form fields
267
+ else:
268
+ st.warning("Please enter a description of your initiative first.")
269
+
270
+ st.markdown("</div>", unsafe_allow_html=True)
271
+
272
+ with col2:
273
+ st.markdown("<div class='form-section'>", unsafe_allow_html=True)
274
+ st.subheader("Initiative Details")
275
+
276
+ # Form for user to input initiative details manually
277
+ initiative_name = st.text_input("Initiative Name", value=st.session_state.initiative_name)
278
+ date = st.text_input("Date", value=st.session_state.date)
279
+ location = st.text_input("Location", value=st.session_state.location)
280
+ owner = st.text_input("Owner", value=st.session_state.owner)
281
+
282
+ working_with = st.text_area("Who will be working with and who will the initiative help?",
283
+ value=st.session_state.working_with, height=100)
284
+ participant_doing = st.text_area("What will the participant be doing?",
285
+ value=st.session_state.participant_doing, height=100)
286
+ alignment = st.text_area("How does your initiative align with our focus areas and how will it change lives?",
287
+ value=st.session_state.alignment, height=100)
288
+
289
+ role_name = st.text_input("Role Name", value=st.session_state.role_name)
290
+ role_description = st.text_area("Role Description", value=st.session_state.role_description, height=100)
291
+
292
+ start_date = st.date_input("Start Date", value=st.session_state.start_date)
293
+ end_date = st.date_input("End Date", value=st.session_state.end_date)
294
+ deadline_date = st.date_input("Deadline Date", value=st.session_state.deadline_date)
295
+
296
+ beneficiary_group = st.selectbox("Beneficiary Group", options=beneficiary_groups,
297
+ index=beneficiary_groups.index(st.session_state.beneficiary_group)
298
+ if st.session_state.beneficiary_group in beneficiary_groups else 0)
299
+
300
+ st.markdown("</div>", unsafe_allow_html=True)
301
+
302
+ # Submit button
303
+ col1, col2, col3 = st.columns([1, 2, 1])
304
+ with col2:
305
+ if st.button("Submit Initiative", key="submit_button"):
306
+ # Here you would add code to save the initiative to your database
307
+ st.success("✅ Initiative created successfully!")
308
+ # Clear form or redirect
309
+
310
+ # Add footer
311
+ st.markdown("""
312
+ ---
313
+ <div style="text-align: center; color: grey; font-size: 12px;">
314
+ CSR Initiative Portal powered by Azure OpenAI - © 2025
315
+ </div>
316
+ """, unsafe_allow_html=True)