Update app.py
Browse files
app.py
CHANGED
@@ -20,7 +20,6 @@ INSTAGRAM_PASSWORD = os.getenv('INSTAGRAM_PASSWORD')
|
|
20 |
logging.basicConfig(level=logging.INFO)
|
21 |
logger = logging.getLogger(__name__)
|
22 |
|
23 |
-
|
24 |
# Check if credentials are available
|
25 |
if not INSTAGRAM_USERNAME or not INSTAGRAM_PASSWORD:
|
26 |
logger.error("Instagram credentials are not set in the environment variables.")
|
@@ -46,21 +45,18 @@ class DownloadResponse(BaseModel):
|
|
46 |
def extract_shortcode(url: str) -> str:
|
47 |
"""Extract Instagram post shortcode from URL"""
|
48 |
url = url.strip()
|
49 |
-
# Correct the check for 'instagram.com'
|
50 |
if 'instagram.com' not in url:
|
51 |
raise ValueError("Invalid Instagram URL")
|
52 |
-
|
53 |
parts = url.split('/')
|
54 |
for i, part in enumerate(parts):
|
55 |
-
if part in ['p', 'reel', 'tv'] and (i+1) < len(parts):
|
56 |
-
shortcode = parts[i+1].split('?')[0]
|
57 |
return shortcode
|
58 |
-
|
59 |
if 'instagram.com/p/' in url:
|
60 |
return url.split('/p/')[1].split('/')[0].split('?')[0]
|
61 |
-
|
62 |
raise ValueError("Invalid Instagram URL")
|
63 |
|
|
|
64 |
@app.post("/dl", response_model=DownloadResponse)
|
65 |
async def download_post(request: PostRequest):
|
66 |
"""Download Instagram post and return media URL"""
|
@@ -72,41 +68,47 @@ async def download_post(request: PostRequest):
|
|
72 |
raise HTTPException(status_code=400, detail=str(e))
|
73 |
|
74 |
L = instaloader.Instaloader()
|
75 |
-
|
76 |
-
|
77 |
-
|
78 |
-
|
79 |
-
|
80 |
-
|
81 |
-
|
82 |
-
|
83 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
84 |
# Configure retry parameters
|
85 |
max_retries = 3
|
86 |
-
retry_delay = random.uniform(
|
87 |
-
|
88 |
for attempt in range(max_retries):
|
89 |
try:
|
90 |
# Fetch post by shortcode
|
91 |
post = instaloader.Post.from_shortcode(L.context, shortcode)
|
92 |
logger.info(f"Fetched post: {post}")
|
93 |
break
|
94 |
-
|
95 |
except instaloader.exceptions.ConnectionException as e:
|
96 |
logger.error(f"Connection error (attempt {attempt + 1}): {e}")
|
97 |
if attempt == max_retries - 1:
|
98 |
raise HTTPException(status_code=500, detail="Failed to connect to Instagram after multiple attempts")
|
99 |
time.sleep(retry_delay)
|
100 |
retry_delay *= 2 # Exponential backoff
|
101 |
-
|
102 |
except instaloader.exceptions.InvalidArgumentException:
|
103 |
logger.error(f"Post not found for shortcode: {shortcode}")
|
104 |
raise HTTPException(status_code=404, detail="Post not found")
|
105 |
-
|
106 |
except instaloader.exceptions.InstaloaderException as e:
|
107 |
logger.error(f"Instaloader error: {e}")
|
108 |
raise HTTPException(status_code=500, detail="Error fetching post")
|
109 |
-
|
110 |
except Exception as e:
|
111 |
logger.error(f"Unexpected error: {e}")
|
112 |
raise HTTPException(status_code=500, detail="Internal server error")
|
@@ -126,4 +128,4 @@ async def download_post(request: PostRequest):
|
|
126 |
|
127 |
@app.get("/api/health")
|
128 |
async def health_check():
|
129 |
-
return {"status": "healthy"}
|
|
|
20 |
logging.basicConfig(level=logging.INFO)
|
21 |
logger = logging.getLogger(__name__)
|
22 |
|
|
|
23 |
# Check if credentials are available
|
24 |
if not INSTAGRAM_USERNAME or not INSTAGRAM_PASSWORD:
|
25 |
logger.error("Instagram credentials are not set in the environment variables.")
|
|
|
45 |
def extract_shortcode(url: str) -> str:
|
46 |
"""Extract Instagram post shortcode from URL"""
|
47 |
url = url.strip()
|
|
|
48 |
if 'instagram.com' not in url:
|
49 |
raise ValueError("Invalid Instagram URL")
|
|
|
50 |
parts = url.split('/')
|
51 |
for i, part in enumerate(parts):
|
52 |
+
if part in ['p', 'reel', 'tv'] and (i + 1) < len(parts):
|
53 |
+
shortcode = parts[i + 1].split('?')[0]
|
54 |
return shortcode
|
|
|
55 |
if 'instagram.com/p/' in url:
|
56 |
return url.split('/p/')[1].split('/')[0].split('?')[0]
|
|
|
57 |
raise ValueError("Invalid Instagram URL")
|
58 |
|
59 |
+
|
60 |
@app.post("/dl", response_model=DownloadResponse)
|
61 |
async def download_post(request: PostRequest):
|
62 |
"""Download Instagram post and return media URL"""
|
|
|
68 |
raise HTTPException(status_code=400, detail=str(e))
|
69 |
|
70 |
L = instaloader.Instaloader()
|
71 |
+
session_file = f"{INSTAGRAM_USERNAME}.session"
|
72 |
+
|
73 |
+
if os.path.exists(session_file):
|
74 |
+
try:
|
75 |
+
L.load_session_from_file(INSTAGRAM_USERNAME, session_file)
|
76 |
+
logger.info("Loaded session from file.")
|
77 |
+
except FileNotFoundError:
|
78 |
+
pass
|
79 |
+
else:
|
80 |
+
try:
|
81 |
+
# Login to Instagram
|
82 |
+
L.login(INSTAGRAM_USERNAME, INSTAGRAM_PASSWORD)
|
83 |
+
logger.info("Successfully logged in to Instagram")
|
84 |
+
L.save_session_to_file(session_file)
|
85 |
+
logger.info("Saved session to file.")
|
86 |
+
except instaloader.exceptions.InstaloaderException as e:
|
87 |
+
logger.error(f"Login error: {e}")
|
88 |
+
raise HTTPException(status_code=500, detail="Error logging in to Instagram")
|
89 |
+
|
90 |
# Configure retry parameters
|
91 |
max_retries = 3
|
92 |
+
retry_delay = random.uniform(1, 3)
|
93 |
+
|
94 |
for attempt in range(max_retries):
|
95 |
try:
|
96 |
# Fetch post by shortcode
|
97 |
post = instaloader.Post.from_shortcode(L.context, shortcode)
|
98 |
logger.info(f"Fetched post: {post}")
|
99 |
break
|
|
|
100 |
except instaloader.exceptions.ConnectionException as e:
|
101 |
logger.error(f"Connection error (attempt {attempt + 1}): {e}")
|
102 |
if attempt == max_retries - 1:
|
103 |
raise HTTPException(status_code=500, detail="Failed to connect to Instagram after multiple attempts")
|
104 |
time.sleep(retry_delay)
|
105 |
retry_delay *= 2 # Exponential backoff
|
|
|
106 |
except instaloader.exceptions.InvalidArgumentException:
|
107 |
logger.error(f"Post not found for shortcode: {shortcode}")
|
108 |
raise HTTPException(status_code=404, detail="Post not found")
|
|
|
109 |
except instaloader.exceptions.InstaloaderException as e:
|
110 |
logger.error(f"Instaloader error: {e}")
|
111 |
raise HTTPException(status_code=500, detail="Error fetching post")
|
|
|
112 |
except Exception as e:
|
113 |
logger.error(f"Unexpected error: {e}")
|
114 |
raise HTTPException(status_code=500, detail="Internal server error")
|
|
|
128 |
|
129 |
@app.get("/api/health")
|
130 |
async def health_check():
|
131 |
+
return {"status": "healthy"}
|