devendergarg14 commited on
Commit
2ad2a7e
·
verified ·
1 Parent(s): 3b316e2

Upload app.py

Browse files
Files changed (1) hide show
  1. app.py +23 -10
app.py CHANGED
@@ -192,7 +192,8 @@ def start_url_monitoring_thread(target_url_id):
192
  # Stop existing thread if it's alive
193
  if "_thread" in url_data_entry and url_data_entry["_thread"].is_alive():
194
  print(f"Monitor for URL ID {target_url_id} already running. Attempting to restart.")
195
- url_data_entry["_stop_event"].set()
 
196
  url_data_entry["_thread"].join(timeout=3) # Wait for thread to stop
197
 
198
  new_stop_event = threading.Event()
@@ -211,7 +212,8 @@ def stop_url_monitoring_thread(target_url_id):
211
  url_data_entry = monitored_urls_store[target_url_id]
212
  if "_thread" in url_data_entry and url_data_entry["_thread"].is_alive():
213
  print(f"Signaling stop for monitor thread of URL ID {target_url_id}")
214
- url_data_entry["_stop_event"].set()
 
215
  # Not joining here to keep API responsive, daemon thread will exit.
216
  url_data_entry.pop("_thread", None)
217
  url_data_entry.pop("_stop_event", None)
@@ -255,8 +257,9 @@ def add_new_url():
255
  with lock:
256
  # Check for duplicates (case-insensitive, ignoring trailing slashes)
257
  normalized_new_url = input_url.rstrip('/').lower()
258
- for existing_url in monitored_urls_store.values():
259
- if existing_url['url'].rstrip('/').lower() == normalized_new_url:
 
260
  return jsonify({"error": "URL already monitored"}), 409 # Conflict
261
 
262
  new_url_id = str(uuid.uuid4())
@@ -266,13 +269,18 @@ def add_new_url():
266
  "id": new_url_id, "url": input_url, "status": 'pending',
267
  "ip": resolved_ip, "responseTime": None, "lastChecked": None, "history": []
268
  }
269
- monitored_urls_store[new_url_id] = url_entry_to_add
 
 
 
 
 
270
  save_data_to_json()
271
 
272
- start_url_monitoring_thread(new_url_id)
273
 
274
- # Return the newly created URL entry (without thread objects)
275
- return jsonify(url_entry_to_add), 201
276
 
277
 
278
  @app.route('/api/urls/<string:target_url_id>', methods=['DELETE'])
@@ -284,7 +292,7 @@ def delete_existing_url(target_url_id):
284
  save_data_to_json()
285
 
286
  # Prepare data for response (without thread objects)
287
- response_data = removed_url_entry.copy()
288
  response_data.pop("_thread", None)
289
  response_data.pop("_stop_event", None)
290
  print(f"Deleted URL ID {target_url_id}")
@@ -301,7 +309,12 @@ if os.environ.get('WERKZEUG_RUN_MAIN') != 'true': # Avoids double load in Flask
301
  if __name__ == '__main__':
302
  # This block is for local development (e.g., `python app.py`)
303
  # `load_data_from_json()` is called above unless Werkzeug reloader is active.
 
 
 
 
 
304
  app.run(debug=True, host='0.0.0.0', port=7860)
305
 
306
  # When run with Gunicorn, Gunicorn imports `app` from this `app.py` file.
307
- # `load_data_from_json()` will have been called during that import.
 
192
  # Stop existing thread if it's alive
193
  if "_thread" in url_data_entry and url_data_entry["_thread"].is_alive():
194
  print(f"Monitor for URL ID {target_url_id} already running. Attempting to restart.")
195
+ if "_stop_event" in url_data_entry and url_data_entry["_stop_event"]: # Check if _stop_event exists
196
+ url_data_entry["_stop_event"].set()
197
  url_data_entry["_thread"].join(timeout=3) # Wait for thread to stop
198
 
199
  new_stop_event = threading.Event()
 
212
  url_data_entry = monitored_urls_store[target_url_id]
213
  if "_thread" in url_data_entry and url_data_entry["_thread"].is_alive():
214
  print(f"Signaling stop for monitor thread of URL ID {target_url_id}")
215
+ if "_stop_event" in url_data_entry and url_data_entry["_stop_event"]: # Check if _stop_event exists
216
+ url_data_entry["_stop_event"].set()
217
  # Not joining here to keep API responsive, daemon thread will exit.
218
  url_data_entry.pop("_thread", None)
219
  url_data_entry.pop("_stop_event", None)
 
257
  with lock:
258
  # Check for duplicates (case-insensitive, ignoring trailing slashes)
259
  normalized_new_url = input_url.rstrip('/').lower()
260
+ for existing_url_id in list(monitored_urls_store.keys()): # Iterate over keys to avoid issues if store is modified
261
+ existing_url_data = monitored_urls_store.get(existing_url_id)
262
+ if existing_url_data and existing_url_data['url'].rstrip('/').lower() == normalized_new_url:
263
  return jsonify({"error": "URL already monitored"}), 409 # Conflict
264
 
265
  new_url_id = str(uuid.uuid4())
 
269
  "id": new_url_id, "url": input_url, "status": 'pending',
270
  "ip": resolved_ip, "responseTime": None, "lastChecked": None, "history": []
271
  }
272
+
273
+ # Make a copy of the entry for the response *before* it's potentially modified
274
+ # by start_url_monitoring_thread with non-serializable objects.
275
+ response_payload = url_entry_to_add.copy()
276
+
277
+ monitored_urls_store[new_url_id] = url_entry_to_add # url_entry_to_add will be modified by start_url_monitoring_thread
278
  save_data_to_json()
279
 
280
+ start_url_monitoring_thread(new_url_id) # This will add _thread and _stop_event to monitored_urls_store[new_url_id]
281
 
282
+ # Return the clean response_payload, which does not have _thread or _stop_event
283
+ return jsonify(response_payload), 201
284
 
285
 
286
  @app.route('/api/urls/<string:target_url_id>', methods=['DELETE'])
 
292
  save_data_to_json()
293
 
294
  # Prepare data for response (without thread objects)
295
+ response_data = removed_url_entry.copy() # Copy before potential modification if stop_url_monitoring_thread didn't pop everything
296
  response_data.pop("_thread", None)
297
  response_data.pop("_stop_event", None)
298
  print(f"Deleted URL ID {target_url_id}")
 
309
  if __name__ == '__main__':
310
  # This block is for local development (e.g., `python app.py`)
311
  # `load_data_from_json()` is called above unless Werkzeug reloader is active.
312
+ # If using Flask's reloader, load_data_from_json will be called twice:
313
+ # once by the main process, once by the reloader's child process.
314
+ # The check for WERKZEUG_RUN_MAIN ensures it only loads in the main one or the child.
315
+ if os.environ.get('WERKZEUG_RUN_MAIN') == 'true': # Ensure data is loaded in the reloaded process too
316
+ load_data_from_json()
317
  app.run(debug=True, host='0.0.0.0', port=7860)
318
 
319
  # When run with Gunicorn, Gunicorn imports `app` from this `app.py` file.
320
+ # `load_data_from_json()` will have been called during that import (due to the WERKZEUG_RUN_MAIN check).