Chrunos commited on
Commit
3e281c8
·
verified ·
1 Parent(s): a865c99

Create main.py

Browse files
Files changed (1) hide show
  1. main.py +110 -0
main.py ADDED
@@ -0,0 +1,110 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ # main.py
2
+ from fastapi import FastAPI, HTTPException
3
+ from pydantic import BaseModel
4
+ import instaloader
5
+ import os
6
+ from dotenv import load_dotenv
7
+ import re
8
+ from typing import Optional, List
9
+
10
+ # Load environment variables
11
+ load_dotenv()
12
+
13
+ # Get credentials from environment variables
14
+ INSTAGRAM_USERNAME = os.getenv('INSTAGRAM_USERNAME')
15
+ INSTAGRAM_PASSWORD = os.getenv('INSTAGRAM_PASSWORD')
16
+
17
+ app = FastAPI(title="Instagram Downloader API")
18
+
19
+ class DownloadRequest(BaseModel):
20
+ url: str
21
+
22
+ class DownloadResponse(BaseModel):
23
+ success: bool
24
+ message: str
25
+ urls: Optional[List[str]] = None
26
+ type: Optional[str] = None
27
+ shortcode: Optional[str] = None
28
+
29
+ def clean_url(url: str) -> Optional[str]:
30
+ """Clean Instagram URL and extract shortcode"""
31
+ try:
32
+ cleaned_url = url.split('?')[0].split('#')[0].strip('/')
33
+ patterns = [
34
+ r'instagram.com/reel/([A-Za-z0-9_-]+)',
35
+ r'instagram.com/p/([A-Za-z0-9_-]+)',
36
+ r'instagram.com/stories/([A-Za-z0-9_-]+)',
37
+ r'/([A-Za-z0-9_-]{11})[/]?$'
38
+ ]
39
+
40
+ for pattern in patterns:
41
+ match = re.search(pattern, cleaned_url)
42
+ if match:
43
+ return match.group(1)
44
+
45
+ segments = cleaned_url.split('/')
46
+ if segments:
47
+ return segments[-1]
48
+
49
+ return None
50
+ except Exception:
51
+ return None
52
+
53
+ @app.post("/api/download", response_model=DownloadResponse)
54
+ async def download_media(request: DownloadRequest):
55
+ try:
56
+ # Extract shortcode
57
+ shortcode = clean_url(request.url)
58
+ if not shortcode:
59
+ raise HTTPException(status_code=400, detail="Invalid URL format")
60
+
61
+ # Initialize loader
62
+ loader = instaloader.Instaloader(
63
+ download_videos=True,
64
+ download_video_thumbnails=False,
65
+ download_geotags=False,
66
+ download_comments=False,
67
+ save_metadata=False,
68
+ compress_json=False
69
+ )
70
+
71
+ # Login
72
+ if not all([INSTAGRAM_USERNAME, INSTAGRAM_PASSWORD]):
73
+ raise HTTPException(status_code=500, detail="Missing Instagram credentials")
74
+
75
+ loader.login(INSTAGRAM_USERNAME, INSTAGRAM_PASSWORD)
76
+
77
+ # Get post
78
+ post = instaloader.Post.from_shortcode(loader.context, shortcode)
79
+
80
+ urls = []
81
+
82
+ if post.is_video:
83
+ media_type = "video"
84
+ urls.append(post.video_url)
85
+ else:
86
+ media_type = "image"
87
+ if post.typename == "GraphSidecar":
88
+ # Multiple images
89
+ for node in post.get_sidecar_nodes():
90
+ urls.append(node.display_url)
91
+ else:
92
+ # Single image
93
+ urls.append(post.url)
94
+
95
+ return DownloadResponse(
96
+ success=True,
97
+ message="Media URLs retrieved successfully",
98
+ urls=urls,
99
+ type=media_type,
100
+ shortcode=shortcode
101
+ )
102
+
103
+ except instaloader.exceptions.InstaloaderException as e:
104
+ raise HTTPException(status_code=400, detail=str(e))
105
+ except Exception as e:
106
+ raise HTTPException(status_code=500, detail=str(e))
107
+
108
+ @app.get("/api/health")
109
+ async def health_check():
110
+ return {"status": "healthy"}