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