zhangqian 1 рік тому
батько
коміт
f37670f13f
2 змінених файлів з 49 додано та 10 видалено
  1. 30 0
      app/api/files.py
  2. 19 10
      app/service/basic.py

+ 30 - 0
app/api/files.py

@@ -1,3 +1,4 @@
+import io
 from typing import Optional
 from typing import Optional
 
 
 import requests
 import requests
@@ -5,6 +6,7 @@ from fastapi import Depends, APIRouter, HTTPException, UploadFile, File, Query,
 from pydantic import BaseModel
 from pydantic import BaseModel
 from sqlalchemy.orm import Session
 from sqlalchemy.orm import Session
 from starlette.responses import StreamingResponse
 from starlette.responses import StreamingResponse
+from werkzeug.utils import send_file
 
 
 from app.api import Response, get_current_user, ResponseList
 from app.api import Response, get_current_user, ResponseList
 from app.config.config import settings
 from app.config.config import settings
@@ -76,6 +78,8 @@ async def download_file(
         agent_id: str = Query(..., description="Agent ID"),
         agent_id: str = Query(..., description="Agent ID"),
         doc_id: Optional[str] = Query(None, description="Optional doc id for ragflow agents"),
         doc_id: Optional[str] = Query(None, description="Optional doc id for ragflow agents"),
         doc_name: Optional[str] = Query(None, description="Optional doc name for ragflow agents"),
         doc_name: Optional[str] = Query(None, description="Optional doc name for ragflow agents"),
+        file_id:  Optional[str] = Query(None, description="Optional file id for basic agents"),
+        file_type:  Optional[str] = Query(None, description="Optional file type for basic agents"),
         db: Session = Depends(get_db)
         db: Session = Depends(get_db)
 ):
 ):
     agent = db.query(AgentModel).filter(AgentModel.id == agent_id).first()
     agent = db.query(AgentModel).filter(AgentModel.id == agent_id).first()
@@ -93,6 +97,10 @@ async def download_file(
             return Response(code=400, msg="doc_id is required")
             return Response(code=400, msg="doc_id is required")
         url = f"{settings.fwr_base_url}/v1/document/get/{doc_id}"
         url = f"{settings.fwr_base_url}/v1/document/get/{doc_id}"
         filename = doc_name
         filename = doc_name
+    elif agent.agent_type == AgentType.BASIC:
+        if agent_id == "basic_excel_talk":
+            return await download_basic_file(file_id, file_type)
+
     else:
     else:
         return Response(code=400, msg="Unsupported agent type")
         return Response(code=400, msg="Unsupported agent type")
 
 
@@ -109,3 +117,25 @@ async def download_file(
         )
         )
     except Exception as e:
     except Exception as e:
         raise HTTPException(status_code=400, detail=f"Error downloading file: {e}")
         raise HTTPException(status_code=400, detail=f"Error downloading file: {e}")
+
+
+async def download_basic_file(file_id: str, file_type: str):
+    service = BasicService(base_url=settings.basic_base_url)
+    if not file_type or not file_id:
+        return Response(code=400, msg="file_type and file_id is required")
+    if file_type == "image":
+        content, filename, mimetype = await service.excel_talk_image_download(file_id)
+        return StreamingResponse(
+                io.BytesIO(content),
+                media_type=mimetype,
+                headers={"Content-Disposition": f"attachment; filename={filename}"}
+            )
+    elif file_type == "excel":
+        content, filename, mimetype = await service.excel_talk_excel_download(file_id)
+        return StreamingResponse(
+            io.BytesIO(content),
+            media_type=mimetype,
+            headers={"Content-Disposition": f"attachment; filename={filename}"}
+        )
+    else:
+        return Response(code=400, msg="Unsupported file type")

+ 19 - 10
app/service/basic.py

@@ -15,16 +15,25 @@ class BasicService:
             raise Exception(f"Failed to fetch data from API: {response.text}")
             raise Exception(f"Failed to fetch data from API: {response.text}")
         return response_data.get("data", {})
         return response_data.get("data", {})
 
 
-    async def download_from_url(self, url: str, params: dict):
+    async def download_from_url(self, url, params=None):
         async with httpx.AsyncClient() as client:
         async with httpx.AsyncClient() as client:
-            response = await client.get(url, params=params, stream=True)
-            if response.status_code == 200:
-                content_disposition = response.headers.get('Content-Disposition')
-                filename = content_disposition.split('filename=')[-1].strip(
-                    '"') if content_disposition else 'unknown_filename'
-                return response.content, filename, response.headers.get('Content-Type')
-            else:
-                return None, None, None
+            async with client.stream('GET', url, params=params) as response:
+                if response.status_code == 200:
+                    # 获取文件名
+                    content_disposition = response.headers.get('Content-Disposition')
+                    if content_disposition:
+                        filename = content_disposition.split('filename=')[1].strip('"')
+                    else:
+                        filename = 'unknown_filename'
+
+                    # 获取内容类型
+                    content_type = response.headers.get('Content-Type')
+
+                    # 读取文件内容
+                    content = await response.aread()
+                    return content, filename, content_type
+                else:
+                    raise Exception(f"Failed to download: {response.status_code}")
 
 
     async def excel_talk_image_download(self, file_id: str):
     async def excel_talk_image_download(self, file_id: str):
         url = f"{self.base_url}/exceltalk/download/image"
         url = f"{self.base_url}/exceltalk/download/image"
@@ -65,4 +74,4 @@ class BasicService:
                         print(e)
                         print(e)
                         return
                         return
                 else:
                 else:
-                    yield f"Error: {response.status_code}"
+                    yield f"Error: {response.status_code}"