API calls to pretranslate files using DeepL plugin no longer work

Hello,

Since DeepL changed their authentication methods, we no longer can pretranslate our files using API calls to Trados 2024. It still work when pretranslating "manually" from within Trados Studio, but when using the API call

project.RunAutomaticTask(targetFiles.GetIds(), AutomaticTaskTemplateIds.PreTranslateFiles)

, it won't work.

We've narrowed it down to DeepL API key authentication: when adding the DeepL provider manually in Trados Studio, the API key is automatically authenticated when you enter it in the settings dialog for DeepL, but when our external tool uses Trados API to add the DeepL provider to the project using our API key, no such validation occurs, and that's what blocks the pretranslation task from working.

So my question is: is there any way to make it work, it worked just fine before the authentication change? We even tried duplicating the API key authentication when adding the provider to the project, but no luck there.

Thanks for any help on this subject.

Parents
  • hey  , what is the version of the plugin that is installed on the machine where you are running the automation?

    Patrick Andrew Hartnett | Developer Experience | Team Lead | RWS Group

  • Hello  !

    How are you trying to use the DeepL provider? 

    I just tested the 7.1.5.0 version and it worked. The code I used is this:

    using System;
    using Sdl.Core.Globalization;
    using Sdl.ProjectAutomation.Core;
    using Sdl.ProjectAutomation.FileBased;
    using Sdl.ProjectAutomation.Settings;
    
    namespace StandAloneConsoleApp_PretranslateUsingProvider
    {
        public class Program
        {
            private static string GetDateTimeToString(DateTime dateTime)
            {
                var value = dateTime.Year +
                            dateTime.Month.ToString().PadLeft(2, '0') +
                            dateTime.Day.ToString().PadLeft(2, '0') +
                            "-" +
                            dateTime.Hour.ToString().PadLeft(2, '0') +
                            dateTime.Minute.ToString().PadLeft(2, '0') +
                            dateTime.Second.ToString().PadLeft(2, '0');
                return value;
            }
    
            private static void Main(string[] args)
            {
                var projectInfo = new ProjectInfo
                {
                    Name = "",
                    SourceLanguage = new Language(""),
                    TargetLanguages = new[] { new Language("") },
                    LocalProjectFolder = $@"PathWhereProjectsWillBeSaved\{GetDateTimeToString(DateTime.Now)}"
                };
    
                var project = new FileBasedProject(projectInfo);
    
                UpdateProjectProviderSettings(project);
    
                var tpConfig = project.GetTranslationProviderConfiguration();
    
                var tpUriString = "deepltranslationprovider:///";
                var tpReference = new TranslationProviderReference(new Uri(tpUriString), null, true);
                var tpCascadeEntry = new TranslationProviderCascadeEntry(tpReference, true, true, false);
                tpConfig.Entries.Add(tpCascadeEntry);
                project.UpdateTranslationProviderConfiguration(tpConfig);
    
                var apiKey = "";
                project.Credentials.AddCredential(new Uri(tpUriString), apiKey);
                project.Save();
    
                var projFiles =
                    project.AddFiles(
                        new[] { @"filepaths" });
    
    	        //var projFiles = project.AddFolderWithFiles(@"", true);
    
                project.RunAutomaticTasks(projFiles.GetIds(), new[]
                {
                    AutomaticTaskTemplateIds.Scan,
                    AutomaticTaskTemplateIds.ConvertToTranslatableFormat,
                    AutomaticTaskTemplateIds.CopyToTargetLanguages,
                    AutomaticTaskTemplateIds.PreTranslateFiles,
                });
    
                project.Save();
            }
    
            private static void UpdateProjectProviderSettings(FileBasedProject project)
            {
                var settings = project.GetSettings();
                var preTranslateSettings = settings.GetSettingsGroup<TranslateTaskSettings>();
                preTranslateSettings.NoTranslationMemoryMatchFoundAction.Value = NoTranslationMemoryMatchFoundAction.ApplyAutomatedTranslation;
                preTranslateSettings.MinimumMatchScore.Value = 75;
    
                project.UpdateSettings(settings);
                project.Save();
            }
        }
    }

Reply
  • Hello  !

    How are you trying to use the DeepL provider? 

    I just tested the 7.1.5.0 version and it worked. The code I used is this:

    using System;
    using Sdl.Core.Globalization;
    using Sdl.ProjectAutomation.Core;
    using Sdl.ProjectAutomation.FileBased;
    using Sdl.ProjectAutomation.Settings;
    
    namespace StandAloneConsoleApp_PretranslateUsingProvider
    {
        public class Program
        {
            private static string GetDateTimeToString(DateTime dateTime)
            {
                var value = dateTime.Year +
                            dateTime.Month.ToString().PadLeft(2, '0') +
                            dateTime.Day.ToString().PadLeft(2, '0') +
                            "-" +
                            dateTime.Hour.ToString().PadLeft(2, '0') +
                            dateTime.Minute.ToString().PadLeft(2, '0') +
                            dateTime.Second.ToString().PadLeft(2, '0');
                return value;
            }
    
            private static void Main(string[] args)
            {
                var projectInfo = new ProjectInfo
                {
                    Name = "",
                    SourceLanguage = new Language(""),
                    TargetLanguages = new[] { new Language("") },
                    LocalProjectFolder = $@"PathWhereProjectsWillBeSaved\{GetDateTimeToString(DateTime.Now)}"
                };
    
                var project = new FileBasedProject(projectInfo);
    
                UpdateProjectProviderSettings(project);
    
                var tpConfig = project.GetTranslationProviderConfiguration();
    
                var tpUriString = "deepltranslationprovider:///";
                var tpReference = new TranslationProviderReference(new Uri(tpUriString), null, true);
                var tpCascadeEntry = new TranslationProviderCascadeEntry(tpReference, true, true, false);
                tpConfig.Entries.Add(tpCascadeEntry);
                project.UpdateTranslationProviderConfiguration(tpConfig);
    
                var apiKey = "";
                project.Credentials.AddCredential(new Uri(tpUriString), apiKey);
                project.Save();
    
                var projFiles =
                    project.AddFiles(
                        new[] { @"filepaths" });
    
    	        //var projFiles = project.AddFolderWithFiles(@"", true);
    
                project.RunAutomaticTasks(projFiles.GetIds(), new[]
                {
                    AutomaticTaskTemplateIds.Scan,
                    AutomaticTaskTemplateIds.ConvertToTranslatableFormat,
                    AutomaticTaskTemplateIds.CopyToTargetLanguages,
                    AutomaticTaskTemplateIds.PreTranslateFiles,
                });
    
                project.Save();
            }
    
            private static void UpdateProjectProviderSettings(FileBasedProject project)
            {
                var settings = project.GetSettings();
                var preTranslateSettings = settings.GetSettingsGroup<TranslateTaskSettings>();
                preTranslateSettings.NoTranslationMemoryMatchFoundAction.Value = NoTranslationMemoryMatchFoundAction.ApplyAutomatedTranslation;
                preTranslateSettings.MinimumMatchScore.Value = 75;
    
                project.UpdateSettings(settings);
                project.Save();
            }
        }
    }

Children
  • Hello  ,

    Thanks for the sample code. Ours is very similar (I'm going to try to put it in as much context as possible, while omitting the irrelevant parts).

            public DeepLPluginOptions()
            {
                _uriBuilder = new TranslationProviderUriBuilder("deepltranslationprovider");
            }
            protected TranslationProviderUriBuilder UriBuilderDL => _uriBuilder;
    
            public void AddDeepLPluginToProject(FileBasedProject project, string apikey, Language locale,
                string settingsName = null, bool cutTag = false)
            {
                var uri = GetUri(apikey, settingsName, cutTag);
                //Console.WriteLine("Saving plugin settings for DeepL/Intento: {0}", uri);
                SaveDeepLPluginSettings(uri, project, locale, apikey);
            }
            
            Uri GetUri(string apikey, string providerId, string providerName, string customAuth = null,
                string customModel = null,
                string glossary = null, string settingsName = null, bool cutTag = false, bool smartRouting = false)
            {
                return UriBuilderDL.Uri;
            }
    
            public void SaveDeepLPluginSettings(Uri uri, FileBasedProject prj, Language locale, string ApiKey)
            {
                TranslationProviderConfiguration pluginSettings = prj.GetTranslationProviderConfiguration(locale);
    
                Console.WriteLine("Preparing the JSON string for DeepL MT provider");
                Uri DeepLUri = new Uri("deepltranslationprovider://");
                string state = GetStateObject(uri, prj, locale);
                Console.WriteLine("Creating Trados provider using DeepL settings");
                TranslationProviderReference reference = new TranslationProviderReference(uri, state, true);
                TranslationProviderCascadeEntry entry = new TranslationProviderCascadeEntry(reference, false, true, true, 0);
                pluginSettings.Entries.Add(entry);
    
                prj = PreTranslationSettings.SetMinimumMatchValue(prj, locale);
                prj.Credentials.AddCredential(DeepLUri, ApiKey);
    
                prj.UpdateTranslationProviderConfiguration(locale, pluginSettings);
     
                prj.Save();
            }
            
            string GetStateObject(Uri uri, FileBasedProject prj, Language locale)
            {
                System.IO.TextWriter tw = new System.IO.StringWriter();
                JsonTextWriter stateWriter = new JsonTextWriter(tw);
                stateWriter.WriteStartObject();
                    stateWriter.WritePropertyName("ApiVersion");
                    stateWriter.WriteValue("V2 (DeepL Pro API subscription)");
                    stateWriter.WritePropertyName("IgnoreTagsParameter");
                    stateWriter.WriteNull();
                    stateWriter.WritePropertyName("LanguagePairOptions");
                    stateWriter.WriteStartArray();
                        stateWriter.WriteStartObject();
                            stateWriter.WritePropertyName("Formality");
                            stateWriter.WriteValue(0);
                            stateWriter.WritePropertyName("SelectedGlossary");
                            stateWriter.WriteStartObject();
                                stateWriter.WritePropertyName("glossary_id");
                                stateWriter.WriteNull();
                                stateWriter.WritePropertyName("IsChecked");
                                stateWriter.WriteValue(false);
                                stateWriter.WritePropertyName("Name");
                                stateWriter.WriteValue("No glossary");
                                stateWriter.WritePropertyName("source_lang");
                                stateWriter.WriteNull();
                                stateWriter.WritePropertyName("target_lang");
                                stateWriter.WriteNull();
                            stateWriter.WriteEndObject();
                            stateWriter.WritePropertyName("LanguagePair");
                            stateWriter.WriteStartObject();
                                stateWriter.WritePropertyName("SourceCultureName");
                                Sdl.ProjectAutomation.Core.ProjectInfo prjSettings = prj.GetProjectInfo();
                                string SrcLang = prjSettings.SourceLanguage.CultureInfo.Name;
                                string TgtLang = locale.CultureInfo.Name;
                                stateWriter.WriteValue(SrcLang);
                                stateWriter.WritePropertyName("TargetCultureName");
                                stateWriter.WriteValue(TgtLang);
                            stateWriter.WriteEndObject();
                        stateWriter.WriteEndObject();
                    stateWriter.WriteEndArray();
                    stateWriter.WritePropertyName("LanguagesSupported");
                    stateWriter.WriteStartObject();
                        stateWriter.WritePropertyName(TgtLang);
                        stateWriter.WriteValue("DeepLTranslator");
                    stateWriter.WriteEndObject();
                    stateWriter.WritePropertyName("PreserveFormattingParameter");
                    stateWriter.WriteValue(false);
                    stateWriter.WritePropertyName("SendPlainTextParameter");
                    stateWriter.WriteValue(false);
                    stateWriter.WritePropertyName("ResendDraftParameter");
                    stateWriter.WriteValue(false);
                    stateWriter.WritePropertyName("ModelTypeParameter");
                    stateWriter.WriteValue("Latency_Optimized");
                    stateWriter.WritePropertyName("TagHandlingParameter");
                    stateWriter.WriteValue("None");
                    stateWriter.WritePropertyName("SplitSentenceHandlingParameter");
                    stateWriter.WriteValue("Default");
                    stateWriter.WritePropertyName("Uri");
                    stateWriter.WriteValue("deepltranslationprovider:///");
                stateWriter.WriteEndObject();
    
                return tw.ToString();
            }
    
            static int Main(string[] args)
            {
    
                MtTask mtTask = new MtTask(args[0]);
    
                try
                {
                    ProjectProcessor processor = new ProjectProcessor();
    
                    FileBasedProject project = processor.SetProject(mtTask.ProjectFile);
    
                    foreach (TargLang targLang in mtTask.TargLangs)
                    {
                        if (targLang.Provider == "DeepL")
                        {
                            Console.WriteLine($"Configuring DeepL Settings for {targLang.Lang.ToString()}...");
                            DeepLPluginOptions options = new DeepLPluginOptions();
                            options.AddDeepLPluginToProject(
                                project,
                                targLang.Api,
                                targLang.ProviderId,
                                targLang.ProviderName,
                                targLang.Lang
                            Console.WriteLine($"Pre-translating {targLang.Lang} files...");
    
                            processor.PreTranslateTargetLanguageFiles(project, targLang.Lang);
                        }
                    }
    
                    return ConsoleHelper.WriteSuccess("PackageCreation");
                }
                catch (Exception ex)
                {
                    return ConsoleHelper.WriteError(ex);
                }
            }
    

    As you can see, for the most part, it goes more or less the same way, except we spell out the json content to be inserted as the provider State. Or do we have to rely completely on Trados to insert it automatically? We tried it that way, and it didn't seem to work...

  • Hey  , not sure if it helps, but also check and update the App.Config file. we identified some dependencies changed with the latest update a few months ago... 
    please check here:
    RE: Create Project Via API shows files as Reference 

    Patrick Andrew Hartnett | Developer Experience | Team Lead | RWS Group

  • Thanks again  , I adapted your code to mine, removing all the complexities we had added to mimic what Trados adds in the provider, and let it do its job, and it worked just fine! That's all there was to it.