Zelyanoth commited on
Commit
98b8066
·
1 Parent(s): cab070d
APSCHEDULER_ANALYSIS_SUMMARY.md ADDED
@@ -0,0 +1,198 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ # APScheduler Analysis Summary
2
+
3
+ ## Problem Diagnosis
4
+
5
+ ### Issue Description
6
+ The user reported that when starting their Lin application, they don't see any output from the APS scheduler in the startup logs. The application starts successfully on port 7860, but there are no scheduler-related messages visible.
7
+
8
+ ### Root Cause Analysis
9
+ After analyzing the code and startup logs, I identified the following issues:
10
+
11
+ 1. **Missing Logging Configuration**: The APScheduler logger is not configured to show debug messages. According to APScheduler documentation, you need to explicitly configure logging for the 'apscheduler' logger to see its output.
12
+
13
+ 2. **No Startup Verification**: There are no explicit verification messages to confirm that APScheduler is initialized and working.
14
+
15
+ 3. **Silent Operation**: APScheduler is working in the background but operates silently without visible feedback.
16
+
17
+ ## Current State Assessment
18
+
19
+ ### What's Working ✅
20
+ - Flask application starts successfully on port 7860
21
+ - APScheduler is properly imported and initialized in `backend/app.py`
22
+ - Scheduler service is correctly configured with logging statements
23
+ - Database integration is properly set up
24
+ - Job creation and execution mechanisms are in place
25
+
26
+ ### What's Missing ❌
27
+ - APScheduler debug messages are not visible in startup logs
28
+ - No startup verification messages
29
+ - No feedback about scheduler status or job counts
30
+ - Logging configuration not properly set up for APScheduler
31
+
32
+ ## Solution Architecture
33
+
34
+ ### Phase 1: Logging Configuration
35
+ **Target File**: `backend/app.py`
36
+ **Changes Required**:
37
+ ```python
38
+ import logging
39
+
40
+ # Configure logging for APScheduler
41
+ logging.basicConfig(
42
+ level=logging.DEBUG,
43
+ format='%(asctime)s - %(name)s - %(levelname)s - %(message)s'
44
+ )
45
+ logging.getLogger('apscheduler').setLevel(logging.DEBUG)
46
+ ```
47
+
48
+ ### Phase 2: Startup Verification
49
+ **Target File**: `backend/app.py`
50
+ **Changes Required**:
51
+ Add verification messages after APScheduler initialization:
52
+ ```python
53
+ # Verify APScheduler initialization
54
+ if hasattr(app, 'scheduler') and app.scheduler.scheduler is not None:
55
+ app.logger.info("✅ APScheduler initialized successfully")
56
+ app.logger.info(f"📊 Current jobs: {len(app.scheduler.scheduler.get_jobs())}")
57
+ app.logger.info("🔄 Schedule loading job added (runs every 5 minutes)")
58
+ else:
59
+ app.logger.warning("⚠️ APScheduler initialization failed")
60
+ ```
61
+
62
+ ### Phase 3: Testing Infrastructure
63
+ **New Files to Create**:
64
+ - `test_scheduler_visibility.py` - Standalone test script
65
+ - `test_scheduler_integration.py` - Integration test script
66
+
67
+ ### Phase 4: Documentation Updates
68
+ **Files to Update**:
69
+ - `APSCHEDULER_SETUP.md` - Add troubleshooting section
70
+ - Create comprehensive test plan and implementation guide
71
+
72
+ ## Expected Results
73
+
74
+ ### Before Fix
75
+ ```
76
+ Starting Lin application on port 7860...
77
+ ============================================================
78
+ ============================================================
79
+ Flask application starting...
80
+ Access the application at:
81
+ http://localhost:7860
82
+ http://127.0.0.1:7860
83
+ ============================================================
84
+ * Serving Flask app 'backend.app'
85
+ * Debug mode: off
86
+ INFO:werkzeug:WARNING: This is a development server...
87
+ ```
88
+
89
+ ### After Fix
90
+ ```
91
+ Starting Lin application on port 7860...
92
+ ============================================================
93
+ ============================================================
94
+ Flask application starting...
95
+ Access the application at:
96
+ http://localhost:7860
97
+ http://127.0.0.1:7860
98
+ ============================================================
99
+ * Serving Flask app 'backend.app'
100
+ * Debug mode: off
101
+ INFO:werkzeug:WARNING: This is a development server...
102
+ INFO:backend.app:Initializing APScheduler...
103
+ INFO:backend.apscheduler_service:Initializing APScheduler...
104
+ INFO:backend.apscheduler_service:Initializing Supabase client...
105
+ INFO:backend.apscheduler_service:Supabase client initialized
106
+ INFO:backend.apscheduler_service:Creating BackgroundScheduler...
107
+ INFO:backend.apscheduler_service:BackgroundScheduler created
108
+ INFO:backend.apscheduler_service:Starting scheduler...
109
+ INFO:backend.apscheduler_service:Scheduler started
110
+ INFO:backend.apscheduler_service:Adding periodic job to load schedules...
111
+ INFO:backend.apscheduler_service:Periodic job added
112
+ INFO:backend.apscheduler_service:Loading schedules immediately...
113
+ INFO:backend.apscheduler_service:Found 0 schedules in database
114
+ INFO:backend.apscheduler_service:Updated APScheduler schedule
115
+ INFO:backend.app:✅ APScheduler initialized successfully
116
+ INFO:backend.app:📊 Current jobs: 1
117
+ INFO:backend.app:🔄 Schedule loading job added (runs every 5 minutes)
118
+ ```
119
+
120
+ ## Implementation Plan
121
+
122
+ ### Step 1: Configure Logging
123
+ - Add logging configuration to `backend/app.py`
124
+ - Ensure APScheduler logger is set to DEBUG level
125
+ - Test that messages now appear in logs
126
+
127
+ ### Step 2: Add Verification
128
+ - Add startup verification messages
129
+ - Include job count information
130
+ - Add clear success/failure indicators
131
+
132
+ ### Step 3: Create Test Scripts
133
+ - Create standalone test script for verification
134
+ - Create integration test for Flask app
135
+ - Document usage and expected outputs
136
+
137
+ ### Step 4: Update Documentation
138
+ - Update setup guide with troubleshooting section
139
+ - Add logging configuration instructions
140
+ - Document test procedures
141
+
142
+ ## Risk Assessment
143
+
144
+ ### Low Risk Changes
145
+ - Logging configuration (no functional changes)
146
+ - Startup verification messages (no functional changes)
147
+ - Test scripts (standalone, don't affect production)
148
+
149
+ ### Medium Risk Changes
150
+ - Any modifications to `backend/app.py` require careful testing
151
+
152
+ ### Mitigation Strategies
153
+ 1. **Backup**: Create backup of `backend/app.py` before changes
154
+ 2. **Testing**: Run test scripts after each change
155
+ 3. **Rollback**: Have rollback plan ready
156
+ 4. **Validation**: Verify application still starts and functions normally
157
+
158
+ ## Success Criteria
159
+
160
+ The solution is successful when:
161
+
162
+ 1. ✅ APScheduler messages are visible in startup logs
163
+ 2. ✅ Startup verification messages appear
164
+ 3. ✅ Test scripts pass successfully
165
+ 4. ✅ Application continues to function normally
166
+ 5. ✅ No new errors are introduced
167
+ 6. ✅ Documentation is updated and accurate
168
+
169
+ ## Next Steps
170
+
171
+ 1. **Approve Implementation Plan** - Review and approve the proposed changes
172
+ 2. **Switch to Code Mode** - Move to implementation phase
173
+ 3. **Execute Changes** - Implement logging configuration and verification
174
+ 4. **Test Solution** - Run test scripts to verify functionality
175
+ 5. **Validate Results** - Confirm APScheduler output is now visible
176
+ 6. **Update Documentation** - Finalize documentation updates
177
+
178
+ ## Files Created/Modified
179
+
180
+ ### Created
181
+ - `APSCHEDULER_VISIBILITY_FIX.md` - Comprehensive fix plan
182
+ - `APSCHEDULER_TEST_PLAN.md` - Detailed test plan with scripts
183
+ - `APSCHEDULER_ANALYSIS_SUMMARY.md` - This analysis summary
184
+
185
+ ### To Be Modified
186
+ - `backend/app.py` - Add logging configuration and verification
187
+ - `APSCHEDULER_SETUP.md` - Update with troubleshooting section
188
+
189
+ ## Conclusion
190
+
191
+ The APScheduler is functional but not visible due to missing logging configuration. The solution is straightforward and low-risk, involving primarily logging configuration and verification messages. Once implemented, users will be able to see APScheduler activity in their logs, making it easier to monitor and debug scheduling issues.
192
+
193
+ The implementation will provide:
194
+ - Clear visibility into APScheduler operations
195
+ - Better debugging capabilities
196
+ - Improved user experience
197
+ - Comprehensive testing infrastructure
198
+ - Updated documentation for future reference
APSCHEDULER_TEST_PLAN.md ADDED
@@ -0,0 +1,462 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ # APScheduler Test Plan
2
+
3
+ ## Overview
4
+
5
+ This document outlines a comprehensive test plan to verify APScheduler functionality and visibility in the Lin application. The plan includes both automated tests and manual verification steps.
6
+
7
+ ## Test Objectives
8
+
9
+ 1. **Verify APScheduler is properly initialized** during application startup
10
+ 2. **Confirm logging configuration** shows APScheduler messages
11
+ 3. **Test schedule loading functionality** from the database
12
+ 4. **Verify job creation and execution** mechanisms
13
+ 5. **Ensure scheduler persistence** and error handling
14
+
15
+ ## Test Environment Setup
16
+
17
+ ### Prerequisites
18
+ - Python 3.8+ installed
19
+ - All dependencies from `backend/requirements.txt` installed
20
+ - Environment variables configured (Supabase credentials, etc.)
21
+ - Access to the Lin application source code
22
+
23
+ ### Test Files to Create
24
+
25
+ #### 1. `test_scheduler_visibility.py`
26
+ **Purpose**: Standalone test script to verify APScheduler logging and basic functionality
27
+
28
+ ```python
29
+ #!/usr/bin/env python3
30
+ """
31
+ Test script for APScheduler visibility and functionality.
32
+ This script tests whether APScheduler is working and properly configured for logging.
33
+ """
34
+
35
+ import sys
36
+ import os
37
+ import logging
38
+ from pathlib import Path
39
+ from datetime import datetime
40
+
41
+ # Add the backend directory to the Python path
42
+ backend_dir = Path(__file__).parent / "backend"
43
+ sys.path.insert(0, str(backend_dir))
44
+
45
+ def setup_logging():
46
+ """Setup logging for the test script."""
47
+ logging.basicConfig(
48
+ level=logging.DEBUG,
49
+ format='%(asctime)s - %(name)s - %(levelname)s - %(message)s'
50
+ )
51
+ # Configure APScheduler logger specifically
52
+ logging.getLogger('apscheduler').setLevel(logging.DEBUG)
53
+ print("🔧 Logging configured for APScheduler")
54
+
55
+ def test_apscheduler_import():
56
+ """Test that APScheduler can be imported."""
57
+ try:
58
+ from backend.scheduler.apscheduler_service import APSchedulerService
59
+ print("✅ APSchedulerService imported successfully")
60
+ return True
61
+ except Exception as e:
62
+ print(f"❌ Failed to import APSchedulerService: {e}")
63
+ return False
64
+
65
+ def test_scheduler_initialization():
66
+ """Test APScheduler initialization with mock app."""
67
+ try:
68
+ from backend.scheduler.apscheduler_service import APSchedulerService
69
+
70
+ # Create a mock app object
71
+ class MockApp:
72
+ def __init__(self):
73
+ self.config = {
74
+ 'SUPABASE_URL': 'https://test.supabase.co',
75
+ 'SUPABASE_KEY': 'test_key',
76
+ 'SCHEDULER_ENABLED': True
77
+ }
78
+
79
+ # Initialize the scheduler service
80
+ app = MockApp()
81
+ scheduler_service = APSchedulerService()
82
+
83
+ # Mock the Supabase client initialization
84
+ class MockSupabaseClient:
85
+ def table(self, table_name):
86
+ return self
87
+
88
+ def select(self, columns):
89
+ return self
90
+
91
+ def execute(self):
92
+ # Return empty schedule data for testing
93
+ return type('obj', (object,), {'data': []})()
94
+
95
+ scheduler_service.supabase_client = MockSupabaseClient()
96
+
97
+ # Test initialization
98
+ scheduler_service.init_app(app)
99
+
100
+ if scheduler_service.scheduler is not None:
101
+ print("✅ APScheduler initialized successfully")
102
+ print(f"📊 Current jobs: {len(scheduler_service.scheduler.get_jobs())}")
103
+ return True
104
+ else:
105
+ print("❌ APScheduler initialization failed")
106
+ return False
107
+
108
+ except Exception as e:
109
+ print(f"❌ Error testing APScheduler initialization: {e}")
110
+ import traceback
111
+ traceback.print_exc()
112
+ return False
113
+
114
+ def test_schedule_loading():
115
+ """Test the schedule loading functionality."""
116
+ try:
117
+ from backend.scheduler.apscheduler_service import APSchedulerService
118
+
119
+ # Create scheduler service
120
+ scheduler_service = APSchedulerService()
121
+
122
+ # Mock the Supabase client
123
+ class MockSupabaseClient:
124
+ def table(self, table_name):
125
+ return self
126
+
127
+ def select(self, columns):
128
+ return self
129
+
130
+ def execute(self):
131
+ # Return mock schedule data
132
+ mock_data = [
133
+ {
134
+ 'id': 'test_schedule_1',
135
+ 'schedule_time': 'Monday 09:00',
136
+ 'adjusted_time': 'Monday 08:55',
137
+ 'Social_network': {
138
+ 'id_utilisateur': 'test_user_1',
139
+ 'token': 'test_token',
140
+ 'sub': 'test_sub'
141
+ }
142
+ }
143
+ ]
144
+ return type('obj', (object,), {'data': mock_data})()
145
+
146
+ scheduler_service.supabase_client = MockSupabaseClient()
147
+
148
+ # Test schedule loading
149
+ scheduler_service.load_schedules()
150
+
151
+ if scheduler_service.scheduler is not None:
152
+ jobs = scheduler_service.scheduler.get_jobs()
153
+ print(f"✅ Schedule loading test completed")
154
+ print(f"📊 Total jobs: {len(jobs)}")
155
+
156
+ # Check for specific job types
157
+ loader_jobs = [job for job in jobs if job.id == 'load_schedules']
158
+ content_jobs = [job for job in jobs if job.id.startswith('gen_')]
159
+ publish_jobs = [job for job in jobs if job.id.startswith('pub_')]
160
+
161
+ print(f"🔄 Loader jobs: {len(loader_jobs)}")
162
+ print(f"📝 Content generation jobs: {len(content_jobs)}")
163
+ print(f"📤 Publishing jobs: {len(publish_jobs)}")
164
+
165
+ return len(jobs) > 0
166
+ else:
167
+ print("❌ Scheduler not initialized for schedule loading test")
168
+ return False
169
+
170
+ except Exception as e:
171
+ print(f"❌ Error testing schedule loading: {e}")
172
+ import traceback
173
+ traceback.print_exc()
174
+ return False
175
+
176
+ def main():
177
+ """Main test function."""
178
+ print("🚀 Testing APScheduler visibility and functionality...")
179
+ print("=" * 60)
180
+
181
+ setup_logging()
182
+
183
+ tests = [
184
+ ("APScheduler Import", test_apscheduler_import),
185
+ ("Scheduler Initialization", test_scheduler_initialization),
186
+ ("Schedule Loading", test_schedule_loading),
187
+ ]
188
+
189
+ passed = 0
190
+ total = len(tests)
191
+
192
+ for test_name, test_func in tests:
193
+ print(f"\n📋 Running test: {test_name}")
194
+ print("-" * 40)
195
+
196
+ if test_func():
197
+ passed += 1
198
+ print(f"✅ {test_name} PASSED")
199
+ else:
200
+ print(f"❌ {test_name} FAILED")
201
+
202
+ print("\n" + "=" * 60)
203
+ print(f"📊 Test Results: {passed}/{total} tests passed")
204
+
205
+ if passed == total:
206
+ print("🎉 All tests passed! APScheduler is working correctly.")
207
+ return True
208
+ else:
209
+ print("⚠️ Some tests failed. Please check the error messages above.")
210
+ return False
211
+
212
+ if __name__ == "__main__":
213
+ success = main()
214
+ sys.exit(0 if success else 1)
215
+ ```
216
+
217
+ #### 2. `test_scheduler_integration.py`
218
+ **Purpose**: Test APScheduler integration with the actual Flask application
219
+
220
+ ```python
221
+ #!/usr/bin/env python3
222
+ """
223
+ Integration test for APScheduler with Flask application.
224
+ Tests the actual application startup and scheduler initialization.
225
+ """
226
+
227
+ import sys
228
+ import os
229
+ import subprocess
230
+ import time
231
+ from pathlib import Path
232
+
233
+ def test_app_startup_with_scheduler():
234
+ """Test that the Flask application starts with APScheduler visible."""
235
+ try:
236
+ # Change to the project directory
237
+ project_dir = Path(__file__).parent
238
+ os.chdir(project_dir)
239
+
240
+ # Start the application
241
+ print("🚀 Starting Flask application with APScheduler...")
242
+ process = subprocess.Popen(
243
+ [sys.executable, "start_app.py"],
244
+ stdout=subprocess.PIPE,
245
+ stderr=subprocess.STDOUT,
246
+ text=True,
247
+ bufsize=1,
248
+ universal_newlines=True
249
+ )
250
+
251
+ # Wait for startup and capture output
252
+ startup_timeout = 30 # 30 seconds timeout
253
+ start_time = time.time()
254
+
255
+ scheduler_found = False
256
+ while time.time() - start_time < startup_timeout:
257
+ output = process.stdout.readline()
258
+ if output:
259
+ print(output.strip())
260
+
261
+ # Check for APScheduler initialization messages
262
+ if "Initializing APScheduler" in output:
263
+ scheduler_found = True
264
+ print("✅ APScheduler initialization message found!")
265
+
266
+ # Check for successful startup
267
+ if "running on http" in output.lower():
268
+ break
269
+
270
+ # Terminate the process
271
+ process.terminate()
272
+ process.wait(timeout=10)
273
+
274
+ if scheduler_found:
275
+ print("✅ APScheduler is visible during application startup")
276
+ return True
277
+ else:
278
+ print("❌ APScheduler messages not found in startup logs")
279
+ return False
280
+
281
+ except Exception as e:
282
+ print(f"❌ Error testing app startup: {e}")
283
+ return False
284
+
285
+ def main():
286
+ """Main integration test function."""
287
+ print("🔗 Testing APScheduler integration with Flask application...")
288
+ print("=" * 60)
289
+
290
+ success = test_app_startup_with_scheduler()
291
+
292
+ print("\n" + "=" * 60)
293
+ if success:
294
+ print("🎉 Integration test passed! APScheduler is working in the Flask app.")
295
+ else:
296
+ print("⚠️ Integration test failed. APScheduler may not be properly configured.")
297
+
298
+ return success
299
+
300
+ if __name__ == "__main__":
301
+ success = main()
302
+ sys.exit(0 if success else 1)
303
+ ```
304
+
305
+ ## Test Execution Steps
306
+
307
+ ### Step 1: Run Standalone Test
308
+ ```bash
309
+ # Navigate to project directory
310
+ cd /path/to/your/project
311
+
312
+ # Run the standalone test
313
+ python test_scheduler_visibility.py
314
+ ```
315
+
316
+ **Expected Output**:
317
+ ```
318
+ 🚀 Testing APScheduler visibility and functionality...
319
+ ============================================================
320
+ 🔧 Logging configured for APScheduler
321
+
322
+ 📋 Running test: APScheduler Import
323
+ ----------------------------------------
324
+ ✅ APSchedulerService imported successfully
325
+ ✅ APScheduler Import PASSED
326
+
327
+ 📋 Running test: Scheduler Initialization
328
+ ----------------------------------------
329
+ ✅ APScheduler initialized successfully
330
+ 📊 Current jobs: 1
331
+ ✅ Scheduler Initialization PASSED
332
+
333
+ 📋 Running test: Schedule Loading
334
+ ----------------------------------------
335
+ ✅ Schedule loading test completed
336
+ 📊 Total jobs: 3
337
+ 🔄 Loader jobs: 1
338
+ 📝 Content generation jobs: 1
339
+ 📤 Publishing jobs: 1
340
+ ✅ Schedule Loading PASSED
341
+
342
+ ============================================================
343
+ 📊 Test Results: 3/3 tests passed
344
+ 🎉 All tests passed! APScheduler is working correctly.
345
+ ```
346
+
347
+ ### Step 2: Run Integration Test
348
+ ```bash
349
+ # Run the integration test
350
+ python test_scheduler_integration.py
351
+ ```
352
+
353
+ **Expected Output**:
354
+ ```
355
+ 🔗 Testing APScheduler integration with Flask application...
356
+ ============================================================
357
+ 🚀 Starting Flask application with APScheduler...
358
+ Starting Lin application on port 7860...
359
+ ============================================================
360
+ ============================================================
361
+ Flask application starting...
362
+ Access the application at:
363
+ http://localhost:7860
364
+ http://127.0.0.1:7860
365
+ ============================================================
366
+ * Serving Flask app 'backend.app'
367
+ * Debug mode: off
368
+ INFO:backend.app:Initializing APScheduler...
369
+ INFO:backend.apscheduler_service:Initializing APScheduler...
370
+ INFO:backend.apscheduler_service:Initializing Supabase client...
371
+ INFO:backend.apscheduler_service:Supabase client initialized
372
+ INFO:backend.apscheduler_service:Creating BackgroundScheduler...
373
+ INFO:backend.apscheduler_service:BackgroundScheduler created
374
+ INFO:backend.apscheduler_service:Starting scheduler...
375
+ INFO:backend.apscheduler_service:Scheduler started
376
+ INFO:backend.apscheduler_service:Adding periodic job to load schedules...
377
+ INFO:backend.apscheduler_service:Periodic job added
378
+ INFO:backend.apscheduler_service:Loading schedules immediately...
379
+ INFO:backend.apscheduler_service:Found 0 schedules in database
380
+ INFO:backend.apscheduler_service:Updated APScheduler schedule
381
+ INFO:backend.app:✅ APScheduler initialized successfully
382
+ INFO:backend.app:📊 Current jobs: 1
383
+ INFO:backend.app:🔄 Schedule loading job added (runs every 5 minutes)
384
+ * Running on all addresses (0.0.0.0)
385
+ * Running on http://127.0.0.1:7860
386
+ * Running on http://10.108.66.211:7860
387
+ ✅ APScheduler initialization message found!
388
+ ✅ APScheduler is visible during application startup
389
+
390
+ ============================================================
391
+ 🎉 Integration test passed! APScheduler is working in the Flask app.
392
+ ```
393
+
394
+ ## Manual Verification Steps
395
+
396
+ ### 1. Check Application Startup Logs
397
+ After implementing the logging configuration, start your application and look for:
398
+ - `Initializing APScheduler...`
399
+ - `BackgroundScheduler created`
400
+ - `Scheduler started`
401
+ - `Adding periodic job to load schedules...`
402
+ - `Schedule loading job added (runs every 5 minutes)`
403
+
404
+ ### 2. Verify Scheduler Functionality
405
+ 1. Create a schedule via the API
406
+ 2. Check logs for schedule loading messages
407
+ 3. Verify that individual jobs are created
408
+ 4. Monitor for job execution at scheduled times
409
+
410
+ ### 3. Test Error Handling
411
+ 1. Test with invalid Supabase credentials
412
+ 2. Test with missing environment variables
413
+ 3. Verify appropriate error messages are logged
414
+
415
+ ## Troubleshooting Guide
416
+
417
+ ### Common Issues and Solutions
418
+
419
+ #### Issue 1: No APScheduler messages in logs
420
+ **Solution**: Ensure logging configuration is added to `backend/app.py`:
421
+ ```python
422
+ import logging
423
+ logging.basicConfig(level=logging.DEBUG)
424
+ logging.getLogger('apscheduler').setLevel(logging.DEBUG)
425
+ ```
426
+
427
+ #### Issue 2: Scheduler initialization fails
428
+ **Solution**: Check environment variables and Supabase connection:
429
+ - Verify `SUPABASE_URL` and `SUPABASE_KEY` are set
430
+ - Check network connectivity to Supabase
431
+ - Verify database tables exist
432
+
433
+ #### Issue 3: Jobs not executing
434
+ **Solution**:
435
+ - Check that the application is running continuously
436
+ - Verify job triggers are correctly configured
437
+ - Check for any exceptions in job execution
438
+
439
+ #### Issue 4: Test script fails
440
+ **Solution**:
441
+ - Ensure all dependencies are installed
442
+ - Check Python path includes the backend directory
443
+ - Verify mock data structure matches actual database schema
444
+
445
+ ## Success Criteria
446
+
447
+ The APScheduler implementation is considered successful when:
448
+
449
+ 1. ✅ **Startup logs** show APScheduler initialization messages
450
+ 2. ✅ **Test scripts** pass all tests
451
+ 3. ✅ **Integration test** shows scheduler working in Flask app
452
+ 4. ✅ **Manual verification** confirms job creation and execution
453
+ 5. ✅ **Error handling** works appropriately
454
+ 6. ✅ **Documentation** is updated with troubleshooting guide
455
+
456
+ ## Next Steps
457
+
458
+ 1. **Approve this test plan**
459
+ 2. **Switch to Code mode** to implement the logging configuration
460
+ 3. **Create the test scripts** outlined in this plan
461
+ 4. **Execute the tests** to verify APScheduler visibility
462
+ 5. **Update documentation** with the final solution
APSCHEDULER_VISIBILITY_FIX.md ADDED
@@ -0,0 +1,170 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ # APScheduler Visibility Fix Plan
2
+
3
+ ## Problem Analysis
4
+
5
+ Based on the provided startup logs and code analysis, the issue is that APScheduler is being initialized in your Flask application but its output is not visible. Here's what's happening:
6
+
7
+ ### Current State
8
+ - ✅ Flask application starts successfully on port 7860
9
+ - ✅ APScheduler is imported and initialized in `backend/app.py`
10
+ - ✅ Scheduler service is properly configured with logging
11
+ - ❌ **No APScheduler output visible in startup logs**
12
+ - ❌ **No verification messages showing scheduler status**
13
+
14
+ ### Root Cause
15
+ The APScheduler logger is not configured to show debug messages. According to APScheduler documentation, you need to explicitly configure logging for the 'apscheduler' logger to see its output.
16
+
17
+ ## Solution Implementation Plan
18
+
19
+ ### Phase 1: Configure APScheduler Logging
20
+
21
+ **File to modify**: `backend/app.py`
22
+
23
+ **Changes needed**:
24
+ 1. Add logging configuration at the beginning of the file
25
+ 2. Configure the 'apscheduler' logger to show DEBUG level messages
26
+ 3. Ensure Flask app logging is also properly configured
27
+
28
+ **Code to add**:
29
+ ```python
30
+ import logging
31
+
32
+ # Configure logging for APScheduler
33
+ logging.basicConfig(
34
+ level=logging.DEBUG,
35
+ format='%(asctime)s - %(name)s - %(levelname)s - %(message)s'
36
+ )
37
+ logging.getLogger('apscheduler').setLevel(logging.DEBUG)
38
+ ```
39
+
40
+ ### Phase 2: Add Startup Verification
41
+
42
+ **File to modify**: `backend/app.py`
43
+
44
+ **Changes needed**:
45
+ 1. Add explicit verification messages after APScheduler initialization
46
+ 2. Check if scheduler started successfully
47
+ 3. Log the number of jobs loaded
48
+
49
+ **Code to add** (after line 131):
50
+ ```python
51
+ # Verify APScheduler initialization
52
+ if hasattr(app, 'scheduler') and app.scheduler.scheduler is not None:
53
+ app.logger.info("✅ APScheduler initialized successfully")
54
+ app.logger.info(f"📊 Current jobs: {len(app.scheduler.scheduler.get_jobs())}")
55
+ app.logger.info("🔄 Schedule loading job added (runs every 5 minutes)")
56
+ else:
57
+ app.logger.warning("⚠️ APScheduler initialization failed")
58
+ ```
59
+
60
+ ### Phase 3: Create Test Script
61
+
62
+ **New file**: `test_scheduler_visibility.py`
63
+
64
+ **Purpose**:
65
+ - Test APScheduler functionality independently
66
+ - Verify logging configuration works
67
+ - Create a test schedule to demonstrate functionality
68
+
69
+ **Features**:
70
+ - Standalone test script
71
+ - Mock database for testing
72
+ - Clear output showing scheduler activity
73
+ - Cleanup of test jobs
74
+
75
+ ### Phase 4: Update Documentation
76
+
77
+ **File to modify**: `APSCHEDULER_SETUP.md`
78
+
79
+ **Additions needed**:
80
+ 1. Section on troubleshooting visibility issues
81
+ 2. Logging configuration instructions
82
+ 3. Test script usage guide
83
+ 4. Common issues and solutions
84
+
85
+ ## Implementation Steps
86
+
87
+ ### Step 1: Configure Logging
88
+ 1. Add logging configuration to `backend/app.py`
89
+ 2. Test that APScheduler messages now appear in logs
90
+
91
+ ### Step 2: Add Verification
92
+ 1. Add startup verification messages
93
+ 2. Ensure scheduler status is clearly reported
94
+
95
+ ### Step 3: Create Test Script
96
+ 1. Create `test_scheduler_visibility.py`
97
+ 2. Test the script to verify functionality
98
+ 3. Document usage instructions
99
+
100
+ ### Step 4: Update Documentation
101
+ 1. Update `APSCHEDULER_SETUP.md` with new troubleshooting section
102
+ 2. Add logging configuration guide
103
+ 3. Document the test script
104
+
105
+ ## Expected Results
106
+
107
+ After implementing this plan, you should see:
108
+
109
+ ### Startup Logs
110
+ ```
111
+ Starting Lin application on port 7860...
112
+ ============================================================
113
+ ============================================================
114
+ Flask application starting...
115
+ Access the application at:
116
+ http://localhost:7860
117
+ http://127.0.0.1:7860
118
+ ============================================================
119
+ * Serving Flask app 'backend.app'
120
+ * Debug mode: off
121
+ INFO:werkzeug:WARNING: This is a development server...
122
+ INFO:backend.app:Initializing APScheduler...
123
+ INFO:backend.apscheduler_service:Initializing APScheduler...
124
+ INFO:backend.apscheduler_service:Initializing Supabase client...
125
+ INFO:backend.apscheduler_service:Supabase client initialized
126
+ INFO:backend.apscheduler_service:Creating BackgroundScheduler...
127
+ INFO:backend.apscheduler_service:BackgroundScheduler created
128
+ INFO:backend.apscheduler_service:Starting scheduler...
129
+ INFO:backend.apscheduler_service:Scheduler started
130
+ INFO:backend.apscheduler_service:Adding periodic job to load schedules...
131
+ INFO:backend.apscheduler_service:Periodic job added
132
+ INFO:backend.apscheduler_service:Loading schedules immediately...
133
+ INFO:backend.apscheduler_service:Found 0 schedules in database
134
+ INFO:backend.apscheduler_service:Updated APScheduler schedule
135
+ INFO:backend.app:✅ APScheduler initialized successfully
136
+ INFO:backend.app:📊 Current jobs: 1
137
+ INFO:backend.app:🔄 Schedule loading job added (runs every 5 minutes)
138
+ ```
139
+
140
+ ### Test Script Output
141
+ ```
142
+ Testing APScheduler visibility...
143
+ ✅ APScheduler initialized successfully
144
+ ✅ Test schedule created
145
+ ✅ Test job added to scheduler
146
+ 📊 Current jobs: 2
147
+ ✅ Test job executed successfully
148
+ ✅ Test job removed
149
+ ✅ All tests passed!
150
+ ```
151
+
152
+ ## Troubleshooting Checklist
153
+
154
+ If you still don't see APScheduler output after implementing this plan:
155
+
156
+ 1. ✅ Check that logging configuration is added to `backend/app.py`
157
+ 2. ✅ Verify that `SCHEDULER_ENABLED=True` in environment variables
158
+ 3. ✅ Check that APScheduler is properly imported and initialized
159
+ 4. ✅ Ensure no other logging configuration is overriding the settings
160
+ 5. ✅ Test with the standalone test script
161
+ 6. ✅ Check for any error messages in the logs
162
+
163
+ ## Next Steps
164
+
165
+ 1. **Approve this plan** - Review and approve the implementation plan
166
+ 2. **Switch to Code mode** - I'll implement the actual code changes
167
+ 3. **Test the solution** - Verify that APScheduler output is now visible
168
+ 4. **Document the fix** - Update documentation for future reference
169
+
170
+ This plan will ensure that APScheduler is not only working but also clearly visible in your application logs, making it easier to monitor and debug scheduling issues.
backend/app.py CHANGED
@@ -1,6 +1,7 @@
1
  import os
2
  import sys
3
  import locale
 
4
  from flask import Flask, send_from_directory, request
5
  from flask_cors import CORS
6
  from flask_jwt_extended import JWTManager
@@ -8,6 +9,13 @@ from flask_jwt_extended import JWTManager
8
  import uuid
9
  from concurrent.futures import ThreadPoolExecutor
10
 
 
 
 
 
 
 
 
11
  # Use relative import for the Config class to work with Hugging Face Spaces
12
  from backend.config import Config
13
  from backend.utils.database import init_supabase
@@ -125,6 +133,14 @@ def create_app():
125
  scheduler = APSchedulerService(app)
126
  app.scheduler = scheduler
127
  app.logger.info("APScheduler initialized successfully")
 
 
 
 
 
 
 
 
128
  except Exception as e:
129
  app.logger.error(f"Failed to initialize APScheduler: {str(e)}")
130
  import traceback
 
1
  import os
2
  import sys
3
  import locale
4
+ import logging
5
  from flask import Flask, send_from_directory, request
6
  from flask_cors import CORS
7
  from flask_jwt_extended import JWTManager
 
9
  import uuid
10
  from concurrent.futures import ThreadPoolExecutor
11
 
12
+ # Configure logging for APScheduler
13
+ logging.basicConfig(
14
+ level=logging.DEBUG,
15
+ format='%(asctime)s - %(name)s - %(levelname)s - %(message)s'
16
+ )
17
+ logging.getLogger('apscheduler').setLevel(logging.DEBUG)
18
+
19
  # Use relative import for the Config class to work with Hugging Face Spaces
20
  from backend.config import Config
21
  from backend.utils.database import init_supabase
 
133
  scheduler = APSchedulerService(app)
134
  app.scheduler = scheduler
135
  app.logger.info("APScheduler initialized successfully")
136
+
137
+ # Verify APScheduler initialization
138
+ if hasattr(app, 'scheduler') and app.scheduler.scheduler is not None:
139
+ app.logger.info("✅ APScheduler initialized successfully")
140
+ app.logger.info(f"📊 Current jobs: {len(app.scheduler.scheduler.get_jobs())}")
141
+ app.logger.info("🔄 Schedule loading job added (runs every 5 minutes)")
142
+ else:
143
+ app.logger.warning("⚠️ APScheduler initialization failed")
144
  except Exception as e:
145
  app.logger.error(f"Failed to initialize APScheduler: {str(e)}")
146
  import traceback
test_scheduler_integration.py ADDED
@@ -0,0 +1,88 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ #!/usr/bin/env python3
2
+ """
3
+ Integration test for APScheduler with Flask application.
4
+ Tests the actual application startup and scheduler initialization.
5
+ """
6
+
7
+ import sys
8
+ import os
9
+ import subprocess
10
+ import time
11
+ from pathlib import Path
12
+
13
+ def test_app_startup_with_scheduler():
14
+ """Test that the Flask application starts with APScheduler visible."""
15
+ try:
16
+ # Change to the project directory
17
+ project_dir = Path(__file__).parent
18
+ os.chdir(project_dir)
19
+
20
+ # Start the application
21
+ print("🚀 Starting Flask application with APScheduler...")
22
+ process = subprocess.Popen(
23
+ [sys.executable, "start_app.py"],
24
+ stdout=subprocess.PIPE,
25
+ stderr=subprocess.STDOUT,
26
+ text=True,
27
+ bufsize=1,
28
+ universal_newlines=True
29
+ )
30
+
31
+ # Wait for startup and capture output
32
+ startup_timeout = 30 # 30 seconds timeout
33
+ start_time = time.time()
34
+
35
+ scheduler_found = False
36
+ verification_found = False
37
+ while time.time() - start_time < startup_timeout:
38
+ output = process.stdout.readline()
39
+ if output:
40
+ print(output.strip())
41
+
42
+ # Check for APScheduler initialization messages
43
+ if "Initializing APScheduler" in output:
44
+ scheduler_found = True
45
+ print("✅ APScheduler initialization message found!")
46
+
47
+ # Check for verification messages
48
+ if "✅ APScheduler initialized successfully" in output:
49
+ verification_found = True
50
+ print("✅ APScheduler verification message found!")
51
+
52
+ # Check for successful startup
53
+ if "running on http" in output.lower():
54
+ break
55
+
56
+ # Terminate the process
57
+ process.terminate()
58
+ process.wait(timeout=10)
59
+
60
+ if scheduler_found and verification_found:
61
+ print("✅ APScheduler is visible during application startup")
62
+ return True
63
+ else:
64
+ print("❌ APScheduler messages not found in startup logs")
65
+ return False
66
+
67
+ except Exception as e:
68
+ print(f"❌ Error testing app startup: {e}")
69
+ return False
70
+
71
+ def main():
72
+ """Main integration test function."""
73
+ print("🔗 Testing APScheduler integration with Flask application...")
74
+ print("=" * 60)
75
+
76
+ success = test_app_startup_with_scheduler()
77
+
78
+ print("\n" + "=" * 60)
79
+ if success:
80
+ print("🎉 Integration test passed! APScheduler is working in the Flask app.")
81
+ else:
82
+ print("⚠️ Integration test failed. APScheduler may not be properly configured.")
83
+
84
+ return success
85
+
86
+ if __name__ == "__main__":
87
+ success = main()
88
+ sys.exit(0 if success else 1)
test_scheduler_visibility.py ADDED
@@ -0,0 +1,186 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ #!/usr/bin/env python3
2
+ """
3
+ Test script for APScheduler visibility and functionality.
4
+ This script tests whether APScheduler is working and properly configured for logging.
5
+ """
6
+
7
+ import sys
8
+ import os
9
+ import logging
10
+ from pathlib import Path
11
+ from datetime import datetime
12
+
13
+ # Add the backend directory to the Python path
14
+ backend_dir = Path(__file__).parent / "backend"
15
+ sys.path.insert(0, str(backend_dir))
16
+
17
+ def setup_logging():
18
+ """Setup logging for the test script."""
19
+ logging.basicConfig(
20
+ level=logging.DEBUG,
21
+ format='%(asctime)s - %(name)s - %(levelname)s - %(message)s'
22
+ )
23
+ # Configure APScheduler logger specifically
24
+ logging.getLogger('apscheduler').setLevel(logging.DEBUG)
25
+ print("Logging configured for APScheduler")
26
+
27
+ def test_apscheduler_import():
28
+ """Test that APScheduler can be imported."""
29
+ try:
30
+ from backend.scheduler.apscheduler_service import APSchedulerService
31
+ print("SUCCESS: APSchedulerService imported successfully")
32
+ return True
33
+ except Exception as e:
34
+ print(f"ERROR: Failed to import APSchedulerService: {e}")
35
+ return False
36
+
37
+ def test_scheduler_initialization():
38
+ """Test APScheduler initialization with mock app."""
39
+ try:
40
+ from backend.scheduler.apscheduler_service import APSchedulerService
41
+
42
+ # Create a mock app object
43
+ class MockApp:
44
+ def __init__(self):
45
+ self.config = {
46
+ 'SUPABASE_URL': 'https://test.supabase.co',
47
+ 'SUPABASE_KEY': 'test_key',
48
+ 'SCHEDULER_ENABLED': True
49
+ }
50
+
51
+ # Initialize the scheduler service
52
+ app = MockApp()
53
+ scheduler_service = APSchedulerService()
54
+
55
+ # Mock the Supabase client initialization
56
+ class MockSupabaseClient:
57
+ def table(self, table_name):
58
+ return self
59
+
60
+ def select(self, columns):
61
+ return self
62
+
63
+ def execute(self):
64
+ # Return empty schedule data for testing
65
+ return type('obj', (object,), {'data': []})()
66
+
67
+ scheduler_service.supabase_client = MockSupabaseClient()
68
+
69
+ # Test initialization
70
+ scheduler_service.init_app(app)
71
+
72
+ if scheduler_service.scheduler is not None:
73
+ print("SUCCESS: APScheduler initialized successfully")
74
+ print(f"INFO: Current jobs: {len(scheduler_service.scheduler.get_jobs())}")
75
+ return True
76
+ else:
77
+ print("ERROR: APScheduler initialization failed")
78
+ return False
79
+
80
+ except Exception as e:
81
+ print(f"ERROR: Error testing APScheduler initialization: {e}")
82
+ import traceback
83
+ traceback.print_exc()
84
+ return False
85
+
86
+ def test_schedule_loading():
87
+ """Test the schedule loading functionality."""
88
+ try:
89
+ from backend.scheduler.apscheduler_service import APSchedulerService
90
+
91
+ # Create scheduler service
92
+ scheduler_service = APSchedulerService()
93
+
94
+ # Mock the Supabase client
95
+ class MockSupabaseClient:
96
+ def table(self, table_name):
97
+ return self
98
+
99
+ def select(self, columns):
100
+ return self
101
+
102
+ def execute(self):
103
+ # Return mock schedule data
104
+ mock_data = [
105
+ {
106
+ 'id': 'test_schedule_1',
107
+ 'schedule_time': 'Monday 09:00',
108
+ 'adjusted_time': 'Monday 08:55',
109
+ 'Social_network': {
110
+ 'id_utilisateur': 'test_user_1',
111
+ 'token': 'test_token',
112
+ 'sub': 'test_sub'
113
+ }
114
+ }
115
+ ]
116
+ return type('obj', (object,), {'data': mock_data})()
117
+
118
+ scheduler_service.supabase_client = MockSupabaseClient()
119
+
120
+ # Test schedule loading
121
+ scheduler_service.load_schedules()
122
+
123
+ if scheduler_service.scheduler is not None:
124
+ jobs = scheduler_service.scheduler.get_jobs()
125
+ print(f"SUCCESS: Schedule loading test completed")
126
+ print(f"INFO: Total jobs: {len(jobs)}")
127
+
128
+ # Check for specific job types
129
+ loader_jobs = [job for job in jobs if job.id == 'load_schedules']
130
+ content_jobs = [job for job in jobs if job.id.startswith('gen_')]
131
+ publish_jobs = [job for job in jobs if job.id.startswith('pub_')]
132
+
133
+ print(f"INFO: Loader jobs: {len(loader_jobs)}")
134
+ print(f"INFO: Content generation jobs: {len(content_jobs)}")
135
+ print(f"INFO: Publishing jobs: {len(publish_jobs)}")
136
+
137
+ return len(jobs) > 0
138
+ else:
139
+ print("ERROR: Scheduler not initialized for schedule loading test")
140
+ return False
141
+
142
+ except Exception as e:
143
+ print(f"ERROR: Error testing schedule loading: {e}")
144
+ import traceback
145
+ traceback.print_exc()
146
+ return False
147
+
148
+ def main():
149
+ """Main test function."""
150
+ print("Testing APScheduler visibility and functionality...")
151
+ print("=" * 60)
152
+
153
+ setup_logging()
154
+
155
+ tests = [
156
+ ("APScheduler Import", test_apscheduler_import),
157
+ ("Scheduler Initialization", test_scheduler_initialization),
158
+ ("Schedule Loading", test_schedule_loading),
159
+ ]
160
+
161
+ passed = 0
162
+ total = len(tests)
163
+
164
+ for test_name, test_func in tests:
165
+ print(f"\nRunning test: {test_name}")
166
+ print("-" * 40)
167
+
168
+ if test_func():
169
+ passed += 1
170
+ print(f"SUCCESS: {test_name} PASSED")
171
+ else:
172
+ print(f"FAILED: {test_name} FAILED")
173
+
174
+ print("\n" + "=" * 60)
175
+ print(f"Test Results: {passed}/{total} tests passed")
176
+
177
+ if passed == total:
178
+ print("SUCCESS: All tests passed! APScheduler is working correctly.")
179
+ return True
180
+ else:
181
+ print("WARNING: Some tests failed. Please check the error messages above.")
182
+ return False
183
+
184
+ if __name__ == "__main__":
185
+ success = main()
186
+ sys.exit(0 if success else 1)