Skip to content

Commit

Permalink
Form Analyzer added
Browse files Browse the repository at this point in the history
  • Loading branch information
heblasco committed Nov 23, 2023
1 parent b530b44 commit 769d55a
Show file tree
Hide file tree
Showing 5 changed files with 370 additions and 4 deletions.
260 changes: 260 additions & 0 deletions src/AIHub/Controllers/FormAnalyzerController.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,260 @@
using System.Diagnostics;
using Microsoft.AspNetCore.Mvc;
using MVCWeb.Models;
using Azure.AI.ContentSafety;
using Azure;
using ContentSafetySampleCode;
using System;
using Azure.Storage.Blobs;
using Azure.Storage.Blobs.Models;
using Azure.Identity;
using Azure.AI.OpenAI;
using System;
using System.Collections.Generic;
using System.Net.Http;
using System.Net.Http.Headers;
using Newtonsoft.Json;
using System.Text;
using System.Text.Json;
using System.Threading.Tasks;
using System.Runtime.InteropServices;


namespace MVCWeb.Controllers;

public class FormAnalyzerController : Controller
{
private readonly ILogger<HomeController> _logger;
private readonly IConfiguration _config;
private string FormRecogEndpoint;
private string FormRecogSubscriptionKey;
private string AOAIendpoint;
private string AOAIsubscriptionKey;
private string storageconnstring;
private readonly BlobServiceClient blobServiceClient;
private readonly BlobContainerClient containerClient;
private readonly IEnumerable<BlobItem> blobs;
private Uri sasUri;


//Results
string result_image_front;
string result_message_front;



private FormAnalyzerModel model;


public FormAnalyzerController(IConfiguration config)
{
_config = config;
FormRecogEndpoint = _config.GetValue<string>("FormAnalyzer:FormRecogEndpoint");
FormRecogSubscriptionKey = _config.GetValue<string>("FormAnalyzer:FormRecogSubscriptionKey");
AOAIendpoint = _config.GetValue<string>("FormAnalyzer:OpenAIEndpoint");
AOAIsubscriptionKey = _config.GetValue<string>("FormAnalyzer:OpenAISubscriptionKey");
storageconnstring = _config.GetValue<string>("Storage:ConnectionString");
BlobServiceClient blobServiceClient = new BlobServiceClient(storageconnstring);
containerClient = blobServiceClient.GetBlobContainerClient(_config.GetValue<string>("FormAnalyzer:ContainerName"));
sasUri = containerClient.GenerateSasUri(Azure.Storage.Sas.BlobContainerSasPermissions.Read, DateTimeOffset.UtcNow.AddHours(1));
// Obtiene una lista de blobs en el contenedor
blobs = containerClient.GetBlobs();
model = new FormAnalyzerModel();
}

public IActionResult FormAnalyzer()
{
return View();
}

[HttpPost]
public async Task<IActionResult> AnalyzeForm(string image_url, string prompt)
{


//1. Get Image
string image = image_url + sasUri.Query;
Console.WriteLine(image);
//ViewBag.PdfUrl = "http://docs.google.com/gview?url="+image+"&embedded=true";
ViewBag.PdfUrl = image;
string output_result;

HttpClient client = new HttpClient();
client.BaseAddress = new Uri(FormRecogEndpoint);

// Add an Accept header for JSON format.
client.DefaultRequestHeaders.Accept.Add(
new MediaTypeWithQualityHeaderValue("application/json"));
client.DefaultRequestHeaders.Add("Ocp-Apim-Subscription-Key", FormRecogSubscriptionKey);

var content = new
{
urlSource = image
};
var json = System.Text.Json.JsonSerializer.Serialize(content);
// Crear un HttpContent con el JSON y el tipo de contenido
HttpContent content_body = new StringContent(json, Encoding.UTF8, "application/json");
// List data response.
HttpResponseMessage response = await client.PostAsync(FormRecogEndpoint, content_body); // Blocking call! Program will wait here until a response is received or a timeout occurs.
response.EnsureSuccessStatusCode();

//string responseBody = await response.Content.ReadAsStringAsync();
string operation_location_url = response.Headers.GetValues("Operation-Location").FirstOrDefault();


client.Dispose();


//llamar a GET OPERATION
HttpClient client2 = new HttpClient();
client2.BaseAddress = new Uri(operation_location_url);

// Add an Accept header for JSON format.
client2.DefaultRequestHeaders.Accept.Add(
new MediaTypeWithQualityHeaderValue("application/json"));
client2.DefaultRequestHeaders.Add("Ocp-Apim-Subscription-Key", FormRecogSubscriptionKey);

// Crear un HttpContent con el JSON y el tipo de contenido
// List data response.
HttpResponseMessage response2 = await client2.GetAsync(operation_location_url); // Blocking call! Program will wait here until a response is received or a timeout occurs.
Console.WriteLine(response2);
response2.EnsureSuccessStatusCode();
var responseBody = await response2.Content.ReadAsStringAsync();
var responsejson = JsonConvert.DeserializeObject<dynamic>(await response2.Content.ReadAsStringAsync());

//var analyzeresult = responseBody.analyzeResult;
while (responsejson.status != "succeeded")
{
Thread.Sleep(10000);
response2 = await client2.GetAsync(operation_location_url);
responsejson = JsonConvert.DeserializeObject<dynamic>(await response2.Content.ReadAsStringAsync());
}
output_result = responsejson.analyzeResult.content.ToString();

// Above three lines can be replaced with new helper method below
// string responseBody = await client.GetStringAsync(uri);

// Parse the response as JSON
// var operationLocation= await response.Headers.ReadAsStringAsync();

client2.Dispose();


try
{

OpenAIClient client_oai = new OpenAIClient(
new Uri(AOAIendpoint),
new AzureKeyCredential(AOAIsubscriptionKey));

// ### If streaming is not selected
Response<ChatCompletions> responseWithoutStream = await client_oai.GetChatCompletionsAsync(
"DemoBuild",
new ChatCompletionsOptions()
{
Messages =
{
new ChatMessage(ChatRole.System, @"You are specialized in understanding PDFs and answering questions about it. Document OCR result is: "+output_result),
new ChatMessage(ChatRole.User, @"User question: "+prompt ),
},
Temperature = (float)0.7,
MaxTokens = 1000,
NucleusSamplingFactor = (float)0.95,
FrequencyPenalty = 0,
PresencePenalty = 0,
});

ChatCompletions completions = responseWithoutStream.Value;
ChatChoice results_analisis = completions.Choices[0];
ViewBag.Message =
//"Hate severity: " + (response.Value.HateResult?.Severity ?? 0);
results_analisis.Message.Content
;

/* result_image_front=image;
Console.WriteLine("1) "+result_image_front);
Console.WriteLine("2) "+result_message_front);
/* ViewBag.Message =
results_analisis.Message.Content
; */
//ViewBag.Image=result_image_front+".jpg";

}
catch (RequestFailedException ex)
{
throw;
}

// var result = await _service.GetBuildingHomeAsync();
// return Ok(result);
return View("FormAnalyzer", model);
}

//Upload a file to my azure storage account
[HttpPost]
public async Task<IActionResult> UploadFile(IFormFile imageFile, string prompt)
{
//Check no image

if (CheckNullValues(imageFile))
{
ViewBag.Message = "You must upload an image";
return View("FormAnalyzer");
}

//Upload file to azure storage account
string url = imageFile.FileName.ToString();
Console.WriteLine(url);
url = url.Replace(" ", "");
Console.WriteLine(url);
BlobClient blobClient = containerClient.GetBlobClient(url);
var httpHeaders = new BlobHttpHeaders
{
ContentType = "application/pdf",
};
await blobClient.UploadAsync(imageFile.OpenReadStream(), new BlobUploadOptions { HttpHeaders = httpHeaders });

//Get the url of the file
Uri blobUrl = blobClient.Uri;

if (CheckImageExtension(blobUrl.ToString()))
{
ViewBag.Message = "You must upload a document with .pdf extension";
return View("FormAnalyzer", model);
}


//Call EvaluateImage with the url
await AnalyzeForm(blobUrl.ToString(), prompt);
ViewBag.Waiting = null;

return View("FormAnalyzer", model);
}



[ResponseCache(Duration = 0, Location = ResponseCacheLocation.None, NoStore = true)]
public IActionResult Error()
{
return View(new ErrorViewModel { RequestId = Activity.Current?.Id ?? HttpContext.TraceIdentifier });
}

private bool CheckNullValues(IFormFile imageFile)
{
if (imageFile == null)
{
return true;
}
return false;
}

private bool CheckImageExtension(string blobUri)
{
string uri_lower = blobUri;
if (uri_lower.Contains(".pdf", StringComparison.OrdinalIgnoreCase))
{
return false;
}
return true;
}
}
13 changes: 13 additions & 0 deletions src/AIHub/Models/FormAnalyzer.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
namespace MVCWeb.Models;

public class FormAnalyzerModel{

public int? Severity { get; set; }
public int? Violence { get; set; }
public int? SelfHarm { get; set; }
public int? Hate { get; set; }
public string? Prompt { get; set; }
public string? Image { get; set; }
public string? Message { get; set; }

}
80 changes: 80 additions & 0 deletions src/AIHub/Views/FormAnalyzer/FormAnalyzer.cshtml
Original file line number Diff line number Diff line change
@@ -0,0 +1,80 @@
@{
ViewData["Title"] = "Form Analyzer";
}

<div class="text-center">
<svg style="fill: var(--main-color)" xmlns="http://www.w3.org/2000/svg" height="4em"
viewBox="0 0 512 512"><!--! Font Awesome Free 6.4.2 by @@fontawesome - https://fontawesome.com License - https://fontawesome.com/license (Commercial License) Copyright 2023 Fonticons, Inc. -->
<path
d="M320 464c8.8 0 16-7.2 16-16V160H256c-17.7 0-32-14.3-32-32V48H64c-8.8 0-16 7.2-16 16V448c0 8.8 7.2 16 16 16H320zM0 64C0 28.7 28.7 0 64 0H229.5c17 0 33.3 6.7 45.3 18.7l90.5 90.5c12 12 18.7 28.3 18.7 45.3V448c0 35.3-28.7 64-64 64H64c-35.3 0-64-28.7-64-64V64z" />
</svg>
<h1 class="sectionTitle">Form Analyzer</h1>
<p class="sectionSubTitle">Analiza tus documentos usando GPT4 y Azure Document Intelligence.</p>
<p class="sectionDetails">Sólo necesitas adjuntar un documento (.pdf).</p>

</div>

@if (ViewBag.Message != null)
{
<div class="row justify-content-center mt-5">
<div class="col-md-6">
<div class="alert alert-primary" role="alert">
@Html.Raw(ViewBag.Message.Replace("\n", "<br />"))
</div>
</div>
<div class="col-md-6">
<div class="alert alert-primary" role="alert">
<iframe src="@ViewBag.PdfUrl" style="width:100%;height:500px;" frameborder="0"></iframe>
</div>
</div>
</div>
}
<form asp-controller="FormAnalyzer" asp-action="UploadFile" method="post" enctype="multipart/form-data">
@* <div class="row justify-content-center mt-5">
<span class="form-group">
<label for="fname">Upload your image to analyze:</label><br>
<input type="text" class="form-control" id="image_url" name="image_url" value="" style="width: 70%;"/>
<input type="file" class="form-control-file" id="imageFile" name="imageFile" />
</div>
<button type="submit" class="btn btn-primary">Upload Image</button>
</div> *@

<div class="col-md-6">

<div class="form-group">
<label for="imageFile">Image File:</label><br>
<input type="file" class="form-control-file" id="imageFile" name="imageFile" />
</br>
<label for="imageFile">Prompt:</label><br>
<textarea class="form-control" id="prompt" name="prompt"
rows="3"> @(Model?.Prompt ?? "Summarize document") </textarea>
</div>
<div id="loadingPanel" style="display: none;">Loading...</div>
<button type="submit" class="btn btn-primary" onclick="submitForm()">Upload Image</button>

</div>
<script>
function submitForm() {
// Disable the button
var btn = document.querySelector('button[type="submit"]');
btn.disabled = true;
// Show the loading panel
var loadingPanel = document.getElementById('loadingPanel');
loadingPanel.style.display = 'block';
// Submit the form
var form = document.querySelector('form');
form.submit();
}
window.onload = function () {
// Enable the button
var btn = document.querySelector('button[type="submit"]');
btn.disabled = false;
// Hide the loading panel
var loadingPanel = document.getElementById('loadingPanel');
loadingPanel.style.display = 'none';
}
</script>
</form>
9 changes: 9 additions & 0 deletions src/AIHub/Views/Home/Index.cshtml
Original file line number Diff line number Diff line change
Expand Up @@ -45,6 +45,15 @@
</div>
</a>
</li>
<li key="formanalyzer">
<a asp-area="" style="text-decoration: none" asp-controller="FormAnalyzer" asp-action="FormAnalyzer">
<div class="homeBlock" >
<svg style="fill: var(--main-color)" xmlns="http://www.w3.org/2000/svg" height="2em" viewBox="0 0 512 512"><!--! Font Awesome Free 6.4.2 by @@fontawesome - https://fontawesome.com License - https://fontawesome.com/license (Commercial License) Copyright 2023 Fonticons, Inc. --><path d="M320 464c8.8 0 16-7.2 16-16V160H256c-17.7 0-32-14.3-32-32V48H64c-8.8 0-16 7.2-16 16V448c0 8.8 7.2 16 16 16H320zM0 64C0 28.7 28.7 0 64 0H229.5c17 0 33.3 6.7 45.3 18.7l90.5 90.5c12 12 18.7 28.3 18.7 45.3V448c0 35.3-28.7 64-64 64H64c-35.3 0-64-28.7-64-64V64z"/></svg>
<p class="homeBlockText">Form Analyzer</p>
<p class="homeBlockTextDetail">Analiza tus documentos</p>
</div>
</a>
</li>
</ul>
<ul class="homeBlockNavList">

Expand Down
12 changes: 8 additions & 4 deletions src/AIHub/Views/Shared/_Layout.cshtml
Original file line number Diff line number Diff line change
Expand Up @@ -35,13 +35,17 @@
</li>

<li class="nav-item">
<a class="nav-link" style="color: var(--layout-text-color);" asp-area="" asp-controller="ImageAnalyzer"
asp-action="ImageAnalyzer">Image Analyzer <svg xmlns="http://www.w3.org/2000/svg" height="1.25em" viewBox="0 0 512 512"><!--! Font Awesome Free 6.4.2 by @@fontawesome - https://fontawesome.com License - https://fontawesome.com/license (Commercial License) Copyright 2023 Fonticons, Inc. --><style>svg{fill: var(--layout-text-color)}</style><path d="M448 80c8.8 0 16 7.2 16 16V415.8l-5-6.5-136-176c-4.5-5.9-11.6-9.3-19-9.3s-14.4 3.4-19 9.3L202 340.7l-30.5-42.7C167 291.7 159.8 288 152 288s-15 3.7-19.5 10.1l-80 112L48 416.3l0-.3V96c0-8.8 7.2-16 16-16H448zM64 32C28.7 32 0 60.7 0 96V416c0 35.3 28.7 64 64 64H448c35.3 0 64-28.7 64-64V96c0-35.3-28.7-64-64-64H64zm80 192a48 48 0 1 0 0-96 48 48 0 1 0 0 96z"/></svg></a>
</li>
<li class="nav-item">
<a class="nav-link" style="color: var(--layout-text-color);" asp-area="" asp-controller="ImageAnalyzer"
asp-action="ImageAnalyzer">Image Analyzer <svg xmlns="http://www.w3.org/2000/svg" height="1.25em" viewBox="0 0 512 512"><!--! Font Awesome Free 6.4.2 by @@fontawesome - https://fontawesome.com License - https://fontawesome.com/license (Commercial License) Copyright 2023 Fonticons, Inc. --><style>svg{fill: var(--layout-text-color)}</style><path d="M448 80c8.8 0 16 7.2 16 16V415.8l-5-6.5-136-176c-4.5-5.9-11.6-9.3-19-9.3s-14.4 3.4-19 9.3L202 340.7l-30.5-42.7C167 291.7 159.8 288 152 288s-15 3.7-19.5 10.1l-80 112L48 416.3l0-.3V96c0-8.8 7.2-16 16-16H448zM64 32C28.7 32 0 60.7 0 96V416c0 35.3 28.7 64 64 64H448c35.3 0 64-28.7 64-64V96c0-35.3-28.7-64-64-64H64zm80 192a48 48 0 1 0 0-96 48 48 0 1 0 0 96z"/></svg></a>
</li>
<li class="nav-item">
<a class="nav-link" style="color: var(--layout-text-color);" asp-area="" asp-controller="BrandAnalyzer"
asp-action="BrandAnalyzer">Brand Analyzer <svg xmlns="http://www.w3.org/2000/svg" height="1.25em" viewBox="0 0 640 512"><!--! Font Awesome Free 6.4.2 by @@fontawesome - https://fontawesome.com License - https://fontawesome.com/license (Commercial License) Copyright 2023 Fonticons, Inc. --><style>svg{fill: var(--layout-text-color)}</style><path d="M36.8 192H603.2c20.3 0 36.8-16.5 36.8-36.8c0-7.3-2.2-14.4-6.2-20.4L558.2 21.4C549.3 8 534.4 0 518.3 0H121.7c-16 0-31 8-39.9 21.4L6.2 134.7c-4 6.1-6.2 13.2-6.2 20.4C0 175.5 16.5 192 36.8 192zM64 224V384v80c0 26.5 21.5 48 48 48H336c26.5 0 48-21.5 48-48V384 224H320V384H128V224H64zm448 0V480c0 17.7 14.3 32 32 32s32-14.3 32-32V224H512z"/></svg></a>
</li>
<li class="nav-item">
<a class="nav-link" style="color: var(--layout-text-color);" asp-area="" asp-controller="FormAnalyzer"
asp-action="FormAnalyzer">Form Analyzer <svg xmlns="http://www.w3.org/2000/svg" height="1.25em" viewBox="0 0 640 512"><!--! Font Awesome Free 6.4.2 by @@fontawesome - https://fontawesome.com License - https://fontawesome.com/license (Commercial License) Copyright 2023 Fonticons, Inc. --><style>svg{fill: var(--layout-text-color)}</style><path d="M320 464c8.8 0 16-7.2 16-16V160H256c-17.7 0-32-14.3-32-32V48H64c-8.8 0-16 7.2-16 16V448c0 8.8 7.2 16 16 16H320zM0 64C0 28.7 28.7 0 64 0H229.5c17 0 33.3 6.7 45.3 18.7l90.5 90.5c12 12 18.7 28.3 18.7 45.3V448c0 35.3-28.7 64-64 64H64c-35.3 0-64-28.7-64-64V64z"/></svg></a>
</li>


<li class="nav-item dropdown">
Expand Down

0 comments on commit 769d55a

Please sign in to comment.