Standard.AI.OpenAI: A Library for .NET Developers

Mabrouk Mahdhi
7 min readFeb 16, 2024
Photo by Steve Johnson on Unsplash

In the rapidly evolving tech landscape, where artificial intelligence (AI) plays a pivotal role in driving innovation and enhancing efficiency, the inception of Standard.AI.OpenAI marked a significant milestone. Initiated by Hassan Habib and subsequently developed by a global cohort of passionate developers including ElbekDeveloper, Brian, Kailu, myself (Mabrouk Mahdhi), and many others, this library stands as a testament to the power of collaboration and shared vision. Designed to serve as a conduit between .NET developers and the extensive capabilities of the OpenAI API, Standard.AI.OpenAI is anchored in adherence to The Standard, ensuring a commitment to engineering excellence, ethical principles, and community engagement. This article explores the foundation upon which Standard.AI.OpenAI was built, elucidating its alignment with The Standard, the library’s commitment to its users, and providing a comprehensive walkthrough for .NET developers eager to harness the power of AI in their applications.

Introduction to Standard.AI.OpenAI

Standard.AI.OpenAI is not just another library; it’s a testament to what can be achieved when a community of software engineers comes together to build a solution that adheres to high standards of engineering principles, patterns, and tooling. Built atop the RESTful endpoints of the OpenAI API, this .NET library facilitates the development of AI-powered solutions, enabling developers to harness the power of advanced machine learning models within their .NET applications.

Standard-Compliance: A Core Philosophy

The development of Standard.AI.OpenAI was guided by a strict adherence to The Standard, an amalgamation of best practices and engineering guidelines designed to ensure the creation of robust, maintainable, and efficient software. This library is the product of countless nights of pair programming, test-driven development, and extensive research, all aimed at crafting a tool that not only meets the technical requirements of developers but also aligns with the ethical standards of software engineering.

Getting Started with Standard.AI.OpenAI

To begin using Standard.AI.OpenAI, developers must navigate through a series of preliminary steps, starting with the creation of an OpenAI account. Following this, the Standard.AI.OpenAI library can be integrated into projects via NuGet, and an API key must be generated through the OpenAI platform. These initial steps lay the groundwork for developers to embark on their journey of building AI-powered .NET applications.

OpenAI Account and API Keys

The first step involves creating an OpenAI account and generating an API key, which serves as the gateway to accessing the vast capabilities of the OpenAI API. This process is straightforward and essential for authenticating requests made from your application to the OpenAI services.

Installing the Library

Once the OpenAI account is set up, the next step is to install the Standard.AI.OpenAI library into your .NET project. This can be done through NuGet, a package manager for .NET, which simplifies the process of incorporating external libraries into your projects.

Writing Your First AI-Powered Program

With the setup out of the way, developers can dive into writing their first AI-powered program. The library offers various functionalities, including completions, chat completions, and fine-tunes, each tailored to different use cases and types of AI interactions. Below are examples of how to implement these functionalities in a .NET application:

Completions: The following example demonstrate how you can write your first Completions program.

using System;
using System.Threading.Tasks;
using Standard.AI.OpenAI.Clients.OpenAIs;
using Standard.AI.OpenAI.Models.Configurations;
using Standard.AI.OpenAI.Models.Services.Foundations.Completions;

namespace ExampleOpenAIDotNet
{
internal class Program
{
static async Task Main(string[] args)
{
var openAIConfigurations = new OpenAIConfigurations
{
ApiKey = "YOUR_API_KEY_HERE",
OrganizationId = "YOUR_OPTIONAL_ORG_ID_HERE"
};

var openAIClient = new OpenAIClient(openAIConfigurations);

var inputCompletion = new Completion
{
Request = new CompletionRequest
{
Prompts = new string[] { "Human: Hello!" },

Model = "text-davinci-003"
}
};

Completion resultCompletion =
await openAIClient.Completions.PromptCompletionAsync(
inputCompletion);

Array.ForEach(
resultCompletion.Response.Choices,
choice => Console.WriteLine(choice.Text));
}
}
}

Chat Completions: The following example demonstrate how you can write your first Chat Completions program.

using System;
using System.Threading.Tasks;
using Standard.AI.OpenAI.Clients.OpenAIs;
using Standard.AI.OpenAI.Models.Configurations;
using Standard.AI.OpenAI.Models.Services.Foundations.ChatCompletions;

namespace ExampleOpenAIDotNet
{
internal class Program
{
static async Task Main(string[] args)
{
var openAIConfigurations = new OpenAIConfigurations
{
ApiKey = "YOUR_API_KEY_HERE",
OrganizationId = "YOUR_OPTIONAL_ORG_ID_HERE"
};

var openAIClient = new OpenAIClient(openAIConfigurations);

var chatCompletion = new ChatCompletion
{
Request = new ChatCompletionRequest
{
Model = "gpt-3.5-turbo",
Messages = new ChatCompletionMessage[]
{
new ChatCompletionMessage
{
Content = "What is c#?",
Role = "user",
}
},
}
};

ChatCompletion resultChatCompletion =
await openAIClient.ChatCompletions.SendChatCompletionAsync(
chatCompletion);

Array.ForEach(
resultChatCompletion.Response.Choices,
choice => Console.WriteLine(
value: $"{choice.Message.Role}: {choice.Message.Content}"));
}
}
}

Fine-Tunes: The following example demonstrate how you can write your first Fine-tunes program.

using System;
using System.IO;
using System.Text;
using System.Threading.Tasks;
using Standard.AI.OpenAI.Clients.OpenAIs;
using Standard.AI.OpenAI.Models.Configurations;
using Standard.AI.OpenAI.Models.Services.Foundations.AIFiles;
using Standard.AI.OpenAI.Models.Services.Foundations.FineTunes;

namespace Examples.Standard.AI.OpenAI.Clients.FineTunes
{
internal class Program
{
static async Task Main(string[] args)
{
var openAIConfigurations = new OpenAIConfigurations
{
ApiKey = "YOUR_API_KEY_HERE",
ApiUrl = "https://api.openai.com"
};

IOpenAIClient openAIClient =
new OpenAIClient(openAIConfigurations);

MemoryStream memoryStream = CreateRandomStream();

var aiFile = new AIFile
{
Request = new AIFileRequest
{
Name = "Test",
Content = memoryStream,
Purpose = "fine-tune"
}
};

AIFile file = await openAIClient.AIFiles
.UploadFileAsync(aiFile);

var fineTune = new FineTune();
fineTune.Request = new FineTuneRequest();

fineTune.Request.FileId =
file.Response.Id;

FineTune fineTuneResult =
await openAIClient.FineTuneClient
.SubmitFineTuneAsync(fineTune);

Console.WriteLine(fineTuneResult);
}

private static MemoryStream CreateRandomStream()
{
string content = "{\"prompt\": \"<prompt text>\", \"completion\": \"<ideal generated text>\"}";

return new MemoryStream(Encoding.UTF8.GetBytes(content));
}
}
}

These examples provide a foundation for developers to start experimenting with AI, encouraging customization and exploration of the various capabilities offered by the OpenAI API.

Handling Exceptions Gracefully

The robust architecture of Standard.AI.OpenAI emphasizes not just functionality but also reliability and resilience, ensuring that applications built using the library are equipped to handle unforeseen errors and exceptions gracefully. In software development, especially when interfacing with external services like the OpenAI API, encountering errors is inevitable. However, the manner in which these errors are managed can significantly impact the stability and usability of your application. This is where Standard.AI.OpenAI’s comprehensive exception handling framework comes into play.

Types of Exceptions:

Standard.AI.OpenAI categorizes exceptions into several types, each designed to represent specific kinds of issues that might arise during the API interaction process. These exceptions provide clarity and context, making it easier for developers to pinpoint the source of an error and address it effectively. Here are some of the custom exceptions defined by the library:

  • ChatCompletionClientValidationException: This exception is thrown when there is a validation error with the chat completions feature. For example, if the input data does not meet the expected format or is missing required fields, this exception alerts developers to the precise nature of the validation issue.
  • ChatCompletionClientDependencyException: Encountered when there’s a dependency issue while using the chat completion feature. This could arise if there’s a failure in an underlying service or library that the chat completion functionality depends on.
  • ChatCompletionClientServiceException: This exception is triggered by service-level errors during chat completion operations. It could be due to issues on the server-side, such as downtime or internal errors within the OpenAI API services.
  • FineTuneClientValidationException: Similar to the ChatCompletionClientValidationException, but specific to the fine-tuning feature of the library. It’s thrown when the data provided for fine-tuning operations fails to meet validation criteria.
  • FineTuneClientDependencyException: This exception indicates a dependency error within the fine-tuning functionality. It could be related to external services or libraries required for fine-tuning operations.
  • FineTuneClientServiceException: Represents errors that occur at the service level during fine-tuning operations. This includes issues like server errors, API rate limits being exceeded, or other service disruptions.

Handling Exceptions:

The design of these exceptions within Standard.AI.OpenAI allows developers to implement sophisticated error handling mechanisms. By catching these exceptions, developers can provide more informative feedback to users, implement retries or fallback logic, and log errors for further investigation. Here’s an example of how one might handle these exceptions in a .NET application:

try
{
// Attempt to perform a chat completion operation
}
catch (ChatCompletionClientValidationException ex)
{
// Handle validation errors (e.g., log the issue, alert the user)
}
catch (ChatCompletionClientDependencyException ex)
{
// Handle dependency errors (e.g., attempt a retry, notify the user)
}
catch (ChatCompletionClientServiceException ex)
{
// Handle service errors (e.g., implement fallback logic)
}
catch (Exception ex)
{
// Catch-all for any other unexpected errors
}

This approach to exception handling ensures that applications remain resilient and user-friendly, even in the face of errors. It allows developers to gracefully manage issues, improving the overall reliability and robustness of their software.

Contributing to Standard.AI.OpenAI

The Standard.AI.OpenAI library is a community effort, and contributions are warmly welcomed. Whether it’s through coding, documentation, or participating in live sessions, there are numerous ways to get involved. The project adheres to C# coding standards and The Team Standard, ensuring that contributions maintain the library’s high quality and standard-compliance.

Live Sessions and Community Engagement

The development of Standard.AI.OpenAI has been an open process, with live coding sessions and discussions broadcasted across multiple platforms. These sessions provide insights into the library’s development, offering a unique opportunity for the community to engage, learn, and contribute.

Summary

Standard.AI.OpenAI stands as a testament to what the .NET community can achieve when it comes together to build something truly remarkable. By adhering to The Standard, embracing ethical practices, and fostering a collaborative environment, this library not only empowers developers to create AI-powered solutions but also does so with a commitment to positive values and community growth. Whether you’re a seasoned .NET developer or just starting out, Standard.AI.OpenAI offers the tools and support you need to explore the exciting possibilities of AI in your applications.

--

--

Mabrouk Mahdhi

Microsoft MVP, Author & Senior Technical Consultant @ eBiz Consulting GmbH