Created
August 23, 2018 07:31
-
-
Save AbhiOnGithub/8098dd9bc03120d1379f2079eb239ba0 to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
using System; | |
using System.Collections.Generic; | |
using System.Linq; | |
using System.Net.Http; | |
using System.Net.Http.Headers; | |
using System.Text; | |
using System.Threading; | |
using System.Threading.Tasks; | |
// NOTE: Install the Newtonsoft.Json NuGet package. | |
using Newtonsoft.Json; | |
namespace QnAMaker | |
{ | |
class Program | |
{ | |
// Represents the various elements used to create HTTP request URIs | |
// for QnA Maker operations. | |
static string host = "https://westus.api.cognitive.microsoft.com"; | |
static string service = "/qnamaker/v4.0"; | |
static string method = "/knowledgebases/create"; | |
// NOTE: Replace this value with a valid QnA Maker subscription key. | |
static string key = "YOUR SUBSCRIPTION KEY HERE"; | |
/// <summary> | |
/// Defines the data source used to create the knowledge base. | |
/// The data source includes a QnA pair, with metadata, | |
/// the URL for the QnA Maker FAQ article, and | |
/// the URL for the Azure Bot Service FAQ article. | |
/// </summary> | |
static string kb = @" | |
{ | |
'name': 'QnA Maker FAQ', | |
'qnaList': [ | |
{ | |
'id': 0, | |
'answer': 'You can use our REST APIs to manage your knowledge base. See here for details: https://westus.dev.cognitive.microsoft.com/docs/services/58994a073d9e04097c7ba6fe/operations/58994a073d9e041ad42d9baa', | |
'source': 'Custom Editorial', | |
'questions': [ | |
'How do I programmatically update my knowledge base?' | |
], | |
'metadata': [ | |
{ | |
'name': 'category', | |
'value': 'api' | |
} | |
] | |
} | |
], | |
'urls': [ | |
'https://docs.microsoft.com/en-in/azure/cognitive-services/qnamaker/faqs', | |
'https://docs.microsoft.com/en-us/bot-framework/resources-bot-framework-faq' | |
], | |
'files': [] | |
} | |
"; | |
/// <summary> | |
/// Represents the HTTP response returned by an HTTP request. | |
/// </summary> | |
public struct Response | |
{ | |
public HttpResponseHeaders headers; | |
public string response; | |
public Response(HttpResponseHeaders headers, string response) | |
{ | |
this.headers = headers; | |
this.response = response; | |
} | |
} | |
/// <summary> | |
/// Formats and indents JSON for display. | |
/// </summary> | |
/// <param name="s">The JSON to format and indent.</param> | |
/// <returns>A string containing formatted and indented JSON.</returns> | |
static string PrettyPrint(string s) | |
{ | |
return JsonConvert.SerializeObject(JsonConvert.DeserializeObject(s), Formatting.Indented); | |
} | |
/// <summary> | |
/// Asynchronously sends a POST HTTP request. | |
/// </summary> | |
/// <param name="uri">The URI of the HTTP request.</param> | |
/// <param name="body">The body of the HTTP request.</param> | |
/// <returns>A <see cref="System.Threading.Tasks.Task{TResult}(QnAMaker.Program.Response)"/> | |
/// object that represents the HTTP response."</returns> | |
async static Task<Response> Post(string uri, string body) | |
{ | |
using (var client = new HttpClient()) | |
using (var request = new HttpRequestMessage()) | |
{ | |
request.Method = HttpMethod.Post; | |
request.RequestUri = new Uri(uri); | |
request.Content = new StringContent(body, Encoding.UTF8, "application/json"); | |
request.Headers.Add("Ocp-Apim-Subscription-Key", key); | |
var response = await client.SendAsync(request); | |
var responseBody = await response.Content.ReadAsStringAsync(); | |
return new Response(response.Headers, responseBody); | |
} | |
} | |
/// <summary> | |
/// Asynchronously sends a GET HTTP request. | |
/// </summary> | |
/// <param name="uri">The URI of the HTTP request.</param> | |
/// <returns>A <see cref="System.Threading.Tasks.Task{TResult}(QnAMaker.Program.Response)"/> | |
/// object that represents the HTTP response."</returns> | |
async static Task<Response> Get(string uri) | |
{ | |
using (var client = new HttpClient()) | |
using (var request = new HttpRequestMessage()) | |
{ | |
request.Method = HttpMethod.Get; | |
request.RequestUri = new Uri(uri); | |
request.Headers.Add("Ocp-Apim-Subscription-Key", key); | |
var response = await client.SendAsync(request); | |
var responseBody = await response.Content.ReadAsStringAsync(); | |
return new Response(response.Headers, responseBody); | |
} | |
} | |
/// <summary> | |
/// Creates a knowledge base. | |
/// </summary> | |
/// <param name="kb">The data source for the knowledge base.</param> | |
/// <returns>A <see cref="System.Threading.Tasks.Task{TResult}(QnAMaker.Program.Response)"/> | |
/// object that represents the HTTP response."</returns> | |
/// <remarks>The method constructs the URI to create a knowledge base in QnA Maker, and then | |
/// asynchronously invokes the <see cref="QnAMaker.Program.Post(string, string)"/> method | |
/// to send the HTTP request.</remarks> | |
async static Task<Response> PostCreateKB(string kb) | |
{ | |
// Builds the HTTP request URI. | |
string uri = host + service + method; | |
// Writes the HTTP request URI to the console, for display purposes. | |
Console.WriteLine("Calling " + uri + "."); | |
// Asynchronously invokes the Post(string, string) method, using the | |
// HTTP request URI and the specified data source. | |
return await Post(uri, kb); | |
} | |
/// <summary> | |
/// Gets the status of the specified QnA Maker operation. | |
/// </summary> | |
/// <param name="operation">The QnA Maker operation to check.</param> | |
/// <returns>A <see cref="System.Threading.Tasks.Task{TResult}(QnAMaker.Program.Response)"/> | |
/// object that represents the HTTP response."</returns> | |
/// <remarks>The method constructs the URI to get the status of a QnA Maker operation, and | |
/// then asynchronously invokes the <see cref="QnAMaker.Program.Get(string)"/> method | |
/// to send the HTTP request.</remarks> | |
async static Task<Response> GetStatus(string operation) | |
{ | |
// Builds the HTTP request URI. | |
string uri = host + service + operation; | |
// Writes the HTTP request URI to the console, for display purposes. | |
Console.WriteLine("Calling " + uri + "."); | |
// Asynchronously invokes the Get(string) method, using the | |
// HTTP request URI. | |
return await Get(uri); | |
} | |
/// <summary> | |
/// Creates a knowledge base, periodically checking status | |
/// until the knowledge base is created. | |
/// </summary> | |
async static void CreateKB() | |
{ | |
try | |
{ | |
// Starts the QnA Maker operation to create the knowledge base. | |
var response = await PostCreateKB(kb); | |
// Retrieves the operation ID, so the operation's status can be | |
// checked periodically. | |
var operation = response.headers.GetValues("Location").First(); | |
// Displays the JSON in the HTTP response returned by the | |
// PostCreateKB(string) method. | |
Console.WriteLine(PrettyPrint(response.response)); | |
// Iteratively gets the state of the operation creating the | |
// knowledge base. Once the operation state is set to something other | |
// than "Running" or "NotStarted", the loop ends. | |
var done = false; | |
while (true != done) | |
{ | |
// Gets the status of the operation. | |
response = await GetStatus(operation); | |
// Displays the JSON in the HTTP response returned by the | |
// GetStatus(string) method. | |
Console.WriteLine(PrettyPrint(response.response)); | |
// Deserialize the JSON into key-value pairs, to retrieve the | |
// state of the operation. | |
var fields = JsonConvert.DeserializeObject<Dictionary<string, string>>(response.response); | |
// Gets and checks the state of the operation. | |
String state = fields["operationState"]; | |
if (state.CompareTo("Running") == 0 || state.CompareTo("NotStarted") == 0) | |
{ | |
// QnA Maker is still creating the knowledge base. The thread is | |
// paused for a number of seconds equal to the Retry-After header value, | |
// and then the loop continues. | |
var wait = response.headers.GetValues("Retry-After").First(); | |
Console.WriteLine("Waiting " + wait + " seconds..."); | |
Thread.Sleep(Int32.Parse(wait) * 1000); | |
} | |
else | |
{ | |
// QnA Maker has completed creating the knowledge base. | |
done = true; | |
} | |
} | |
} | |
catch | |
{ | |
// An error occurred while creating the knowledge base. Ensure that | |
// you included your QnA Maker subscription key where directed in the sample. | |
Console.WriteLine("An error occurred while creating the knowledge base."); | |
} | |
finally | |
{ | |
Console.WriteLine("Press any key to continue."); | |
} | |
} | |
static void Main(string[] args) | |
{ | |
// Invoke the CreateKB() method to create a knowledge base, periodically | |
// checking the status of the QnA Maker operation until the | |
// knowledge base is created. | |
CreateKB(); | |
// The console waits for a key to be pressed before closing. | |
Console.ReadLine(); | |
} | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment