sdp / app /file_serving.py
drix60's picture
update code
f5fce04
Raw
History Blame Contribute Delete
2.25 kB
"""
File serving utilities for FastAPI app.
"""
from fastapi.responses import FileResponse, HTMLResponse, StreamingResponse
HTML_EXTS = [".html", ".htm"]
HTML_GZ_EXT = ".html.gz"
IMAGE_EXTS = [".png", ".jpg", ".jpeg", ".gif", ".bmp", ".webp", ".svg"]
PDF_EXT = ".pdf"
def serve_html_file(file_resp, file_path):
content = file_resp.read() if hasattr(file_resp, "read") else file_resp
if isinstance(content, bytes):
content = content.decode("utf-8", errors="replace")
return HTMLResponse(content, media_type="text/html; charset=utf-8")
def serve_html_gz_file(file_resp, file_path):
import io
import unicodedata
content = file_resp.read() if hasattr(file_resp, "read") else file_resp
if not isinstance(content, bytes):
content = bytes(content)
safe_filename = file_path[:-3]
try:
safe_filename.encode('ascii')
except UnicodeEncodeError:
safe_filename = unicodedata.normalize('NFKD', safe_filename).encode('ascii', 'ignore').decode('ascii')
if not safe_filename:
safe_filename = 'file.html'
headers = {
"Content-Encoding": "gzip",
"Content-Disposition": f"inline; filename={safe_filename}"
}
return StreamingResponse(io.BytesIO(content), media_type="text/html", headers=headers)
def serve_image_file(file_resp, file_path):
import tempfile, os
from starlette.background import BackgroundTask
def get_image_bytes(file_resp):
if hasattr(file_resp, "read"):
return file_resp.read()
return file_resp if isinstance(file_resp, bytes) else bytes(file_resp)
image_bytes = get_image_bytes(file_resp)
ext = file_path.split(".")[-1].lower()
media_type = f"image/{'jpeg' if ext == 'jpg' else ext}"
with tempfile.NamedTemporaryFile(delete=False, suffix=f'.{ext}') as tmp:
tmp.write(image_bytes)
tmp_path = tmp.name
def cleanup():
try:
os.remove(tmp_path)
except Exception:
pass
return FileResponse(tmp_path, media_type=media_type, filename=file_path, background=BackgroundTask(cleanup))
def serve_binary_file(file_resp, file_path, media_type=None):
return FileResponse(file_resp, filename=file_path, media_type=media_type)