rkihacker commited on
Commit
69bfb34
·
verified ·
1 Parent(s): 4f9dc53

Update main.py

Browse files
Files changed (1) hide show
  1. main.py +12 -24
main.py CHANGED
@@ -2,7 +2,7 @@ import os
2
  import asyncio
3
  from telethon.sync import TelegramClient
4
  from telethon.sessions import StringSession
5
- from fastapi import FastAPI, UploadFile, File, HTTPException
6
  from fastapi.responses import FileResponse
7
  import uvicorn
8
  import tempfile
@@ -20,15 +20,12 @@ UPLOAD_DIR = tempfile.gettempdir()
20
 
21
  app = FastAPI()
22
 
23
- # NOTE: The in-memory file_map has been REMOVED for a stateless design.
24
-
25
  async def upload_to_telegram(file_path: str):
26
  """Uploads a file and returns the full Telegram message object."""
27
  if not all([SESSION_STRING, API_ID, API_HASH]):
28
  raise ValueError("Server is not configured with Telegram credentials.")
29
  async with TelegramClient(StringSession(SESSION_STRING), API_ID, API_HASH) as client:
30
  try:
31
- # force_document=True ensures it's treated as a file with a consistent filename
32
  message = await client.send_file(TARGET_CHANNEL, file_path, force_document=True)
33
  if not message or not message.media:
34
  raise HTTPException(status_code=500, detail="Upload failed to return a valid message.")
@@ -51,9 +48,9 @@ async def upload_file(file: UploadFile = File(...)):
51
 
52
  original_filename = next((attr.file_name for attr in doc.attributes if hasattr(attr, 'file_name')), file.filename)
53
 
 
54
  return {
55
  "message": "File uploaded successfully. Use the 'message_id' to download.",
56
- "channel": TARGET_CHANNEL,
57
  "telegram_details": {
58
  "message_id": message.id,
59
  "file_id": doc.id,
@@ -69,7 +66,7 @@ async def upload_file(file: UploadFile = File(...)):
69
  os.remove(file_location)
70
 
71
  @app.get("/v1/download/{message_id}")
72
- async def download_file(message_id: int):
73
  """
74
  Downloads a file from Telegram using its unique message_id from the channel.
75
  This method is stateless and resilient to server restarts.
@@ -77,33 +74,24 @@ async def download_file(message_id: int):
77
  if not all([SESSION_STRING, API_ID, API_HASH]):
78
  raise HTTPException(status_code=500, detail="Server is not configured for downloads.")
79
 
80
- download_path = None
81
  try:
82
  async with TelegramClient(StringSession(SESSION_STRING), API_ID, API_HASH) as client:
83
- # Fetch the message directly using its ID
84
  message = await client.get_messages(TARGET_CHANNEL, ids=message_id)
85
 
86
  if not message or not message.media:
87
- raise HTTPException(status_code=404, detail=f"A message with ID '{message_id}' was not found or contains no media.")
88
 
89
- # Determine the original filename for the response
90
  original_filename = message.file.name if message.file and message.file.name else f"download_{message_id}"
91
-
92
- # Download the file to a temporary location on the server
93
  download_path = await client.download_media(message, file=UPLOAD_DIR)
 
 
 
 
 
 
94
 
95
- # Stream the file back to the client
96
  return FileResponse(download_path, media_type='application/octet-stream', filename=original_filename)
97
 
98
  except Exception as e:
99
- raise HTTPException(status_code=500, detail=f"Failed to download from Telegram: {e}")
100
- finally:
101
- # Crucially, clean up the temporary file from the server after sending it
102
- if download_path and os.path.exists(download_path):
103
- os.remove(download_path)
104
-
105
- if __name__ == "__main__":
106
- if not all([SESSION_STRING, API_ID, API_HASH]):
107
- print("FATAL ERROR: The environment variables SESSION_STRING, API_ID, and API_HASH must be set.")
108
- else:
109
- uvicorn.run(app, host="0.0.0.0", port=8000)
 
2
  import asyncio
3
  from telethon.sync import TelegramClient
4
  from telethon.sessions import StringSession
5
+ from fastapi import FastAPI, UploadFile, File, HTTPException, BackgroundTasks
6
  from fastapi.responses import FileResponse
7
  import uvicorn
8
  import tempfile
 
20
 
21
  app = FastAPI()
22
 
 
 
23
  async def upload_to_telegram(file_path: str):
24
  """Uploads a file and returns the full Telegram message object."""
25
  if not all([SESSION_STRING, API_ID, API_HASH]):
26
  raise ValueError("Server is not configured with Telegram credentials.")
27
  async with TelegramClient(StringSession(SESSION_STRING), API_ID, API_HASH) as client:
28
  try:
 
29
  message = await client.send_file(TARGET_CHANNEL, file_path, force_document=True)
30
  if not message or not message.media:
31
  raise HTTPException(status_code=500, detail="Upload failed to return a valid message.")
 
48
 
49
  original_filename = next((attr.file_name for attr in doc.attributes if hasattr(attr, 'file_name')), file.filename)
50
 
51
+ # Return details without the channel link, as requested.
52
  return {
53
  "message": "File uploaded successfully. Use the 'message_id' to download.",
 
54
  "telegram_details": {
55
  "message_id": message.id,
56
  "file_id": doc.id,
 
66
  os.remove(file_location)
67
 
68
  @app.get("/v1/download/{message_id}")
69
+ async def download_file(message_id: int, background_tasks: BackgroundTasks):
70
  """
71
  Downloads a file from Telegram using its unique message_id from the channel.
72
  This method is stateless and resilient to server restarts.
 
74
  if not all([SESSION_STRING, API_ID, API_HASH]):
75
  raise HTTPException(status_code=500, detail="Server is not configured for downloads.")
76
 
 
77
  try:
78
  async with TelegramClient(StringSession(SESSION_STRING), API_ID, API_HASH) as client:
 
79
  message = await client.get_messages(TARGET_CHANNEL, ids=message_id)
80
 
81
  if not message or not message.media:
82
+ raise HTTPException(status_code=440, detail=f"A message with ID '{message_id}' was not found or contains no media.")
83
 
 
84
  original_filename = message.file.name if message.file and message.file.name else f"download_{message_id}"
 
 
85
  download_path = await client.download_media(message, file=UPLOAD_DIR)
86
+
87
+ # **THE FIX IS HERE:**
88
+ # The os.remove is now a background task. It will only run AFTER the
89
+ # FileResponse has been fully sent to the client, preventing the error.
90
+ if download_path:
91
+ background_tasks.add_task(os.remove, download_path)
92
 
 
93
  return FileResponse(download_path, media_type='application/octet-stream', filename=original_filename)
94
 
95
  except Exception as e:
96
+ # Catch potential errors like file not found in Telegram
97
+ raise HTTPException(status_code=500, detail=f"Failed to download from Telegram: {e}")