Skip to content

Commit fc2425f

Browse files
authored
Merge pull request #139 from cnblogs/show-file-status
feat: support upload files api
2 parents e40ff56 + 808caac commit fc2425f

File tree

51 files changed

+892
-151
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

51 files changed

+892
-151
lines changed

README.zh-Hans.md

Lines changed: 80 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -1173,13 +1173,46 @@ Usage: in(31)/out(34)/reasoning()/total(65)
11731173

11741174
尽管 QWen-Long 支持直接传入字符串,但还是推荐先将文件上传后再通过 FileId 的形式传入 `message` 数组中。
11751175

1176-
上传文件,使用 `UploadFileAsync()` 方法传入文件(注意不是 `UploadTemporaryFileAsync`, 后者是用于上传媒体文件的)
1176+
上传文件,使用 `OpenAiCompatibleUploadFileAsync()` 方法传入文件:
11771177

11781178
```csharp
1179-
var file1 = await client.UploadFileAsync(File.OpenRead("1024-1.txt"), "file1.txt");
1179+
var file1 = await client.OpenAiCompatibleUploadFileAsync(File.OpenRead("1024-1.txt"), "file1.txt");
11801180
```
11811181

1182-
然后将文件作为 `system` 消息传入消息数组中,注意第一条 `system` 消息不能省略,否则模型可能会将文件里的内容当作 System prompt 。
1182+
如果文件比较大,服务端可能需要几秒的时间进行解析。根据返回的 `file.Status` 属性是否为 `processed` 可以判断是否解析完成。未解析完成的文件无法被模型使用,需要等待解析完成。以下是一个示例方法,自动等待文档解析完毕或超时抛出异常:
1183+
1184+
```csharp
1185+
private static async Task EnsureFileProcessedAsync(
1186+
IDashScopeClient client,
1187+
DashScopeFileId id,
1188+
int timeoutInSeconds = 5)
1189+
{
1190+
var timeout = Task.Delay(TimeSpan.FromSeconds(timeoutInSeconds));
1191+
while (timeout.IsCompleted == false)
1192+
{
1193+
var file = await client.GetFileAsync(id);
1194+
if (file.Status == "processed")
1195+
{
1196+
return;
1197+
}
1198+
1199+
await Task.Delay(1000);
1200+
}
1201+
1202+
throw new InvalidOperationException($"File not processed within timeout, fileId: {id}");
1203+
}
1204+
```
1205+
1206+
调用方式:
1207+
1208+
```csharp
1209+
if (file.Status != "processed")
1210+
{
1211+
await EnsureFileProcessedAsync(client, file.Id, 3); // 最多等待 3 秒
1212+
}
1213+
```
1214+
1215+
待文档解析完成后,将文件作为 `system` 消息传入消息数组中,注意第一条 `system` 消息不能省略,否则模型可能会将文件里的内容当作 `System prompt`
11831216

11841217
```csharp
11851218
var messages = new List<TextChatMessage>();
@@ -1211,22 +1244,25 @@ var completion = client.GetTextCompletionStreamAsync(
12111244
});
12121245
```
12131246

1214-
最后可以通过 `DeleteFileAsync()` 方法删除上传的文件
1247+
最后可以通过 `OpenAiCompatibleDeleteFileAsync()` 方法删除上传的文件
12151248

12161249
```csharp
1217-
var result = await client.DeleteFileAsync(file1.Id);
1250+
var result = await client.OpenAiCompatibleDeleteFileAsync(file1.Id);
12181251
Console.WriteLine(result.Deleted ? "Success" : "Failed");
12191252
```
12201253

12211254
完整示例
12221255

12231256
```csharp
12241257
Console.WriteLine("Uploading file1...");
1225-
var file1 = await client.UploadFileAsync(File.OpenRead("1024-1.txt"), "file1.txt");
1258+
var file1 = await client.OpenAiCompatibleUploadFileAsync(File.OpenRead("1024-1.txt"), "file1.txt");
12261259
Console.WriteLine("Uploading file2...");
1227-
var file2 = await client.UploadFileAsync(File.OpenRead("1024-2.txt"), "file2.txt");
1260+
var file2 = await client.OpenAiCompatibleUploadFileAsync(File.OpenRead("1024-2.txt"), "file2.txt");
12281261
Console.WriteLine($"Uploaded, file1 id: {file1.Id.ToUrl()}, file2 id: {file2.Id.ToUrl()}");
12291262

1263+
await EnsureFileProcessedAsync(client, file1);
1264+
await EnsureFileProcessedAsync(client, file2);
1265+
12301266
var messages = new List<TextChatMessage>();
12311267
messages.Add(TextChatMessage.System("You are a helpful assistant"));
12321268
messages.Add(TextChatMessage.File(file1.Id));
@@ -1292,6 +1328,31 @@ Console.Write("Deleting file2...");
12921328
result = await client.DeleteFileAsync(file2.Id);
12931329
Console.WriteLine(result.Deleted ? "Success" : "Failed");
12941330

1331+
private static async Task EnsureFileProcessedAsync(
1332+
IDashScopeClient client,
1333+
DashScopeFile file,
1334+
int timeoutInSeconds = 5)
1335+
{
1336+
if (file.Status == "processed")
1337+
{
1338+
return;
1339+
}
1340+
1341+
var timeout = Task.Delay(TimeSpan.FromSeconds(timeoutInSeconds));
1342+
while (timeout.IsCompleted == false)
1343+
{
1344+
var realtime = await client.GetFileAsync(file.Id);
1345+
if (realtime.Status == "processed")
1346+
{
1347+
return;
1348+
}
1349+
1350+
await Task.Delay(1000);
1351+
}
1352+
1353+
throw new InvalidOperationException($"File not processed within timeout, fileId: {file.Id}");
1354+
}
1355+
12951356
/*
12961357
Uploading file1...
12971358
Uploading file2...
@@ -1324,6 +1385,14 @@ Deleting file2...Success
13241385
*/
13251386
```
13261387

1388+
**注意及时删除上传的文件,这个接口有文件总数(1万)和文件总量(100GB)限制。**
1389+
1390+
你可以使用 `ListFileAsync` 获取完整的文件列表并删除不再需要使用的文件
1391+
1392+
示例:
1393+
1394+
1395+
13271396
### 翻译能力(Qwen-MT)
13281397

13291398
翻译能力主要通过 `Parameters` 里的 `TranslationOptions` 进行配置。
@@ -1507,10 +1576,10 @@ Usage: in(147)/out(130)/total(277)
15071576

15081577
### 数据挖掘(Qwen-doc-turbo)
15091578

1510-
上传文件,使用 `UploadFileAsync()` 方法传入文件(注意不是 `UploadTemporaryFileAsync`, 后者是用于上传媒体文件的):
1579+
上传文件,使用 `OpenAiCompatibleUploadFileAsync()` 方法传入文件(注意不是 `UploadTemporaryFileAsync`, 后者是用于上传媒体文件的):
15111580

15121581
```csharp
1513-
var file1 = await client.UploadFileAsync(File.OpenRead("1024-1.txt"), "file1.txt");
1582+
var file1 = await client.OpenAiCompatibleUploadFileAsync(File.OpenRead("1024-1.txt"), "file1.txt");
15141583
```
15151584

15161585
然后将文件作为 `system` 消息传入消息数组中,注意第一条 `system` 消息不能省略,否则模型可能会将文件里的内容当作 System prompt 。
@@ -1549,7 +1618,7 @@ var completion = client.GetTextCompletionStreamAsync(
15491618

15501619
````csharp
15511620
Console.WriteLine("Uploading file1...");
1552-
var file1 = await client.UploadFileAsync(File.OpenRead("1024-1.txt"), "file1.txt");
1621+
var file1 = await client.OpenAiCompatibleUploadFileAsync(File.OpenRead("1024-1.txt"), "file1.txt");
15531622
var messages = new List<TextChatMessage>();
15541623
messages.Add(TextChatMessage.System("You are a helpful assistant"));
15551624
messages.Add(TextChatMessage.File(file1.Id));
@@ -1593,7 +1662,7 @@ if (usage != null)
15931662

15941663
// Deleting files
15951664
Console.Write("Deleting file1...");
1596-
var result = await client.DeleteFileAsync(file1.Id);
1665+
var result = await client.OpenAiCompatibleDeleteFileAsync(file1.Id);
15971666
Console.WriteLine(result.Deleted ? "Success" : "Failed");
15981667

15991668
/*
Lines changed: 37 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,37 @@
1+
using System.Text.Json;
2+
using Cnblogs.DashScope.Core;
3+
4+
namespace Cnblogs.DashScope.Sample.Files;
5+
6+
public class FileUploadSample : ISample
7+
{
8+
/// <inheritdoc />
9+
public string Description => "Upload File Sample";
10+
11+
/// <inheritdoc />
12+
public async Task RunAsync(IDashScopeClient client)
13+
{
14+
var json = new JsonSerializerOptions(JsonSerializerDefaults.Web) { WriteIndented = true };
15+
var file = new FileInfo("Lenna.jpg");
16+
Console.WriteLine("Uploading file...");
17+
var response = await client.UploadFilesAsync(
18+
"file-extract",
19+
[new DashScopeUploadFileInput(file.OpenRead(), file.Name, "Lenna")]);
20+
Console.WriteLine($"File uploaded, fileId: {response.Data.UploadedFiles[0].FileId}");
21+
22+
await Task.Delay(1000);
23+
Console.WriteLine("Get file info...");
24+
var fileInfo = await client.GetFileAsync(response.Data.UploadedFiles[0].FileId);
25+
Console.WriteLine(JsonSerializer.Serialize(fileInfo.Data, json));
26+
27+
await Task.Delay(1000);
28+
Console.WriteLine("List files...");
29+
var list = await client.ListFilesAsync(1, 2);
30+
Console.WriteLine(JsonSerializer.Serialize(list.Data.Files, json));
31+
32+
await Task.Delay(1000);
33+
Console.Write("Delete file...");
34+
await client.DeleteFileAsync(response.Data.UploadedFiles[0].FileId);
35+
Console.WriteLine("Success");
36+
}
37+
}

sample/Cnblogs.DashScope.Sample/Text/DataMiningSample.cs

Lines changed: 8 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -12,11 +12,13 @@ public class DataMiningSample : ISample
1212
public async Task RunAsync(IDashScopeClient client)
1313
{
1414
Console.WriteLine("Uploading file1...");
15-
var file1 = await client.UploadFileAsync(File.OpenRead("1024-1.txt"), "file1.txt");
16-
var messages = new List<TextChatMessage>();
17-
messages.Add(TextChatMessage.System("You are a helpful assistant"));
18-
messages.Add(TextChatMessage.File(file1.Id));
19-
messages.Add(TextChatMessage.User("这篇文章讲了什么,整理成一个 JSON,需要包含标题(title)和摘要(description)"));
15+
var file1 = await client.OpenAiCompatibleUploadFileAsync(File.OpenRead("1024-1.txt"), "file1.txt");
16+
var messages = new List<TextChatMessage>
17+
{
18+
TextChatMessage.System("You are a helpful assistant"),
19+
TextChatMessage.File(file1.Id),
20+
TextChatMessage.User("这篇文章讲了什么,整理成一个 JSON,需要包含标题(title)和摘要(description)")
21+
};
2022
messages.ForEach(m => Console.WriteLine($"{m.Role} > {m.Content}"));
2123
var completion = client.GetTextCompletionStreamAsync(
2224
new ModelRequest<TextGenerationInput, ITextGenerationParameters>()
@@ -56,7 +58,7 @@ public async Task RunAsync(IDashScopeClient client)
5658

5759
// Deleting files
5860
Console.Write("Deleting file1...");
59-
var result = await client.DeleteFileAsync(file1.Id);
61+
var result = await client.OpenAiCompatibleDeleteFileAsync(file1.Id);
6062
Console.WriteLine(result.Deleted ? "Success" : "Failed");
6163
}
6264
}

sample/Cnblogs.DashScope.Sample/Text/LongContextSample.cs

Lines changed: 39 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -12,16 +12,21 @@ public class LongContextSample : ISample
1212
public async Task RunAsync(IDashScopeClient client)
1313
{
1414
Console.WriteLine("Uploading file1...");
15-
var file1 = await client.UploadFileAsync(File.OpenRead("1024-1.txt"), "file1.txt");
15+
var file1 = await client.OpenAiCompatibleUploadFileAsync(File.OpenRead("1024-1.txt"), "file1.txt");
1616
Console.WriteLine("Uploading file2...");
17-
var file2 = await client.UploadFileAsync(File.OpenRead("1024-2.txt"), "file2.txt");
17+
var file2 = await client.OpenAiCompatibleUploadFileAsync(File.OpenRead("1024-2.txt"), "file2.txt");
1818
Console.WriteLine($"Uploaded, file1 id: {file1.Id.ToUrl()}, file2 id: {file2.Id.ToUrl()}");
1919

20-
var messages = new List<TextChatMessage>();
21-
messages.Add(TextChatMessage.System("You are a helpful assistant"));
22-
messages.Add(TextChatMessage.File(file1.Id));
23-
messages.Add(TextChatMessage.File(file2.Id));
24-
messages.Add(TextChatMessage.User("这两篇文章分别讲了什么?"));
20+
await EnsureFileProcessedAsync(client, file1);
21+
await EnsureFileProcessedAsync(client, file2);
22+
23+
var messages = new List<TextChatMessage>
24+
{
25+
TextChatMessage.System("You are a helpful assistant"),
26+
TextChatMessage.File(file1.Id),
27+
TextChatMessage.File(file2.Id),
28+
TextChatMessage.User("这两篇文章分别讲了什么?")
29+
};
2530

2631
messages.ForEach(m => Console.WriteLine($"{m.Role} > {m.Content}"));
2732
var completion = client.GetTextCompletionStreamAsync(
@@ -72,12 +77,37 @@ public async Task RunAsync(IDashScopeClient client)
7277

7378
// Deleting files
7479
Console.Write("Deleting file1...");
75-
var result = await client.DeleteFileAsync(file1.Id);
80+
var result = await client.OpenAiCompatibleDeleteFileAsync(file1.Id);
7681
Console.WriteLine(result.Deleted ? "Success" : "Failed");
7782
Console.Write("Deleting file2...");
78-
result = await client.DeleteFileAsync(file2.Id);
83+
result = await client.OpenAiCompatibleDeleteFileAsync(file2.Id);
7984
Console.WriteLine(result.Deleted ? "Success" : "Failed");
8085
}
86+
87+
private static async Task EnsureFileProcessedAsync(
88+
IDashScopeClient client,
89+
DashScopeFile file,
90+
int timeoutInSeconds = 5)
91+
{
92+
if (file.Status == "processed")
93+
{
94+
return;
95+
}
96+
97+
var timeout = Task.Delay(TimeSpan.FromSeconds(timeoutInSeconds));
98+
while (timeout.IsCompleted == false)
99+
{
100+
var realtime = await client.OpenAiCompatibleGetFileAsync(file.Id);
101+
if (realtime.Status == "processed")
102+
{
103+
return;
104+
}
105+
106+
await Task.Delay(1000);
107+
}
108+
109+
throw new InvalidOperationException($"File not processed within timeout, fileId: {file.Id}");
110+
}
81111
}
82112

83113
/*

0 commit comments

Comments
 (0)