chipling commited on
Commit
d6fb459
·
verified ·
1 Parent(s): 44bafb2

Update app.py

Browse files
Files changed (1) hide show
  1. app.py +95 -3
app.py CHANGED
@@ -1,7 +1,99 @@
1
- from fastapi import FastAPI
 
 
 
 
 
 
 
2
 
 
 
 
 
 
 
 
3
  app = FastAPI()
 
 
 
 
 
 
 
4
 
5
  @app.get("/")
6
- def greet_json():
7
- return {"Hello": "World!"}
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ from pytubefix import YouTube
2
+ from pytubefix.cli import on_progress
3
+ from fastapi import FastAPI, HTTPException
4
+ from fastapi.middleware.cors import CORSMiddleware
5
+ import logging as log
6
+ import subprocess
7
+ import json
8
+ from typing import Tuple
9
 
10
+ # --- Logging Setup ---
11
+ log.basicConfig(
12
+ level=log.INFO,
13
+ format="%(asctime)s [%(levelname)s] %(message)s",
14
+ )
15
+
16
+ # --- FastAPI Setup ---
17
  app = FastAPI()
18
+ app.add_middleware(
19
+ CORSMiddleware,
20
+ allow_origins=["*"], # Adjust in production
21
+ allow_credentials=True,
22
+ allow_methods=["*"],
23
+ allow_headers=["*"],
24
+ )
25
 
26
  @app.get("/")
27
+ def index():
28
+ return {"message": "Hello, World!"}
29
+
30
+
31
+ # --- Shell Command Runner ---
32
+ def cmd(command, check=True, shell=True, capture_output=True, text=True):
33
+ log.info(f"Executing command: {command}")
34
+ try:
35
+ result = subprocess.run(
36
+ command,
37
+ check=check,
38
+ shell=shell,
39
+ capture_output=capture_output,
40
+ text=text
41
+ )
42
+ log.info("Command executed successfully.")
43
+ return result
44
+ except subprocess.CalledProcessError as error:
45
+ log.error(f"Command failed: {error}")
46
+ raise HTTPException(status_code=500, detail="Token generation failed.")
47
+
48
+
49
+ # --- Token Generator ---
50
+ def generate_youtube_token() -> dict:
51
+ result = cmd("node test.js")
52
+ if not result or not result.stdout:
53
+ log.error("No output received from test.js")
54
+ raise HTTPException(status_code=500, detail="Invalid token response")
55
+
56
+ try:
57
+ data = json.loads(result.stdout)
58
+ log.info(f"Token data received: {data}")
59
+ return data
60
+ except json.JSONDecodeError as e:
61
+ log.error(f"Failed to decode token JSON: {e}")
62
+ raise HTTPException(status_code=500, detail="Invalid JSON from token generator")
63
+
64
+
65
+ # --- Token Verifier Function ---
66
+ def po_token_verifier() -> Tuple[str, str]:
67
+ token_object = generate_youtube_token()
68
+ return token_object["visitorData"], token_object["poToken"]
69
+
70
+
71
+ # --- Video Fetch Endpoint ---
72
+ @app.get("/api/video/{id}")
73
+ def video_id(id: str):
74
+ url = f"https://www.youtube.com/watch?v={id}"
75
+ log.info(f"Fetching YouTube video for ID: {id}")
76
+
77
+ try:
78
+ yt = YouTube(
79
+ url,
80
+ use_po_token=True,
81
+ po_token_verifier=po_token_verifier
82
+ )
83
+ ys = yt.streams.get_highest_resolution()
84
+
85
+ if not ys:
86
+ log.warning("No suitable video stream found.")
87
+ raise HTTPException(status_code=404, detail="No suitable video stream found")
88
+
89
+ log.info(f"Video fetched: {yt.title}")
90
+ return {
91
+ "title": yt.title,
92
+ "url": ys.url,
93
+ "thumbnail": yt.thumbnail_url,
94
+ "description": yt.description
95
+ }
96
+
97
+ except Exception as e:
98
+ log.error(f"Failed to fetch video info: {e}")
99
+ raise HTTPException(status_code=500, detail=str(e))