Skip to content

Commit fb32da0

Browse files
committed
initial commit
1 parent 35dd0ca commit fb32da0

31 files changed

+2636
-3
lines changed

.dockerignore

Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,25 @@
1+
**/.classpath
2+
**/.dockerignore
3+
**/.env
4+
**/.git
5+
**/.gitignore
6+
**/.project
7+
**/.settings
8+
**/.toolstarget
9+
**/.vs
10+
**/.vscode
11+
**/*.*proj.user
12+
**/*.dbmdl
13+
**/*.jfm
14+
**/azds.yaml
15+
**/bin
16+
**/charts
17+
**/docker-compose*
18+
**/Dockerfile*
19+
**/node_modules
20+
**/npm-debug.log
21+
**/obj
22+
**/secrets.dev.yaml
23+
**/values.dev.yaml
24+
LICENSE
25+
README.md

.github/CODE_OF_CONDUCT.md

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
# Microsoft Open Source Code of Conduct
2+
3+
This project has adopted the [Microsoft Open Source Code of Conduct](https://opensource.microsoft.com/codeofconduct/).
4+
5+
Resources:
6+
7+
- [Microsoft Open Source Code of Conduct](https://opensource.microsoft.com/codeofconduct/)
8+
- [Microsoft Code of Conduct FAQ](https://opensource.microsoft.com/codeofconduct/faq/)
9+
- Contact [opencode@microsoft.com](mailto:opencode@microsoft.com) with questions or concerns

.github/ISSUE_TEMPLATE.md

Lines changed: 33 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,33 @@
1+
<!--
2+
IF SUFFICIENT INFORMATION IS NOT PROVIDED VIA THE FOLLOWING TEMPLATE THE ISSUE MIGHT BE CLOSED WITHOUT FURTHER CONSIDERATION OR INVESTIGATION
3+
-->
4+
> Please provide us with the following information:
5+
> ---------------------------------------------------------------
6+
7+
### This issue is for a: (mark with an `x`)
8+
```
9+
- [ ] bug report -> please search issues before submitting
10+
- [ ] feature request
11+
- [ ] documentation issue or request
12+
- [ ] regression (a behavior that used to work and stopped in a new release)
13+
```
14+
15+
### Minimal steps to reproduce
16+
>
17+
18+
### Any log messages given by the failure
19+
>
20+
21+
### Expected/desired behavior
22+
>
23+
24+
### OS and Version?
25+
> Windows 7, 8 or 10. Linux (which distribution). macOS (Yosemite? El Capitan? Sierra?)
26+
27+
### Versions
28+
>
29+
30+
### Mention any other details that might be useful
31+
32+
> ---------------------------------------------------------------
33+
> Thanks! We'll be in touch soon.

.gitignore

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
.azure
2+
.vs
3+
*\bin
4+
*\obj
5+
*\properties

CONTRIBUTING.md

Lines changed: 76 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,76 @@
1+
# Contributing to [project-title]
2+
3+
This project welcomes contributions and suggestions. Most contributions require you to agree to a
4+
Contributor License Agreement (CLA) declaring that you have the right to, and actually do, grant us
5+
the rights to use your contribution. For details, visit https://cla.opensource.microsoft.com.
6+
7+
When you submit a pull request, a CLA bot will automatically determine whether you need to provide
8+
a CLA and decorate the PR appropriately (e.g., status check, comment). Simply follow the instructions
9+
provided by the bot. You will only need to do this once across all repos using our CLA.
10+
11+
This project has adopted the [Microsoft Open Source Code of Conduct](https://opensource.microsoft.com/codeofconduct/).
12+
For more information see the [Code of Conduct FAQ](https://opensource.microsoft.com/codeofconduct/faq/) or
13+
contact [opencode@microsoft.com](mailto:opencode@microsoft.com) with any additional questions or comments.
14+
15+
- [Code of Conduct](#coc)
16+
- [Issues and Bugs](#issue)
17+
- [Feature Requests](#feature)
18+
- [Submission Guidelines](#submit)
19+
20+
## <a name="coc"></a> Code of Conduct
21+
Help us keep this project open and inclusive. Please read and follow our [Code of Conduct](https://opensource.microsoft.com/codeofconduct/).
22+
23+
## <a name="issue"></a> Found an Issue?
24+
If you find a bug in the source code or a mistake in the documentation, you can help us by
25+
[submitting an issue](#submit-issue) to the GitHub Repository. Even better, you can
26+
[submit a Pull Request](#submit-pr) with a fix.
27+
28+
## <a name="feature"></a> Want a Feature?
29+
You can *request* a new feature by [submitting an issue](#submit-issue) to the GitHub
30+
Repository. If you would like to *implement* a new feature, please submit an issue with
31+
a proposal for your work first, to be sure that we can use it.
32+
33+
* **Small Features** can be crafted and directly [submitted as a Pull Request](#submit-pr).
34+
35+
## <a name="submit"></a> Submission Guidelines
36+
37+
### <a name="submit-issue"></a> Submitting an Issue
38+
Before you submit an issue, search the archive, maybe your question was already answered.
39+
40+
If your issue appears to be a bug, and hasn't been reported, open a new issue.
41+
Help us to maximize the effort we can spend fixing issues and adding new
42+
features, by not reporting duplicate issues. Providing the following information will increase the
43+
chances of your issue being dealt with quickly:
44+
45+
* **Overview of the Issue** - if an error is being thrown a non-minified stack trace helps
46+
* **Version** - what version is affected (e.g. 0.1.2)
47+
* **Motivation for or Use Case** - explain what are you trying to do and why the current behavior is a bug for you
48+
* **Browsers and Operating System** - is this a problem with all browsers?
49+
* **Reproduce the Error** - provide a live example or a unambiguous set of steps
50+
* **Related Issues** - has a similar issue been reported before?
51+
* **Suggest a Fix** - if you can't fix the bug yourself, perhaps you can point to what might be
52+
causing the problem (line of code or commit)
53+
54+
You can file new issues by providing the above information at the corresponding repository's issues link: https://github.com/[organization-name]/[repository-name]/issues/new].
55+
56+
### <a name="submit-pr"></a> Submitting a Pull Request (PR)
57+
Before you submit your Pull Request (PR) consider the following guidelines:
58+
59+
* Search the repository (https://github.com/[organization-name]/[repository-name]/pulls) for an open or closed PR
60+
that relates to your submission. You don't want to duplicate effort.
61+
62+
* Make your changes in a new git fork:
63+
64+
* Commit your changes using a descriptive commit message
65+
* Push your fork to GitHub:
66+
* In GitHub, create a pull request
67+
* If we suggest changes then:
68+
* Make the required updates.
69+
* Rebase your fork and force push to your GitHub repository (this will update your Pull Request):
70+
71+
```shell
72+
git rebase master -i
73+
git push -f
74+
```
75+
76+
That's it! Thank you for your contribution!

LICENSE.md

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
1+
MIT License
2+
3+
Copyright (c) Microsoft Corporation.
4+
5+
Permission is hereby granted, free of charge, to any person obtaining a copy
6+
of this software and associated documentation files (the "Software"), to deal
7+
in the Software without restriction, including without limitation the rights
8+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9+
copies of the Software, and to permit persons to whom the Software is
10+
furnished to do so, subject to the following conditions:
11+
12+
The above copyright notice and this permission notice shall be included in all
13+
copies or substantial portions of the Software.
14+
15+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21+
SOFTWARE

OutputCacheDallESample.sln

Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,25 @@
1+
2+
Microsoft Visual Studio Solution File, Format Version 12.00
3+
# Visual Studio Version 17
4+
VisualStudioVersion = 17.8.34004.107
5+
MinimumVisualStudioVersion = 10.0.40219.1
6+
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "OutputCacheDallESample", "OutputCacheDallESample\OutputCacheDallESample.csproj", "{4EE39425-0641-4865-8472-62D31144525A}"
7+
EndProject
8+
Global
9+
GlobalSection(SolutionConfigurationPlatforms) = preSolution
10+
Debug|Any CPU = Debug|Any CPU
11+
Release|Any CPU = Release|Any CPU
12+
EndGlobalSection
13+
GlobalSection(ProjectConfigurationPlatforms) = postSolution
14+
{4EE39425-0641-4865-8472-62D31144525A}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
15+
{4EE39425-0641-4865-8472-62D31144525A}.Debug|Any CPU.Build.0 = Debug|Any CPU
16+
{4EE39425-0641-4865-8472-62D31144525A}.Release|Any CPU.ActiveCfg = Release|Any CPU
17+
{4EE39425-0641-4865-8472-62D31144525A}.Release|Any CPU.Build.0 = Release|Any CPU
18+
EndGlobalSection
19+
GlobalSection(SolutionProperties) = preSolution
20+
HideSolutionNode = FALSE
21+
EndGlobalSection
22+
GlobalSection(ExtensibilityGlobals) = postSolution
23+
SolutionGuid = {D7C6A8A9-50EA-4D7E-A84D-3E3E51BF5A7A}
24+
EndGlobalSection
25+
EndGlobal

OutputCacheDallESample/Dockerfile

Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,30 @@
1+
# See https://aka.ms/customizecontainer to learn how to customize your debug container and how Visual Studio uses this Dockerfile to build your images for faster debugging.
2+
3+
# This stage is used when running from VS in fast mode (Default for Debug configuration)
4+
FROM mcr.microsoft.com/dotnet/aspnet:9.0 AS base
5+
USER $APP_UID
6+
WORKDIR /app
7+
EXPOSE 8080
8+
EXPOSE 8081
9+
10+
11+
# This stage is used to build the service project
12+
FROM mcr.microsoft.com/dotnet/sdk:9.0 AS build
13+
ARG BUILD_CONFIGURATION=Release
14+
WORKDIR /src
15+
COPY ["OutputCacheDallESample.csproj", "."]
16+
RUN dotnet restore "OutputCacheDallESample.csproj"
17+
COPY . .
18+
WORKDIR "/src/."
19+
RUN dotnet build "OutputCacheDallESample.csproj" -c $BUILD_CONFIGURATION -o /app/build
20+
21+
# This stage is used to publish the service project to be copied to the final stage
22+
FROM build AS publish
23+
ARG BUILD_CONFIGURATION=Release
24+
RUN dotnet publish "OutputCacheDallESample.csproj" -c $BUILD_CONFIGURATION -o /app/publish /p:UseAppHost=false
25+
26+
# This stage is used in production or when running from VS in regular mode (Default when not using the Debug configuration)
27+
FROM base AS final
28+
WORKDIR /app
29+
COPY --from=publish /app/publish .
30+
ENTRYPOINT ["dotnet", "OutputCacheDallESample.dll"]
Lines changed: 52 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,52 @@
1+
using Azure.AI.OpenAI;
2+
using Azure;
3+
using Redis.OM;
4+
using Redis.OM.Vectorizers;
5+
using Microsoft.AspNetCore.DataProtection.KeyManagement;
6+
using OpenAI.Images;
7+
8+
namespace OutputCacheDallESample
9+
{
10+
public static class GenerateImageSC
11+
{
12+
private static RedisConnectionProvider _provider;
13+
public static async Task GenerateImageSCAsync(HttpContext context, string _prompt, IConfiguration _config)
14+
{
15+
string imageURL;
16+
17+
string endpoint = _config["AZURE_OPENAI_ENDPOINT"];
18+
string key = _config["apiKey"];
19+
20+
_provider = new RedisConnectionProvider(_config["SemanticCacheAzureProvider"]);
21+
var cache = _provider.AzureOpenAISemanticCache(_config["apiKey"], _config["AOAIResourceName"], _config["AOAIEmbeddingDeploymentName"], 1536);
22+
23+
if (cache.GetSimilar(_prompt).Length > 0)
24+
{
25+
imageURL = cache.GetSimilar(_prompt)[0];
26+
await context.Response.WriteAsync("<!DOCTYPE html><html><body> " +
27+
$"<img src=\"{imageURL}\" alt=\"AI Generated Picture {_prompt}\" width=\"460\" height=\"345\">" +
28+
" </body> </html>");
29+
}
30+
else
31+
{
32+
AzureOpenAIClient client = new(new Uri(endpoint), new AzureKeyCredential(key));
33+
34+
ImageClient imageClient = client.GetImageClient("dall-e-3");
35+
GeneratedImage generatedImage = await imageClient.GenerateImageAsync(_prompt, new ImageGenerationOptions() {
36+
Size = GeneratedImageSize.W1024xH1024
37+
});
38+
39+
// Image Generations responses provide URLs you can use to retrieve requested images
40+
imageURL = generatedImage.ImageUri.AbsoluteUri;
41+
42+
await cache.StoreAsync(_prompt, imageURL);
43+
44+
await context.Response.WriteAsync("<!DOCTYPE html><html><body> " +
45+
$"<img src=\"{imageURL}\" alt=\"AI Generated Picture {_prompt}\" width=\"460\" height=\"345\">" +
46+
" </body> </html>");
47+
}
48+
49+
50+
}
51+
}
52+
}
Lines changed: 31 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,31 @@
1+
using Azure.AI.OpenAI;
2+
using Azure;
3+
using Microsoft.AspNetCore.DataProtection.KeyManagement;
4+
using OpenAI.Images;
5+
6+
namespace OutputCacheDallESample
7+
{
8+
public static class GenerateImageSDK
9+
{
10+
public static async Task GenerateImageSDKAsync(HttpContext context, string _prompt, IConfiguration _config)
11+
{
12+
string endpoint = _config["AZURE_OPENAI_ENDPOINT"];
13+
string key = _config["apiKey"];
14+
15+
AzureOpenAIClient client = new(new Uri(endpoint), new AzureKeyCredential(key));
16+
17+
ImageClient imageClient = client.GetImageClient("dall-e-3");
18+
GeneratedImage generatedImage = await imageClient.GenerateImageAsync(_prompt, new ImageGenerationOptions()
19+
{
20+
Size = GeneratedImageSize.W1024xH1024
21+
});
22+
23+
// Image Generations responses provide URLs you can use to retrieve requested images
24+
string imageURL = generatedImage.ImageUri.AbsoluteUri;
25+
26+
await context.Response.WriteAsync("<!DOCTYPE html><html><body> " +
27+
$"<img src=\"{imageURL}\" alt=\"Flowers in Chania\" width=\"460\" height=\"345\">" +
28+
" </body> </html>");
29+
}
30+
}
31+
}
Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,20 @@
1+
<Project Sdk="Microsoft.NET.Sdk.Web">
2+
3+
<PropertyGroup>
4+
<TargetFramework>net9.0</TargetFramework>
5+
<Nullable>enable</Nullable>
6+
<ImplicitUsings>enable</ImplicitUsings>
7+
<UserSecretsId>877065af-a9e5-49fc-82b9-28f250cdf6ae</UserSecretsId>
8+
<DockerDefaultTargetOS>Linux</DockerDefaultTargetOS>
9+
</PropertyGroup>
10+
11+
<ItemGroup>
12+
<PackageReference Include="Azure.AI.OpenAI" Version="2.1.0" />
13+
<PackageReference Include="Microsoft.AspNetCore.OutputCaching.StackExchangeRedis" Version="9.0.0" />
14+
<PackageReference Include="Microsoft.Extensions.Caching.StackExchangeRedis" Version="9.0.0" />
15+
<PackageReference Include="Microsoft.VisualStudio.Azure.Containers.Tools.Targets" Version="1.21.0" />
16+
<PackageReference Include="Redis.OM" Version="0.7.6" />
17+
<PackageReference Include="Redis.OM.Vectorizers" Version="0.7.6" />
18+
</ItemGroup>
19+
20+
</Project>

OutputCacheDallESample/Program.cs

Lines changed: 47 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,47 @@
1+
using Microsoft.AspNetCore.OutputCaching;
2+
using OutputCacheDallESample;
3+
using Redis.OM;
4+
using Redis.OM.Vectorizers;
5+
6+
var builder = WebApplication.CreateBuilder(args);
7+
8+
// add services
9+
builder.Services.AddStackExchangeRedisOutputCache(options => {
10+
options.Configuration = builder.Configuration["RedisCacheConnection"];
11+
});
12+
builder.Services.AddOutputCache(options => {
13+
// optional: named output-cache profiles
14+
});
15+
16+
var app = builder.Build();
17+
18+
app.MapGet("/", async (HttpContext context) => { await context.Response.WriteAsync("<h1>Welcome to OpenAI Art Gallery</h1>"); });
19+
20+
app.MapGet("/nocache/{prompt}", async (HttpContext context, string prompt, IConfiguration config) =>
21+
{
22+
await GenerateImageSDK.GenerateImageSDKAsync(context, prompt, config);
23+
});
24+
25+
app.MapGet("/semanticcache/{prompt}", async (HttpContext context, string prompt, IConfiguration config) =>
26+
{
27+
await GenerateImageSC.GenerateImageSCAsync(context, prompt, config);
28+
});
29+
30+
app.MapGet("/cached/{prompt}", async (HttpContext context, string prompt, IConfiguration config) =>
31+
{ await GenerateImageSDK.GenerateImageSDKAsync(context, prompt, config);
32+
}).CacheOutput();
33+
34+
app.MapGet("/cachedByAnnotation/{prompt}", [OutputCache(Duration = 15)] async (HttpContext context, string prompt, IConfiguration config) =>
35+
{ await GenerateImageSDK.GenerateImageSDKAsync(context, prompt, config);
36+
});
37+
38+
app.MapGet("/cached/Gardens/{prompt}", async (HttpContext context, string prompt, IConfiguration config) =>
39+
{ await GenerateImageSDK.GenerateImageSDKAsync(context, prompt, config);
40+
}).CacheOutput(x => x.Tag("Gardens"));
41+
42+
app.MapPost("/purge/{tag}", async (IOutputCacheStore cache, string tag) =>
43+
{await cache.EvictByTagAsync(tag, default);
44+
});
45+
46+
app.UseOutputCache();
47+
app.Run();

0 commit comments

Comments
 (0)