public static IActionResult RunAcronymLinker( [HttpTrigger(AuthorizationLevel.Function, "get", "post", Route = null)] HttpRequest req, ILogger log, ExecutionContext executionContext) { log.LogInformation("Link Acronyms Custom Skill: C# HTTP trigger function processed a request."); string skillName = executionContext.FunctionName; IEnumerable <WebApiRequestRecord> requestRecords = WebApiSkillHelpers.GetRequestRecords(req); if (requestRecords == null) { return(new BadRequestObjectResult($"{skillName} - Invalid request record array.")); } AcronymLinker acronymLinker = new AcronymLinker(executionContext.FunctionAppDirectory); WebApiSkillResponse response = WebApiSkillHelpers.ProcessRequestRecords(skillName, requestRecords, (inRecord, outRecord) => { string word = inRecord.Data["word"] as string; if (word.All(char.IsUpper) && acronymLinker.Acronyms.TryGetValue(word, out string description)) { outRecord.Data["acronym"] = new { value = word, description }; } return(outRecord); }); return(new OkObjectResult(response)); }
public static async Task <IActionResult> Run( [HttpTrigger(AuthorizationLevel.Anonymous, "get", "post", Route = null)] HttpRequest req, ILogger log) { IEnumerable <WebApiRequestRecord> requestRecords = WebApiSkillHelpers.GetRequestRecords(req); if (requestRecords == null) { return(new BadRequestObjectResult($"GetMetaData - Invalid request record array.")); } WebApiSkillResponse response = WebApiSkillHelpers.ProcessRequestRecords("GetMetaData", requestRecords, (inRecord, outRecord) => { var input1 = inRecord.Data["field_1"].ToString(); var input2 = inRecord.Data["field_2"].ToString(); outRecord.Data["output_field_1"] = input1; outRecord.Data["output_field_2"] = input2; return(outRecord); }); return((ActionResult) new OkObjectResult(response)); }
public static IActionResult RunHocrGenerator( [HttpTrigger(AuthorizationLevel.Function, "post", Route = null)] HttpRequest req, ILogger log, ExecutionContext executionContext) { log.LogInformation("hOCR Generator Custom Skill: C# HTTP trigger function processed a request."); string skillName = executionContext.FunctionName; IEnumerable <WebApiRequestRecord> requestRecords = WebApiSkillHelpers.GetRequestRecords(req); if (requestRecords == null || requestRecords.Count() != 1) { return(new BadRequestObjectResult($"{skillName} - Invalid request record array: Skill requires exactly 1 image per request.")); } WebApiSkillResponse response = WebApiSkillHelpers.ProcessRequestRecords(skillName, requestRecords, (inRecord, outRecord) => { List <OcrImageMetadata> imageMetadataList = ((JArray)inRecord.Data["ocrImageMetadataList"]).ToObject <List <OcrImageMetadata> >(); Dictionary <string, string> annotations = ((JArray)inRecord.Data["wordAnnotations"]) .Where(o => o.Type != JTokenType.Null) .GroupBy(o => o["value"].Value <string>()) .Select(g => g.First()) .ToDictionary(o => o["value"].Value <string>(), o => o["description"].Value <string>()); List <HocrPage> pages = imageMetadataList .Select((imageMetadata, i) => new HocrPage(imageMetadata, i, annotations)) .ToList(); outRecord.Data["hocrDocument"] = new HocrDocument(pages); return(outRecord); }); return(new OkObjectResult(response)); }
public static IActionResult RunAcronymLinkerForLists([HttpTrigger(AuthorizationLevel.Function, "post", Route = null)] HttpRequest req, ILogger log, ExecutionContext executionContext) { log.LogInformation("Link Acronyms List Custom Skill: C# HTTP trigger function processed a request."); string skillName = executionContext.FunctionName; IEnumerable <WebApiRequestRecord> requestRecords = WebApiSkillHelpers.GetRequestRecords(req); if (requestRecords == null) { return(new BadRequestObjectResult($"{skillName} - Invalid request record array.")); } AcronymLinker acronymLinker = new AcronymLinker(executionContext.FunctionAppDirectory); WebApiSkillResponse response = WebApiSkillHelpers.ProcessRequestRecords(skillName, requestRecords, (inRecord, outRecord) => { var words = JsonConvert.DeserializeObject <JArray>(JsonConvert.SerializeObject(inRecord.Data["words"])); var acronyms = words .Distinct() .Select(jword => { var word = jword.Value <string>(); if (word.All(char.IsUpper) && acronymLinker.Acronyms.TryGetValue(word, out string description)) { return(new { value = word, description }); } return(null); }) .Where(acronym => acronym != null); outRecord.Data["acronyms"] = acronyms.ToArray(); return(outRecord); });
public static IActionResult RunUploadToQnaMaker( [HttpTrigger(AuthorizationLevel.Function, "post", Route = null)] HttpRequest req, [Queue("upload-to-qna"), StorageAccount("AzureWebJobsStorage")] ICollector <QnAQueueMessageBatch> msg, ILogger log, ExecutionContext executionContext) { log.LogInformation("UploadToQnAMaker Custom Skill: C# HTTP trigger function processed a request."); string skillName = executionContext.FunctionName; IEnumerable <WebApiRequestRecord> requestRecords = WebApiSkillHelpers.GetRequestRecords(req); if (requestRecords == null) { return(new BadRequestObjectResult($"{skillName} - Invalid request record array.")); } var msgBatch = new QnAQueueMessageBatch(); WebApiSkillResponse response = WebApiSkillHelpers.ProcessRequestRecords(skillName, requestRecords, (inRecord, outRecord) => { string id = (inRecord.Data.TryGetValue("id", out object idObject) ? idObject : null) as string; string blobName = (inRecord.Data.TryGetValue("blobName", out object blobNameObject) ? blobNameObject : null) as string; string blobUrl = (inRecord.Data.TryGetValue("blobUrl", out object blobUrlObject) ? blobUrlObject : null) as string; string sasToken = (inRecord.Data.TryGetValue("sasToken", out object sasTokenObject) ? sasTokenObject : null) as string; long blobSizeInKBs = (inRecord.Data.TryGetValue("blobSize", out object blobSizeObject) ? (long)blobSizeObject : 0) / 1024; if (string.IsNullOrWhiteSpace(blobUrl)) { outRecord.Errors.Add(new WebApiErrorWarningContract() { Message = $"Parameter '{nameof(blobUrl)}' is required to be present and a valid uri." }); return(outRecord); } string fileUri = WebApiSkillHelpers.CombineSasTokenWithUri(blobUrl, sasToken); if (!IsValidFile(blobName, blobSizeInKBs)) { log.LogError("upload-to-qna-queue-trigger: unable to extract qnas from this file " + blobName + " of size " + blobSizeInKBs); outRecord.Data["status"] = "Failed"; } else { var queueMessage = new QnAQueueMessage { Id = id, FileName = blobName, FileUri = fileUri }; msgBatch.Values.Add(queueMessage); if (msgBatch.Values.Count >= 10) { msg.Add(msgBatch); msgBatch.Values.Clear(); } outRecord.Data["status"] = "InQueue"; } return(outRecord); });
public static IActionResult RunDecryptBlobFile( [HttpTrigger(AuthorizationLevel.Function, "post", Route = null)] HttpRequest req, ILogger log, ExecutionContext executionContext) { log.LogInformation("DecryptBlobFile Custom Skill: C# HTTP trigger function processed a request."); string skillName = executionContext.FunctionName; IEnumerable <WebApiRequestRecord> requestRecords = WebApiSkillHelpers.GetRequestRecords(req); if (requestRecords == null) { return(new BadRequestObjectResult($"{skillName} - Invalid request record array.")); } // Set up access to keyvault to retrieve the key to decrypt the document with // Requires that this Azure Function has access via managed identity to the Keyvault where the key is stored. var azureServiceTokenProvider1 = new AzureServiceTokenProvider(); var kv = new KeyVaultClient(new KeyVaultClient.AuthenticationCallback(azureServiceTokenProvider1.KeyVaultTokenCallback)); KeyVaultKeyResolver cloudResolver = new KeyVaultKeyResolver(kv); BlobEncryptionPolicy policy = new BlobEncryptionPolicy(null, cloudResolver); BlobRequestOptions options = new BlobRequestOptions() { EncryptionPolicy = policy }; WebApiSkillResponse response = WebApiSkillHelpers.ProcessRequestRecords(skillName, requestRecords, (inRecord, outRecord) => { string blobUrl = (inRecord.Data.TryGetValue("blobUrl", out object blobUrlObject) ? blobUrlObject : null) as string; string sasToken = (inRecord.Data.TryGetValue("sasToken", out object sasTokenObject) ? sasTokenObject : null) as string; if (string.IsNullOrWhiteSpace(blobUrl)) { outRecord.Errors.Add(new WebApiErrorWarningContract() { Message = $"Parameter '{nameof(blobUrl)}' is required to be present and a valid uri." }); return(outRecord); } CloudBlockBlob blob = new CloudBlockBlob(new Uri(WebApiSkillHelpers.CombineSasTokenWithUri(blobUrl, sasToken))); byte[] decryptedFileData; using (var np = new MemoryStream()) { blob.DownloadToStream(np, null, options, null); decryptedFileData = np.ToArray(); } FileReference decryptedFileReference = new FileReference() { data = Convert.ToBase64String(decryptedFileData) }; JObject jObject = JObject.FromObject(decryptedFileReference); jObject["$type"] = "file"; outRecord.Data["decrypted_file_data"] = jObject; return(outRecord); });
public static IActionResult RunProjection( [HttpTrigger(AuthorizationLevel.Function, "post", Route = null)] HttpRequest req, ILogger log, ExecutionContext executionContext) { log.LogInformation("Projection: C# HTTP trigger function processed a request."); string skillName = executionContext.FunctionName; log.LogInformation($"REQUEST: {new StreamReader(req.Body).ReadToEnd()}"); req.Body.Position = 0; IEnumerable <WebApiRequestRecord> requestRecords = WebApiSkillHelpers.GetRequestRecords(req); if (requestRecords == null) { return(new BadRequestObjectResult($"{skillName} - Invalid request record array.")); } WebApiSkillResponse response = WebApiSkillHelpers.ProcessRequestRecords(skillName, requestRecords, (inRecord, outRecord) => { Conversation[] turns = JsonConvert.DeserializeObject <Conversation[]>(inRecord.Data["conversation"].ToString()); List <Conversation> output = turns.ToList <Conversation>(); if (output == null || output.All(x => x == null)) { outRecord.Data["result"] = null; outRecord.Data["summary"] = null; return(outRecord); } var sortedList = output.OrderBy(foo => foo.offset).ToList(); ConversationSummary summary = new ConversationSummary(); summary.Turns = turns.Length; if (sortedList.Where(c => c.speaker == "1").FirstOrDefault() == null) { summary.AverageSentiment = 0; summary.LowestSentiment = 0; summary.HighestSentiment = 0; summary.MaxChange = new Tuple <int, float>(0, 0.0f); } else { summary.AverageSentiment = sortedList.Where(c => c.speaker == "1").Select(a => a.sentiment).Average(); summary.LowestSentiment = sortedList.Where(c => c.speaker == "1").Select(a => a.sentiment).Min(); summary.HighestSentiment = sortedList.Where(c => c.speaker == "1").Select(a => a.sentiment).Max(); //summary.MaxChange = ConversationSummary.MaxDiff(sortedList.Where(c => c.speaker == "1").Select(a => a.sentiment).ToList()); summary.Moment = ConversationSummary.GetKeyMoment(sortedList); } outRecord.Data["result"] = sortedList; outRecord.Data["summary"] = summary; return(outRecord); }); log.LogInformation(JsonConvert.SerializeObject(response)); return(new OkObjectResult(response)); }
public static IActionResult RunGetFileExtension( [HttpTrigger(AuthorizationLevel.Anonymous, "post", Route = null)] HttpRequest req, ExecutionContext executionContext, ILogger log) { var config = new ConfigurationBuilder() .SetBasePath(executionContext.FunctionAppDirectory) .AddJsonFile("local.settings.json", optional: true, reloadOnChange: true) .AddEnvironmentVariables() .Build(); string skillName = executionContext.FunctionName; log.LogInformation($"{skillName} Custom Skill: C# HTTP trigger function processed a request."); var requestRecords = WebApiSkillHelpers.GetRequestRecords(req); if (requestRecords == null) { return(new BadRequestObjectResult($"{skillName} - Invalid request record array.")); } var response = WebApiSkillHelpers.ProcessRequestRecords(skillName, requestRecords, (inRecord, outRecord) => { try { var documentName = inRecord.Data["documentName"] as string; var extension = ""; var fileName = ""; if (!string.IsNullOrWhiteSpace(documentName)) { extension = Path.GetExtension(documentName); fileName = Path.GetFileNameWithoutExtension(documentName); } outRecord.Data.Add("extension", extension); outRecord.Data.Add("fileName", fileName); } catch (Exception e) { outRecord.Errors.Add(new WebApiErrorWarningContract { Message = e.ToString() }); } return(outRecord); }); return(new OkObjectResult(response)); }
public static IActionResult RunKewit( [HttpTrigger(AuthorizationLevel.Function, "post", Route = null)] HttpRequest req, ILogger log, ExecutionContext executionContext) { log.LogInformation("Projection: C# HTTP trigger function processed a request."); string skillName = executionContext.FunctionName; log.LogInformation($"REQUEST: {new StreamReader(req.Body).ReadToEnd()}"); req.Body.Position = 0; IEnumerable <WebApiRequestRecord> requestRecords = WebApiSkillHelpers.GetRequestRecords(req); if (requestRecords == null) { return(new BadRequestObjectResult($"{skillName} - Invalid request record array.")); } WebApiSkillResponse response = WebApiSkillHelpers.ProcessRequestRecords(skillName, requestRecords, (inRecord, outRecord) => { string content = inRecord.Data["text"].ToString(); string regex = inRecord.Data["regex"].ToString(); if (regex == null) { regex = "^[A-Z]{2,5}$"; } Regex rx = new Regex(regex); MatchCollection matches = rx.Matches(content); foreach (Match match in matches) { GroupCollection groups = match.Groups; Console.WriteLine("'{0}' repeated at positions {1} and {2}", groups["word"].Value, groups[0].Index, groups[1].Index); } var list = matches.Cast <Match>().Select(match => new { match.Value, match.Index }).ToList(); outRecord.Data["matches"] = list; return(outRecord); }); //log.LogInformation(JsonConvert.SerializeObject(response)); return(new OkObjectResult(response)); }
public static async Task <IActionResult> RunDistinct( [HttpTrigger(AuthorizationLevel.Function, "post", Route = null)] HttpRequest req, ILogger log, ExecutionContext executionContext) { log.LogInformation("Distinct Custom Skill: C# HTTP trigger function processed a request."); string skillName = executionContext.FunctionName; IEnumerable <WebApiRequestRecord> requestRecords = WebApiSkillHelpers.GetRequestRecords(req); if (requestRecords == null) { return(new BadRequestObjectResult($"{skillName} - Invalid request record array.")); } Thesaurus thesaurus = null; try { thesaurus = new Thesaurus(executionContext.FunctionAppDirectory); } catch (Exception e) { throw new Exception("Failed to read and parse thesaurus.json.", e); } WebApiSkillResponse response = WebApiSkillHelpers.ProcessRequestRecords(skillName, requestRecords, (inRecord, outRecord) => { JArray wordsParameter = inRecord.Data.TryGetValue("words", out object wordsParameterObject) ? wordsParameterObject as JArray : null; if (wordsParameter is null) { throw new ArgumentException("Input data is missing a `words` array of words to de-duplicate.", "words"); } var words = wordsParameter.Values <string>(); outRecord.Data["distinct"] = thesaurus.Dedupe(words); return(outRecord); }); return(new OkObjectResult(response)); }
public static async Task <IActionResult> RunCustomEntityLookup( [HttpTrigger(AuthorizationLevel.Function, "post", Route = null)] HttpRequest req, ILogger log, ExecutionContext executionContext) { log.LogInformation("Custom Entity Search function: C# HTTP trigger function processed a request."); if (_impl == null || executionContext.FunctionName == "unitTestFunction") { _impl = new CustomEntityLookupImplementation(CustomEntitiesDefinition.ParseCustomEntityDefinition(EntityDefinitionLocation)); } IEnumerable <WebApiRequestRecord> requestRecords = WebApiSkillHelpers.GetRequestRecords(req); if (requestRecords == null) { return(new BadRequestObjectResult($"{executionContext.FunctionName} - Invalid request record array.")); } WebApiSkillResponse response = WebApiSkillHelpers.ProcessRequestRecords(executionContext.FunctionName, requestRecords, (inRecord, outRecord) => { if (!inRecord.Data.ContainsKey("text") || inRecord.Data["text"] == null) { outRecord.Errors.Add(new WebApiErrorWarningContract { Message = "Cannot process record without the given key 'text' with a string value" }); return(outRecord); } string text = inRecord.Data["text"] as string; var foundEntities = _impl.GetCustomLookupResult(text, System.Threading.CancellationToken.None); outRecord.Data["entities"] = foundEntities; return(outRecord); }); return(new OkObjectResult(response)); }
public static async Task <IActionResult> RunJapaneseOCR( [HttpTrigger(AuthorizationLevel.Function, "post", Route = null)] HttpRequest req, ILogger log, ExecutionContext executionContext) { log.LogInformation("JapaneseOCR remove spaces Custom Skill: C# HTTP trigger function processed a request."); string skillName = executionContext.FunctionName; IEnumerable <WebApiRequestRecord> requestRecords = WebApiSkillHelpers.GetRequestRecords(req); if (requestRecords == null) { return(new BadRequestObjectResult($"{skillName} - Invalid request record array.")); } WebApiSkillResponse response = WebApiSkillHelpers.ProcessRequestRecords(skillName, requestRecords, (inRecord, outRecord) => { var inputText = inRecord.Data["text"] as string; outRecord.Data["ocrtext"] = ""; if (string.IsNullOrEmpty(inputText)) { return(outRecord); } // 正規表現で全角文字+半白スペースの場合、半角スペースのみを除去 var newContent = Regex.Replace(inputText, @"([^\x01-\x7E])\x20", "$1"); // 全角文字+ハイフン+半角スペースの場合、ハイフンを全角長音に変換し半角スペースを除去 newContent = Regex.Replace(newContent, @"([^\x01-\x7E])-\x20?", "$1ー"); log.LogInformation($"newContent: {newContent}"); outRecord.Data["ocrtext"] = newContent; return(outRecord); }); return(new OkObjectResult(response)); }
public static IActionResult RunTokenizer( [HttpTrigger(AuthorizationLevel.Function, "post", Route = null)] HttpRequest req, ILogger log, ExecutionContext executionContext) { log.LogInformation("Tokenizer Custom Skill: C# HTTP trigger function processed a request."); string skillName = executionContext.FunctionName; IEnumerable <WebApiRequestRecord> requestRecords = WebApiSkillHelpers.GetRequestRecords(req); if (requestRecords == null) { return(new BadRequestObjectResult($"{skillName} - Invalid request record array.")); } WebApiSkillResponse response = WebApiSkillHelpers.ProcessRequestRecords(skillName, requestRecords, (inRecord, outRecord) => { var text = new TextData { Text = inRecord.Data["text"] as string }; StopWordsRemovingEstimator.Language language = MapToMlNetLanguage(inRecord.Data.TryGetValue("languageCode", out object languageCode) ? languageCode as string : "en"); var mlContext = new MLContext(); IDataView emptyDataView = mlContext.Data.LoadFromEnumerable(new List <TextData>()); EstimatorChain <StopWordsRemovingTransformer> textPipeline = mlContext.Transforms.Text .NormalizeText("Text", caseMode: TextNormalizingEstimator.CaseMode.Lower, keepDiacritics: true, keepPunctuations: false, keepNumbers: false) .Append(mlContext.Transforms.Text.TokenizeIntoWords("Words", "Text", separators: new[] { ' ' })) .Append(mlContext.Transforms.Text.RemoveDefaultStopWords("Words", language: language)); TransformerChain <StopWordsRemovingTransformer> textTransformer = textPipeline.Fit(emptyDataView); PredictionEngine <TextData, TransformedTextData> predictionEngine = mlContext.Model.CreatePredictionEngine <TextData, TransformedTextData>(textTransformer); outRecord.Data["words"] = predictionEngine.Predict(text).Words ?? Array.Empty <string>(); return(outRecord); }); return(new OkObjectResult(response)); }
public static async Task <IActionResult> RunHelloWorld( [HttpTrigger(AuthorizationLevel.Function, "post", Route = null)] HttpRequest req, ILogger log, ExecutionContext executionContext) { log.LogInformation("Hello World Custom Skill: C# HTTP trigger function processed a request."); string skillName = executionContext.FunctionName; IEnumerable <WebApiRequestRecord> requestRecords = WebApiSkillHelpers.GetRequestRecords(req); if (requestRecords == null) { return(new BadRequestObjectResult($"{skillName} - Invalid request record array.")); } WebApiSkillResponse response = WebApiSkillHelpers.ProcessRequestRecords(skillName, requestRecords, (inRecord, outRecord) => { var name = inRecord.Data["name"] as string; outRecord.Data["greeting"] = $"Hello, {name}"; return(outRecord); }); return(new OkObjectResult(response)); }
public static async Task <IActionResult> RunCustomEntitySearch( [HttpTrigger(AuthorizationLevel.Function, "post", Route = null)] HttpRequest req, ILogger log, ExecutionContext executionContext) { if (preLoadedWords == null) { preLoadedWords = WordLinker.WordLink(executionContext.FunctionAppDirectory, "csv").Words; } log.LogInformation("Custom Entity Search function: C# HTTP trigger function processed a request."); string skillName = executionContext.FunctionName; IEnumerable <WebApiRequestRecord> requestRecords = WebApiSkillHelpers.GetRequestRecords(req); if (requestRecords == null) { return(new BadRequestObjectResult($"{skillName} - Invalid request record array.")); } WebApiSkillResponse response = WebApiSkillHelpers.ProcessRequestRecords(skillName, requestRecords, (inRecord, outRecord) => { if (!inRecord.Data.ContainsKey("text") || inRecord.Data["text"] == null) { outRecord.Errors.Add(new WebApiErrorWarningContract { Message = "Cannot process record without the given key 'text' with a string value" }); return(outRecord); } if (!inRecord.Data.ContainsKey("words") && (inRecord.Data.ContainsKey("synonyms") || inRecord.Data.ContainsKey("exactMatches") || inRecord.Data.ContainsKey("fuzzyMatchOffset"))) { outRecord.Errors.Add(new WebApiErrorWarningContract { Message = "Cannot process record without the given key 'words' in the dictionary" }); return(outRecord); } string text = inRecord.Data["text"] as string; IList <string> words; if (inRecord.Data.ContainsKey("words") == true) { words = inRecord.GetOrCreateList <List <string> >("words"); } else { outRecord.Warnings.Add(new WebApiErrorWarningContract { Message = "Used predefined key words from customLookupSkill configuration file " + "since no 'words' parameter was supplied in web request" }); words = preLoadedWords; } Dictionary <string, string[]> synonyms = inRecord.GetOrCreateDictionary <Dictionary <string, string[]> >("synonyms"); IList <string> exactMatches = inRecord.GetOrCreateList <List <string> >("exactMatches"); int offset = (inRecord.Data.ContainsKey("fuzzyMatchOffset")) ? Math.Max(0, Convert.ToInt32(inRecord.Data["fuzzyMatchOffset"])) : 0; bool caseSensitive = (inRecord.Data.ContainsKey("caseSensitive")) ? (bool)inRecord.Data.ContainsKey("caseSensitive") : false; if (words.Count == 0 || (words.Count(word => !String.IsNullOrEmpty(word)) == 0)) { try { WordLinker userInput = WordLinker.WordLink(executionContext.FunctionDirectory, "json"); words = userInput.Words; synonyms = userInput.Synonyms; exactMatches = userInput.ExactMatch; offset = (userInput.FuzzyMatchOffset >= 0) ? userInput.FuzzyMatchOffset : 0; caseSensitive = userInput.CaseSensitive; outRecord.Warnings.Add(new WebApiErrorWarningContract { Message = "Used predefined key words from customLookupSkill configuration file " + "since no 'words' parameter was supplied in web request" }); } catch (Exception) { outRecord.Errors.Add(new WebApiErrorWarningContract { Message = "Could not parse predefined words.json" }); return(outRecord); } } var entities = new List <Entity>(); var entitiesFound = new HashSet <string>(); if (!string.IsNullOrWhiteSpace(text)) { foreach (string word in words) { if (string.IsNullOrEmpty(word)) { continue; } int leniency = (exactMatches != null && exactMatches.Contains(word)) ? 0 : offset; string wordCharArray = (caseSensitive) ? CreateWordArray(word) : CreateWordArray(word.ToLower(CultureInfo.CurrentCulture)); if (leniency >= wordCharArray.Length) { outRecord.Warnings.Add(new WebApiErrorWarningContract { Message = @"The provided fuzzy offset of " + leniency + @", is larger than the length of the provided word, """ + word + @"""." }); leniency = Math.Max(0, wordCharArray.Length - 1); } AddValues(word, text, wordCharArray, entities, entitiesFound, leniency, caseSensitive); if (synonyms.TryGetValue(word, out string[] wordSynonyms)) { foreach (string synonym in wordSynonyms) { leniency = (exactMatches != null && exactMatches.Contains(synonym)) ? 0 : offset; string synonymCharArray = (caseSensitive) ? CreateWordArray(synonym) : CreateWordArray(synonym.ToLower(CultureInfo.CurrentCulture)); if (leniency >= synonym.Length) { outRecord.Warnings.Add(new WebApiErrorWarningContract { Message = @"The provided fuzzy offset of " + leniency + @", is larger than the length of the provided synonym, """ + synonym + @"""." }); leniency = Math.Max(0, synonymCharArray.Length - 1); } AddValues(synonym, text, synonymCharArray, entities, entitiesFound, leniency, caseSensitive); } } }
public static async Task <IActionResult> RunSplitImageSkill( [HttpTrigger(AuthorizationLevel.Function, "post", Route = null)] HttpRequest req, ILogger log, ExecutionContext executionContext) { log.LogInformation("Split Image Custom Skill: C# HTTP trigger function processed a request."); string skillName = executionContext.FunctionName; IEnumerable <WebApiRequestRecord> requestRecords = WebApiSkillHelpers.GetRequestRecords(req); if (requestRecords == null) { return(new BadRequestObjectResult($"{skillName} - Invalid request record array.")); } WebApiSkillResponse response = WebApiSkillHelpers.ProcessRequestRecords(skillName, requestRecords, (inRecord, outRecord) => { var imageUrl = (inRecord.Data.TryGetValue("imageLocation", out object imageUrlObject) ? imageUrlObject : null) as string; var sasToken = (inRecord.Data.TryGetValue("imageLocation", out object sasTokenObject) ? sasTokenObject : null) as string; if (string.IsNullOrWhiteSpace(imageUrl)) { outRecord.Errors.Add(new WebApiErrorWarningContract() { Message = "Parameter 'imageUrl' is required to be present and a valid uri." }); return(outRecord); } JArray splitImages = new JArray(); using (WebClient client = new WebClient()) { byte[] fileData = executionContext.FunctionName == "unitTestFunction" ? fileData = File.ReadAllBytes(imageUrl) // this is a unit test, find the file locally : fileData = client.DownloadData(new Uri(CombineSasTokenWithUri(imageUrl, sasToken))); // download the file from remote server using (var stream = new MemoryStream(fileData)) { var originalImage = Image.Load(stream); // chunk the document up into pieces // overlap the chunks to reduce the chances of cutting words in half // (and not being able to OCR that data) for (int x = 0; x < originalImage.Width; x += (MaxImageDimension - ImageOverlapInPixels)) { for (int y = 0; y < originalImage.Height; y += (MaxImageDimension - ImageOverlapInPixels)) { int startX = x; int endX = x + MaxImageDimension >= originalImage.Width ? originalImage.Width : x + MaxImageDimension; int startY = y; int endY = y + MaxImageDimension >= originalImage.Height ? originalImage.Height : y + MaxImageDimension; var newImageData = CropImage(originalImage, startX, endX, startY, endY); var imageData = new JObject(); imageData["$type"] = "file"; imageData["data"] = System.Convert.ToBase64String(newImageData); imageData["width"] = endX - startX; imageData["height"] = endY - startY; splitImages.Add(imageData); } } } } outRecord.Data["splitImages"] = splitImages; return(outRecord); });
public static async Task <IActionResult> Run( [HttpTrigger(AuthorizationLevel.Function, "post", Route = null)] HttpRequest req, ILogger log, Microsoft.Azure.WebJobs.ExecutionContext executionContext) { log.LogInformation("LUIS-D Extractor and Classifier function"); string skillName = executionContext.FunctionName; IEnumerable <WebApiRequestRecord> requestRecords = WebApiSkillHelpers.GetRequestRecords(req); if (requestRecords == null) { return(new BadRequestObjectResult($"{skillName} - Invalid request record array.")); } WebApiSkillResponse response = WebApiSkillHelpers.ProcessRequestRecords(skillName, requestRecords, (inRecord, outRecord) => { var text = inRecord.Data["text"] as string; Dictionary <string, string> luisQuery = new Dictionary <string, string>(); luisQuery.Add("query", text); string luisInput = JsonConvert.SerializeObject(luisQuery); //call luis log.LogInformation("Sending the document to LUIS-D for classification and extraction"); string operationId = null; using (var requestMessage = new HttpRequestMessage(HttpMethod.Post, string.Format(LUISPredictionendpoint, LUISAppId))) { requestMessage.Headers.Add("Ocp-Apim-Subscription-Key", LUISPredictionKey); requestMessage.Content = new StringContent(luisInput); requestMessage.Content.Headers.ContentType = new System.Net.Http.Headers.MediaTypeHeaderValue("application/json"); HttpResponseMessage response = httpClient.SendAsync(requestMessage).GetAwaiter().GetResult(); operationId = JsonConvert.DeserializeObject <Dictionary <string, string> >(response.Content.ReadAsStringAsync().GetAwaiter().GetResult())["operationId"]; } log.LogInformation("Checking for classification and extraction status..."); string status = null; do { Thread.Sleep(1000); using (var requestMessage = new HttpRequestMessage(HttpMethod.Get, string.Format(LUISCheckOperationStatusEndpoint, LUISAppId, operationId))) { requestMessage.Headers.Add("Ocp-Apim-Subscription-Key", LUISPredictionKey); HttpResponseMessage response = httpClient.SendAsync(requestMessage).GetAwaiter().GetResult(); status = JsonConvert.DeserializeObject <Dictionary <string, string> >(response.Content.ReadAsStringAsync().GetAwaiter().GetResult())["status"]; } log.LogInformation($"Extraction status: {status}"); }while (status != "succeeded" && status != "failed"); if (status == "succeeded") { LUISResult luisResult = null; log.LogInformation("Downloading for classification and extraction results..."); using (var requestMessage = new HttpRequestMessage(HttpMethod.Get, string.Format(LUISGetResultEndpoint, LUISAppId, operationId))) { requestMessage.Headers.Add("Ocp-Apim-Subscription-Key", LUISPredictionKey); HttpResponseMessage response = httpClient.SendAsync(requestMessage).GetAwaiter().GetResult(); luisResult = JsonConvert.DeserializeObject <LUISResult>(response.Content.ReadAsStringAsync().GetAwaiter().GetResult()); } Dictionary <string, object> output = new Dictionary <string, object>(); if (luisResult.prediction.classifiers != null && luisResult.prediction.classifiers.Count > 0) { outRecord.Data.Add("Class", luisResult.prediction.classifiers.First().Value); } foreach (var entity in luisResult.prediction.extractors) { if (entity.Key != "$instance") { outRecord.Data.Add(entity.Key, entity.Value); } } outRecord.Data["result"] = "success"; } else { outRecord.Data["result"] = "failed"; } return(outRecord); }); return(new OkObjectResult(response)); }