Azure / azure-sdk-for-net

This repository is for active development of the Azure SDK for .NET. For consumers of the SDK we recommend visiting our public developer docs at https://learn.microsoft.com/dotnet/azure/ or our versioned developer docs at https://azure.github.io/azure-sdk-for-net.
MIT License
5.47k stars 4.8k forks source link

[BUG][LUIS] Authoring client uses LUIS version 2.0; Runtime client uses LUIS version 3.0-preview #6834

Closed v-jaswel closed 5 years ago

v-jaswel commented 5 years ago

Describe the bug In the Azure SDK for .NET, the LUIS runtime client is set to use version 3.0-preview of the service instead of 2.0.

https://github.com/Azure/azure-sdk-for-net/blob/master/sdk/cognitiveservices/Language.LUIS.Runtime/src/Generated/LUISRuntimeClient.cs line 183:

BaseUri = "{Endpoint}/luis/v3.0-preview";

This is different from the Azure SDKs for all other languages (Python, Go, Java) except JS. See issue 4189 (https://github.com/Azure/azure-sdk-for-js/issues/4189).

Meanwhile, the LUIS authoring client is set to use version 2.0.

https://github.com/Azure/azure-sdk-for-net/blob/master/sdk/cognitiveservices/Language.LUIS.Authoring/src/Generated/LUISAuthoringClient.cs line 237:

BaseUri = "{Endpoint}/luis/api/v2.0";

As a result you cannot use the Azure SDK for .NET to do the following tasks.

  1. Create an application (this uses the Authoring client).
  2. Query the application for predictions (this uses the Runtime client).

The reason is that methods on LUIS version 3.0 cannot see applications that were created with LUIS version 2.0.

See also issue 4189 (https://github.com/Azure/azure-sdk-for-js/issues/4189), which describes how to reproduce this with the API testing consoles.

Exception or Stack Trace

"   at Microsoft.Azure.CognitiveServices.Language.LUIS.Runtime.PredictionOperations.<GetVersionPredictionWithHttpMessagesAsync>d__5.MoveNext()\r\n--- End of stack trace from previous location where exception was thrown ---\r\n   at System.Runtime.CompilerServices.TaskAwaiter.ThrowForNonSuccess(Task task)\r\n   at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task)\r\n   at Microsoft.Azure.CognitiveServices.Language.LUIS.Runtime.PredictionOperationsExtensions.<GetVersionPredictionAsync>d__0.MoveNext()\r\n--- End of stack trace from previous location where exception was thrown ---\r\n   at System.Runtime.CompilerServices.TaskAwaiter.ThrowForNonSuccess(Task task)\r\n   at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task)\r\n   at System.Runtime.CompilerServices.TaskAwaiter`1.GetResult()\r\n   at LUIS_Prediction_CS.Program.<Query_App>d__9.MoveNext() in C:\\Users\\<user>\\Documents\\Quickstarts20190604\\LUIS_Prediction_CS\\LUIS_Prediction_CS\\Program.cs:line 92"

To Reproduce

  1. Get a LUIS subscription key.
  2. Set the environment variable LUIS_SUBSCRIPTION_KEY to your subscription key.
  3. Set the environment variable LUIS_REGION to the region for your subscription key (example: westus).
  4. Create a C# .NET Framework console app.
  5. Add the NuGet packages Microsoft.Azure.CognitiveServices.Language.LUIS.Authoring (version 3.0.0), Microsoft.Azure.CognitiveServices.Language.LUIS.Runtime (version 2.8.0-preview).
  6. Run the following code.

Code Snippet

using System;
using System.Threading.Tasks;

/* Note: Add the following NuGet packages to your solution.
 * - Microsoft.Azure.CognitiveServices.Language.LUIS.Authoring v3.0.0
 * - Microsoft.Azure.CognitiveServices.Language.LUIS.Runtime v2.8.0-preview
*/
using Microsoft.Azure.CognitiveServices.Language.LUIS.Authoring;
using Microsoft.Azure.CognitiveServices.Language.LUIS.Authoring.Models;
using Microsoft.Azure.CognitiveServices.Language.LUIS.Runtime;
using Microsoft.Azure.CognitiveServices.Language.LUIS.Runtime.Models;

namespace LUIS_Prediction_CS
{
    struct ApplicationInfo
    {
        public Guid ID;
        public string Version;
    }

    class Program
    {
        private const string key_var = "LUIS_SUBSCRIPTION_KEY";
        private static readonly string subscription_key = Environment.GetEnvironmentVariable(key_var);

        // Note you must use the same region as you used to get your subscription key.
        private const string region_var = "LUIS_REGION";
        private static readonly string region = Environment.GetEnvironmentVariable(region_var);
        private static readonly string endpoint = "https://" + region + ".api.cognitive.microsoft.com";

        static Program()
        {
            if (null == subscription_key)
            {
                throw new Exception("Please set/export the environment variable: " + key_var);
            }
            if (null == region)
            {
                throw new Exception("Please set/export the environment variable: " + region_var);
            }
        }

        // Create a new LUIS application. Return the application ID and version.
        async static Task<ApplicationInfo> CreateApplication(LUISAuthoringClient client)
        {
            string app_version = "0.1";
            var app_info = new ApplicationCreateObject()
            {
                Name = String.Format("Contoso {0}", DateTime.Now),
                InitialVersionId = app_version,
                Description = "Flight booking app built with LUIS .NET SDK.",
                Culture = "en-us"
            };
            var app_id = await client.Apps.AddAsync(app_info);
            Console.WriteLine("Created new LUIS application {0}\n with ID {1}.", app_info.Name, app_id);
            return new ApplicationInfo() { ID = app_id, Version = app_version };
        }

        // Train a LUIS application.
        async static Task Train_App(LUISAuthoringClient client, ApplicationInfo app)
        {
            var response = await client.Train.TrainVersionAsync(app.ID, app.Version);
            Console.WriteLine("Training status: " + response.Status);
        }

        // Publish a LUIS application and show the endpoint URL for the published application.
        async static Task Publish_App(LUISAuthoringClient client, ApplicationInfo app)
        {
            ApplicationPublishObject obj = new ApplicationPublishObject
            {
                VersionId = app.Version
            };
            var info = await client.Apps.PublishAsync(app.ID, obj);
            Console.WriteLine("Endpoint URL: " + info.EndpointUrl);
        }

        // Send a query to a LUIS application.
        async static Task Query_App(LUISRuntimeClient client, ApplicationInfo app, string query)
        {
            PredictionRequest obj = new PredictionRequest
            {
                Query = query
            };
            try
            {
                var info = await client.Prediction.GetVersionPredictionAsync(app.ID, app.Version, obj);
                Console.WriteLine(info.ToString());
            }
            catch (ErrorException e)
            {
                Console.WriteLine(e.Message);
                Console.WriteLine(e.Response.Content);
            }
        }

        // Delete a LUIS application.
        async static Task Delete_App(LUISAuthoringClient client, ApplicationInfo app)
        {
            await client.Apps.DeleteAsync(app.ID);
            Console.WriteLine("Deleted application with ID {0}.", app.ID);
        }

        async static Task RunQuickstart()
        {
            // Generate the credentials and create the client.
            var credentials = new Microsoft.Azure.CognitiveServices.Language.LUIS.Authoring.ApiKeyServiceClientCredentials(subscription_key);
            var authoring_client = new LUISAuthoringClient(credentials, new System.Net.Http.DelegatingHandler[] { })
            {
                Endpoint = "https://" + region + ".api.cognitive.microsoft.com"
            };
            var runtime_client = new LUISRuntimeClient(credentials, new System.Net.Http.DelegatingHandler[] { })
            {
                Endpoint = "https://" + region + ".api.cognitive.microsoft.com"
            };

            Console.WriteLine("Creating application...");
            var app = await CreateApplication(authoring_client);
            Console.WriteLine();

            /* We skip adding entities, intents, and utterances because the
             * predict method will not find the app anyway. */

            Console.WriteLine("Training application...");
            await Train_App(authoring_client, app);
            Console.WriteLine("Waiting 30 seconds for training to complete...");
            System.Threading.Thread.Sleep(30000);
            Console.WriteLine();

            Console.WriteLine("Publishing application...");
            await Publish_App(authoring_client, app);
            Console.WriteLine();

            Console.WriteLine("Querying application...");
            /* It doesn't matter what query we send because the predict method
             * will not find the app anyway. */
            await Query_App(runtime_client, app, "test");
            Console.WriteLine();

            Console.WriteLine("Deleting application...");
            await Delete_App(authoring_client, app);
        }

        static void Main(string[] args)
        {
            Task.WaitAll(RunQuickstart());
            Console.WriteLine("Press any key to exit.");
            Console.Read();
        }
    }
}

Output:

Creating application...
Created new LUIS application Contoso 7/7/2019 1:45:54 PM
 with ID 5d326f2f-fc42-424b-b885-7e91403bdae1.

Training application...
Training status: Queued
Waiting 30 seconds for training to complete...

Publishing application...
Endpoint URL: https://westus.api.cognitive.microsoft.com/luis/v2.0/apps/5d326f2f-fc42-424b-b885-7e91403bdae1

Querying application...
Operation returned an invalid status code 'NotFound'
{
  "error": {
    "code": "NotFound",
    "message": "The application wasn't found. Please make sure that the application is published to this region."
  }
}

Deleting application...
Deleted application with ID 5d326f2f-fc42-424b-b885-7e91403bdae1.
Press any key to exit.

Expected behavior Microsoft.Azure.CognitiveServices.Language.LUIS.Runtime.Prediction.GetVersionPredictionAsyncdoes not raise an exception.

Setup (please complete the following information):

Information Checklist Kindly make sure that you have added all the following information above and checkoff the required fields otherwise we will treat the issuer as an incomplete report

maggiepint commented 5 years ago

Thanks for the feedback. I have routed to the appropriate team for follow up.

kayousef-zz commented 5 years ago

Hi @v-jaswel Thank you for reporting your concern.

Please note that API version for authoring is totally independent from the runtime. However, all versions communicate with the same service, so you can author your apps using Authoring V2.0 and query them using Runtime V2.0 or V3.0-preview.

As for your specific issue, I'd like you to share your exact requests for publishing the app, and query using runtime V3.0 to be able to assist.

We support two ways for publish, either using slots (PRODUCTION/STAGING) or using versions (i.e. 1.0, 2.0 ... etc) as described here Then, we support with runtime V3.0-preview two options for querying the published app (based on the publish method used). Either using slot or by version

My take is that you publish using slot publishing, query with v3.0-preview with version (hence it doesn't work), and query with 2.0 using slot (hence it works)

Please, let me know if that matches your case. If not, please share with me the details of your requests and I'll be happy to assist.

ghost commented 5 years ago

Thanks for working with Microsoft on GitHub! Tell us how you feel about your experience using the reactions on this comment.