RozzaCreat commited on
Commit
e2cd30d
·
verified ·
1 Parent(s): 48e8d35

Update app.py

Browse files
Files changed (1) hide show
  1. app.py +107 -392
app.py CHANGED
@@ -1,358 +1,123 @@
1
- import gradio as gr
2
- import requests
3
- import json
4
- import datetime
5
- import re
6
- from bs4 import BeautifulSoup
7
- from typing import Optional, Dict, Any
8
- from urllib.parse import quote, urljoin
9
-
10
- class ShabbatCandleLightingAgent:
11
- """
12
- AI Agent for finding Shabbat candle lighting times worldwide using Chabad.org
13
- """
14
 
15
- def __init__(self):
16
- self.base_url = "https://www.chabad.org"
17
- self.candle_lighting_url = "https://www.chabad.org/calendar/candlelighting_cdo/aid/6226/jewish/Accurate-Shabbat-Candle-Lighting-Times.htm"
18
 
19
- def search_city_on_chabad(self, city_name: str) -> Optional[str]:
20
- """
21
- Search for a city on Chabad.org and get the specific URL for candle lighting times
22
- """
23
- try:
24
- # Clean and format city name
25
- city_clean = city_name.strip()
26
- search_query = quote(city_clean)
27
-
28
- headers = {
29
- 'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/120.0.0.0 Safari/537.36',
30
- 'Accept': 'text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,*/*;q=0.8',
31
- 'Accept-Language': 'en-US,en;q=0.5',
32
- 'Accept-Encoding': 'gzip, deflate',
33
- 'Connection': 'keep-alive',
34
- 'Upgrade-Insecure-Requests': '1'
35
- }
36
-
37
- # Try different search approaches for Chabad.org
38
- search_strategies = [
39
- # Direct city page approach
40
- f"https://www.chabad.org/calendar/candlelighting_cdo/jewish/{search_query}.htm",
41
- # Search with city parameter
42
- f"https://www.chabad.org/calendar/candlelighting_cdo/aid/6226/jewish/Accurate-Shabbat-Candle-Lighting-Times.htm?city={search_query}",
43
- # Alternative format
44
- f"https://www.chabad.org/calendar/candlelighting_cdo/aid/6226/jewish/Candle-Lighting-Times-{search_query}.htm",
45
- # General search
46
- f"https://www.chabad.org/calendar/candlelighting_cdo/aid/6226/jewish/Accurate-Shabbat-Candle-Lighting-Times.htm"
47
- ]
48
-
49
- for url in search_strategies:
50
- try:
51
- response = requests.get(url, headers=headers, timeout=15)
52
- if response.status_code == 200:
53
- # Check if the response contains candle lighting information
54
- content_lower = response.text.lower()
55
- if any(keyword in content_lower for keyword in ['candle lighting', 'light candles', 'shabbat', 'friday']):
56
- return url
57
- except Exception as e:
58
- print(f"Failed to fetch {url}: {e}")
59
- continue
60
-
61
- # Try POST request to the main search page
62
- try:
63
- post_data = {
64
- 'city': city_clean,
65
- 'submit': 'Get Times'
66
- }
67
- response = requests.post(self.candle_lighting_url, data=post_data, headers=headers, timeout=15)
68
- if response.status_code == 200 and 'candle lighting' in response.text.lower():
69
- return response.url
70
- except Exception as e:
71
- print(f"POST request failed: {e}")
72
-
73
- except Exception as e:
74
- print(f"City search error: {e}")
75
 
76
- return self.candle_lighting_url # Return main page as fallback
77
-
78
- def extract_candle_lighting_times(self, html_content: str, city_name: str) -> Dict[str, Any]:
79
- """
80
- Extract candle lighting times from Chabad.org HTML content using multiple strategies
81
- """
82
- try:
83
- soup = BeautifulSoup(html_content, 'html.parser')
84
- text = soup.get_text().lower()
85
-
86
- # Multiple patterns to find candle lighting times
87
- candle_patterns = [
88
- r'candle\s+lighting[:\s]*(\d{1,2}:\d{2}(?:\s*[ap]m)?)',
89
- r'light\s+candles[:\s]*(\d{1,2}:\d{2}(?:\s*[ap]m)?)',
90
- r'friday[:\s]*(\d{1,2}:\d{2}(?:\s*[ap]m)?)',
91
- r'(\d{1,2}:\d{2}\s*[ap]m?)(?=.*candle)',
92
- r'(\d{1,2}:\d{2}\s*[ap]m?)(?=.*light)',
93
- r'(\d{1,2}:\d{2}\s*[ap]m?)(?=.*friday)'
94
- ]
95
-
96
- # Patterns for Havdalah times
97
- havdalah_patterns = [
98
- r'havdalah[:\s]*(\d{1,2}:\d{2}(?:\s*[ap]m)?)',
99
- r'saturday[:\s]*(\d{1,2}:\d{2}(?:\s*[ap]m)?)',
100
- r'(\d{1,2}:\d{2}\s*[ap]m?)(?=.*havdalah)',
101
- r'(\d{1,2}:\d{2}\s*[ap]m?)(?=.*saturday)'
102
- ]
103
-
104
- # Find candle lighting time
105
- candle_time = None
106
- for pattern in candle_patterns:
107
- match = re.search(pattern, text, re.IGNORECASE)
108
- if match:
109
- candle_time = match.group(1)
110
- break
111
-
112
- # Find Havdalah time
113
- havdalah_time = None
114
- for pattern in havdalah_patterns:
115
- match = re.search(pattern, text, re.IGNORECASE)
116
- if match:
117
- havdalah_time = match.group(1)
118
- break
119
-
120
- # Look for times in common HTML elements
121
- if not candle_time or not havdalah_time:
122
- # Check for time elements with specific classes or IDs
123
- time_selectors = [
124
- '[class*="time"]',
125
- '[class*="candle"]',
126
- '[class*="light"]',
127
- '[id*="time"]',
128
- '[id*="candle"]',
129
- 'td', 'span', 'div'
130
- ]
131
 
132
- for selector in time_selectors:
133
- elements = soup.select(selector)
134
- for element in elements:
135
- element_text = element.get_text().strip()
136
- time_match = re.search(r'\d{1,2}:\d{2}(?:\s*[ap]m)?', element_text, re.IGNORECASE)
137
- if time_match:
138
- time_found = time_match.group()
139
- if not candle_time and any(word in element_text.lower() for word in ['candle', 'light', 'friday']):
140
- candle_time = time_found
141
- elif not havdalah_time and any(word in element_text.lower() for word in ['havdalah', 'saturday']):
142
- havdalah_time = time_found
143
-
144
- # Calculate current Shabbat dates
145
- now = datetime.datetime.now()
146
- days_until_friday = (4 - now.weekday()) % 7
147
- if days_until_friday == 0 and now.hour >= 18: # If it's Friday evening, get next Friday
148
- days_until_friday = 7
149
-
150
- friday = now + datetime.timedelta(days=days_until_friday)
151
- saturday = friday + datetime.timedelta(days=1)
152
-
153
- return {
154
- 'city': city_name,
155
- 'candle_lighting_time': candle_time,
156
- 'havdalah_time': havdalah_time,
157
- 'friday_date': friday.strftime('%B %d, %Y'),
158
- 'saturday_date': saturday.strftime('%B %d, %Y'),
159
- 'found_data': bool(candle_time or havdalah_time),
160
- 'search_successful': True
161
- }
162
-
163
- except Exception as e:
164
- print(f"Time extraction error: {e}")
165
- return {
166
- 'city': city_name,
167
- 'candle_lighting_time': None,
168
- 'havdalah_time': None,
169
- 'friday_date': None,
170
- 'saturday_date': None,
171
- 'found_data': False,
172
- 'search_successful': False,
173
- 'error': str(e)
174
- }
175
-
176
- def get_backup_times(self, city_name: str) -> Optional[Dict[str, Any]]:
177
- """
178
- Try alternative sources for Shabbat times when Chabad.org fails
179
- """
180
- try:
181
- # Alternative Jewish calendar websites
182
- backup_urls = [
183
- f"https://www.hebcal.com/shabbat?city={quote(city_name)}",
184
- f"https://www.myzmanim.com/search.aspx?city={quote(city_name)}"
185
- ]
186
-
187
- headers = {
188
- 'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/120.0.0.0 Safari/537.36'
189
- }
190
-
191
- for url in backup_urls:
192
- try:
193
- response = requests.get(url, headers=headers, timeout=10)
194
- if response.status_code == 200:
195
- times = self.extract_candle_lighting_times(response.text, city_name)
196
- if times.get('found_data'):
197
- times['source'] = 'backup'
198
- return times
199
- except Exception as e:
200
- print(f"Backup source {url} failed: {e}")
201
- continue
202
-
203
- except Exception as e:
204
- print(f"Backup sources error: {e}")
205
 
206
- return None
207
-
208
- def get_shabbat_times(self, city_input: str = "") -> str:
209
- """
210
- Main function to get Shabbat candle lighting times
211
- """
212
- try:
213
- city_name = city_input.strip()
214
-
215
- if not city_name:
216
- return self._format_error_response("❌ Please enter a city name to search for Shabbat times.")
 
 
 
 
 
 
 
 
 
 
 
 
 
 
217
 
218
- # Search Chabad.org for the city
219
- print(f"🔍 Searching for Shabbat times in: {city_name}")
220
- city_url = self.search_city_on_chabad(city_name)
 
 
221
 
222
- result_data = None
223
- source = "Chabad.org"
 
 
 
224
 
225
- if city_url:
226
- try:
227
- headers = {
228
- 'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/120.0.0.0 Safari/537.36'
229
- }
230
- response = requests.get(city_url, headers=headers, timeout=15)
231
-
232
- if response.status_code == 200:
233
- result_data = self.extract_candle_lighting_times(response.text, city_name)
234
- print(f"📊 Extraction result: {result_data}")
235
-
236
- except Exception as e:
237
- print(f"❌ Chabad.org fetch error: {e}")
238
 
239
- # Try backup sources if Chabad.org didn't work well
240
- if not result_data or not result_data.get('found_data'):
241
- print("🔄 Trying backup sources...")
242
- backup_data = self.get_backup_times(city_name)
243
- if backup_data and backup_data.get('found_data'):
244
- result_data = backup_data
245
- source = "Alternative Jewish calendar source"
246
 
247
- # Format and return the response
248
- if result_data and result_data.get('found_data'):
249
- return self._format_success_response(result_data, source, city_url)
250
- else:
251
- return self._format_not_found_response(city_name, city_url)
252
-
253
- except Exception as e:
254
- print(f"Main function error: {e}")
255
- return self._format_error_response(f"❌ An error occurred: {str(e)}")
256
-
257
- def _format_success_response(self, data: Dict[str, Any], source: str, url: str = None) -> str:
258
- """Format successful response with Shabbat times"""
259
- candle_time = data.get('candle_lighting_time', 'Not found')
260
- havdalah_time = data.get('havdalah_time', 'Not found')
261
 
262
- response = f"""
263
- # 🕯️ Shabbat Candle Lighting Times
264
-
265
- ## 📍 Location: {data.get('city', 'Unknown')}
266
-
267
- ### 🕯️ **Candle Lighting (Friday)**
268
- **Time:** {candle_time}
269
- **Date:** {data.get('friday_date', 'This Friday')}
270
-
271
- ### ⭐ **Havdalah (Saturday)**
272
- **Time:** {havdalah_time}
273
- **Date:** {data.get('saturday_date', 'This Saturday')}
274
-
275
- ---
276
-
277
- ## 📋 **Important Notes:**
278
- - 🕯️ Light Shabbat candles **18 minutes before sunset** on Friday
279
- - ⭐ Havdalah is performed after **3 stars appear** on Saturday night
280
- - 🌍 Times are specific to your geographic location
281
- - ⏰ Always verify times with your local rabbi or Jewish community
282
-
283
- ## 📚 **Source Information:**
284
- **Data from:** {source}
285
- **Retrieved:** {datetime.datetime.now().strftime('%B %d, %Y at %I:%M %p')}
286
- {f"**URL:** {url}" if url else ""}
287
-
288
- ---
289
-
290
- ## 🙏 **Shabbat Shalom!**
291
- *May your Shabbat be filled with peace, joy, and spiritual connection.*
292
-
293
- **🔔 Reminder:** Set an alarm 30 minutes before candle lighting time to prepare properly.
294
- """
295
- return response
296
 
297
- def _format_not_found_response(self, city_name: str, url: str = None) -> str:
298
- """Format response when times are not found"""
299
- return f"""
300
- # 🕯️ Shabbat Candle Lighting Times
301
-
302
- ## ❌ Times Not Found for {city_name}
303
-
304
- We searched multiple sources but couldn't find specific Shabbat candle lighting times for **{city_name}**.
305
-
306
- ### 🔍 **What you can try:**
307
- 1. **Check spelling** - Make sure the city name is spelled correctly
308
- 2. **Add country** - Try "City, Country" format (e.g., "Paris, France")
309
- 3. **Use major city** - Try the nearest major city instead
310
- 4. **Alternative spellings** - Try different variations of the city name
311
-
312
- ### 📍 **General Guidelines for {city_name}:**
313
- - 🕯️ **Candle lighting:** Typically 18 minutes before sunset on Friday
314
- - ⭐ **Havdalah:** Approximately 25-42 minutes after sunset on Saturday
315
- - 🌍 **Location matters:** Times vary significantly by geographic location
316
-
317
- ### 🌐 **Manual Resources:**
318
- - 📱 **Chabad.org:** [Direct search]({url or 'https://www.chabad.org/calendar/candlelighting_cdo/aid/6226/jewish/Accurate-Shabbat-Candle-Lighting-Times.htm'})
319
- - 📱 **Hebcal.com:** Alternative Jewish calendar
320
- - 📞 **Local contacts:** Your synagogue or Chabad house
321
-
322
- ### 📞 **Local Resources:**
323
- - Contact your local Chabad house or synagogue
324
- - Check with your Jewish community center
325
- - Consult your rabbi for precise local customs
326
-
327
- ---
328
 
329
- **Retrieved:** {datetime.datetime.now().strftime('%B %d, %Y at %I:%M %p')}
330
- """
 
331
 
332
- def _format_error_response(self, error_message: str) -> str:
333
- """Format error response"""
334
- return f"""
335
- # 🕯️ Shabbat Candle Lighting Times
336
-
337
- ## ⚠️ Error
338
-
339
- {error_message}
340
-
341
- ### 🔄 **Please try:**
342
- 1. **Refresh** and try again
343
- 2. **Check internet connection**
344
- 3. **Use a different city name**
345
- 4. **Visit Chabad.org directly:** [Candle Lighting Times](https://www.chabad.org/calendar/candlelighting_cdo/aid/6226/jewish/Accurate-Shabbat-Candle-Lighting-Times.htm)
346
-
347
- ### 📞 **Alternative:**
348
- Contact your local synagogue or Chabad house for accurate times.
349
-
350
- ---
351
-
352
- **Time:** {datetime.datetime.now().strftime('%B %d, %Y at %I:%M %p')}
353
- """
354
-
355
- def create_shabbat_interface():
356
  """Create the Gradio interface for the Shabbat Candle Lighting Agent"""
357
 
358
  agent = ShabbatCandleLightingAgent()
@@ -392,13 +157,6 @@ def create_shabbat_interface():
392
  - Add country for common city names (e.g., "Paris, France")
393
  - Try nearest major city if yours isn't found
394
  - Use English city names for best search results
395
-
396
- ### 🇮🇱 **Popular Israeli Cities:**
397
- Jerusalem, Tel Aviv, Haifa, Beer Sheva, Netanya, Ashdod,
398
- Petah Tikva, Ramat Gan, Bnei Brak, Herzliya
399
-
400
- ### 🌍 **International Examples:**
401
- London, UK • Paris, France • New York, USA • Toronto, Canada
402
  """)
403
 
404
  with gr.Column(scale=2):
@@ -409,62 +167,19 @@ def create_shabbat_interface():
409
 
410
  👆 **Enter your city name above and click 'Get Shabbat Times'**
411
 
412
- Or click one of the popular cities below for a quick search.
413
-
414
- ### 🇮🇱 **Common Israeli Cities:**
415
- Use any of these city names: Jerusalem, Tel Aviv, Haifa, Beer Sheva, Netanya, Ashdod
416
-
417
- ### 🌍 **International Cities:**
418
- Include country name: London, UK • Paris, France • New York, USA
419
-
420
  ---
421
 
422
  **🕯️ Every Friday evening, Jewish families around the world light candles to welcome Shabbat**
423
  """
424
  )
425
 
426
- # Example buttons for popular cities
427
- gr.Markdown("### 🌍 Quick Search - Popular Cities:")
428
-
429
- with gr.Row():
430
- # Israeli cities first for the detected user
431
- popular_cities = [
432
- "Jerusalem, Israel",
433
- "Tel Aviv, Israel",
434
- "Haifa, Israel",
435
- "Beer Sheva, Israel",
436
- "Netanya, Israel",
437
- "Ashdod, Israel",
438
- # International cities
439
- "New York, NY",
440
- "London, UK",
441
- "Paris, France",
442
- "Toronto, Canada",
443
- "Los Angeles, CA",
444
- "Miami, FL"
445
- ]
446
-
447
- example_btns = []
448
- for i in range(0, len(popular_cities), 4):
449
- with gr.Row():
450
- for city in popular_cities[i:i+4]:
451
- btn = gr.Button(f"📍 {city}", size="sm")
452
- example_btns.append((btn, city))
453
-
454
- # Button click handlers
455
  search_btn.click(
456
  fn=agent.get_shabbat_times,
457
  inputs=[city_input],
458
  outputs=output_area
459
  )
460
 
461
- # Example button handlers
462
- for btn, city in example_btns:
463
- btn.click(
464
- fn=lambda c=city: agent.get_shabbat_times(c),
465
- outputs=output_area
466
- )
467
-
468
  # Resources and information
469
  with gr.Accordion("📚 Resources & Information", open=False):
470
  gr.Markdown("""
 
1
+ def create_shabbat_interface():
2
+ """Create the Gradio interface for the Shabbat Candle Lighting Agent"""
 
 
 
 
 
 
 
 
 
 
 
3
 
4
+ agent = ShabbatCandleLightingAgent()
 
 
5
 
6
+ with gr.Blocks(title="🕯️ Shabbat Candle Lighting Times", theme=gr.themes.Soft()) as app:
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
7
 
8
+ gr.Markdown("""
9
+ # 🕯️ Shabbat Candle Lighting Times AI Agent
10
+
11
+ **Get accurate Shabbat candle lighting and Havdalah times for any city worldwide**
12
+
13
+ This AI agent searches Chabad.org and other reliable Jewish sources to find precise ritual times for your location.
14
+
15
+ ---
16
+ """)
17
+
18
+ with gr.Row():
19
+ with gr.Column(scale=1):
20
+ gr.Markdown("### 📍 Location Input")
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
21
 
22
+ city_input = gr.Textbox(
23
+ label="🏙️ City Name",
24
+ placeholder="Enter city name (e.g., 'New York', 'London, UK', 'Tel Aviv, Israel')",
25
+ info="Please enter your city name to get accurate Shabbat times",
26
+ lines=1
27
+ )
28
+
29
+ search_btn = gr.Button(
30
+ "🔍 Get Shabbat Times",
31
+ variant="primary",
32
+ size="lg"
33
+ )
34
+
35
+ gr.Markdown("""
36
+ ### 💡 **City Input Tips:**
37
+ - Use full city names for better results
38
+ - Add country for common city names (e.g., "Paris, France")
39
+ - Try nearest major city if yours isn't found
40
+ - Use English city names for best search results
41
+ """)
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
42
 
43
+ with gr.Column(scale=2):
44
+ output_area = gr.Markdown(
45
+ label="📋 Shabbat Times Results",
46
+ value="""
47
+ # 🕯️ Welcome!
48
+
49
+ 👆 **Enter your city name above and click 'Get Shabbat Times'**
50
+
51
+ ---
52
+
53
+ **🕯️ Every Friday evening, Jewish families around the world light candles to welcome Shabbat**
54
+ """
55
+ )
56
+
57
+ # Button click handler
58
+ search_btn.click(
59
+ fn=agent.get_shabbat_times,
60
+ inputs=[city_input],
61
+ outputs=output_area
62
+ )
63
+
64
+ # Resources and information
65
+ with gr.Accordion("📚 Resources & Information", open=False):
66
+ gr.Markdown("""
67
+ ### 🕯️ **About Shabbat Candle Lighting:**
68
 
69
+ **Candle Lighting Time:**
70
+ - Performed on Friday evening before sunset
71
+ - Typically 18 minutes before sunset (varies by community)
72
+ - Marks the beginning of Shabbat
73
+ - Usually done by the woman of the house
74
 
75
+ **Havdalah Time:**
76
+ - Performed on Saturday evening after sunset
77
+ - When three medium-sized stars are visible in the sky
78
+ - Marks the end of Shabbat
79
+ - Includes blessings over wine, spices, and candle
80
 
81
+ ### 🌐 **Data Sources:**
82
+ - **Primary:** [Chabad.org](https://www.chabad.org/calendar/candlelighting_cdo/aid/6226/jewish/Accurate-Shabbat-Candle-Lighting-Times.htm)
83
+ - **Backup:** Hebcal.com and other Jewish calendar sites
84
+ - **Method:** Intelligent web scraping with multiple fallback strategies
 
 
 
 
 
 
 
 
 
85
 
86
+ ### ⚠️ **Important Disclaimers:**
87
+ - Always consult your local rabbi for specific customs
88
+ - Times may vary based on local Jewish community practices
89
+ - This tool is for reference only - not a substitute for religious guidance
90
+ - Some communities light candles at different intervals before sunset
 
 
91
 
92
+ ### 🔧 **Technical Features:**
93
+ - Multiple search strategies for maximum success on Chabad.org
94
+ - Intelligent pattern matching to extract candle lighting times
95
+ - Fallback to alternative Jewish calendar sources if needed
96
+ - Manual city input for maximum accuracy and reliability
97
+ """)
 
 
 
 
 
 
 
 
98
 
99
+ gr.Markdown("""
100
+ ---
101
+
102
+ **🙏 Shabbat Shalom!** | Built with ❤️ for the global Jewish community
103
+
104
+ *For questions about Jewish law or local customs, please consult your rabbi or local Jewish community.*
105
+ """)
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
106
 
107
+ return app
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
108
 
109
+ # Main execution
110
+ if __name__ == "__main__":
111
+ app = create_shabbat_interface()
112
 
113
+ # Launch the application
114
+ app.launch(
115
+ server_name="0.0.0.0",
116
+ server_port=7860,
117
+ share=False,
118
+ debug=False,
119
+ show_error=True
120
+ )def create_shabbat_interface():
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
121
  """Create the Gradio interface for the Shabbat Candle Lighting Agent"""
122
 
123
  agent = ShabbatCandleLightingAgent()
 
157
  - Add country for common city names (e.g., "Paris, France")
158
  - Try nearest major city if yours isn't found
159
  - Use English city names for best search results
 
 
 
 
 
 
 
160
  """)
161
 
162
  with gr.Column(scale=2):
 
167
 
168
  👆 **Enter your city name above and click 'Get Shabbat Times'**
169
 
 
 
 
 
 
 
 
 
170
  ---
171
 
172
  **🕯️ Every Friday evening, Jewish families around the world light candles to welcome Shabbat**
173
  """
174
  )
175
 
176
+ # Button click handler
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
177
  search_btn.click(
178
  fn=agent.get_shabbat_times,
179
  inputs=[city_input],
180
  outputs=output_area
181
  )
182
 
 
 
 
 
 
 
 
183
  # Resources and information
184
  with gr.Accordion("📚 Resources & Information", open=False):
185
  gr.Markdown("""