mirror of
https://github.com/infiniflow/ragflow.git
synced 2026-05-03 08:47:48 +08:00
Feat: File uploads for future conversations on SDK API (#13378)
### What problem does this PR solve? This PR aims to: 1. Enable file uploads for the public API, similarly to what /document/upload_info accomplishes for the frontend; 2. Enable files sent to the /chat/:chat_id/completions endpoint to be used within the conversation. We classify the first item as a new future, while classifying the second one as a bug fix. ### Type of change - [x] Bug Fix (non-breaking change which fixes an issue) - [x] New Feature (non-breaking change which adds functionality) *The work related to this PR was co-authored by* [Bruno Ferreira](https://github.com/brunopferreira): Custom Solutions Manager @ [Orbcom](https://orbcom.pt/) [Pedro Ferreira](https://github.com/sirj0k3r): Lead Software Developer @ [Orbcom](https://orbcom.pt/) [Pedro Cardoso](https://github.com/pedromiguel4560): Associate Software Developer @ [Orbcom](https://orbcom.pt/) *This PR replaces #13248* --------- Co-authored-by: Pedro Cardoso <pedrocardoso@orbcom.pt> Co-authored-by: Pedro Ferreira <pedroferreira@orbcom.pt>
This commit is contained in:
committed by
GitHub
parent
020068dd16
commit
61209ff3bf
@ -148,6 +148,62 @@ async def upload(tenant_id):
|
||||
return server_error_response(e)
|
||||
|
||||
|
||||
@manager.route("/file/upload_info", methods=["POST"]) # noqa: F821
|
||||
@token_required
|
||||
async def upload_info(tenant_id):
|
||||
"""
|
||||
Upload runtime file metadata for SDK chat completions.
|
||||
---
|
||||
tags:
|
||||
- File
|
||||
security:
|
||||
- ApiKeyAuth: []
|
||||
parameters:
|
||||
- in: formData
|
||||
name: file
|
||||
type: file
|
||||
required: false
|
||||
description: File(s) to upload as runtime attachments.
|
||||
- in: query
|
||||
name: url
|
||||
type: string
|
||||
required: false
|
||||
description: Optional URL to fetch and convert into a runtime attachment.
|
||||
responses:
|
||||
200:
|
||||
description: Runtime attachment descriptor(s) for the `files` field in completions requests.
|
||||
"""
|
||||
files = await request.files
|
||||
file_objs = files.getlist("file") if files and files.get("file") else []
|
||||
url = request.args.get("url")
|
||||
|
||||
if file_objs and url:
|
||||
return get_json_result(
|
||||
data=False,
|
||||
message="Provide either multipart file(s) or ?url=..., not both.",
|
||||
code=RetCode.BAD_REQUEST,
|
||||
)
|
||||
|
||||
if not file_objs and not url:
|
||||
return get_json_result(
|
||||
data=False,
|
||||
message="Missing input: provide multipart file(s) or url",
|
||||
code=RetCode.BAD_REQUEST,
|
||||
)
|
||||
|
||||
try:
|
||||
if url and not file_objs:
|
||||
return get_json_result(data=FileService.upload_info(tenant_id, None, url))
|
||||
|
||||
if len(file_objs) == 1:
|
||||
return get_json_result(data=FileService.upload_info(tenant_id, file_objs[0], None))
|
||||
|
||||
results = [FileService.upload_info(tenant_id, f) for f in file_objs]
|
||||
return get_json_result(data=results)
|
||||
except Exception as e:
|
||||
return server_error_response(e)
|
||||
|
||||
|
||||
@manager.route('/file/create', methods=['POST']) # noqa: F821
|
||||
@token_required
|
||||
async def create(tenant_id):
|
||||
|
||||
@ -158,6 +158,11 @@ async def async_completion(tenant_id, chat_id, question, name="New session", ses
|
||||
"role": "user",
|
||||
"id": str(uuid4())
|
||||
}
|
||||
|
||||
# Propagate runtime attachments so downstream chat flow can resolve file content.
|
||||
if isinstance(kwargs.get("files"), list) and kwargs["files"]:
|
||||
question["files"] = kwargs["files"]
|
||||
|
||||
conv.message.append(question)
|
||||
for m in conv.message:
|
||||
if m["role"] == "system":
|
||||
|
||||
@ -6124,6 +6124,69 @@ Failure:
|
||||
|
||||
---
|
||||
|
||||
### Upload document
|
||||
|
||||
**POST** `/api/v1/file/upload_info`
|
||||
|
||||
Uploads a file and creates the respective document
|
||||
|
||||
#### Request
|
||||
|
||||
- Method: POST
|
||||
- URL: `/api/v1/file/upload_info`
|
||||
- Headers:
|
||||
- `'Content-Type: multipart/form-data`
|
||||
- `'Authorization: Bearer <YOUR_API_KEY>'`
|
||||
- Form:
|
||||
- `'file=@{FILE_PATH}'`
|
||||
|
||||
##### Request example
|
||||
|
||||
```bash
|
||||
curl --request POST \
|
||||
--url http://{address}/api/v1/file/upload_info \
|
||||
--header 'Content-Type: multipart/form-data' \
|
||||
--header 'Authorization: Bearer <YOUR_API_KEY>' \
|
||||
--form 'file=@./test1.pdf'
|
||||
```
|
||||
|
||||
##### Request parameters
|
||||
|
||||
- `'file'`: (*Form parameter*), `file`, *Required*
|
||||
The file to upload.
|
||||
|
||||
#### Response
|
||||
|
||||
Success:
|
||||
|
||||
```json
|
||||
{
|
||||
"code": 0,
|
||||
"data": {
|
||||
"created_at": 1772451421.7924063,
|
||||
"created by": "be951084066611f18f5f00155d2f98f4",
|
||||
"extension": "pdf",
|
||||
"id": "2143a03d162c11f1b80f00155d334d02",
|
||||
"mime_type": "application/pdf",
|
||||
"name": "test1.pdf",
|
||||
"preview_url": null,
|
||||
"size": 49705
|
||||
},
|
||||
"message": "success"
|
||||
}
|
||||
```
|
||||
|
||||
Failure:
|
||||
|
||||
```json
|
||||
{
|
||||
"code": 400,
|
||||
"message": "Provide either multipart file(s) or ?url=...!"
|
||||
}
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
### Create file or folder
|
||||
|
||||
**POST** `/api/v1/file/create`
|
||||
|
||||
Reference in New Issue
Block a user