""" 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)