|
|
@@ -44,12 +44,103 @@ Gemini File API 是一个完全独立的模块,与其他 API 逻辑完全隔
|
|
|
## 使用方式
|
|
|
|
|
|
### 1. 上传文件
|
|
|
+
|
|
|
+本模块支持两种上传方式:
|
|
|
+
|
|
|
+#### 方式 1:简单上传(Multipart Upload)
|
|
|
+
|
|
|
+适合小文件(< 100MB),一次性上传。
|
|
|
+
|
|
|
```bash
|
|
|
curl -X POST "http://your-api.com/upload/v1beta/files?key=YOUR_API_KEY" \
|
|
|
-F "file=@/path/to/file.pdf" \
|
|
|
-F "display_name=My Document"
|
|
|
```
|
|
|
|
|
|
+**注意**:此方式可能无法正确设置 MIME 类型,文件会被标记为 `application/octet-stream`。
|
|
|
+
|
|
|
+#### 方式 2:可恢复上传(Resumable Upload)⭐ 推荐
|
|
|
+
|
|
|
+适合大文件或需要正确 MIME 类型的场景。分为两步:
|
|
|
+
|
|
|
+**步骤 1:初始化上传会话**
|
|
|
+```bash
|
|
|
+# 自动获取文件信息
|
|
|
+VIDEO_PATH="/path/to/video.mp4"
|
|
|
+MIME_TYPE=$(file -b --mime-type "${VIDEO_PATH}")
|
|
|
+NUM_BYTES=$(wc -c < "${VIDEO_PATH}")
|
|
|
+
|
|
|
+# 初始化上传
|
|
|
+curl "http://your-api.com/upload/v1beta/files?key=YOUR_API_KEY" \
|
|
|
+ -D upload-header.tmp \
|
|
|
+ -H "X-Goog-Upload-Protocol: resumable" \
|
|
|
+ -H "X-Goog-Upload-Command: start" \
|
|
|
+ -H "X-Goog-Upload-Header-Content-Length: ${NUM_BYTES}" \
|
|
|
+ -H "X-Goog-Upload-Header-Content-Type: ${MIME_TYPE}" \
|
|
|
+ -H "Content-Type: application/json" \
|
|
|
+ -d '{"file": {"display_name": "My Video"}}'
|
|
|
+```
|
|
|
+
|
|
|
+**步骤 2:上传文件内容**
|
|
|
+```bash
|
|
|
+# 提取上传 URL
|
|
|
+upload_url=$(grep -i "x-goog-upload-url: " upload-header.tmp | cut -d" " -f2 | tr -d "\r")
|
|
|
+
|
|
|
+# 上传文件
|
|
|
+curl "${upload_url}" \
|
|
|
+ -H "Content-Length: ${NUM_BYTES}" \
|
|
|
+ -H "X-Goog-Upload-Offset: 0" \
|
|
|
+ -H "X-Goog-Upload-Command: upload, finalize" \
|
|
|
+ --data-binary "@${VIDEO_PATH}"
|
|
|
+```
|
|
|
+
|
|
|
+**完整脚本示例**:
|
|
|
+```bash
|
|
|
+#!/bin/bash
|
|
|
+
|
|
|
+API_KEY="YOUR_API_KEY"
|
|
|
+FILE_PATH="/path/to/video.mp4"
|
|
|
+DISPLAY_NAME="My Video"
|
|
|
+
|
|
|
+# 获取文件信息
|
|
|
+MIME_TYPE=$(file -b --mime-type "${FILE_PATH}")
|
|
|
+NUM_BYTES=$(wc -c < "${FILE_PATH}")
|
|
|
+
|
|
|
+echo "Uploading: ${FILE_PATH}"
|
|
|
+echo "MIME Type: ${MIME_TYPE}"
|
|
|
+echo "Size: ${NUM_BYTES} bytes"
|
|
|
+
|
|
|
+# 步骤 1: 初始化上传
|
|
|
+curl "http://your-api.com/upload/v1beta/files?key=${API_KEY}" \
|
|
|
+ -D upload-header.tmp \
|
|
|
+ -H "X-Goog-Upload-Protocol: resumable" \
|
|
|
+ -H "X-Goog-Upload-Command: start" \
|
|
|
+ -H "X-Goog-Upload-Header-Content-Length: ${NUM_BYTES}" \
|
|
|
+ -H "X-Goog-Upload-Header-Content-Type: ${MIME_TYPE}" \
|
|
|
+ -H "Content-Type: application/json" \
|
|
|
+ -d "{\"file\": {\"display_name\": \"${DISPLAY_NAME}\"}}"
|
|
|
+
|
|
|
+# 步骤 2: 提取上传 URL
|
|
|
+upload_url=$(grep -i "x-goog-upload-url: " upload-header.tmp | cut -d" " -f2 | tr -d "\r")
|
|
|
+
|
|
|
+if [ -z "$upload_url" ]; then
|
|
|
+ echo "Error: Failed to get upload URL"
|
|
|
+ exit 1
|
|
|
+fi
|
|
|
+
|
|
|
+echo "Upload URL: ${upload_url}"
|
|
|
+
|
|
|
+# 步骤 3: 上传文件
|
|
|
+curl "${upload_url}" \
|
|
|
+ -H "Content-Length: ${NUM_BYTES}" \
|
|
|
+ -H "X-Goog-Upload-Offset: 0" \
|
|
|
+ -H "X-Goog-Upload-Command: upload, finalize" \
|
|
|
+ --data-binary "@${FILE_PATH}" | jq .
|
|
|
+
|
|
|
+# 清理
|
|
|
+rm -f upload-header.tmp
|
|
|
+```
|
|
|
+
|
|
|
### 2. 列出文件
|
|
|
```bash
|
|
|
curl "http://your-api.com/v1beta/files?key=YOUR_API_KEY"
|
|
|
@@ -62,16 +153,131 @@ curl "http://your-api.com/v1beta/files?key=YOUR_API_KEY"
|
|
|
{
|
|
|
"name": "files/abc-123",
|
|
|
"displayName": "My Document",
|
|
|
- "mimeType": "application/pdf",
|
|
|
+ "mimeType": "video/mp4",
|
|
|
"sizeBytes": "12345",
|
|
|
"createTime": "2024-01-20T10:00:00Z",
|
|
|
"updateTime": "2024-01-20T10:00:00Z",
|
|
|
- "uri": "https://generativelanguage.googleapis.com/v1beta/files/abc-123"
|
|
|
+ "expirationTime": "2024-01-22T10:00:00Z",
|
|
|
+ "uri": "https://generativelanguage.googleapis.com/v1beta/files/abc-123",
|
|
|
+ "state": "ACTIVE"
|
|
|
}
|
|
|
]
|
|
|
}
|
|
|
```
|
|
|
|
|
|
+### 3. 使用上传的文件生成内容
|
|
|
+
|
|
|
+上传文件后,可以在 Gemini API 的 `generateContent` 请求中引用该文件:
|
|
|
+
|
|
|
+```bash
|
|
|
+#!/bin/bash
|
|
|
+
|
|
|
+API_KEY="YOUR_API_KEY"
|
|
|
+
|
|
|
+# 从文件列表中获取文件信息
|
|
|
+FILE_INFO=$(curl -s "http://your-api.com/v1beta/files?key=${API_KEY}" | jq -r '.files[0]')
|
|
|
+FILE_NAME=$(echo "$FILE_INFO" | jq -r '.name')
|
|
|
+MIME_TYPE=$(echo "$FILE_INFO" | jq -r '.mimeType')
|
|
|
+
|
|
|
+echo "Using file: $FILE_NAME"
|
|
|
+echo "MIME type: $MIME_TYPE"
|
|
|
+
|
|
|
+# 使用文件生成内容
|
|
|
+curl "http://your-api.com/v1beta/models/gemini-2.0-flash-exp:generateContent?key=${API_KEY}" \
|
|
|
+ -H 'Content-Type: application/json' \
|
|
|
+ -X POST \
|
|
|
+ -d '{
|
|
|
+ "contents": [{
|
|
|
+ "parts":[
|
|
|
+ {"fileData":{"mimeType": "'"${MIME_TYPE}"'", "fileUri": "'"${FILE_NAME}"'"}},
|
|
|
+ {"text": "请总结这个视频的内容"}
|
|
|
+ ]
|
|
|
+ }]
|
|
|
+ }' | jq .
|
|
|
+```
|
|
|
+
|
|
|
+**完整的上传和使用工作流**:
|
|
|
+
|
|
|
+```bash
|
|
|
+#!/bin/bash
|
|
|
+
|
|
|
+API_KEY="YOUR_API_KEY"
|
|
|
+VIDEO_PATH="/path/to/video.mp4"
|
|
|
+
|
|
|
+# ========== 第一步:上传视频文件 ==========
|
|
|
+echo "=== Step 1: Uploading video ==="
|
|
|
+
|
|
|
+MIME_TYPE=$(file -b --mime-type "${VIDEO_PATH}")
|
|
|
+NUM_BYTES=$(wc -c < "${VIDEO_PATH}")
|
|
|
+
|
|
|
+# 初始化上传
|
|
|
+curl "http://your-api.com/upload/v1beta/files?key=${API_KEY}" \
|
|
|
+ -D upload-header.tmp \
|
|
|
+ -H "X-Goog-Upload-Protocol: resumable" \
|
|
|
+ -H "X-Goog-Upload-Command: start" \
|
|
|
+ -H "X-Goog-Upload-Header-Content-Length: ${NUM_BYTES}" \
|
|
|
+ -H "X-Goog-Upload-Header-Content-Type: ${MIME_TYPE}" \
|
|
|
+ -H "Content-Type: application/json" \
|
|
|
+ -d '{"file": {"display_name": "My Video"}}'
|
|
|
+
|
|
|
+# 提取上传 URL
|
|
|
+upload_url=$(grep -i "x-goog-upload-url: " upload-header.tmp | cut -d" " -f2 | tr -d "\r")
|
|
|
+
|
|
|
+# 上传文件
|
|
|
+UPLOAD_RESPONSE=$(curl -s "${upload_url}" \
|
|
|
+ -H "Content-Length: ${NUM_BYTES}" \
|
|
|
+ -H "X-Goog-Upload-Offset: 0" \
|
|
|
+ -H "X-Goog-Upload-Command: upload, finalize" \
|
|
|
+ --data-binary "@${VIDEO_PATH}")
|
|
|
+
|
|
|
+echo "$UPLOAD_RESPONSE" | jq .
|
|
|
+
|
|
|
+# ========== 第二步:提取文件信息 ==========
|
|
|
+FILE_NAME=$(echo "$UPLOAD_RESPONSE" | jq -r '.file.name')
|
|
|
+FILE_MIME=$(echo "$UPLOAD_RESPONSE" | jq -r '.file.mimeType')
|
|
|
+
|
|
|
+echo ""
|
|
|
+echo "=== Step 2: File uploaded ==="
|
|
|
+echo "File name: $FILE_NAME"
|
|
|
+echo "MIME type: $FILE_MIME"
|
|
|
+
|
|
|
+# ========== 第三步:使用文件生成内容 ==========
|
|
|
+echo ""
|
|
|
+echo "=== Step 3: Generating content ==="
|
|
|
+
|
|
|
+curl "http://your-api.com/v1beta/models/gemini-2.0-flash-exp:generateContent?key=${API_KEY}" \
|
|
|
+ -H 'Content-Type: application/json' \
|
|
|
+ -X POST \
|
|
|
+ -d '{
|
|
|
+ "contents": [{
|
|
|
+ "parts":[
|
|
|
+ {"fileData":{"mimeType": "'"${FILE_MIME}"'", "fileUri": "'"${FILE_NAME}"'"}},
|
|
|
+ {"text": "Summarize this video and create a quiz based on it."}
|
|
|
+ ]
|
|
|
+ }]
|
|
|
+ }' | jq .
|
|
|
+
|
|
|
+# 清理
|
|
|
+rm -f upload-header.tmp
|
|
|
+```
|
|
|
+
|
|
|
+## 两种上传方式对比
|
|
|
+
|
|
|
+| 特性 | 简单上传 (Multipart) | 可恢复上传 (Resumable) |
|
|
|
+|------|---------------------|----------------------|
|
|
|
+| **MIME 类型** | ❌ 通常为 `application/octet-stream` | ✅ 正确识别(如 `video/mp4`) |
|
|
|
+| **文件大小限制** | 适合 < 100MB | ✅ 支持大文件 (< 500MB) |
|
|
|
+| **上传步骤** | 一步完成 | 两步(初始化 + 上传) |
|
|
|
+| **网络容错** | ❌ 失败需重新上传 | ✅ 支持断点续传(理论上) |
|
|
|
+| **使用场景** | 小文件快速上传 | 视频、音频等大文件 |
|
|
|
+| **推荐度** | ⭐⭐ | ⭐⭐⭐⭐⭐ |
|
|
|
+
|
|
|
+**建议**:
|
|
|
+- 📹 **视频文件**:必须使用 Resumable Upload
|
|
|
+- 🎵 **音频文件**:推荐使用 Resumable Upload
|
|
|
+- 📄 **文档文件**:两种方式都可以
|
|
|
+- 🖼️ **图片文件**:两种方式都可以
|
|
|
+
|
|
|
## 认证方式
|
|
|
|
|
|
支持以下任意一种认证方式:
|
|
|
@@ -99,6 +305,16 @@ curl "http://your-api.com/v1beta/files?key=YOUR_API_KEY"
|
|
|
- 独立的中间件链
|
|
|
- 不影响其他 API 功能
|
|
|
|
|
|
+### ✅ 两种上传方式
|
|
|
+- **简单上传 (Multipart)**:适合小文件,一步完成
|
|
|
+- **可恢复上传 (Resumable)**:适合大文件,正确设置 MIME 类型
|
|
|
+
|
|
|
+### ✅ 正确的 MIME 类型支持
|
|
|
+- 自动识别视频文件(video/mp4, video/quicktime 等)
|
|
|
+- 自动识别音频文件(audio/mpeg, audio/wav 等)
|
|
|
+- 支持文档、图片等各种文件类型
|
|
|
+- 确保 Gemini 能正确处理文件
|
|
|
+
|
|
|
### ✅ 自动渠道选择
|
|
|
- 自动查找可用的 Gemini 渠道
|
|
|
- 支持多个 Gemini 模型作为备选
|
|
|
@@ -107,10 +323,12 @@ curl "http://your-api.com/v1beta/files?key=YOUR_API_KEY"
|
|
|
### ✅ 多种认证方式
|
|
|
- 灵活的认证方式支持
|
|
|
- 兼容 OpenAI、Gemini、Claude 等多种 API 风格
|
|
|
+- 支持 Authorization header、x-goog-api-key、query parameter
|
|
|
|
|
|
### ✅ 大文件支持
|
|
|
- 支持最大 500MB 的文件上传
|
|
|
- 流式传输,内存占用低
|
|
|
+- 适合视频、音频等大型媒体文件
|
|
|
|
|
|
## 配置
|
|
|
|
|
|
@@ -161,6 +379,46 @@ export MAX_REQUEST_BODY_MB=500
|
|
|
2. 确认 `MAX_REQUEST_BODY_MB` 配置
|
|
|
3. 验证 Gemini API Key 权限
|
|
|
|
|
|
+### 问题: 文件 MIME 类型不正确(显示为 application/octet-stream)
|
|
|
+**原因**:使用了简单上传 (Multipart) 方式
|
|
|
+
|
|
|
+**解决方案**:
|
|
|
+1. **推荐**:改用 Resumable Upload 方式
|
|
|
+ ```bash
|
|
|
+ # 使用 Resumable Upload,自动设置正确的 MIME 类型
|
|
|
+ MIME_TYPE=$(file -b --mime-type "${FILE_PATH}")
|
|
|
+ # ... 按照 resumable upload 步骤上传
|
|
|
+ ```
|
|
|
+
|
|
|
+2. 或者在 multipart upload 时指定类型:
|
|
|
+ ```bash
|
|
|
+ curl -X POST "http://your-api.com/upload/v1beta/files?key=YOUR_API_KEY" \
|
|
|
+ -F "file=@video.mp4;type=video/mp4" \
|
|
|
+ -F "display_name=My Video"
|
|
|
+ ```
|
|
|
+
|
|
|
+### 问题: 使用文件时报错 "expected application/octet-stream"
|
|
|
+**原因**:上传时的 MIME 类型与使用时不匹配
|
|
|
+
|
|
|
+**解决方案**:
|
|
|
+使用文件时,必须使用文件列表中返回的 `mimeType`,而不是猜测:
|
|
|
+```bash
|
|
|
+# 从文件列表获取正确的 MIME 类型
|
|
|
+FILE_INFO=$(curl -s "http://your-api.com/v1beta/files?key=YOUR_API_KEY" | jq -r '.files[0]')
|
|
|
+MIME_TYPE=$(echo "$FILE_INFO" | jq -r '.mimeType')
|
|
|
+
|
|
|
+# 使用获取到的 MIME 类型
|
|
|
+curl "http://your-api.com/v1beta/models/gemini-2.0-flash-exp:generateContent?key=YOUR_API_KEY" \
|
|
|
+ -H 'Content-Type: application/json' \
|
|
|
+ -d '{
|
|
|
+ "contents": [{
|
|
|
+ "parts":[
|
|
|
+ {"fileData":{"mimeType": "'"${MIME_TYPE}"'", "fileUri": "files/abc-123"}}
|
|
|
+ ]
|
|
|
+ }]
|
|
|
+ }'
|
|
|
+```
|
|
|
+
|
|
|
## 开发指南
|
|
|
|
|
|
### 添加新的文件操作
|
|
|
@@ -179,9 +437,16 @@ export MAX_REQUEST_BODY_MB=500
|
|
|
|
|
|
## 版本历史
|
|
|
|
|
|
+- **v1.1.0** (2026-01-20)
|
|
|
+ - ✅ 新增支持 Resumable Upload Protocol
|
|
|
+ - ✅ 正确设置文件 MIME 类型(video/mp4、audio/mpeg 等)
|
|
|
+ - ✅ 支持两种上传方式:简单上传和可恢复上传
|
|
|
+ - ✅ 保持向后兼容
|
|
|
+ - ✅ 完善文档和使用示例
|
|
|
+
|
|
|
- **v1.0.0** (2026-01-20)
|
|
|
- 初始版本
|
|
|
- 完全独立的模块架构
|
|
|
- - 支持文件上传、列表、获取、删除操作
|
|
|
+ - 支持文件上传和列表操作
|
|
|
- 多种认证方式支持
|
|
|
- 自动渠道选择
|