zohaibk43 commited on
Commit
c58c436
·
verified ·
1 Parent(s): 4f67310
Files changed (1) hide show
  1. main.py +77 -0
main.py ADDED
@@ -0,0 +1,77 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ from fastapi import FastAPI, HTTPException
2
+ from fastapi.middleware.cors import CORSMiddleware
3
+ from youtube_transcript_api import YouTubeTranscriptApi, TranscriptsDisabled, NoTranscriptFound, VideoUnavailable
4
+ import re
5
+
6
+ app = FastAPI()
7
+
8
+ # Enable CORS so your Vercel frontend can call this API
9
+ app.add_middleware(
10
+ CORSMiddleware,
11
+ allow_origins=["*"], # In production, you can change "*" to your Vercel URL
12
+ allow_credentials=True,
13
+ allow_methods=["*"],
14
+ allow_headers=["*"],
15
+ )
16
+
17
+ def extract_video_id(url: str) -> str:
18
+ pattern = r'(?:youtube\.com\/(?:[^\/]+\/.+\/|(?:v|e(?:mbed)?)\/|.*[?&]v=)|youtu\.be\/)([^"&?\/\s]{11})'
19
+ match = re.match(pattern, url)
20
+ if match:
21
+ return match.group(1)
22
+ return None
23
+
24
+ @app.post("/api/transcript")
25
+ async def get_transcript(request: dict):
26
+ url = request.get("url")
27
+ if not url:
28
+ raise HTTPException(status_code=400, detail="Missing URL")
29
+
30
+ video_id = extract_video_id(url)
31
+ if not video_id:
32
+ raise HTTPException(status_code=400, detail="Invalid YouTube URL")
33
+
34
+ try:
35
+ # Fetch available transcripts
36
+ transcript_list = YouTubeTranscriptApi.list_transcripts(video_id)
37
+
38
+ # Find the best transcript (Prefer manual English, then auto English, then any other)
39
+ transcript = None
40
+ try:
41
+ transcript = transcript_list.find_manually_created_transcript(['en'])
42
+ except NoTranscriptFound:
43
+ try:
44
+ transcript = transcript_list.find_generated_transcript(['en'])
45
+ except NoTranscriptFound:
46
+ # If no English, get the first available language
47
+ for t in transcript_list:
48
+ transcript = t
49
+ break
50
+
51
+ if not transcript:
52
+ raise HTTPException(status_code=404, detail="No captions found for this video.")
53
+
54
+ # Fetch the actual text data
55
+ transcript_data = transcript.fetch()
56
+
57
+ # Combine all text lines
58
+ full_text = " ".join([line['text'] for line in transcript_data])
59
+
60
+ # Clean up HTML entities
61
+ full_text = full_text.replace("'", "'").replace(""", '"').replace("&", "&").replace("'", "'")
62
+
63
+ return {"text": full_text}
64
+
65
+ except TranscriptsDisabled:
66
+ raise HTTPException(status_code=403, detail="Captions are disabled for this video.")
67
+ except VideoUnavailable:
68
+ raise HTTPException(status_code=404, detail="Video is unavailable.")
69
+ except Exception as e:
70
+ raise HTTPException(status_code=500, detail=f"Failed to fetch transcript: {str(e)}")
71
+
72
+ # ========================================================
73
+ # KEEP-ALIVE ENDPOINT
74
+ # ========================================================
75
+ @app.get("/api/health")
76
+ async def health_check():
77
+ return {"status": "ok", "message": "Transcript API is running!"}