Update app.py
Browse files
app.py
CHANGED
@@ -120,137 +120,7 @@ async def download_post(request: PostRequest):
|
|
120 |
return {"download_url": download_url}
|
121 |
|
122 |
|
123 |
-
# Directly embed session data
|
124 |
-
SESSION_DATA = {
|
125 |
-
"sessionid": "49379440378%3AAMKUUgo79iWhmt%3A1%3AAYcuPYtZFJAwzPlT0u_xuXkaiBHbDJ-8igmXkPBmzQ",
|
126 |
-
"mid": "Z07d8AALAAHe7OnMarRANiQOAt7a",
|
127 |
-
"ig_pr": "1",
|
128 |
-
"ig_vw": "1920",
|
129 |
-
"ig_cb": "1",
|
130 |
-
"csrftoken": "xNZpGQiAKQkf4IU2E8UAV0snSGMZEPCt",
|
131 |
-
"s_network": "",
|
132 |
-
"ds_user_id": "49379440378",
|
133 |
-
"ig_did": "0DCC4ACA-6794-4778-88D8-573410BD5CC4"
|
134 |
-
}
|
135 |
|
136 |
-
app = FastAPI()
|
137 |
-
|
138 |
-
class DownloadRequest(BaseModel):
|
139 |
-
url: str
|
140 |
-
|
141 |
-
class DownloadResponse(BaseModel):
|
142 |
-
success: bool
|
143 |
-
message: str
|
144 |
-
urls: Optional[List[str]] = None
|
145 |
-
type: Optional[str] = None
|
146 |
-
shortcode: Optional[str] = None
|
147 |
-
|
148 |
-
class StoryRequest(BaseModel):
|
149 |
-
username: Optional[str] = None
|
150 |
-
url: Optional[str] = None
|
151 |
-
|
152 |
-
class StoryResponse(BaseModel):
|
153 |
-
success: bool
|
154 |
-
message: str
|
155 |
-
urls: Optional[List[str]] = None
|
156 |
-
|
157 |
-
def get_authenticated_loader():
|
158 |
-
"""Create and return an authenticated Instaloader instance"""
|
159 |
-
loader = instaloader.Instaloader(
|
160 |
-
download_videos=True,
|
161 |
-
download_video_thumbnails=False,
|
162 |
-
download_geotags=False,
|
163 |
-
download_comments=False,
|
164 |
-
save_metadata=False,
|
165 |
-
compress_json=False,
|
166 |
-
sleep=True,
|
167 |
-
quiet=True
|
168 |
-
)
|
169 |
-
|
170 |
-
try:
|
171 |
-
# Set the session data directly
|
172 |
-
loader.context._session.cookies.update(SESSION_DATA)
|
173 |
-
|
174 |
-
# Verify session is valid
|
175 |
-
test_profile = instaloader.Profile.from_username(loader.context, INSTAGRAM_USERNAME)
|
176 |
-
_ = test_profile.userid
|
177 |
-
logger.info("Successfully loaded and verified session")
|
178 |
-
return loader
|
179 |
-
|
180 |
-
except Exception as e:
|
181 |
-
logger.error(f"Failed to load session: {str(e)}")
|
182 |
-
raise HTTPException(
|
183 |
-
status_code=500,
|
184 |
-
detail="Failed to authenticate with Instagram"
|
185 |
-
)
|
186 |
-
|
187 |
-
@app.post("/api/story", response_model=StoryResponse)
|
188 |
-
async def download_story(request: StoryRequest):
|
189 |
-
try:
|
190 |
-
# Extract username from request
|
191 |
-
if request.url:
|
192 |
-
username = request.url.split('/')[-1].split('?')[0]
|
193 |
-
elif request.username:
|
194 |
-
username = request.username
|
195 |
-
else:
|
196 |
-
raise HTTPException(status_code=400, detail="Username or URL is required")
|
197 |
-
|
198 |
-
# Add small delay to avoid rate limiting
|
199 |
-
time.sleep(random.uniform(1, 3))
|
200 |
-
|
201 |
-
# Get authenticated loader
|
202 |
-
loader = get_authenticated_loader()
|
203 |
-
|
204 |
-
try:
|
205 |
-
# Fetch profile
|
206 |
-
profile = instaloader.Profile.from_username(loader.context, username)
|
207 |
-
|
208 |
-
# Add small delay before fetching stories
|
209 |
-
time.sleep(random.uniform(2, 4))
|
210 |
-
|
211 |
-
# Get stories
|
212 |
-
story_items = loader.get_stories(userids=[profile.userid])
|
213 |
-
|
214 |
-
urls = []
|
215 |
-
story_item_count = 0
|
216 |
-
|
217 |
-
for story in story_items:
|
218 |
-
for item in story.get_items():
|
219 |
-
story_item_count += 1
|
220 |
-
if item.is_video:
|
221 |
-
urls.append(item.video_url)
|
222 |
-
else:
|
223 |
-
urls.append(item.url)
|
224 |
-
|
225 |
-
if story_item_count == 0:
|
226 |
-
return StoryResponse(
|
227 |
-
success=True,
|
228 |
-
message="No active stories found for this user",
|
229 |
-
urls=[]
|
230 |
-
)
|
231 |
-
|
232 |
-
return StoryResponse(
|
233 |
-
success=True,
|
234 |
-
message=f"Retrieved {story_item_count} stories successfully",
|
235 |
-
urls=urls
|
236 |
-
)
|
237 |
-
|
238 |
-
except instaloader.exceptions.ProfileNotExistsException:
|
239 |
-
raise HTTPException(status_code=404, detail="Instagram profile not found")
|
240 |
-
|
241 |
-
except Exception as e:
|
242 |
-
if "429" in str(e):
|
243 |
-
raise HTTPException(
|
244 |
-
status_code=429,
|
245 |
-
detail="Rate limited by Instagram. Please try again in 15 minutes."
|
246 |
-
)
|
247 |
-
raise
|
248 |
-
|
249 |
-
except HTTPException:
|
250 |
-
raise
|
251 |
-
except Exception as e:
|
252 |
-
logger.error(f"Story download error: {str(e)}")
|
253 |
-
raise HTTPException(status_code=500, detail=str(e))
|
254 |
|
255 |
@app.get("/api/health")
|
256 |
async def health_check():
|
|
|
120 |
return {"download_url": download_url}
|
121 |
|
122 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
123 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
124 |
|
125 |
@app.get("/api/health")
|
126 |
async def health_check():
|