ALI7ADEL commited on
Commit
706cf87
·
verified ·
1 Parent(s): 9dff554

Update run.py

Browse files
Files changed (1) hide show
  1. run.py +138 -137
run.py CHANGED
@@ -1,137 +1,138 @@
1
- """
2
- Main entry point for YouTube Study Notes AI.
3
- Provides CLI interface and server startup.
4
- """
5
-
6
- import sys
7
- import argparse
8
- from pathlib import Path
9
-
10
- # Import necessary modules for server and middleware
11
- from src.utils.logger import setup_logger
12
- from src.utils.config import settings
13
-
14
- logger = setup_logger(__name__)
15
-
16
-
17
- def run_server():
18
- """Start the FastAPI server with CORS enabled for Flutter Web."""
19
- import uvicorn
20
- from fastapi.middleware.cors import CORSMiddleware
21
- from src.api.main import app # Import the app instance directly
22
-
23
- logger.info("Configuring CORS for Flutter Web...")
24
-
25
- # Add CORS Middleware to allow requests from Chrome/Flutter
26
- app.add_middleware(
27
- CORSMiddleware,
28
- allow_origins=["*"], # Allows all origins
29
- allow_credentials=True,
30
- allow_methods=["*"], # Allows all methods
31
- allow_headers=["*"], # Allows all headers
32
- )
33
-
34
- logger.info("Starting YouTube Study Notes AI server...")
35
- logger.info(
36
- f"Server will be available at http://{settings.api_host}:{settings.api_port}"
37
- )
38
- logger.info(
39
- f"API Documentation: http://{settings.api_host}:{settings.api_port}/docs"
40
- )
41
-
42
- # Run the server using the app object directly
43
- # Note: reload is disabled here to ensure CORS settings are applied correctly from this script
44
- uvicorn.run(app, host=settings.api_host, port=settings.api_port, log_level="info")
45
-
46
-
47
- def run_cli(youtube_url: str, output_file: str = None):
48
- """
49
- Run note generation from command line.
50
-
51
- Args:
52
- youtube_url: YouTube video URL
53
- output_file: Optional output file path
54
- """
55
- from src.audio.downloader import YouTubeDownloader
56
- from src.transcription.whisper_transcriber import WhisperTranscriber
57
- from src.summarization.note_generator import NoteGenerator
58
-
59
- logger.info("Starting CLI mode")
60
- logger.info(f"Processing URL: {youtube_url}")
61
-
62
- try:
63
- # Step 1: Download audio
64
- logger.info("Step 1/3: Downloading audio...")
65
- downloader = YouTubeDownloader()
66
- video_info = downloader.get_video_info(youtube_url)
67
- audio_file = downloader.download_audio(youtube_url)
68
-
69
- # Step 2: Transcribe
70
- logger.info("Step 2/3: Transcribing audio...")
71
- transcriber = WhisperTranscriber()
72
- transcript_data = transcriber.transcribe(audio_file)
73
-
74
- # Step 3: Generate notes
75
- logger.info("Step 3/3: Generating notes...")
76
- note_gen = NoteGenerator()
77
- notes = note_gen.generate_notes_from_full_transcript(
78
- transcript_data["text"], video_info["title"]
79
- )
80
-
81
- # Format and save
82
- final_notes = note_gen.format_final_notes(
83
- notes, video_info["title"], youtube_url, video_info["duration"]
84
- )
85
-
86
- if output_file:
87
- output_path = Path(output_file)
88
- else:
89
- output_path = settings.output_dir / f"{video_info['title'][:50]}_notes.md"
90
-
91
- output_path.write_text(final_notes, encoding="utf-8")
92
-
93
- logger.info(f"✅ Notes saved to: {output_path}")
94
- print(f"\nSuccess! Notes saved to: {output_path}")
95
-
96
- # Cleanup
97
- downloader.cleanup(audio_file)
98
-
99
- except Exception as e:
100
- logger.error(f"Failed: {e}")
101
- print(f"\n❌ Error: {e}")
102
- sys.exit(1)
103
-
104
-
105
- def main():
106
- """Main entry point with argument parsing."""
107
- parser = argparse.ArgumentParser(
108
- description="YouTube Study Notes AI - Generate structured notes from educational videos"
109
- )
110
-
111
- parser.add_argument(
112
- "mode",
113
- choices=["server", "cli"],
114
- help="Run mode: server (API + web UI) or cli (direct processing)",
115
- )
116
-
117
- parser.add_argument(
118
- "--url", type=str, help="YouTube video URL (required for cli mode)"
119
- )
120
-
121
- parser.add_argument(
122
- "--output", type=str, help="Output file path (optional for cli mode)"
123
- )
124
-
125
- args = parser.parse_args()
126
-
127
- if args.mode == "server":
128
- run_server()
129
- elif args.mode == "cli":
130
- if not args.url:
131
- print("Error: --url is required for cli mode")
132
- sys.exit(1)
133
- run_cli(args.url, args.output)
134
-
135
-
136
- if __name__ == "__main__":
137
- main()
 
 
1
+ """
2
+ Main entry point for YouTube Study Notes AI.
3
+ Provides CLI interface and server startup.
4
+ """
5
+
6
+ import sys
7
+ import argparse
8
+ from pathlib import Path
9
+ import os # Added to read environment variables
10
+
11
+ # Import necessary modules for server and middleware
12
+ from src.utils.logger import setup_logger
13
+ from src.utils.config import settings
14
+
15
+ logger = setup_logger(__name__)
16
+
17
+
18
+ def run_server():
19
+ """Start the FastAPI server with CORS enabled for Flutter Web."""
20
+ import uvicorn
21
+ from fastapi.middleware.cors import CORSMiddleware
22
+ from src.api.main import app # Import the app instance directly
23
+
24
+ logger.info("Configuring CORS for Flutter Web...")
25
+
26
+ # Add CORS Middleware to allow requests from Chrome/Flutter
27
+ app.add_middleware(
28
+ CORSMiddleware,
29
+ allow_origins=["*"], # Allows all origins
30
+ allow_credentials=True,
31
+ allow_methods=["*"], # Allows all methods
32
+ allow_headers=["*"], # Allows all headers
33
+ )
34
+
35
+ # Use port 7860 for Hugging Face, or default to 8000 locally
36
+ # This ensures compatibility with Hugging Face Spaces
37
+ port = int(os.environ.get("PORT", 7860))
38
+
39
+ logger.info("Starting YouTube Study Notes AI server...")
40
+ logger.info(f"Server will be available at http://0.0.0.0:{port}")
41
+ logger.info(f"API Documentation: http://0.0.0.0:{port}/docs")
42
+
43
+ # Run the server using the app object directly
44
+ # IMPORTANT: host must be "0.0.0.0" and port must be 7860 for Hugging Face
45
+ uvicorn.run(app, host="0.0.0.0", port=port, log_level="info")
46
+
47
+
48
+ def run_cli(youtube_url: str, output_file: str = None):
49
+ """
50
+ Run note generation from command line.
51
+
52
+ Args:
53
+ youtube_url: YouTube video URL
54
+ output_file: Optional output file path
55
+ """
56
+ from src.audio.downloader import YouTubeDownloader
57
+ from src.transcription.whisper_transcriber import WhisperTranscriber
58
+ from src.summarization.note_generator import NoteGenerator
59
+
60
+ logger.info("Starting CLI mode")
61
+ logger.info(f"Processing URL: {youtube_url}")
62
+
63
+ try:
64
+ # Step 1: Download audio
65
+ logger.info("Step 1/3: Downloading audio...")
66
+ downloader = YouTubeDownloader()
67
+ video_info = downloader.get_video_info(youtube_url)
68
+ audio_file = downloader.download_audio(youtube_url)
69
+
70
+ # Step 2: Transcribe
71
+ logger.info("Step 2/3: Transcribing audio...")
72
+ transcriber = WhisperTranscriber()
73
+ transcript_data = transcriber.transcribe(audio_file)
74
+
75
+ # Step 3: Generate notes
76
+ logger.info("Step 3/3: Generating notes...")
77
+ note_gen = NoteGenerator()
78
+ notes = note_gen.generate_notes_from_full_transcript(
79
+ transcript_data["text"], video_info["title"]
80
+ )
81
+
82
+ # Format and save
83
+ final_notes = note_gen.format_final_notes(
84
+ notes, video_info["title"], youtube_url, video_info["duration"]
85
+ )
86
+
87
+ if output_file:
88
+ output_path = Path(output_file)
89
+ else:
90
+ output_path = settings.output_dir / f"{video_info['title'][:50]}_notes.md"
91
+
92
+ output_path.write_text(final_notes, encoding="utf-8")
93
+
94
+ logger.info(f"✅ Notes saved to: {output_path}")
95
+ print(f"\n✅ Success! Notes saved to: {output_path}")
96
+
97
+ # Cleanup
98
+ downloader.cleanup(audio_file)
99
+
100
+ except Exception as e:
101
+ logger.error(f"Failed: {e}")
102
+ print(f"\n❌ Error: {e}")
103
+ sys.exit(1)
104
+
105
+
106
+ def main():
107
+ """Main entry point with argument parsing."""
108
+ parser = argparse.ArgumentParser(
109
+ description="YouTube Study Notes AI - Generate structured notes from educational videos"
110
+ )
111
+
112
+ parser.add_argument(
113
+ "mode",
114
+ choices=["server", "cli"],
115
+ help="Run mode: server (API + web UI) or cli (direct processing)",
116
+ )
117
+
118
+ parser.add_argument(
119
+ "--url", type=str, help="YouTube video URL (required for cli mode)"
120
+ )
121
+
122
+ parser.add_argument(
123
+ "--output", type=str, help="Output file path (optional for cli mode)"
124
+ )
125
+
126
+ args = parser.parse_args()
127
+
128
+ if args.mode == "server":
129
+ run_server()
130
+ elif args.mode == "cli":
131
+ if not args.url:
132
+ print("Error: --url is required for cli mode")
133
+ sys.exit(1)
134
+ run_cli(args.url, args.output)
135
+
136
+
137
+ if __name__ == "__main__":
138
+ main()