From 4445b98e877cf4820fac99d04ffabd42d339a429 Mon Sep 17 00:00:00 2001 From: claudiogodoy99 Date: Sat, 28 Jun 2025 20:04:04 -0300 Subject: [PATCH 01/13] chore: add ASP.NET Core example and update README --- README.md | 40 ++++++ examples/ASP.NET Core/ASP.NET Core.sln | 24 ++++ examples/ASP.NET Core/Program.cs | 41 ++++++ examples/ASP.NET Core/README.md | 118 ++++++++++++++++++ .../ASP.NET Core/appsettings.Development.json | 8 ++ examples/ASP.NET Core/appsettings.json | 14 +++ examples/ASP.NET Core/client-di.csproj | 15 +++ 7 files changed, 260 insertions(+) create mode 100644 examples/ASP.NET Core/ASP.NET Core.sln create mode 100644 examples/ASP.NET Core/Program.cs create mode 100644 examples/ASP.NET Core/README.md create mode 100644 examples/ASP.NET Core/appsettings.Development.json create mode 100644 examples/ASP.NET Core/appsettings.json create mode 100644 examples/ASP.NET Core/client-di.csproj diff --git a/README.md b/README.md index 026fb5759..d691c607c 100644 --- a/README.md +++ b/README.md @@ -138,6 +138,46 @@ AudioClient ttsClient = client.GetAudioClient("tts-1"); AudioClient whisperClient = client.GetAudioClient("whisper-1"); ``` +## How to use dependency injection + +The OpenAI clients are **thread-safe** and can be safely registered as **singletons** in ASP.NET Core's Dependency Injection container. This maximizes resource efficiency and HTTP connection reuse. + +Register the `OpenAIClient` as a singleton in your `Program.cs`: + +```csharp +builder.Services.AddSingleton(serviceProvider => +{ + var apiKey = Environment.GetEnvironmentVariable("OPENAI_API_KEY"); + + return new OpenAIClient(apiKey); +}); +``` + +Then inject and use the client in your controllers or services: + +```csharp +[ApiController] +[Route("api/[controller]")] +public class ChatController : ControllerBase +{ + private readonly OpenAIClient _openAIClient; + + public ChatController(OpenAIClient openAIClient) + { + _openAIClient = openAIClient; + } + + [HttpPost("complete")] + public async Task CompleteChat([FromBody] string message) + { + ChatClient chatClient = _openAIClient.GetChatClient("gpt-4o"); + ChatCompletion completion = await chatClient.CompleteChatAsync(message); + + return Ok(new { response = completion.Content[0].Text }); + } +} +``` + ## How to use chat completions with streaming When you request a chat completion, the default behavior is for the server to generate it in its entirety before sending it back in a single response. Consequently, long chat completions can require waiting for several seconds before hearing back from the server. To mitigate this, the OpenAI REST API supports the ability to stream partial results back as they are being generated, allowing you to start processing the beginning of the completion before it is finished. diff --git a/examples/ASP.NET Core/ASP.NET Core.sln b/examples/ASP.NET Core/ASP.NET Core.sln new file mode 100644 index 000000000..7dcb33a54 --- /dev/null +++ b/examples/ASP.NET Core/ASP.NET Core.sln @@ -0,0 +1,24 @@ +Microsoft Visual Studio Solution File, Format Version 12.00 +# Visual Studio Version 17 +VisualStudioVersion = 17.5.2.0 +MinimumVisualStudioVersion = 10.0.40219.1 +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "client-di", "client-di.csproj", "{F3F2E48A-807D-4AC2-064F-2417457154CA}" +EndProject +Global + GlobalSection(SolutionConfigurationPlatforms) = preSolution + Debug|Any CPU = Debug|Any CPU + Release|Any CPU = Release|Any CPU + EndGlobalSection + GlobalSection(ProjectConfigurationPlatforms) = postSolution + {F3F2E48A-807D-4AC2-064F-2417457154CA}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {F3F2E48A-807D-4AC2-064F-2417457154CA}.Debug|Any CPU.Build.0 = Debug|Any CPU + {F3F2E48A-807D-4AC2-064F-2417457154CA}.Release|Any CPU.ActiveCfg = Release|Any CPU + {F3F2E48A-807D-4AC2-064F-2417457154CA}.Release|Any CPU.Build.0 = Release|Any CPU + EndGlobalSection + GlobalSection(SolutionProperties) = preSolution + HideSolutionNode = FALSE + EndGlobalSection + GlobalSection(ExtensibilityGlobals) = postSolution + SolutionGuid = {33398145-928F-4A73-A7AE-4B3ED3CE96C2} + EndGlobalSection +EndGlobal diff --git a/examples/ASP.NET Core/Program.cs b/examples/ASP.NET Core/Program.cs new file mode 100644 index 000000000..2f3587701 --- /dev/null +++ b/examples/ASP.NET Core/Program.cs @@ -0,0 +1,41 @@ +using System.ClientModel; +using OpenAI.Chat; + +var builder = WebApplication.CreateBuilder(args); + +// Add services to the container. +builder.Services.AddEndpointsApiExplorer(); +builder.Services.AddSwaggerGen(); + +builder.Services.AddSingleton(serviceProvider => new ChatClient(builder.Configuration["OpenAI:Model"], + new ApiKeyCredential(builder.Configuration["OpenAI:ApiKey"] + ?? Environment.GetEnvironmentVariable("OPENAI_API_KEY") + ?? throw new InvalidOperationException("OpenAI API key not found"))) +); + + +var app = builder.Build(); + +// Configure the HTTP request pipeline. +if (app.Environment.IsDevelopment()) +{ + app.UseSwagger(); + app.UseSwaggerUI(); +} + +app.UseHttpsRedirection(); + +// Chat completion endpoint using injected ChatClient client +app.MapPost("/chat/complete", async (ChatRequest request, ChatClient client) => +{ + var completion = await client.CompleteChatAsync(request.Message); + + return new ChatResponse(completion.Value.Content[0].Text); +}); + +app.Run(); + +record ChatRequest(string Message); +record ChatResponse(string Response); +record EmbeddingRequest(string Text); +record EmbeddingResponse(float[] Vector); diff --git a/examples/ASP.NET Core/README.md b/examples/ASP.NET Core/README.md new file mode 100644 index 000000000..16be5fdbb --- /dev/null +++ b/examples/ASP.NET Core/README.md @@ -0,0 +1,118 @@ +# OpenAI ASP.NET Core Example + +This example demonstrates how to use the OpenAI .NET client library with ASP.NET Core's dependency injection container, registering a ChatClient as a singleton for optimal performance and resource usage. + +## Features + +- **Singleton Registration**: ChatClient registered as singleton in DI container +- **Thread-Safe**: Demonstrates concurrent usage for chat completion endpoints +- **Configurable Model**: Model selection via configuration (appsettings.json) +- **Modern ASP.NET Core**: Uses minimal APIs with async/await patterns + +## Prerequisites + +- .NET 8.0 or later +- OpenAI API key + +## Setup + +1. **Set your OpenAI API key** using one of these methods: + + **Environment Variable (Recommended):** + + ```bash + export OPENAI_API_KEY="your-api-key-here" + ``` + + **Configuration (appsettings.json):** + + ```json + { + "OpenAI": { + "Model": "gpt-4o-mini", + "ApiKey": "your-api-key-here" + } + } + ``` + +2. **Install dependencies:** + + ```bash + dotnet restore + ``` + +3. **Run the application:** + + ```bash + dotnet run + ``` + +## API Endpoints + +### Chat Completion + +- **POST** `/chat/complete` +- **Request Body:** + + ```json + { + "message": "Hello, how are you?" + } + ``` + +- **Response:** + + ```json + { + "response": "I'm doing well, thank you for asking! How can I help you today?" + } + ``` + +## Testing with cURL + +**Chat Completion:** + +```bash +curl -X POST "https://localhost:7071/chat/complete" \ + -H "Content-Type: application/json" \ + -d '{"message": "What is the capital of France?"}' +``` + +## Key Implementation Details + +### Singleton Registration + +```csharp +builder.Services.AddSingleton(serviceProvider => new ChatClient( + builder.Configuration["OpenAI:Model"], + new ApiKeyCredential(builder.Configuration["OpenAI:ApiKey"] + ?? Environment.GetEnvironmentVariable("OPENAI_API_KEY") + ?? throw new InvalidOperationException("OpenAI API key not found"))) +); +``` + +### Dependency Injection Usage + +```csharp +app.MapPost("/chat/complete", async (ChatRequest request, ChatClient client) => +{ + var completion = await client.CompleteChatAsync(request.Message); + + return new ChatResponse(completion.Value.Content[0].Text); +}); +``` + +## Why Singleton? + +- **Thread-Safe**: ChatClient is thread-safe and can handle concurrent requests +- **Resource Efficient**: Reuses HTTP connections and avoids creating multiple instances +- **Performance**: Reduces object allocation overhead +- **Stateless**: Clients don't maintain per-request state + +## Swagger UI + +When running in development mode, you can access the Swagger UI at: + +- `https://localhost:7071/swagger` + +This provides an interactive interface to test the API endpoints. diff --git a/examples/ASP.NET Core/appsettings.Development.json b/examples/ASP.NET Core/appsettings.Development.json new file mode 100644 index 000000000..0c208ae91 --- /dev/null +++ b/examples/ASP.NET Core/appsettings.Development.json @@ -0,0 +1,8 @@ +{ + "Logging": { + "LogLevel": { + "Default": "Information", + "Microsoft.AspNetCore": "Warning" + } + } +} diff --git a/examples/ASP.NET Core/appsettings.json b/examples/ASP.NET Core/appsettings.json new file mode 100644 index 000000000..8636efc3a --- /dev/null +++ b/examples/ASP.NET Core/appsettings.json @@ -0,0 +1,14 @@ +{ + "Logging": { + "LogLevel": { + "Default": "Information", + "Microsoft.AspNetCore": "Warning" + } + }, + "AllowedHosts": "*", + "OpenAI": + { + "Model": "gpt-4.1-mini", + "ApiKey": "YOUR_API_KEY" + } +} diff --git a/examples/ASP.NET Core/client-di.csproj b/examples/ASP.NET Core/client-di.csproj new file mode 100644 index 000000000..04f0cfbd1 --- /dev/null +++ b/examples/ASP.NET Core/client-di.csproj @@ -0,0 +1,15 @@ + + + + net8.0 + enable + enable + ASP.NET_Core + + + + + + + + From 0f85f5e69d30cb96600c7046f844684391bbf5a4 Mon Sep 17 00:00:00 2001 From: Claudio Godoy <40471021+claudiogodoy99@users.noreply.github.com> Date: Sun, 13 Jul 2025 12:10:21 -0300 Subject: [PATCH 02/13] Update examples/ASP.NET Core/README.md Co-authored-by: Jesse Squire --- examples/ASP.NET Core/README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/examples/ASP.NET Core/README.md b/examples/ASP.NET Core/README.md index 16be5fdbb..702df36ba 100644 --- a/examples/ASP.NET Core/README.md +++ b/examples/ASP.NET Core/README.md @@ -1,6 +1,6 @@ # OpenAI ASP.NET Core Example -This example demonstrates how to use the OpenAI .NET client library with ASP.NET Core's dependency injection container, registering a ChatClient as a singleton for optimal performance and resource usage. +This example demonstrates how to use the OpenAI .NET client library with ASP.NET Core's dependency injection container, registering a `ChatClient` as a singleton for optimal performance and resource usage. ## Features From 8f28bf851dde627c480c115312c47f3ee0599685 Mon Sep 17 00:00:00 2001 From: Claudio Godoy <40471021+claudiogodoy99@users.noreply.github.com> Date: Sun, 13 Jul 2025 12:11:37 -0300 Subject: [PATCH 03/13] Update examples/ASP.NET Core/README.md Co-authored-by: Jesse Squire --- examples/ASP.NET Core/README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/examples/ASP.NET Core/README.md b/examples/ASP.NET Core/README.md index 702df36ba..65ca23d8a 100644 --- a/examples/ASP.NET Core/README.md +++ b/examples/ASP.NET Core/README.md @@ -104,7 +104,7 @@ app.MapPost("/chat/complete", async (ChatRequest request, ChatClient client) => ## Why Singleton? -- **Thread-Safe**: ChatClient is thread-safe and can handle concurrent requests +- **Thread-Safe**: `ChatClient` is thread-safe and can handle concurrent requests - **Resource Efficient**: Reuses HTTP connections and avoids creating multiple instances - **Performance**: Reduces object allocation overhead - **Stateless**: Clients don't maintain per-request state From 049302d00c7a22cdf1c23bbcc0a07a7171a664e0 Mon Sep 17 00:00:00 2001 From: claudiogodoy99 Date: Sun, 13 Jul 2025 12:57:35 -0300 Subject: [PATCH 04/13] fix: missing table content for new paragraph --- README.md | 1 + 1 file changed, 1 insertion(+) diff --git a/README.md b/README.md index d691c607c..d41c735a0 100644 --- a/README.md +++ b/README.md @@ -15,6 +15,7 @@ It is generated from our [OpenAPI specification](https://github.com/openai/opena - [Namespace organization](#namespace-organization) - [Using the async API](#using-the-async-api) - [Using the `OpenAIClient` class](#using-the-openaiclient-class) +- [How to use dependency injection](#how-to-use-dependency-injection) - [How to use chat completions with streaming](#how-to-use-chat-completions-with-streaming) - [How to use chat completions with tools and function calling](#how-to-use-chat-completions-with-tools-and-function-calling) - [How to use chat completions with structured outputs](#how-to-use-chat-completions-with-structured-outputs) From 312a4aca1dc98f5671fa7b82b6b6098db20b8e06 Mon Sep 17 00:00:00 2001 From: claudiogodoy99 Date: Sun, 13 Jul 2025 12:59:06 -0300 Subject: [PATCH 05/13] fix: rename structure new example project --- examples/ASP.NET Core/ASP.NET Core.sln | 24 ------------------- .../{ASP.NET Core => aspnet-core}/Program.cs | 0 .../{ASP.NET Core => aspnet-core}/README.md | 0 .../appsettings.Development.json | 0 .../appsettings.json | 0 .../aspnet-core.csproj} | 0 6 files changed, 24 deletions(-) delete mode 100644 examples/ASP.NET Core/ASP.NET Core.sln rename examples/{ASP.NET Core => aspnet-core}/Program.cs (100%) rename examples/{ASP.NET Core => aspnet-core}/README.md (100%) rename examples/{ASP.NET Core => aspnet-core}/appsettings.Development.json (100%) rename examples/{ASP.NET Core => aspnet-core}/appsettings.json (100%) rename examples/{ASP.NET Core/client-di.csproj => aspnet-core/aspnet-core.csproj} (100%) diff --git a/examples/ASP.NET Core/ASP.NET Core.sln b/examples/ASP.NET Core/ASP.NET Core.sln deleted file mode 100644 index 7dcb33a54..000000000 --- a/examples/ASP.NET Core/ASP.NET Core.sln +++ /dev/null @@ -1,24 +0,0 @@ -Microsoft Visual Studio Solution File, Format Version 12.00 -# Visual Studio Version 17 -VisualStudioVersion = 17.5.2.0 -MinimumVisualStudioVersion = 10.0.40219.1 -Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "client-di", "client-di.csproj", "{F3F2E48A-807D-4AC2-064F-2417457154CA}" -EndProject -Global - GlobalSection(SolutionConfigurationPlatforms) = preSolution - Debug|Any CPU = Debug|Any CPU - Release|Any CPU = Release|Any CPU - EndGlobalSection - GlobalSection(ProjectConfigurationPlatforms) = postSolution - {F3F2E48A-807D-4AC2-064F-2417457154CA}.Debug|Any CPU.ActiveCfg = Debug|Any CPU - {F3F2E48A-807D-4AC2-064F-2417457154CA}.Debug|Any CPU.Build.0 = Debug|Any CPU - {F3F2E48A-807D-4AC2-064F-2417457154CA}.Release|Any CPU.ActiveCfg = Release|Any CPU - {F3F2E48A-807D-4AC2-064F-2417457154CA}.Release|Any CPU.Build.0 = Release|Any CPU - EndGlobalSection - GlobalSection(SolutionProperties) = preSolution - HideSolutionNode = FALSE - EndGlobalSection - GlobalSection(ExtensibilityGlobals) = postSolution - SolutionGuid = {33398145-928F-4A73-A7AE-4B3ED3CE96C2} - EndGlobalSection -EndGlobal diff --git a/examples/ASP.NET Core/Program.cs b/examples/aspnet-core/Program.cs similarity index 100% rename from examples/ASP.NET Core/Program.cs rename to examples/aspnet-core/Program.cs diff --git a/examples/ASP.NET Core/README.md b/examples/aspnet-core/README.md similarity index 100% rename from examples/ASP.NET Core/README.md rename to examples/aspnet-core/README.md diff --git a/examples/ASP.NET Core/appsettings.Development.json b/examples/aspnet-core/appsettings.Development.json similarity index 100% rename from examples/ASP.NET Core/appsettings.Development.json rename to examples/aspnet-core/appsettings.Development.json diff --git a/examples/ASP.NET Core/appsettings.json b/examples/aspnet-core/appsettings.json similarity index 100% rename from examples/ASP.NET Core/appsettings.json rename to examples/aspnet-core/appsettings.json diff --git a/examples/ASP.NET Core/client-di.csproj b/examples/aspnet-core/aspnet-core.csproj similarity index 100% rename from examples/ASP.NET Core/client-di.csproj rename to examples/aspnet-core/aspnet-core.csproj From f533118a145b29baba21e02d09cc8a731249b4d7 Mon Sep 17 00:00:00 2001 From: claudiogodoy99 Date: Sun, 13 Jul 2025 13:36:17 -0300 Subject: [PATCH 06/13] chore: refactor example README.md to follow Windows first approach --- examples/aspnet-core/Program.cs | 37 +++++++++++++++++++-------- examples/aspnet-core/README.md | 19 +++++++------- examples/aspnet-core/appsettings.json | 2 +- 3 files changed, 38 insertions(+), 20 deletions(-) diff --git a/examples/aspnet-core/Program.cs b/examples/aspnet-core/Program.cs index 2f3587701..5c3703f09 100644 --- a/examples/aspnet-core/Program.cs +++ b/examples/aspnet-core/Program.cs @@ -12,6 +12,7 @@ ?? Environment.GetEnvironmentVariable("OPENAI_API_KEY") ?? throw new InvalidOperationException("OpenAI API key not found"))) ); +builder.Services.AddScoped(); var app = builder.Build(); @@ -25,17 +26,33 @@ app.UseHttpsRedirection(); -// Chat completion endpoint using injected ChatClient client -app.MapPost("/chat/complete", async (ChatRequest request, ChatClient client) => -{ - var completion = await client.CompleteChatAsync(request.Message); +var chatHandler = app.Services.GetRequiredService(); - return new ChatResponse(completion.Value.Content[0].Text); -}); +app.MapPost("/chat/complete", chatHandler.HandleChatRequest); app.Run(); -record ChatRequest(string Message); -record ChatResponse(string Response); -record EmbeddingRequest(string Text); -record EmbeddingResponse(float[] Vector); +public class ChatHttpHandler +{ + private readonly ChatClient _client; + private readonly ILogger _logger; + + // Chat completion endpoint using injected ChatClient client + public ChatHttpHandler(ChatClient client, ILogger logger) + { + _client = client; + _logger = logger; + } + + public async Task HandleChatRequest(ChatRequest request) + { + _logger.LogInformation("Handling chat request: {Message}", request.Message); + var completion = await _client.CompleteChatAsync(request.Message); + return new ChatResponse(completion.Value.Content[0].Text); + } +} + +public record ChatRequest(string Message); +public record ChatResponse(string Response); +public record EmbeddingRequest(string Text); +public record EmbeddingResponse(float[] Vector); diff --git a/examples/aspnet-core/README.md b/examples/aspnet-core/README.md index 65ca23d8a..527d139bf 100644 --- a/examples/aspnet-core/README.md +++ b/examples/aspnet-core/README.md @@ -20,8 +20,8 @@ This example demonstrates how to use the OpenAI .NET client library with ASP.NET **Environment Variable (Recommended):** - ```bash - export OPENAI_API_KEY="your-api-key-here" + ```powershell + $env:OPENAI_API_KEY = "your-api-key-here" ``` **Configuration (appsettings.json):** @@ -37,13 +37,13 @@ This example demonstrates how to use the OpenAI .NET client library with ASP.NET 2. **Install dependencies:** - ```bash + ```powershell dotnet restore ``` 3. **Run the application:** - ```bash + ```powershell dotnet run ``` @@ -68,14 +68,15 @@ This example demonstrates how to use the OpenAI .NET client library with ASP.NET } ``` -## Testing with cURL +## Testing with PowerShell **Chat Completion:** -```bash -curl -X POST "https://localhost:7071/chat/complete" \ - -H "Content-Type: application/json" \ - -d '{"message": "What is the capital of France?"}' +```powershell +Invoke-RestMethod -Uri "https://localhost:5000/chat/complete" ` + -Method POST ` + -ContentType "application/json" ` + -Body '{"message": "What is the capital of France?"}' ``` ## Key Implementation Details diff --git a/examples/aspnet-core/appsettings.json b/examples/aspnet-core/appsettings.json index 8636efc3a..af10f3391 100644 --- a/examples/aspnet-core/appsettings.json +++ b/examples/aspnet-core/appsettings.json @@ -9,6 +9,6 @@ "OpenAI": { "Model": "gpt-4.1-mini", - "ApiKey": "YOUR_API_KEY" + "ApiKey": "" } } From b1edf205671033aa2db16b784bcae2fa2af892ed Mon Sep 17 00:00:00 2001 From: claudiogodoy99 Date: Sun, 13 Jul 2025 13:47:30 -0300 Subject: [PATCH 07/13] docs: add Additional resources paragraph on README.md --- examples/aspnet-core/README.md | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/examples/aspnet-core/README.md b/examples/aspnet-core/README.md index 527d139bf..a695da925 100644 --- a/examples/aspnet-core/README.md +++ b/examples/aspnet-core/README.md @@ -117,3 +117,9 @@ When running in development mode, you can access the Swagger UI at: - `https://localhost:7071/swagger` This provides an interactive interface to test the API endpoints. + +## Additional Resources + +- [Tutorial: Create a minimal API with ASP.NET Core](https://learn.microsoft.com/aspnet/core/tutorials/min-web-api) +- [.NET dependency injection](https://learn.microsoft.com/dotnet/core/extensions/dependency-injection) +- [Logging in C# and .NET](https://learn.microsoft.com/dotnet/core/extensions/logging) \ No newline at end of file From d5b3d708c695c71a35b2725c9eb51e0ec756d1ca Mon Sep 17 00:00:00 2001 From: claudiogodoy99 Date: Sun, 13 Jul 2025 13:54:50 -0300 Subject: [PATCH 08/13] chore: remove api secret and unused records --- examples/aspnet-core/Program.cs | 4 +--- examples/aspnet-core/appsettings.json | 4 ++++ 2 files changed, 5 insertions(+), 3 deletions(-) diff --git a/examples/aspnet-core/Program.cs b/examples/aspnet-core/Program.cs index 5c3703f09..9efff6261 100644 --- a/examples/aspnet-core/Program.cs +++ b/examples/aspnet-core/Program.cs @@ -53,6 +53,4 @@ public async Task HandleChatRequest(ChatRequest request) } public record ChatRequest(string Message); -public record ChatResponse(string Response); -public record EmbeddingRequest(string Text); -public record EmbeddingResponse(float[] Vector); +public record ChatResponse(string Response); \ No newline at end of file diff --git a/examples/aspnet-core/appsettings.json b/examples/aspnet-core/appsettings.json index af10f3391..1b2b65ec1 100644 --- a/examples/aspnet-core/appsettings.json +++ b/examples/aspnet-core/appsettings.json @@ -8,7 +8,11 @@ "AllowedHosts": "*", "OpenAI": { +<<<<<<< HEAD "Model": "gpt-4.1-mini", +======= + "Model": "gpt-4.1", +>>>>>>> 2ef2c53 (chore: remove api secret and unused records) "ApiKey": "" } } From 03172e4f7014811904063b4e2d0ecfe3dbeabd7e Mon Sep 17 00:00:00 2001 From: claudiogodoy99 Date: Sun, 13 Jul 2025 13:59:26 -0300 Subject: [PATCH 09/13] remove record from new example --- examples/aspnet-core/Program.cs | 21 +++++++++++++++++++-- 1 file changed, 19 insertions(+), 2 deletions(-) diff --git a/examples/aspnet-core/Program.cs b/examples/aspnet-core/Program.cs index 9efff6261..f6cb39b6e 100644 --- a/examples/aspnet-core/Program.cs +++ b/examples/aspnet-core/Program.cs @@ -52,5 +52,22 @@ public async Task HandleChatRequest(ChatRequest request) } } -public record ChatRequest(string Message); -public record ChatResponse(string Response); \ No newline at end of file +public class ChatRequest +{ + public string Message { get; set; } + + public ChatRequest(string message) + { + Message = message; + } +} + +public class ChatResponse +{ + public string Response { get; set; } + + public ChatResponse(string response) + { + Response = response; + } +} \ No newline at end of file From d4a6c9621987da01be740bc30d9083c18b3b867c Mon Sep 17 00:00:00 2001 From: Claudio Godoy <40471021+claudiogodoy99@users.noreply.github.com> Date: Thu, 17 Jul 2025 09:27:08 -0300 Subject: [PATCH 10/13] Update examples/aspnet-core/appsettings.json Co-authored-by: Jesse Squire --- examples/aspnet-core/appsettings.json | 4 ---- 1 file changed, 4 deletions(-) diff --git a/examples/aspnet-core/appsettings.json b/examples/aspnet-core/appsettings.json index 1b2b65ec1..af10f3391 100644 --- a/examples/aspnet-core/appsettings.json +++ b/examples/aspnet-core/appsettings.json @@ -8,11 +8,7 @@ "AllowedHosts": "*", "OpenAI": { -<<<<<<< HEAD "Model": "gpt-4.1-mini", -======= - "Model": "gpt-4.1", ->>>>>>> 2ef2c53 (chore: remove api secret and unused records) "ApiKey": "" } } From b710a0cc88a42aa44f89f032cf03774750faac81 Mon Sep 17 00:00:00 2001 From: Claudio Godoy <40471021+claudiogodoy99@users.noreply.github.com> Date: Thu, 17 Jul 2025 09:27:15 -0300 Subject: [PATCH 11/13] Update examples/aspnet-core/aspnet-core.csproj Co-authored-by: Jesse Squire --- examples/aspnet-core/aspnet-core.csproj | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/examples/aspnet-core/aspnet-core.csproj b/examples/aspnet-core/aspnet-core.csproj index 04f0cfbd1..5a9167509 100644 --- a/examples/aspnet-core/aspnet-core.csproj +++ b/examples/aspnet-core/aspnet-core.csproj @@ -8,7 +8,7 @@ - + From c488445db3bc9fca40ee57e678d04b77b09eb64d Mon Sep 17 00:00:00 2001 From: claudiogodoy99 Date: Fri, 18 Jul 2025 09:42:14 -0300 Subject: [PATCH 12/13] chore: fix CI by excluding aspnet-core subdirectory --- examples/OpenAI.Examples.csproj | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/examples/OpenAI.Examples.csproj b/examples/OpenAI.Examples.csproj index cbdcde445..2fa8f7894 100644 --- a/examples/OpenAI.Examples.csproj +++ b/examples/OpenAI.Examples.csproj @@ -10,6 +10,13 @@ latest + + + + + + + From a35be7938c796b7d38b398a761b8a8658ed1e110 Mon Sep 17 00:00:00 2001 From: claudiogodoy99 Date: Fri, 18 Jul 2025 09:47:45 -0300 Subject: [PATCH 13/13] chore: update README to use ChatClient instead of OpenAIClient --- README.md | 15 +++++++-------- 1 file changed, 7 insertions(+), 8 deletions(-) diff --git a/README.md b/README.md index d41c735a0..745d94659 100644 --- a/README.md +++ b/README.md @@ -143,14 +143,14 @@ AudioClient whisperClient = client.GetAudioClient("whisper-1"); The OpenAI clients are **thread-safe** and can be safely registered as **singletons** in ASP.NET Core's Dependency Injection container. This maximizes resource efficiency and HTTP connection reuse. -Register the `OpenAIClient` as a singleton in your `Program.cs`: +Register the `ChatClient` as a singleton in your `Program.cs`: ```csharp -builder.Services.AddSingleton(serviceProvider => +builder.Services.AddSingleton(serviceProvider => { var apiKey = Environment.GetEnvironmentVariable("OPENAI_API_KEY"); - return new OpenAIClient(apiKey); + return new ChatClient(apiKey); }); ``` @@ -161,18 +161,17 @@ Then inject and use the client in your controllers or services: [Route("api/[controller]")] public class ChatController : ControllerBase { - private readonly OpenAIClient _openAIClient; + private readonly ChatClient _chatClient; - public ChatController(OpenAIClient openAIClient) + public ChatController(ChatClient chatClient) { - _openAIClient = openAIClient; + _chatClient = chatClient; } [HttpPost("complete")] public async Task CompleteChat([FromBody] string message) { - ChatClient chatClient = _openAIClient.GetChatClient("gpt-4o"); - ChatCompletion completion = await chatClient.CompleteChatAsync(message); + ChatCompletion completion = await _chatClient.CompleteChatAsync(message); return Ok(new { response = completion.Content[0].Text }); }