-
Notifications
You must be signed in to change notification settings - Fork 4
Expand file tree
/
Copy pathDocumentTranslationService.cs
More file actions
209 lines (181 loc) · 8.15 KB
/
DocumentTranslationService.cs
File metadata and controls
209 lines (181 loc) · 8.15 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
using Azure.AI.Translation.Document;
using Azure.Storage.Blobs;
using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.Threading;
using System.Threading.Tasks;
namespace DocumentTranslationService.Core
{
public partial class DocumentTranslationService
{
#region Properties
/// <summary>
/// The "Connection String" of the Azure blob storage resource. Get from properties of Azure storage.
/// </summary>
public string StorageConnectionString { get; set; } = string.Empty;
/// <summary>
/// Holds the Custom Translator category.
/// </summary>
public string Category { get; set; }
/// <summary>
/// Your Azure Translator resource key. Get from properties of the Translator resource
/// </summary>
public string SubscriptionKey { get; set; } = string.Empty;
/// <summary>
/// The region of your Translator subscription.
/// Needed only for text translation; can remain empty for document translation.
/// </summary>
public string AzureRegion { get; set; }
/// <summary>
/// The Uri of the Azure Document Translation endpoint
/// </summary>
public string AzureResourceName { get; set; } = string.Empty;
/// <summary>
/// The URI of the Azure Text Translation endpoint
/// </summary>
public string TextTransUri { get; set; } = string.Empty;
/// <summary>
/// Sets the string to be used as a flight
/// </summary>
public string FlightString { get; set; } = string.Empty;
internal BlobContainerClient ContainerClientSource { get; set; }
internal Dictionary<string, BlobContainerClient> ContainerClientTargets { get; set; } = new();
/// <summary>
/// Holds the Azure Http Status to check during the run of the translation
/// </summary>
internal Azure.Response AzureHttpStatus;
public DocumentTranslationOperation DocumentTranslationOperation { get => documentTranslationOperation; set => documentTranslationOperation = value; }
private DocumentTranslationClient documentTranslationClient;
private DocumentTranslationOperation documentTranslationOperation;
private CancellationToken cancellationToken;
private CancellationTokenSource cancellationTokenSource;
#endregion Properties
#region Constants
/// <summary>
/// The base URL template for making translation requests.
/// </summary>
private const string baseUriTemplate = ".cognitiveservices.azure.com/";
#endregion Constants
#region Methods
/// <summary>
/// Constructor
/// </summary>
public DocumentTranslationService(string SubscriptionKey, string AzureResourceName, string StorageConnectionString)
{
this.SubscriptionKey = SubscriptionKey;
this.AzureResourceName = AzureResourceName;
this.StorageConnectionString = StorageConnectionString;
}
public DocumentTranslationService()
{
}
/// <summary>
/// Fires when initialization is complete.
/// </summary>
public event EventHandler OnInitializeComplete;
/// <summary>
/// Fills the properties with values from the service.
/// </summary>
/// <returns></returns>
public async Task InitializeAsync()
{
if (string.IsNullOrEmpty(AzureResourceName)) throw new CredentialsException("name");
if (string.IsNullOrEmpty(SubscriptionKey)) throw new CredentialsException("key");
if (string.IsNullOrEmpty(TextTransUri)) TextTransUri = "https://api.cognitive.microsofttranslator.com/";
string DocTransEndpoint;
if (!AzureResourceName.Contains('.')) DocTransEndpoint = "https://" + AzureResourceName + baseUriTemplate;
else DocTransEndpoint = AzureResourceName;
var options = new DocumentTranslationClientOptions();
if (!string.IsNullOrEmpty(FlightString)) options.AddPolicy(new FlightPolicy(FlightString.Trim()), Azure.Core.HttpPipelinePosition.PerCall);
documentTranslationClient = new(new Uri(DocTransEndpoint), new Azure.AzureKeyCredential(SubscriptionKey), options);
List<Task> tasks = new()
{
GetDocumentFormatsAsync(),
GetGlossaryFormatsAsync()
};
try
{
await Task.WhenAll(tasks);
await GetLanguagesAsync();
}
catch (CredentialsException ex)
{
throw new CredentialsException(ex.Message, ex);
}
OnInitializeComplete?.Invoke(this, EventArgs.Empty);
}
/// <summary>
/// Retrieve the status of the translation progress.
/// </summary>
/// <returns></returns>
public async Task<DocumentTranslationOperation> CheckStatusAsync()
{
for (int i = 0; i < 3; i++)
{
AzureHttpStatus = await documentTranslationOperation.UpdateStatusAsync(cancellationToken);
if (AzureHttpStatus.IsError)
{
await Task.Delay(300);
continue;
}
return documentTranslationOperation;
}
return null;
}
/// <summary>
/// Cancels an ongoing translation run.
/// </summary>
/// <returns></returns>
public async Task<Azure.Response> CancelRunAsync()
{
cancellationTokenSource.Cancel();
await documentTranslationOperation.CancelAsync(cancellationToken);
Azure.Response response = await documentTranslationOperation.UpdateStatusAsync(cancellationToken);
Debug.WriteLine($"Cancellation: {response.Status} {response.ReasonPhrase}");
return response;
}
/// <summary>
/// Submit the translation request to the Document Translation Service.
/// </summary>
/// <param name="input">An object defining the input of what to translate</param>
/// <returns>The status ID</returns>
public async Task<string> SubmitTranslationRequestAsync(DocumentTranslationInput input)
{
if (String.IsNullOrEmpty(AzureResourceName)) throw new CredentialsException("name");
if (String.IsNullOrEmpty(SubscriptionKey)) throw new CredentialsException("key");
if (String.IsNullOrEmpty(StorageConnectionString)) throw new CredentialsException("storage");
cancellationTokenSource = new();
cancellationToken = cancellationTokenSource.Token;
try
{
documentTranslationOperation = await documentTranslationClient.StartTranslationAsync(input, cancellationToken);
}
catch (Azure.RequestFailedException ex)
{
Debug.WriteLine("Request failed: " + ex.Source + ": " + ex.Message);
throw new Exception(ex.Message);
}
catch (System.InvalidOperationException ex)
{
Debug.WriteLine("Request failed: " + ex.Source + ": " + ex.Message);
throw new Exception(ex.Message);
}
await documentTranslationOperation.UpdateStatusAsync();
Debug.WriteLine("Translation Request submitted. Status: " + documentTranslationOperation.Status);
return documentTranslationOperation.Id;
}
public async Task<List<DocumentStatusResult>> GetFinalResultsAsync()
{
List<DocumentStatusResult> documentStatuses = new();
Debug.WriteLine("Final results:");
await foreach (DocumentStatusResult document in documentTranslationOperation.GetValuesAsync(cancellationToken))
{
documentStatuses.Add(document);
Debug.WriteLine($"{document.SourceDocumentUri}\t{document.Error}\t{document.Status}\t{document.TranslatedToLanguageCode}");
}
return documentStatuses;
}
#endregion Methods
}
}