Skip to content

Commit

Permalink
document comparison added
Browse files Browse the repository at this point in the history
  • Loading branch information
rag2111 committed Mar 5, 2024
1 parent 9b197a3 commit d1eb892
Show file tree
Hide file tree
Showing 8 changed files with 244 additions and 129 deletions.
16 changes: 16 additions & 0 deletions infra/modules/openai/main.tf
Original file line number Diff line number Diff line change
Expand Up @@ -40,6 +40,22 @@ resource "azurerm_cognitive_deployment" "embedding" {
}
}

resource "azurerm_cognitive_deployment" "gpt4" {
name = "gpt4"
cognitive_account_id = azurerm_cognitive_account.openai.id
rai_policy_name = "Microsoft.Default"
model {
format = "OpenAI"
name = "gpt-4"
version = "0613"
}

scale {
type = "Standard"
capacity = 120
}
}

resource "azurerm_role_assignment" "openai_user" {
scope = azurerm_cognitive_account.openai.id
role_definition_name = "Cognitive Services OpenAI User"
Expand Down
74 changes: 21 additions & 53 deletions src/AIHub/Controllers/DocumentComparisonController.cs
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,7 @@ public DocumentComparisonController(IConfiguration config, IHttpClientFactory cl
AOAIendpoint = config.GetValue<string>("DocumentComparison:OpenAIEndpoint") ?? throw new ArgumentNullException("OpenAIEndpoint");
AOAIsubscriptionKey = config.GetValue<string>("DocumentComparison:OpenAISubscriptionKey") ?? throw new ArgumentNullException("OpenAISubscriptionKey");
storageconnstring = config.GetValue<string>("Storage:ConnectionString") ?? throw new ArgumentNullException("ConnectionString");
AOAIDeploymentName = config.GetValue<string>("BrandAnalyzer:DeploymentName") ?? throw new ArgumentNullException("DeploymentName");
AOAIDeploymentName = config.GetValue<string>("DocumentComparison:DeploymentName") ?? throw new ArgumentNullException("DeploymentName");
BlobServiceClient blobServiceClient = new BlobServiceClient(storageconnstring);
containerClient = blobServiceClient.GetBlobContainerClient(config.GetValue<string>("DocumentComparison:ContainerName"));
sasUri = containerClient.GenerateSasUri(Azure.Storage.Sas.BlobContainerSasPermissions.Read, DateTimeOffset.UtcNow.AddHours(1));
Expand All @@ -38,61 +38,24 @@ public IActionResult DocumentComparison()
}

[HttpPost]
public async Task<IActionResult> DocumentComparison(string[] document_urls, string prompt)
public async Task<IActionResult> DocumentComparison(string[] document_urls, string[] tab_names, string prompt)
{
//1. Get Documents
model.PdfUrl1 = document_urls[0] + sasUri.Query;
model.PdfUrl2 = document_urls[1] + sasUri.Query;
ViewBag.PdfUrl1 = document_urls[0] + sasUri.Query;
ViewBag.PdfUrl2 = document_urls[1] + sasUri.Query;
model.tabName1= tab_names[0];
model.tabName2= tab_names[1];

string[] output_result = new string[2];

//2. Call Form Recognizer
for (int i = 0; i < document_urls.Length; i++)
{
httpClient.BaseAddress = new Uri(FormRecogEndpoint);
// Add an Accept header for JSON format.
httpClient.DefaultRequestHeaders.Accept.Add(new MediaTypeWithQualityHeaderValue("application/json"));
httpClient.DefaultRequestHeaders.Add("Ocp-Apim-Subscription-Key", FormRecogSubscriptionKey);

var content = new
{
urlSource = document_urls[i] + sasUri.Query
};

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 httpClient.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").First();

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

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

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

while (responsejson.status != "succeeded")
{
if (response2 != null)
{
Thread.Sleep(10000);
response2 = await httpClient.GetAsync(operation_location_url);
responsejson = JsonSerializer.Deserialize<dynamic>(await response2.Content.ReadAsStringAsync())!;
}
}
output_result[i] = responsejson.analyzeResult.content.ToString();
var client = new DocumentAnalysisClient(new Uri(FormRecogEndpoint), new AzureKeyCredential(FormRecogSubscriptionKey));
var operation = await client.AnalyzeDocumentFromUriAsync(WaitUntil.Completed, "prebuilt-layout", new Uri(document_urls[i] + sasUri.Query));
output_result[i] = operation.Value.Content;
}

try
Expand Down Expand Up @@ -130,26 +93,29 @@ public async Task<IActionResult> DocumentComparison(string[] document_urls, stri

ChatCompletions completions = responseWithoutStream.Value;
ChatChoice results_analisis = completions.Choices[0];
model.Message = results_analisis.Message.Content;
ViewBag.Message = results_analisis.Message.Content;

}
catch (RequestFailedException)
{
throw;
}

return View("DocumentComparison", model);
return Ok(model);
}

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

List<IFormFile> documentFiles = Request.Form.Files.ToList();

// pre-validations
if (documentFiles == null || !documentFiles.Count.Equals(2))
{
ViewBag.Message = "You must upload exactly two documents";
return View("DocumentComparison");
return View("DocumentComparison", model);
}

foreach (var documentFile in documentFiles)
Expand All @@ -162,10 +128,12 @@ public async Task<IActionResult> UploadFile(List<IFormFile> documentFiles, strin
}

string[] urls = new string[2];
string[] tabNames = new string[2];
for (int i = 0; i < documentFiles.Count; i++)
{
string url = documentFiles[i].FileName.ToString();
url = url.Replace(" ", "");
tabNames[i] = url;
BlobClient blobClient = containerClient.GetBlobClient(url);
var httpHeaders = new BlobHttpHeaders
{
Expand All @@ -176,10 +144,10 @@ public async Task<IActionResult> UploadFile(List<IFormFile> documentFiles, strin
}

// Call EvaluateImage with the url
await DocumentComparison(urls, prompt);
await DocumentComparison(urls, tabNames, Request.Form["prompt"].ToString());
ViewBag.Waiting = null;

return View("DocumentComparison", model);
return Ok(model);
}

[ResponseCache(Duration = 0, Location = ResponseCacheLocation.None, NoStore = true)]
Expand Down
5 changes: 4 additions & 1 deletion src/AIHub/Models/DocumentComparisonModel.cs
Original file line number Diff line number Diff line change
Expand Up @@ -5,5 +5,8 @@ public class DocumentComparisonModel
public string? Prompt { get; set; }
public string? Document { get; set; }
public string? Message { get; set; }

public string? PdfUrl1 { get; set; }
public string? PdfUrl2 { get; set; }
public string? tabName1 { get; set; }
public string? tabName2 { get; set; }
}
171 changes: 102 additions & 69 deletions src/AIHub/Views/DocumentComparison/DocumentComparison.cshtml
Original file line number Diff line number Diff line change
@@ -1,87 +1,120 @@
@model DocumentComparisonModel
@{
ViewData["Title"] = "Document Comparison";
}

<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">Document Comparison</h1>
<p class="sectionSubTitle">Compara dos versiones de un mismo documento usando GPT4 y Azure Document Intelligence.</p>
<p class="sectionDetails">Sólo necesitas adjuntar las dos versiones del 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">
<iframe src="@ViewBag.PdfUrl1" style="width:100%;height:500px;" frameborder="0"></iframe>
<!-- Start Content-->
<div class="container-fluid">

<!-- start page title -->
<div class="row">
<div class="col-12">
<div class="page-title-box">
<div class="page-title-right">
<ol class="breadcrumb m-0">
<li class="breadcrumb-item">Services</li>
<li class="breadcrumb-item active">Document Comparison</li>
</ol>
</div>
<h4 class="page-title">Document Comparison</h4>
</div>
</div>
<div class="col-md-6">
<div class="alert alert-primary" role="alert">
<iframe src="@ViewBag.PdfUrl2" style="width:100%;height:500px;" frameborder="0"></iframe>
</div>
<!-- end page title -->

<div class="row">
<div class="col-12">
<div class="card">
<div class="card-body">
<h4 class="header-title">Document Comparison with Azure OpenAI Services</h4>
<p class="text-muted font-14">Compare different versions of your documents with the powerful combination of GPT-4 and Azure Document Intelligence.</p>
<form asp-controller="DocumentComparison" asp-action="UploadFile" method="post" enctype="multipart/form-data" id="upload-form" class="dropzone" data-plugin="dropzone" data-previews-container="#file-previews" data-upload-preview-template="#uploadPreviewTemplate">
<div class="mb-3">
<label class="form-label">Prompt:</label>
<textarea class="form-control" id="prompt" name="prompt" maxlength="225" rows="3"> @(Model?.Prompt ?? "Compare the two documents provided, and detail their differences.") </textarea>
</div>
<div class="tab-content form-control">
<div class="tab-pane show active" id="file-upload-preview">

<div class="fallback">
<input type="file" id="documentFiles" name="documentFiles" multiple />
</div>
<div class="dz-message needsclick">
<i class="h1 text-muted ri-upload-cloud-2-line"></i>
<h3>Drop files here or click to upload. </h3>
<span class="text-muted font-13"><strong>You just need to upload two documents (.pdf).</strong> </span>
</div>

<!-- Preview -->
<div class="dropzone-previews mt-3" id="file-previews"></div>

</div> <!-- end preview-->
</div> <!-- end tab-content-->
</form>
</div>
<!-- end card-body -->
</div>
<!-- end card-->
</div>
</div>
<div class="row justify-content-center mt-5">
<div class="col-md-12">
<div class="alert alert-primary" role="alert">
@Html.Raw(ViewBag.Message.Replace("\n", "<br />"))

<div class="row d-none" id="loader">
<div class="col-12">
<div class="card">
<div class="card-body">
<div class="d-flex align-items-center">
<strong>Loading...</strong>
<div class="spinner-border ms-auto" role="status" aria-hidden="true"></div>
</div>
</div>
<!-- end card-body -->
</div>
<!-- end card-->
</div>
</div>
}
<form asp-controller="DocumentComparison" 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">
<!--- show results -->
<div class="row d-none" id="showresult">
<div class="col-lg-12">
<div class="card">
<div class="row g-0 align-items-center">
<div class="col-md-5">

<div class="form-group">
<label for="documentFiles">Document File:</label><br>
<input type="file" class="form-control-file" id="documentFiles" name="documentFiles" multiple />
</br>
<label for="documentFiles">Prompt:</label><br>
<textarea class="form-control" id="prompt" name="prompt"
rows="3"> @(Model?.Prompt ?? "Compare the two documents provided, and detail their differences.") </textarea>
</div>
<div id="loadingPanel" style="display: none;">Loading...</div>
<button type="submit" class="btn btn-primary" onclick="submitForm()">Upload PDF</button>
<ul class="nav nav-pills bg-nav-pills nav-justified mb-2">
<li class="nav-item">
<a href="#tabcontent1" data-bs-toggle="tab" aria-expanded="true" class="nav-link rounded-0 active">
<span class="d-none d-md-block" id="tabname1"></span>
</a>
</li>
<li class="nav-item">
<a href="#tabcontent2" data-bs-toggle="tab" aria-expanded="false" class="nav-link rounded-0">
<span class="d-none d-md-block" id="tabname2"></span>
</a>
</li>
</ul>
<div class="tab-content">
<div class="tab-pane show active" id="tabcontent1">
</div>
<div class="tab-pane" id="tabcontent2">
</div>
</div>

</div>
<div class="col-md-7">
<div class="card-body">
<h2 class="header-title mt-0 mb-3">Document Comparison Result <span class="badge bg-success rounded-pill">Analysis Success</span></h2>
<p class="text-muted font-16 mb-3" id="show-message-result"></p>
</div>
</div>
</div>
</div>
</div>
</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;
</div>
<!-- container -->

// Hide the loading panel
var loadingPanel = document.getElementById('loadingPanel');
loadingPanel.style.display = 'none';
}
</script>
</form>
@section Scripts {
@{await Html.RenderPartialAsync("_DocumentComparisonScriptsPartial");}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@

<link rel="stylesheet" href="/css/dropzonecustom.css">

<script src="/vendor/dropzone/dropzone.min.js"></script>
<script src="/js/ui/documentcomparison.js"></script>
Loading

0 comments on commit d1eb892

Please sign in to comment.