Custom Translator not applied with Azure Translator - azure-cognitive-services

I'm trying to setup a Custom Translator with a Phrase Dictionary for my company.
I followed the official documentation and this tutorial: https://soltisweb.com/blog/detail/2019-08-13-using-a-custom-translator-with-azure-co.
When I translate it seems that it's not using my custom model, here is my setup:
1 Azure Translator:
Location: Global
Pricing Tier: S1
1 Worspace in Custom Translator, connected to the Azure Translator above:
Subscription name: ****
Subscription type: TextTranslation
Pricing tier: S1
Subscription region: Global
I've created one project:
Category: Global
Language Pair: English - Spanish
I uploaded the same Phrase Dictionary as in the tutorial (Phrase Dictionary):
EN
ES
one
uno
two
dos
three
tres
four
cuatro
five
cinco
six
seis
seven
siete
eight
ocho
nine
nueve
ten
diez
hi
hola
hello
buenos dias
I've generated a model and deployed it everywhere (America, Europe, Asia) without any error.
I've tried to translate "hello" with the following C# code:
// Input and output languages are defined as parameters.
string route = "/translate?api-version=3.0&category=*MyWorkspaceId*-GENERAL&from=en&to=es&allowFallback=true";
string textToTranslate = "hello";
object[] body = new object[] { new { Text = textToTranslate } };
var requestBody = JsonConvert.SerializeObject(body);
using (var client = new HttpClient())
using (var request = new HttpRequestMessage())
{
// Build the request.
request.Method = HttpMethod.Post;
request.RequestUri = new Uri("https://api.cognitive.microsofttranslator.com/" + route);
request.Content = new StringContent(requestBody, Encoding.UTF8, "application/json");
request.Headers.Add("Ocp-Apim-Subscription-Key", subscriptionKey);
request.Headers.Add("Ocp-Apim-Subscription-Region", "global");
// Send the request and get response.
HttpResponseMessage response = await client.SendAsync(request).ConfigureAwait(false);
// Read response as a string.
string result = await response.Content.ReadAsStringAsync();
Console.WriteLine(result);
}
The result is:
[{"translations":[{"text":"Hola","to":"es"}]}]
The result should be "buenos dias".
I might be missing something really basic... I already tried to re-create everything from scratch with no success.
Update 1
Switched allowFallback=true to allowFallback=false.
{Method: POST, RequestUri: 'https://api.cognitive.microsofttranslator.com//translate?api-version=3.0&category=***-GENERAL&from=en&to=es&allowFallback=false',
Version: 1.1,
Content: System.Net.Http.StringContent,
Headers:
{
Ocp-Apim-Subscription-Key: ***
Ocp-Apim-Subscription-Region: global
Content-Type: application/json; charset=utf-8
}}
Input:
"one, two, three, four, five, six, seven, eight, nine, ten, hi, hello, My name is Doe."
Ouput:
[{"translations":[{"text":"uno, dos, tres, cuatro, cinco, seis, siete, ocho, nueve, diez, hola, hola, Mi nombre es Doe.","to":"es"}]}]
Thanks for your support,
Cyril

We rolled out a hot fix. Issue should be resolved now. Sorry for the inconvenience.

There is a possibility you are not hitting your custom model. So, let's first make small change to your API call.
&allowFallback=false to ensure if you don't hit your custom model, the call would fail instead of getting served from our standard model.
Best,
Mohamed

Related

how to change dotnet core outgoing http request hostname from the default localhost

I am able to successfully send requests to a sandbox via postman, given by a provider following their specs (see images below)
Successful request (see below)
In order to do that, aside from the respective headers and parameters (see image 2) I have to add a ssl/Tls certificate (.pfx) given that the server requires a 2 way handshake so it needs SSl client certificate:
Authorization (see below).
Headers (see below)
Body (see below)
Now, I am trying to do ir programatically using dotnet core 6, but I keep running into the same problem:
And here is my code:
public static string GetAccessToken(IConfiguration _config)
{
string UserName = Environment.GetEnvironmentVariable("USER_NAME");
string Password = Environment.GetEnvironmentVariable("PASSWORD");
var client = new RestClient("https://connect2.xyz.com/auth/token");
var request = new RestRequest();
X509Certificate2 FullChainCertificate = new X509Certificate2("Path/to/Cert/cert.pfx", "test");
client.Options.ClientCertificates = new X509CertificateCollection() { FullChainCertificate };
client.Options.Proxy = new WebProxy("connect2.xyz.com");
var restrequest = new RestRequest();
restrequest.Method = Method.Get;
restrequest.AddHeader("Accept", "*/*");
restrequest.AddHeader("Cache-Control", "no-cache");
restrequest.AddHeader("Content-Type", "application/x-www-form-urlencoded");
restrequest.AddHeader("Authorization", "Basic " + Convert.ToBase64String(Encoding.Default.GetBytes($"{UserName}:{Password}")));
restrequest.AddParameter("grant_type", "client_credentials");
RestResponse response = client.Execute(restrequest);
AccessTokenPointClickCare accessToken = JsonConvert.DeserializeObject<AccessTokenPointClickCare>(response.Content);
string strToken = accessToken.access_token;
return strToken;
}
Now, as the error seems to show, it has to do with the certificates (apparently), but I don't know if something in the code is wrong, or if I'm missing something, etc...
It is worth noting that this code did run in someone else's pc with the same set-up, but of course with that person's own pfx, but for the rest, it is essentially the same, and not to mention that it does work on my postman.
Finally, as the title on this question, the only thing I can think it might also be affecting the request is the host. If I reference the postman, there is a field where I have to place the host name of the server https://connect2.xyz.com/auth/token
So made it work by changing to a new Windows 10. Researching in other Stackoverflow threads found the answer: .NET CORE 5 '''HandshakeFailure'" when making HTTPS request
So I conclude it has to do with the cyphers

Using Graph in Outlook addin to read email in MIME format

I am getting lost with Outlook addin development and really need some help.
I have developed an addin that sends selected email to another server via REST API and it worked fine, but there was a limitation to 1MB so I tried to develop a solution that use ewsURL + SOAP but faced with CORS issues.
Now I got a suggestion to use GRAPH approach (fine with me) but I have no idea how that suppose to work using JavaScript.
Basically I need to get an email as MIME/EML format.
I was guided to check this article: https://learn.microsoft.com/en-us/graph/outlook-get-mime-message
There is endpoint that looks promissing:
https://graph.microsoft.com/v1.0/me/messages/4aade2547798441eab5188a7a2436bc1/$value
But I do not see explanation
how to make authorization process?
I have tried to get token from getCallbackTokenAsync but that did not work
I have tried Office.context.auth.getAccessTokenAsync but getting an issue:
Error code: 13000 Error name: API Not Supported.
Error message: The identity API is not supported for this add-in.
how to get email id
I have tried to do Office.context.mailbox.item.itemId but it looks different compare to what I have seen in the examples (but hopefully that is not a problem)
Please help :-)
There are 2 solutions here. It is preferred longer term to use graph end point with https://learn.microsoft.com/en-us/office/dev/add-ins/develop/authorize-to-microsoft-graph and you can use https://graph.microsoft.com/v1.0/me/messages/4aade2547798441eab5188a7a2436bc1/$value. However this solution requires a backend / service . Transferring through backend is preferable for large content so the content can transfer directly from Exchange to the service.
Alternatively, you can get token from getCallbackTokenAsync, from this doc: https://learn.microsoft.com/en-us/office/dev/add-ins/outlook/use-rest-api
As you noted is that you will need to translate the ews id using convertToRestId. Putting together, your solution should look something like this:
Office.context.mailbox.getCallbackTokenAsync({isRest: true}, function(result){
if (result.status === "succeeded") {
let token = result.value;
var ewsItemId = Office.context.mailbox.item.itemId;
const itemId = Office.context.mailbox.convertToRestId(
ewsItemId,
Office.MailboxEnums.RestVersion.v2_0);
// Request the message's attachment info
var getMessageUrl = Office.context.mailbox.restUrl +
'/v2.0/me/messages/' + itemId + '/$value';
var xhr = new XMLHttpRequest();
xhr.open('GET', getMessageUrl);
xhr.setRequestHeader("Authorization", "Bearer " + token);
xhr.onload = function (e) {
console.log(this.response);
}
xhr.onerror = function (e) {
console.log("error occurred");
}
xhr.send();
}
});

The number of keys specified in the URI does not match number of key properties for the resource 'microsoft.graph.bookingAppointment

We are trying to use Graph APIs for Bookings application. In fact, we are customizing
the C# code from the microsoft sample :
https://microsoft.github.io/bookings-samples/
We have the application registration and all the permissions configured in Azure.
Using the BookingsSampleNativeConsole, we are able to query the graphService.BookingBusinesses
as shown below.
var graphService = new GraphService(GraphService.ServiceRoot,
() => authenticationResult.CreateAuthorizationHeader());
Unfortunately none of the other entities gets populated. So we are using the following to query the appointments:
Uri appointUri = new Uri("https://graph.microsoft.com/beta/bookingBusinesses/{id}/appointments");
var appointParams = new UriOperationParameter[]
{
new UriOperationParameter("start", "2020-08-01T00:00:00Z"),
new UriOperationParameter("end", "2020-08-31T00:00:00Z")
};
var resp = graphService.Execute(appointUri, "GET", appointParams);
But this call returns :
An error occurred while processing this request. --->
Microsoft.OData.Client.DataServiceClientException:
{
"error":
{
"code": "BadRequest",
"message": "The number of keys specified in the URI does not match number of key properties for the resource 'microsoft.graph.bookingAppointment'."
}
}
Any idea what we are missing or wrong with appointParams ?
Thanks in advance.
(2)Graph APIs for Bookings has been in beta for quite sometime now. Any idea
when is the probable release date for version 1.0 ?
Ajit19

Mailgun - POST body is not interpreted as url-encoded

I'm trying to send emails through mailgun email service. I'm using angular 2. This is what my service looks like:
sendEmail(fromName, fromEmail, message) {
var headers = new Headers();
var recieverMail = "abc#123.se";//service#csc.kth.se"
var subject = "error report submitted by interactive screen"
headers.append("Authorization", "Basic "+btoa("MY_API_KEY"));
headers.append("content-type", "application/x-www-form-urlencoded");
var url = "https://api.mailgun.net/v3/mymailgun.mailgun.org/messages";
var data = "from="+fromName+"&to=" +recieverMail+"&subject="+subject+"&text="+message;
return this.http.post(url,data, {headers: headers});
}
I got two different programs that is using this service and they both passes the service strings but the service only fails for one of them.
Applcation 1 recieves an error message saying that the "from" parameter is missing and it is because the mail data is not interpreted as url-encoded for some reason. It is just interpreted as plain text!
Application 2 successfully sends messages with the same service and input. As you can see, this time the mail data is interpreted as url-encoded and the mailgun API recognizes the mail parameters.
Any suggestions on what might be causing this problem for application 1?
(I know that the data is not 100% identical from the screenshot but the problem that i want to illustrate is that they interpret the mail data differently)

Mailchimp RESTful API 3.0 HTTP Basic Auth

I'm trying to use the Mailchimp API version 3.0 with basic auth. I'm using Classic ASP.
The Json response is always: "API Key Missing".
Set HttpReq = Server.CreateObject("MSXML2.ServerXMLHTTP")
HttpReq.open "GET", "https://us4.api.mailchimp.com/3.0/", False
HttpReq.setRequestHeader "Content-Type", "application/json"
HttpReq.setRequestHeader "apikey", "xxxxxx"
HttpReq.send ""
Response.Write HttpReq.ResponseText
Set HttpReq = Nothing
I'm sending it as a header.
What am I doing wrong..?
The answer is:
HttpReq.setRequestHeader "Authorization", "apikey xxxxxx"
If you're trying to use Basic Auth, you need to actually follow the spec. You can build the header yourself using the wiki article as your guide, but the easiest thing is to just use your HTTP Library's built-in support for that. In your case, this will probably help.
To roll your own, you need two pieces of information. The first is the username the second is the password. For MailChimp v3.0, the username can be anything. I tend to use 'apikey' as the username. The password is the API Key itself. Let's say my API Key is 'xxxxxxxxxx-yyy'. Now, you Base 64 Encode the string apikey:xxxxxxxxxx-yyy. That gives me YXBpa2V5Onh4eHh4eHh4eHgteXl5. Now the header I create is:
Authorization: Basic YXBpa2V5Onh4eHh4eHh4eHgteXl5
The method you're using will work, but is very custom to MailChimp and might confuse future visitors to your code.
I see that the question was based on #C but I had the same problem with java.(I am new to java so fell free to edit my code).
public String get(String url) throws IOException {
HttpGet get = new HttpGet(url);
String apiEncode = "apikey:9590e52MyAPI8-us9";
String encoding = Base64.encodeBytes(apiEncode.getBytes());
get.setHeader("Authorization","Basic " + encoding );
HttpResponse response = http.execute(get);
if (response.getEntity() != null) {
return EntityUtils.toString(response.getEntity(), "UTF-8").trim();
} else {
throw new IOException(response.getStatusLine().toString());
}
}

Resources