from fastapi import FastAPI, File, UploadFile, HTTPException from fastapi.responses import HTMLResponse, FileResponse from starlette.responses import Response import os import uvicorn app = FastAPI() # Utilizar el directorio persistente en Hugging Face Spaces UPLOAD_DIRECTORY = "/mnt/data/uploads" # Crear el directorio de uploads si no existe os.makedirs(UPLOAD_DIRECTORY, exist_ok=True) @app.get("/", response_class=HTMLResponse) async def home(): # Devuelve la página principal HTML with open("index.html", "r") as f: return f.read() @app.get("/styles.css", response_class=FileResponse) async def get_styles(): # Devuelve el archivo CSS file_path = "styles.css" if not os.path.exists(file_path): raise HTTPException(status_code=404, detail="CSS no encontrado") return FileResponse(file_path) @app.post("/upload") async def upload_file(file: UploadFile = File(...)): # Asegurarse de que el nombre del archivo esté definido correctamente if not file.filename: raise HTTPException(status_code=400, detail="Nombre de archivo no definido") # Definir la ruta completa para guardar el archivo file_path = os.path.join(UPLOAD_DIRECTORY, file.filename) # Guardar el archivo subido en el directorio de uploads with open(file_path, "wb") as f: f.write(await file.read()) # Retornar la respuesta con el nombre del archivo y la URL de descarga return {"message": "Archivo subido con éxito", "filename": file.filename, "url": f"/download/{file.filename}"} @app.get("/download/{filename}") async def download_file(filename: str): # Definir la ruta completa del archivo solicitado file_path = os.path.join(UPLOAD_DIRECTORY, filename) # Verificar si el archivo existe, si no, lanzar una excepción HTTP 404 if not os.path.exists(file_path): raise HTTPException(status_code=404, detail="Archivo no encontrado") # Forzar la descarga del archivo excluyendo extensiones específicas extensions_excluidas = ['.txt', '.csv'] # Agrega las extensiones que deseas excluir # Forzar descarga de archivos en lugar de visualizarlos en el navegador # Esto se aplica a todos los archivos excepto aquellos con extensiones excluidas if not any(filename.endswith(ext) for ext in extensions_excluidas): return FileResponse( file_path, media_type='application/octet-stream', headers={'Content-Disposition': f'attachment; filename="{filename}"'} ) else: # Devuelve una respuesta regular si la extensión está excluida return FileResponse(file_path) if __name__ == "__main__": uvicorn.run(app, host="0.0.0.0", port=7860)