Spaces:
Runtime error
Runtime error
acecalisto3
commited on
Commit
•
09dd92c
1
Parent(s):
f0b5677
Update app2.py
Browse files
app2.py
CHANGED
@@ -2,91 +2,64 @@ import asyncio
|
|
2 |
import gradio as gr
|
3 |
from sqlalchemy.exc import SQLAlchemyError
|
4 |
from sqlalchemy.ext.asyncio import create_async_engine, AsyncSession
|
5 |
-
from sqlalchemy.future import select
|
6 |
from sqlalchemy.orm import sessionmaker
|
7 |
import logging
|
8 |
import os
|
9 |
import sys
|
10 |
-
|
11 |
-
current_dir = os.path.dirname(os.path.realpath(__file__))
|
12 |
-
parent_dir = os.path.abspath(os.path.join(current_dir, ".."))
|
13 |
-
sys.path.insert(0, parent_dir)
|
14 |
-
|
15 |
-
logger = logging.getLogger(__name__)
|
16 |
|
17 |
# Global variables for database session and engine
|
18 |
db_session = None
|
19 |
engine = None
|
20 |
-
monitoring_task = None
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
21 |
|
22 |
-
#
|
23 |
-
async def
|
24 |
while True:
|
25 |
try:
|
26 |
-
await
|
27 |
-
|
28 |
-
except
|
29 |
-
|
30 |
-
await asyncio.sleep(60) # Wait for 60 seconds before checking again
|
31 |
|
32 |
-
#
|
33 |
-
async def
|
34 |
try:
|
35 |
-
result = await db_session.execute(
|
36 |
-
select(Article).order_by(Article.timestamp.desc()).limit(20)
|
37 |
-
)
|
38 |
articles = result.scalars().all() # Fetch latest articles
|
39 |
feed = {
|
40 |
'title': 'Website Changes Feed',
|
41 |
-
'link':
|
42 |
'description': 'Feed of changes detected on monitored websites.',
|
43 |
-
'items': [{
|
44 |
-
'title': article.title,
|
45 |
-
'link': article.url,
|
46 |
-
'description': article.content,
|
47 |
-
'pubDate': str(article.timestamp)
|
48 |
-
} for article in articles]
|
49 |
}
|
50 |
return feed
|
51 |
-
except SQLAlchemyError as e:
|
52 |
-
logger.error(f"Database error: {e}")
|
53 |
-
return None
|
54 |
-
|
55 |
-
# Periodic feed updater with error handling
|
56 |
-
async def periodic_update_with_error_handling():
|
57 |
-
while True:
|
58 |
-
try:
|
59 |
-
await asyncio.sleep(300) # Wait for 5 minutes
|
60 |
-
await update_feed_content() # Update the feed content
|
61 |
-
except Exception as e:
|
62 |
-
logger.error(f"Error in periodic update: {e}")
|
63 |
-
|
64 |
-
# Function for dynamically setting the database connection
|
65 |
-
async def set_db_connection(host, port, user, password, db_name):
|
66 |
-
global db_session, engine
|
67 |
-
try:
|
68 |
-
engine = create_async_engine(
|
69 |
-
f"mysql+aiomysql://{user}:{password}@{host}:{port}/{db_name}",
|
70 |
-
echo=False
|
71 |
-
)
|
72 |
-
Session = sessionmaker(engine, class_=AsyncSession, expire_on_commit=False)
|
73 |
-
db_session = Session()
|
74 |
-
return "Database connection established."
|
75 |
except Exception as e:
|
76 |
-
logger.error(f"
|
77 |
-
return
|
78 |
|
79 |
# Main application that runs Gradio UI and background tasks
|
80 |
async def main():
|
81 |
global db_session, monitoring_task
|
82 |
engine = None
|
83 |
-
|
84 |
demo = gr.Blocks()
|
85 |
-
|
86 |
# Define the Gradio interface
|
87 |
with demo:
|
88 |
gr.Markdown("# Website Monitor and Chatbot")
|
89 |
-
|
90 |
with gr.Row():
|
91 |
with gr.Column():
|
92 |
gr.Markdown("## Database Settings")
|
@@ -95,95 +68,48 @@ async def main():
|
|
95 |
db_user = gr.Textbox(label="Database User", placeholder="username", value="")
|
96 |
db_pass = gr.Textbox(label="Database Password", placeholder="password", type="password", value="")
|
97 |
db_name = gr.Textbox(label="Database Name", placeholder="database_name", value="monitoring")
|
98 |
-
|
99 |
db_status_textbox = gr.Textbox(label="Database Status", interactive=False)
|
100 |
status_text = gr.Textbox(label="Status", interactive=False)
|
101 |
-
|
102 |
gr.Markdown("## RSS Feed Reader Settings")
|
103 |
feed_target_url = gr.Textbox(label="RSS Feed Target URL", placeholder="http://yourwebsite.com/feed")
|
104 |
view_button = gr.Button("View Feed")
|
105 |
-
|
106 |
-
|
107 |
-
label="Target URLs (comma-separated)",
|
108 |
-
placeholder="https://example.com, https://another-site.com"
|
109 |
-
)
|
110 |
-
storage_location = gr.Textbox(
|
111 |
-
label="Storage Location (CSV file path)",
|
112 |
-
placeholder="/path/to/your/file.csv"
|
113 |
-
)
|
114 |
feed_rss_checkbox = gr.Checkbox(label="Enable RSS Feed")
|
115 |
start_button = gr.Button("Start Monitoring")
|
116 |
stop_button = gr.Button("Stop Monitoring")
|
117 |
-
|
118 |
with gr.Column():
|
119 |
feed_content = gr.JSON(label="RSS Feed Content")
|
120 |
chatbot_interface = gr.Chatbot(type='messages')
|
121 |
message_input = gr.Textbox(placeholder="Type your message here...")
|
122 |
send_button = gr.Button("Send")
|
123 |
-
|
124 |
-
|
125 |
-
async def on_start_click(target_urls_str: str, storage_loc: str, feed_enabled: bool,
|
126 |
-
host: str, port: str, user: str, password: str, db_name: str):
|
127 |
global monitoring_task
|
128 |
urls = [url.strip() for url in target_urls_str.split(",")]
|
129 |
-
await set_db_connection(host, port, user, password, db_name)
|
130 |
-
monitoring_task = asyncio.create_task(start_monitoring(urls, storage_loc, feed_enabled))
|
131 |
return "Monitoring started."
|
132 |
-
|
133 |
-
async def on_stop_click(): # Define the on_stop_click function
|
134 |
global monitoring_task
|
135 |
if monitoring_task:
|
136 |
-
monitoring_task.cancel()
|
137 |
monitoring_task = None
|
138 |
-
|
139 |
-
else:
|
140 |
-
return "Monitoring is not running."
|
141 |
-
|
142 |
async def on_view_feed_click(feed_url: str):
|
143 |
-
# Logic to fetch and view RSS feed data based on URL
|
144 |
return await fetch_feed_content(feed_url)
|
145 |
-
|
146 |
stop_button.click(on_stop_click, outputs=[status_text])
|
147 |
view_button.click(on_view_feed_click, inputs=[feed_target_url], outputs=[feed_content])
|
148 |
-
send_button.click(
|
149 |
-
chatbot_response,
|
150 |
-
inputs=[message_input, chatbot_interface],
|
151 |
-
outputs=[chatbot_interface, message_input]
|
152 |
-
)
|
153 |
-
|
154 |
# Set up the timer for periodic updates
|
155 |
feed_updater = gr.Timer(interval=300)
|
156 |
feed_updater.tick(fn=update_feed_content, outputs=feed_content)
|
157 |
-
|
158 |
# Load and check database status when the UI is loaded
|
159 |
demo.load(update_db_status, outputs=db_status_textbox)
|
160 |
-
asyncio.create_task(periodic_update_with_error_handling())
|
161 |
-
|
162 |
# Launch the Gradio demo
|
163 |
await demo.launch()
|
164 |
|
165 |
-
|
166 |
-
# Logic to fetch RSS feed content from the provided URL
|
167 |
-
return {
|
168 |
-
'title': 'Sample Feed',
|
169 |
-
'link': feed_url,
|
170 |
-
'items': [
|
171 |
-
{'title': 'Sample Item 1', 'link': feed_url + '/1', 'description': 'This is a sample item.', 'pubDate': '2024-01-01'},
|
172 |
-
{'title': 'Sample Item 2', 'link': feed_url + '/2', 'description': 'This is another sample item.', 'pubDate': '2024-01-02'}
|
173 |
-
]
|
174 |
-
}
|
175 |
-
|
176 |
-
async def start_monitoring(urls, storage_location, feed_enabled):
|
177 |
-
# Logic to start monitoring URLs and optionally save to CSV or enable RSS
|
178 |
-
print(f"Starting monitoring for {urls}, saving to {storage_location}, RSS enabled: {feed_enabled}")
|
179 |
-
return
|
180 |
-
|
181 |
-
async def chatbot_response(message, chat_interface):
|
182 |
-
# Example chatbot logic to respond to a user message
|
183 |
-
response = f"Echo: {message}"
|
184 |
-
chat_interface.append((message, response))
|
185 |
-
return chat_interface, ""
|
186 |
-
|
187 |
-
# Launch the app using asyncio
|
188 |
if __name__ == "__main__":
|
189 |
asyncio.run(main())
|
|
|
2 |
import gradio as gr
|
3 |
from sqlalchemy.exc import SQLAlchemyError
|
4 |
from sqlalchemy.ext.asyncio import create_async_engine, AsyncSession
|
5 |
+
from sqlalchemy.future import select
|
6 |
from sqlalchemy.orm import sessionmaker
|
7 |
import logging
|
8 |
import os
|
9 |
import sys
|
10 |
+
from typing import List, Dict, Any
|
|
|
|
|
|
|
|
|
|
|
11 |
|
12 |
# Global variables for database session and engine
|
13 |
db_session = None
|
14 |
engine = None
|
15 |
+
monitoring_task = None
|
16 |
+
logger = logging.getLogger(__name__)
|
17 |
+
|
18 |
+
# Function for dynamically setting the database connection
|
19 |
+
async def set_db_connection(host: str, port: str, user: str, password: str, db_name: str):
|
20 |
+
global db_session, engine
|
21 |
+
try:
|
22 |
+
engine = create_async_engine(f"mysql+aiomysql://{user}:{password}@{host}:{port}/{db_name}", echo=False)
|
23 |
+
Session = sessionmaker(engine, class_=AsyncSession, expire_on_commit=False)
|
24 |
+
db_session = Session()
|
25 |
+
return "Database connection established."
|
26 |
+
except Exception as e:
|
27 |
+
logger.error(f"Failed to establish database connection: {e}")
|
28 |
+
return f"Failed to connect to database: {e}"
|
29 |
|
30 |
+
# Periodic feed updater with error handling and logging improvements
|
31 |
+
async def periodic_update_with_error_handling():
|
32 |
while True:
|
33 |
try:
|
34 |
+
await asyncio.sleep(300) # Wait for 5 minutes before updating the feed content.
|
35 |
+
await update_feed_content() # Update the feed content.
|
36 |
+
except Exception as e: # Catch all exceptions for logging purposes.
|
37 |
+
logger.error(f"Error in periodic update: {e}") # Improved logging message format.
|
|
|
38 |
|
39 |
+
# Function to fetch RSS feed content from the provided URL with error handling and logging improvements.
|
40 |
+
async def fetch_feed_content(feed_url: str) -> Dict[str, Any]:
|
41 |
try:
|
42 |
+
result = await db_session.execute(select(Article).order_by(Article.timestamp.desc()).limit(20))
|
|
|
|
|
43 |
articles = result.scalars().all() # Fetch latest articles
|
44 |
feed = {
|
45 |
'title': 'Website Changes Feed',
|
46 |
+
'link': feed_url,
|
47 |
'description': 'Feed of changes detected on monitored websites.',
|
48 |
+
'items': [{'title': article.title, 'link': article.url, 'description': article.content, 'pubDate': str(article.timestamp)} for article in articles] if articles else []
|
|
|
|
|
|
|
|
|
|
|
49 |
}
|
50 |
return feed
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
51 |
except Exception as e:
|
52 |
+
logger.error(f"Error fetching feed content: {e}")
|
53 |
+
return {}
|
54 |
|
55 |
# Main application that runs Gradio UI and background tasks
|
56 |
async def main():
|
57 |
global db_session, monitoring_task
|
58 |
engine = None
|
|
|
59 |
demo = gr.Blocks()
|
|
|
60 |
# Define the Gradio interface
|
61 |
with demo:
|
62 |
gr.Markdown("# Website Monitor and Chatbot")
|
|
|
63 |
with gr.Row():
|
64 |
with gr.Column():
|
65 |
gr.Markdown("## Database Settings")
|
|
|
68 |
db_user = gr.Textbox(label="Database User", placeholder="username", value="")
|
69 |
db_pass = gr.Textbox(label="Database Password", placeholder="password", type="password", value="")
|
70 |
db_name = gr.Textbox(label="Database Name", placeholder="database_name", value="monitoring")
|
|
|
71 |
db_status_textbox = gr.Textbox(label="Database Status", interactive=False)
|
72 |
status_text = gr.Textbox(label="Status", interactive=False)
|
|
|
73 |
gr.Markdown("## RSS Feed Reader Settings")
|
74 |
feed_target_url = gr.Textbox(label="RSS Feed Target URL", placeholder="http://yourwebsite.com/feed")
|
75 |
view_button = gr.Button("View Feed")
|
76 |
+
target_urls = gr.Textbox(label="Target URLs (comma-separated)", placeholder="https://example.com, https://another-site.com")
|
77 |
+
storage_location = gr.Textbox(label="Storage Location (CSV file path)", placeholder="/path/to/your/file.csv")
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
78 |
feed_rss_checkbox = gr.Checkbox(label="Enable RSS Feed")
|
79 |
start_button = gr.Button("Start Monitoring")
|
80 |
stop_button = gr.Button("Stop Monitoring")
|
|
|
81 |
with gr.Column():
|
82 |
feed_content = gr.JSON(label="RSS Feed Content")
|
83 |
chatbot_interface = gr.Chatbot(type='messages')
|
84 |
message_input = gr.Textbox(placeholder="Type your message here...")
|
85 |
send_button = gr.Button("Send")
|
86 |
+
# Define button actions
|
87 |
+
async def on_start_click(target_urls_str: str, storage_loc: str, feed_enabled: bool, host: str, port: str, user: str, password: str, db_name: str):
|
|
|
|
|
88 |
global monitoring_task
|
89 |
urls = [url.strip() for url in target_urls_str.split(",")]
|
90 |
+
await set_db_connection(host, port, user, password, db_name)
|
91 |
+
monitoring_task = asyncio.create_task(start_monitoring(urls, storage_loc, feed_enabled))
|
92 |
return "Monitoring started."
|
93 |
+
async def on_stop_click():
|
|
|
94 |
global monitoring_task
|
95 |
if monitoring_task:
|
96 |
+
monitoring_task.cancel()
|
97 |
monitoring_task = None
|
98 |
+
return "Monitoring stopped."
|
|
|
|
|
|
|
99 |
async def on_view_feed_click(feed_url: str):
|
|
|
100 |
return await fetch_feed_content(feed_url)
|
|
|
101 |
stop_button.click(on_stop_click, outputs=[status_text])
|
102 |
view_button.click(on_view_feed_click, inputs=[feed_target_url], outputs=[feed_content])
|
103 |
+
send_button.click(chatbot_response, inputs=[message_input, chatbot_interface], outputs=[chatbot_interface, message_input])
|
|
|
|
|
|
|
|
|
|
|
104 |
# Set up the timer for periodic updates
|
105 |
feed_updater = gr.Timer(interval=300)
|
106 |
feed_updater.tick(fn=update_feed_content, outputs=feed_content)
|
|
|
107 |
# Load and check database status when the UI is loaded
|
108 |
demo.load(update_db_status, outputs=db_status_textbox)
|
109 |
+
asyncio.create_task(periodic_update_with_error_handling())
|
|
|
110 |
# Launch the Gradio demo
|
111 |
await demo.launch()
|
112 |
|
113 |
+
# Launch the app using asyncio
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
114 |
if __name__ == "__main__":
|
115 |
asyncio.run(main())
|