Davizig10jojo commited on
Commit
bbbd17f
·
verified ·
1 Parent(s): beefbaa

Update app.py

Browse files
Files changed (1) hide show
  1. app.py +23 -65
app.py CHANGED
@@ -2,7 +2,7 @@ import os
2
  import urllib.parse
3
  from fastapi import FastAPI, HTTPException, Request, status
4
  from fastapi.middleware.cors import CORSMiddleware
5
- from fastapi.responses import FileResponse, StreamingResponse
6
  from pydantic import BaseModel
7
 
8
  app = FastAPI()
@@ -102,79 +102,37 @@ async def receive_upload(filename: str, request: Request):
102
  except Exception as e:
103
  raise HTTPException(status_code=500, detail=str(e))
104
 
105
- # 🎬 3. DOWNLOAD E STREAMING OTIMIZADO DE VÍDEO (Com suporte a Range Requests)
 
106
  @app.get("/download")
107
- def download_file(name: str, request: Request):
108
  try:
109
  filepath = os.path.join(STORAGE_DIR, name)
110
  if not os.path.exists(filepath):
111
  raise HTTPException(status_code=404, detail="Arquivo não encontrado")
112
 
113
- file_size = os.path.getsize(filepath)
114
- range_header = request.headers.get("range")
115
-
116
- # Se o navegador pedir apenas partes do arquivo (comum em players de vídeo/áudio)
117
- if range_header:
118
- try:
119
- # Exemplo de range: "bytes=0-1024"
120
- byte_ranges = range_header.replace("bytes=", "").split("-")
121
- start = int(byte_ranges[0])
122
- end = int(byte_ranges[1]) if byte_ranges[1] else file_size - 1
123
- except ValueError:
124
- raise HTTPException(status_code=status.HTTP_416_REQUESTED_RANGE_NOT_SATISFIABLE, detail="Intervalo de bytes inválido")
125
-
126
- if start >= file_size or end >= file_size:
127
- raise HTTPException(status_code=status.HTTP_416_REQUESTED_RANGE_NOT_SATISFIABLE, detail="Intervalo fora do limite do arquivo")
128
-
129
- chunk_size = end - start + 1
130
-
131
- def file_generator(path, offset, size):
132
- with open(path, "rb") as f:
133
- f.seek(offset)
134
- remaining = size
135
- while remaining > 0:
136
- chunk_to_read = min(1024 * 1024, remaining) # Lendo em partes de 1MB
137
- data = f.read(chunk_to_read)
138
- if not data:
139
- break
140
- remaining -= len(data)
141
- yield data
142
-
143
- headers = {
144
- "Content-Range": f"bytes {start}-{end}/{file_size}",
145
- "Accept-Ranges": "bytes",
146
- "Content-Length": str(chunk_size),
147
- "Access-Control-Expose-Headers": "Content-Range, Content-Length, Accept-Ranges",
148
- "Cache-Control": "public, max-age=31536000, immutable"
149
- }
150
-
151
- # Descobre o MIME Type do arquivo
152
- lower_name = name.lower()
153
- media_type = "application/octet-stream"
154
- if lower_name.endswith(".mp4"):
155
- media_type = "video/mp4"
156
- elif lower_name.endswith(".webm"):
157
- media_type = "video/webm"
158
- elif lower_name.endswith(".mkv"):
159
- media_type = "video/x-matroska"
160
- elif lower_name.endswith(".mp3"):
161
- media_type = "audio/mpeg"
162
-
163
- return StreamingResponse(
164
- file_generator(filepath, start, chunk_size),
165
- status_code=206,
166
- headers=headers,
167
- media_type=media_type
168
- )
169
-
170
- # Se for um download comum (sem range request)
171
- return FileResponse(
172
  filepath,
173
- media_type="application/octet-stream",
174
  filename=name
175
  )
176
- except HTTPException as h_err:
177
- raise h_err
 
 
178
  except Exception as e:
179
  raise HTTPException(status_code=500, detail=str(e))
180
 
 
2
  import urllib.parse
3
  from fastapi import FastAPI, HTTPException, Request, status
4
  from fastapi.middleware.cors import CORSMiddleware
5
+ from fastapi.responses import FileResponse
6
  from pydantic import BaseModel
7
 
8
  app = FastAPI()
 
102
  except Exception as e:
103
  raise HTTPException(status_code=500, detail=str(e))
104
 
105
+ # 🎬 3. DOWNLOAD E STREAMING NATIVO DE ALTA PERFORMANCE (Usa FileResponse nativo do FastAPI)
106
+ # O FileResponse lida automaticamente com Range Requests de forma assíncrona extremamente veloz.
107
  @app.get("/download")
108
+ def download_file(name: str):
109
  try:
110
  filepath = os.path.join(STORAGE_DIR, name)
111
  if not os.path.exists(filepath):
112
  raise HTTPException(status_code=404, detail="Arquivo não encontrado")
113
 
114
+ # Descobre o MIME Type do arquivo para que o navegador saiba como reproduzir
115
+ lower_name = name.lower()
116
+ media_type = "application/octet-stream"
117
+ if lower_name.endswith(".mp4"):
118
+ media_type = "video/mp4"
119
+ elif lower_name.endswith(".webm"):
120
+ media_type = "video/webm"
121
+ elif lower_name.endswith(".mkv"):
122
+ media_type = "video/x-matroska"
123
+ elif lower_name.endswith(".mp3"):
124
+ media_type = "audio/mpeg"
125
+
126
+ # FileResponse do FastAPI cuida de Range Requests automaticamente e de forma performática
127
+ response = FileResponse(
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
128
  filepath,
129
+ media_type=media_type,
130
  filename=name
131
  )
132
+ response.headers["Accept-Ranges"] = "bytes"
133
+ response.headers["Cache-Control"] = "public, max-age=31536000, immutable"
134
+ return response
135
+
136
  except Exception as e:
137
  raise HTTPException(status_code=500, detail=str(e))
138