-
Notifications
You must be signed in to change notification settings - Fork 27
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
Showing
5 changed files
with
370 additions
and
4 deletions.
There are no files selected for viewing
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
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; | ||
} | ||
} |
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
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; } | ||
|
||
} |
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
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> |
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
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