Featured image of post Generate a custom C# ChatGPT API client in minutes with Kiota

Generate a custom C# ChatGPT API client in minutes with Kiota

Generate a custom C# ChatGPT API client with Kiota for greater control, security, flexibility, and extensibility.

During my recent visit to the Microsoft offices in Montréal for a meetup organized by the MSDEVMTL Meetup group, I had the opportunity to learn more about Kiota, an incredible tool developed by Microsoft. The Kiota development team showcased its capabilities and demonstrated how it streamlines the process of generating client SDKs for various APIs.

Kiota is an OpenAPI-driven code generation tool that enables developers to create SDKs in different programming languages. By using Kiota, you can generate a custom C# client for a given API, tailored to your specific needs. This is an alternative to using third-party packages, as it allows for greater flexibility and control over your implementation.

In this blog post, we will dive into the process of generating a C# client for the ChatGPT API using Kiota, and explore the benefits of having a custom SDK at your disposal instead of third-party NuGet packages developed by the community.

Why generate your own C# client with Kiota?

Using Kiota to generate your own C# client for any OpenAPI-based API offers several advantages over using a prebuilt, third-party client library.

  1. Customization and extensibility: Kiota gives you full control over the codebase, and it can be customized according to your needs and requirements.
  2. Up-to-date API coverage: You can generate an up-to-date C# client anytime the API specification changes.
  3. Reduced dependency on external packages: Kiota helps avoid potential issues related to version compatibility or package deprecation.
  4. Increased security: Avoiding the use of third-party client libraries reduces the attack surface.
  5. Batteries included: Kiota’s default HTTP client includes built-in OpenTelemetry support, a retry helper, a compression handler and more.

The best example of Kiota’s capabilities is its use in generating Microsoft Graph SDKs. For the past few months, these SDKs have been generated from the ~25MB Microsoft Graph OpenAPI specification. Microsoft utilizes Kiota with this specification to generate SDKs for multiple languages, not just C#, in a matter of seconds.

Installing Kiota

The easiest way to install Kiota is as a .NET tool. Make sure you have .NET SDK 7 installed on your system. Simply open a terminal or command prompt and execute the following command:

dotnet tool install --global Microsoft.OpenApi.Kiota

Once the installation is complete, you’ll have access to the kiota command line tool, which we’ll use in a next section to generate the C# client for the ChatGPT API.

Preparing OpenAI’s OpenAPI specification for Kiota

TL;DR: OpenAI’s OpenAPI specification contains an invalid number value default: inf for the CreateChatCompletionRequest.max_tokens property. Fortunately, we can fix the specification by replacing the line with nullable: true.

To generate a C# SDK client with Kiota, we need OpenAI’s OpenAPI specification. It’s hosted on this GitHub repository, and you can download the current specification directly.

However, OpenAI’s API specification includes an invalid number value that makes Kiota generate invalid C#, so we’ll need to modify it manually:

Replace ‘default: inf’ with ’nullable: true’ for the CreateChatCompletionRequest.max_tokens property

The modified compatible OpenAI OpenAPI specification can be found here.

Generating OpenAI C# client with Kiota

The final code sample can be found on my GitHub repository.

Given an existing C# project named MyApp and OpenAI’s OpenAPI specification in a ./openai.yaml file, execute the following command:

kiota generate --language csharp --openapi ./openai.yaml --class-name OpenAiClient --namespace-name MyApp.OpenAi --output ./OpenAi

Next, copy the output directory ./OpenAi to the MyApp project and add the required Kiota dependencies:

dotnet add package Microsoft.Kiota.Abstractions
dotnet add package Microsoft.Kiota.Http.HttpClientLibrary
dotnet add package Microsoft.Kiota.Serialization.Form
dotnet add package Microsoft.Kiota.Serialization.Json
dotnet add package Microsoft.Kiota.Serialization.Text

Now we’re almost done. The generated OpenAiClient requires an implementation of IRequestAdapter, which is a way for Kiota to understand how to make HTTP requests. Fortunately, the package Microsoft.Kiota.Http.HttpClientLibrary comes with a defaut implementation: HttpClientRequestAdapter.

As Kiota does not know the specific API authentication mechanism, the HttpClientRequestAdapter needs an implementation of the IAuthenticationProvider interface. By default, the package Microsoft.Kiota.Abstractions includes the following implementations:

  • AnonymousAuthenticationProvider: for APIs that do not require authentication.
  • ApiKeyAuthenticationProvider: adds an HTTP request header or query parameter for authenticating HTTP requests.
  • BaseBearerTokenAuthenticationProvider: for more complex scenarios when the API requires a bearer token.

The OpenAI API uses API keys for authentication, in the form of a HTTP header Authorization: Bearer OPENAI_API_KEY. This makes it a perfect candidate for ApiKeyAuthenticationProvider. We can extend this class to create our own OpenAiAuthenticationProvider:

public sealed class OpenAiAuthenticationProvider : ApiKeyAuthenticationProvider
{
    public OpenAiAuthenticationProvider(string apiKey)
        : base("Bearer " + apiKey, "Authorization", KeyLocation.Header)
    {
    }
}

Using the generated OpenAI C# client to consume ChatGPT completion API

It is time to consume OpenAI API using our generated C# client! Get your OpenAI API key, then let’s call the chat completion API:

using Microsoft.Kiota.Http.HttpClientLibrary;
using MyApp.OpenAi;
using MyApp.OpenAi.Models;

var authProvider = new OpenAiAuthenticationProvider("<OPENAI_API_KEY>");
var requestAdapter = new HttpClientRequestAdapter(authProvider);
var client = new OpenAiClient(requestAdapter);

var response = await client.Chat.Completions.PostAsync(new CreateChatCompletionRequest
{
    Model = "gpt-3.5-turbo",
    Messages = new List<ChatCompletionRequestMessage>
    {
        new ChatCompletionRequestMessage
        {
            Role = ChatCompletionRequestMessage_role.System,
            Content = "You are a helpful assistant."
        },
        new ChatCompletionRequestMessage
        {
            Role = ChatCompletionRequestMessage_role.User,
            Content = "Who won the world series in 2020?"
        },
        new ChatCompletionRequestMessage
        {
            Role = ChatCompletionRequestMessage_role.Assistant,
            Content = "The Los Angeles Dodgers won the World Series in 2020."
        },
        new ChatCompletionRequestMessage
        {
            Role = ChatCompletionRequestMessage_role.User,
            Content = "Where was it played?"
        }
    }
});

// Prints "The 2020 World Series was played at Globe Life Field in Arlington, Texas."
Console.WriteLine(response.Choices[0].Message.Content);

Conclusion

In this blog post, we’ve demonstrated how to use Kiota to generate a custom C# client for the ChatGPT API. By creating your own client, you gain full control over the codebase, allowing for better customization, extensibility, and security. Additionally, you can easily keep your client up-to-date with any API changes and minimize dependencies on external packages. This opens up new possibilities and flexibility in how you interact with the ChatGPT API and other OpenAPI-based APIs, making it easier to integrate them into your projects.

Now that you’re equipped with the knowledge of how to generate and use a custom C# client with Kiota, you can explore other OpenAPI specifications and generate clients for different APIs, tailoring them to your specific needs.