Spaces:
Sleeping
Sleeping
Yash Worlikar
commited on
Commit
·
a00a692
1
Parent(s):
920638b
Added Temporary Configs
Browse files- Components/Pages/Home.razor +97 -5
- FoodCheckerService.cs +21 -3
- Models/TemporaryConfig.cs +23 -0
- README.md +3 -3
- wwwroot/app.css +3 -1
Components/Pages/Home.razor
CHANGED
@@ -1,16 +1,74 @@
|
|
1 |
@page "/"
|
2 |
@using FoodHealthChecker.Components.Layout
|
3 |
@using FoodHealthChecker
|
|
|
4 |
@using Markdig
|
5 |
@using Microsoft.AspNetCore.Components
|
6 |
@using System.Runtime.CompilerServices
|
|
|
|
|
7 |
@implements IDisposable
|
8 |
<PageTitle> Food Health Checker</PageTitle>
|
|
|
|
|
|
|
9 |
|
10 |
<div class="container mt-2">
|
11 |
-
<div
|
12 |
-
<h3 class="card-title mb-2 fw-bold">AI Food Health Checker</h3>
|
13 |
-
<
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
14 |
</div>
|
15 |
|
16 |
<div class="row justify-content-center ">
|
@@ -93,13 +151,47 @@
|
|
93 |
</div>
|
94 |
|
95 |
@code {
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
96 |
public string ImageUrl { get; set; } = string.Empty;
|
97 |
public ReadOnlyMemory<byte> ImageData { get; set; }
|
98 |
public string ImageName { get; set; } = string.Empty;
|
99 |
|
100 |
public string Ingredients { get; set; } = string.Empty;
|
101 |
public string Result { get; set; } = string.Empty;
|
102 |
-
public string duplicateSpace
|
103 |
|
104 |
[Inject]
|
105 |
public MarkdownPipeline pipeline { get; set; } = default!;
|
@@ -115,7 +207,7 @@
|
|
115 |
duplicateSpace = Config.GetValue<string>("HFDuplicateSpace") ?? string.Empty;
|
116 |
if (!_foodCheckerService.IsValid())
|
117 |
{
|
118 |
-
errorMessage = "API keys missing.
|
119 |
}
|
120 |
}
|
121 |
|
|
|
1 |
@page "/"
|
2 |
@using FoodHealthChecker.Components.Layout
|
3 |
@using FoodHealthChecker
|
4 |
+
@using FoodHealthChecker.Models
|
5 |
@using Markdig
|
6 |
@using Microsoft.AspNetCore.Components
|
7 |
@using System.Runtime.CompilerServices
|
8 |
+
@rendermode InteractiveServer
|
9 |
+
|
10 |
@implements IDisposable
|
11 |
<PageTitle> Food Health Checker</PageTitle>
|
12 |
+
@{
|
13 |
+
var showClass = isPopupVisible ? "d-block" : "d-none";
|
14 |
+
}
|
15 |
|
16 |
<div class="container mt-2">
|
17 |
+
<div class="d-flex justify-content-between gap-2">
|
18 |
+
<h3 class="card-title mb-2 fw-bold text-start">AI Food Health Checker</h3>
|
19 |
+
<div>
|
20 |
+
<a class="card-title mb-2 fw-bold btn btn-dark" href="@duplicateSpace" target="_blank">Duplicate this space</a>
|
21 |
+
<button @onclick="OpenModal" class="card-title mb-2 fw-bold btn btn-dark">Add temporary Config</button>
|
22 |
+
</div>
|
23 |
+
</div>
|
24 |
+
|
25 |
+
<!-- temporaryConfig Modal -->
|
26 |
+
<div class="modal @showClass" tabindex="-1" role="dialog" id="temporaryConfigModal">
|
27 |
+
<div class="modal-dialog modal-lg" role="document">
|
28 |
+
<div class="modal-content">
|
29 |
+
<div class="modal-header">
|
30 |
+
<h5 class="modal-title fw-bold">Add Temporary Config (Any one)</h5>
|
31 |
+
<button type="button" class="btn-close" @onclick="CloseModal"></button>
|
32 |
+
</div>
|
33 |
+
<div class="modal-body">
|
34 |
+
<EditForm Model="@temporaryConfig" OnSubmit="SubmitForm" FormName="Configs">
|
35 |
+
<div class="form-section">
|
36 |
+
<h5 class="fw-bold">Azure OpenAI</h5>
|
37 |
+
<div class="row">
|
38 |
+
<div class="col-md-6">
|
39 |
+
<label for="AzureOpenAI_DeploymentName" class="form-label">Deployment Name</label>
|
40 |
+
<InputText class="form-control" id="AzureOpenAI_DeploymentName" @bind-Value="temporaryConfig.AzureOpenAI_DeploymentName" placeholder="Enter Deployment Name" />
|
41 |
+
</div>
|
42 |
+
<div class="col-md-6">
|
43 |
+
<label for="AzureOpenAI_Endpoint" class="form-label">Endpoint</label>
|
44 |
+
<InputText class="form-control" id="AzureOpenAI_Endpoint" @bind-Value="temporaryConfig.AzureOpenAI_Endpoint" placeholder="Enter Endpoint" />
|
45 |
+
</div>
|
46 |
+
<div class="col-md-6">
|
47 |
+
<label for="AzureOpenAI_ApiKey" class="form-label">API Key</label>
|
48 |
+
<InputText type="password" class="form-control" id="AzureOpenAI_ApiKey" @bind-Value="temporaryConfig.AzureOpenAI_ApiKey" placeholder="Enter API Key" />
|
49 |
+
</div>
|
50 |
+
</div>
|
51 |
+
</div>
|
52 |
+
<div class="form-section">
|
53 |
+
<h5 class="fw-bold">OpenAI</h5>
|
54 |
+
<div class="row">
|
55 |
+
<div class="col-md-6">
|
56 |
+
<label for="OpenAI_ModelId" class="form-label">Model ID</label>
|
57 |
+
<InputText class="form-control" id="OpenAI_ModelId" @bind-Value="temporaryConfig.OpenAI_ModelId" placeholder="Enter Model ID" />
|
58 |
+
</div>
|
59 |
+
<div class="col-md-6">
|
60 |
+
<label for="OpenAI_ApiKey" class="form-label">API Key</label>
|
61 |
+
<InputText class="form-control" type="password" id="OpenAI_ApiKey" @bind-Value="temporaryConfig.OpenAI_ApiKey" placeholder="Enter API Key" />
|
62 |
+
</div>
|
63 |
+
</div>
|
64 |
+
</div>
|
65 |
+
<div class="col-12">
|
66 |
+
<button type="submit" class="btn btn-primary">Submit</button>
|
67 |
+
</div>
|
68 |
+
</EditForm>
|
69 |
+
</div>
|
70 |
+
</div>
|
71 |
+
</div>
|
72 |
</div>
|
73 |
|
74 |
<div class="row justify-content-center ">
|
|
|
151 |
</div>
|
152 |
|
153 |
@code {
|
154 |
+
public TemporaryConfig temporaryConfig { get; set; } = new TemporaryConfig();
|
155 |
+
private bool isPopupVisible = false;
|
156 |
+
private async Task OpenModal()
|
157 |
+
{
|
158 |
+
isPopupVisible = true;
|
159 |
+
StateHasChanged();
|
160 |
+
}
|
161 |
+
|
162 |
+
private async Task CloseModal()
|
163 |
+
{
|
164 |
+
isPopupVisible = false;
|
165 |
+
StateHasChanged();
|
166 |
+
}
|
167 |
+
|
168 |
+
private async Task SubmitForm()
|
169 |
+
{
|
170 |
+
try
|
171 |
+
{
|
172 |
+
if (!(temporaryConfig.isAzureOpenAIConfigValid() || temporaryConfig.isOpenAIConfigValid()))
|
173 |
+
{
|
174 |
+
errorMessage = "Invalid Config";
|
175 |
+
}
|
176 |
+
else
|
177 |
+
{
|
178 |
+
errorMessage = string.Empty;
|
179 |
+
_foodCheckerService.UpdateTemporaryKernel(temporaryConfig);
|
180 |
+
}
|
181 |
+
}
|
182 |
+
catch (Exception ex)
|
183 |
+
{
|
184 |
+
errorMessage = "Unexpected Error occured";
|
185 |
+
}
|
186 |
+
await CloseModal();
|
187 |
+
}
|
188 |
public string ImageUrl { get; set; } = string.Empty;
|
189 |
public ReadOnlyMemory<byte> ImageData { get; set; }
|
190 |
public string ImageName { get; set; } = string.Empty;
|
191 |
|
192 |
public string Ingredients { get; set; } = string.Empty;
|
193 |
public string Result { get; set; } = string.Empty;
|
194 |
+
public string duplicateSpace { get; set; } = string.Empty;
|
195 |
|
196 |
[Inject]
|
197 |
public MarkdownPipeline pipeline { get; set; } = default!;
|
|
|
207 |
duplicateSpace = Config.GetValue<string>("HFDuplicateSpace") ?? string.Empty;
|
208 |
if (!_foodCheckerService.IsValid())
|
209 |
{
|
210 |
+
errorMessage = "API keys missing from config. Add temporary keys (Space must be public for accessing image URLs)";
|
211 |
}
|
212 |
}
|
213 |
|
FoodCheckerService.cs
CHANGED
@@ -1,5 +1,5 @@
|
|
1 |
-
using FoodHealthChecker.
|
2 |
-
using FoodHealthChecker.
|
3 |
using FoodHealthChecker.SemanticKernel.Plugins;
|
4 |
using Microsoft.SemanticKernel;
|
5 |
|
@@ -7,7 +7,7 @@ namespace FoodHealthChecker
|
|
7 |
{
|
8 |
public class FoodCheckerService
|
9 |
{
|
10 |
-
private
|
11 |
private bool isValid = false;
|
12 |
private readonly FoodCheckerPlugin _foodCheckerPlugin;
|
13 |
public FoodCheckerService(IConfiguration config, FoodCheckerPlugin foodCheckerPlugin)
|
@@ -36,6 +36,24 @@ namespace FoodHealthChecker
|
|
36 |
_kernel = kernel;
|
37 |
}
|
38 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
39 |
public bool IsValid()
|
40 |
{
|
41 |
return isValid;
|
|
|
1 |
+
using FoodHealthChecker.Models;
|
2 |
+
using FoodHealthChecker.Options;
|
3 |
using FoodHealthChecker.SemanticKernel.Plugins;
|
4 |
using Microsoft.SemanticKernel;
|
5 |
|
|
|
7 |
{
|
8 |
public class FoodCheckerService
|
9 |
{
|
10 |
+
private Kernel _kernel;
|
11 |
private bool isValid = false;
|
12 |
private readonly FoodCheckerPlugin _foodCheckerPlugin;
|
13 |
public FoodCheckerService(IConfiguration config, FoodCheckerPlugin foodCheckerPlugin)
|
|
|
36 |
_kernel = kernel;
|
37 |
}
|
38 |
|
39 |
+
public void UpdateTemporaryKernel(TemporaryConfig config)
|
40 |
+
{
|
41 |
+
var kernelBuilder = Kernel.CreateBuilder();
|
42 |
+
|
43 |
+
if (config.isAzureOpenAIConfigValid())
|
44 |
+
{
|
45 |
+
kernelBuilder.AddAzureOpenAIChatCompletion(config.AzureOpenAI_DeploymentName,config.AzureOpenAI_ApiKey, config.AzureOpenAI_Endpoint);
|
46 |
+
isValid = true;
|
47 |
+
}
|
48 |
+
else if (config.isOpenAIConfigValid())
|
49 |
+
{
|
50 |
+
kernelBuilder.AddOpenAIChatCompletion(config.OpenAI_ModelId,config.OpenAI_ApiKey);
|
51 |
+
isValid = true;
|
52 |
+
}
|
53 |
+
var kernel = kernelBuilder.Build();
|
54 |
+
kernel.Plugins.AddFromObject(_foodCheckerPlugin);
|
55 |
+
_kernel = kernel;
|
56 |
+
}
|
57 |
public bool IsValid()
|
58 |
{
|
59 |
return isValid;
|
Models/TemporaryConfig.cs
ADDED
@@ -0,0 +1,23 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
using Microsoft.AspNetCore.DataProtection.KeyManagement;
|
2 |
+
|
3 |
+
namespace FoodHealthChecker.Models
|
4 |
+
{
|
5 |
+
|
6 |
+
public class TemporaryConfig
|
7 |
+
{
|
8 |
+
public string AzureOpenAI_DeploymentName { get; set; }
|
9 |
+
public string AzureOpenAI_Endpoint { get; set; }
|
10 |
+
public string AzureOpenAI_ApiKey { get; set; }
|
11 |
+
public string OpenAI_ModelId { get; set; }
|
12 |
+
public string OpenAI_ApiKey { get; set; }
|
13 |
+
|
14 |
+
public bool isAzureOpenAIConfigValid()
|
15 |
+
{
|
16 |
+
return !string.IsNullOrEmpty(AzureOpenAI_DeploymentName) && !string.IsNullOrEmpty(AzureOpenAI_ApiKey) && !string.IsNullOrEmpty(AzureOpenAI_Endpoint);
|
17 |
+
}
|
18 |
+
public bool isOpenAIConfigValid()
|
19 |
+
{
|
20 |
+
return !string.IsNullOrEmpty(OpenAI_ApiKey) && !string.IsNullOrEmpty(OpenAI_ModelId);
|
21 |
+
}
|
22 |
+
}
|
23 |
+
}
|
README.md
CHANGED
@@ -11,11 +11,11 @@ app_port: 8080
|
|
11 |
|
12 |
## FoodHealthChecker
|
13 |
|
14 |
-
|
15 |
|
16 |
-
Build using .Net Semantic Kernel and Azure OpenAI/OpenAI
|
17 |
|
18 |
-
**NOTE Running this
|
19 |
|
20 |
|
21 |
|
|
|
11 |
|
12 |
## FoodHealthChecker
|
13 |
|
14 |
+
This is an C# blazor server app app that lists all the ingredients and nutritional info present in a given food products and predicts whether it is healthy or not.
|
15 |
|
16 |
+
Build using .Net with the Semantic Kernel SDK and Azure OpenAI/OpenAI models.
|
17 |
|
18 |
+
**NOTE Running this app requires either an Azure OpenAI endpoint or an OpenAI APIKey present in the app settings to function properly.**
|
19 |
|
20 |
|
21 |
|
wwwroot/app.css
CHANGED
@@ -108,7 +108,9 @@ h4 {
|
|
108 |
.container {
|
109 |
background-color: #E0F2F1;
|
110 |
}
|
111 |
-
|
|
|
|
|
112 |
h1, h2, h3, h4, h5, h6 {
|
113 |
color: #00695C;
|
114 |
}
|
|
|
108 |
.container {
|
109 |
background-color: #E0F2F1;
|
110 |
}
|
111 |
+
.modal-header {
|
112 |
+
background-color: #E0F2F1;
|
113 |
+
}
|
114 |
h1, h2, h3, h4, h5, h6 {
|
115 |
color: #00695C;
|
116 |
}
|