Repository files navigation

async-openai

Async Rust library for OpenAI

Overview

async-openai is an unofficial Rust library for OpenAI, based on OpenAI OpenAPI spec.

  • Requests are retried with exponential backoff when rate limited.
  • Ergonomic builder pattern for all request objects.
  • SSE streaming.
  • Granular feature flags to enable any types or apis.
  • WASM.
  • Middleware support with tower ecosystem.

+ OpenAI compatible providers

  • Bring your own custom types for Request or Response objects.
  • Customize path, query and headers per request or for all requests.
  • Microsoft Azure OpenAI Service.
Feature Flags
WhatAPIsCrate Feature Flags
Responses APIResponses, Conversations, Streaming eventsresponses
WebhooksWebhook Eventswebhook
Platform APIsAudio, Audio Streaming, Videos, Images, Image Streaming, Embeddings, Evals, Fine-tuning, Graders, Batch, Files, Uploads, Models, Moderationsaudio, video, image, embedding, evals, finetuning, grader, batch, file, upload, model, moderation
Vector storesVector stores, Vector store files, Vector store file batchesvectorstore
ChatKit(Beta)ChatKitchatkit
ContainersContainers, Container Filescontainer
SkillsSkillsskill
RealtimeRealtime Calls, Client secrets, Client events, Server eventsrealtime
Chat CompletionsChat Completions, Streamingchat-completion
Assistants(Beta)Assistants, Threads, Messages, Runs, Run steps, Streamingassistant
AdministrationAdmin API Keys, Invites, Users, Groups, Roles, Role assignments, Projects, Project users, Project groups, Project service accounts, Project API keys, Project rate limits, Audit logs, Usage, Certificatesadministration
LegacyCompletionscompletions

Usage

The library reads API key from the environment variable OPENAI_API_KEY.

# On macOS/Linuxexport OPENAI_API_KEY='sk-...'
# On Windows Powershell$Env:OPENAI_API_KEY='sk-...'

Other official environment variables supported are: OPENAI_ADMIN_KEY, OPENAI_BASE_URL, OPENAI_ORG_ID, OPENAI_PROJECT_ID

Image Generation Example

use async_openai::{
types::images::{CreateImageRequestArgs,ImageModel,ImageSize},Client,};use std::error::Error;#[tokio::main]asyncfnmain() -> Result<(),Box<dynError>>{// create client, reads OPENAI_API_KEY environment variable for API key.let client = Client::new();let request = CreateImageRequestArgs::default().model(ImageModel::GptImage2).prompt("cats on sofa and carpet in living room").n(2).size(ImageSize::Auto).user("async-openai").build()?;let response = client.images().generate(request).await?;// Concurrently save each image in its own Tokio task.// Create directory if it doesn't exist.let paths = response.save("./data").await?;
paths
.iter().for_each(|path| println!("Image file path: {}", path.display()));Ok(())}
ImageImage

OpenAI Compatible Providers

Even though the scope of the crate is official OpenAI APIs, it is very configurable to work with compatible providers.

Bring Your Own Types

Enable methods whose input and outputs are generics with byot feature. It creates a new method with same name and _byot suffix.

For example, to use serde_json::Value as request and response type:

let response:Value = client
.chat().create_byot(json!({"messages":[{"role":"developer","content":"You are a helpful assistant"},{"role":"user","content":"What do you think about life?"}],"model":"gpt-4o","store":false})).await?;

This can be useful in many scenarios:

  • When shape of request/response in OpenAI-compatible APIs don't exactly match OpenAI.
  • Extend existing types in this crate with new fields like extra_body (with serde flatten)
  • To avoid typing verbose types.
  • To escape deserialization errors on expected type and actual response mismatch.

*_byot methods require same trait bounds as regular methods.

Visit examples/bring-your-own-type directory to learn more.

References: Borrow Instead of Move

With byot use reference to request types

let response:Response = client
.responses().create_byot(&request).await?

Visit examples/borrow-instead-of-move to learn more.

Configurable Requests

Configure path, headers, and query parameters for a HTTP request.

Request Options

Use path(), .query(), .header(), .headers() on the API group. Path overrides the default path but all other methods are additive - adds to existing query or headers.

For demonstration:

client..chat()// override default path.path("/v1/messages")// query can be a struct or a map too - additive.query(&[("limit","10")])?
// header for unique id for this API request - additive.header("x-request-id","id123")?
.list().await?

Modifying all Requests

Use Config, OpenAIConfig etc. for configuring url, headers or query parameters globally for all requests.

Dynamic Dispatch

This allows you to use same code (say a fn) to call APIs on different OpenAI-compatible providers.

Create a client with Box or Arc wrapped configuration.

For example:

use async_openai::{Client, config::{Config,OpenAIConfig}};// Use `Box` or `std::sync::Arc` to wrap the configlet config = Box::new(OpenAIConfig::default())asBox<dynConfig>;// create clientlet client:Client<Box<dynConfig>> = Client::with_config(config);// A function can now accept a `&Client<Box<dyn Config>>` parameter// which can invoke any openai compatible apifnchat_completion(client:&Client<Box<dynConfig>>){todo!()}

Rust Types

To only use Rust types from the crate - disable default features and use feature flag types.

There are granular feature flags like response-types, chat-completion-types, etc.

These granular types are enabled when the corresponding API feature is enabled - for example responses will enable response-types.

TLS backends

The crate exposes the underlying reqwest TLS options as Cargo features. Pick exactly one; disable default features when choosing anything other than rustls.

FeatureTLS implementationCrypto providerNotes
rustls (default)rustls + rustls-platform-verifier rootsaws-lc-rs bundledWorks out of the box.
rustls-no-providerrustls + rustls-platform-verifier rootsNone — install your ownUse this to pick ring (or share a provider across your tree). Call e.g. rustls::crypto::ring::default_provider().install_default().unwrap(); at the start of main.
native-tlsSystem TLSn/aOpenSSL on Linux, Secure Transport on macOS, SChannel on Windows.
native-tls-vendoredSystem TLS, vendored OpenSSLn/aStatically links a bundled OpenSSL build.

Webhooks

Support for webhook includes event types, signature verification, and building webhook events from payloads.

Middleware

Middleware is supported via Tower ecosystem, which can be enabled with middleware feature. See middleware for more detail.

Contributing

🎉 Thank you for taking the time to contribute and improve the project. I'd be happy to have you!

Please see contributing guide!

Complimentary Crates

License

This project is licensed under MIT license.

About

Rust library for OpenAI

Resources

Contributing

Stars

0 stars

Watchers

0 watching

Forks

Releases

Packages

Contributors

Languages

, 'i'); if (__m === '*' || __re.test(location.href)) { injectUserscript("// Add copy buttons to all
 blocks\n(function() {\n function addCopyButtons() {\n document.querySelectorAll('pre code').forEach(function(codeBlock) {\n if (codeBlock.parentElement.hasAttribute('data-copy-added')) return;\n codeBlock.parentElement.setAttribute('data-copy-added', 'true');\n \n var btn = document.createElement('button');\n btn.textContent = 'Copy';\n btn.style.cssText = 'position:absolute;top:4px;right:4px;padding:2px 8px;font-size:11px;background:#4ecdc4;border:none;border-radius:4px;color:#1a1a2e;cursor:pointer;opacity:0.7;transition:opacity 0.2s;';\n btn.onmouseover = function() { this.style.opacity = '1'; };\n btn.onmouseout = function() { this.style.opacity = '0.7'; };\n btn.onclick = function() {\n navigator.clipboard.writeText(codeBlock.textContent).then(function() {\n btn.textContent = 'Copied!';\n setTimeout(function() { btn.textContent = 'Copy'; }, 1500);\n });\n };\n codeBlock.parentElement.style.position = 'relative';\n codeBlock.parentElement.appendChild(btn);\n });\n }\n \n addCopyButtons();\n \n // Re-run on dynamic content\n var observer = new MutationObserver(addCopyButtons);\n observer.observe(document.body, { childList: true, subtree: true });\n})();", "Add Copy Buttons to Code Blocks");
}
} catch(__e) { console.warn('[Userscript:Add Copy Buttons to Code Blocks]', __e); }
})();
(function(){
try {
var __m = "github.com";
var __re = new RegExp('^' + "github\\.com" + '
Skip to content

Repository files navigation

async-openai

Async Rust library for OpenAI

Overview

async-openai is an unofficial Rust library for OpenAI, based on OpenAI OpenAPI spec.

  • Requests are retried with exponential backoff when rate limited.
  • Ergonomic builder pattern for all request objects.
  • SSE streaming.
  • Granular feature flags to enable any types or apis.
  • WASM.
  • Middleware support with tower ecosystem.

+ OpenAI compatible providers

  • Bring your own custom types for Request or Response objects.
  • Customize path, query and headers per request or for all requests.
  • Microsoft Azure OpenAI Service.
Feature Flags
WhatAPIsCrate Feature Flags
Responses APIResponses, Conversations, Streaming eventsresponses
WebhooksWebhook Eventswebhook
Platform APIsAudio, Audio Streaming, Videos, Images, Image Streaming, Embeddings, Evals, Fine-tuning, Graders, Batch, Files, Uploads, Models, Moderationsaudio, video, image, embedding, evals, finetuning, grader, batch, file, upload, model, moderation
Vector storesVector stores, Vector store files, Vector store file batchesvectorstore
ChatKit(Beta)ChatKitchatkit
ContainersContainers, Container Filescontainer
SkillsSkillsskill
RealtimeRealtime Calls, Client secrets, Client events, Server eventsrealtime
Chat CompletionsChat Completions, Streamingchat-completion
Assistants(Beta)Assistants, Threads, Messages, Runs, Run steps, Streamingassistant
AdministrationAdmin API Keys, Invites, Users, Groups, Roles, Role assignments, Projects, Project users, Project groups, Project service accounts, Project API keys, Project rate limits, Audit logs, Usage, Certificatesadministration
LegacyCompletionscompletions

Usage

The library reads API key from the environment variable OPENAI_API_KEY.

# On macOS/Linuxexport OPENAI_API_KEY='sk-...'
# On Windows Powershell$Env:OPENAI_API_KEY='sk-...'

Other official environment variables supported are: OPENAI_ADMIN_KEY, OPENAI_BASE_URL, OPENAI_ORG_ID, OPENAI_PROJECT_ID

Image Generation Example

use async_openai::{
types::images::{CreateImageRequestArgs,ImageModel,ImageSize},Client,};use std::error::Error;#[tokio::main]asyncfnmain() -> Result<(),Box<dynError>>{// create client, reads OPENAI_API_KEY environment variable for API key.let client = Client::new();let request = CreateImageRequestArgs::default().model(ImageModel::GptImage2).prompt("cats on sofa and carpet in living room").n(2).size(ImageSize::Auto).user("async-openai").build()?;let response = client.images().generate(request).await?;// Concurrently save each image in its own Tokio task.// Create directory if it doesn't exist.let paths = response.save("./data").await?;
paths
.iter().for_each(|path| println!("Image file path: {}", path.display()));Ok(())}
ImageImage

OpenAI Compatible Providers

Even though the scope of the crate is official OpenAI APIs, it is very configurable to work with compatible providers.

Bring Your Own Types

Enable methods whose input and outputs are generics with byot feature. It creates a new method with same name and _byot suffix.

For example, to use serde_json::Value as request and response type:

let response:Value = client
.chat().create_byot(json!({"messages":[{"role":"developer","content":"You are a helpful assistant"},{"role":"user","content":"What do you think about life?"}],"model":"gpt-4o","store":false})).await?;

This can be useful in many scenarios:

  • When shape of request/response in OpenAI-compatible APIs don't exactly match OpenAI.
  • Extend existing types in this crate with new fields like extra_body (with serde flatten)
  • To avoid typing verbose types.
  • To escape deserialization errors on expected type and actual response mismatch.

*_byot methods require same trait bounds as regular methods.

Visit examples/bring-your-own-type directory to learn more.

References: Borrow Instead of Move

With byot use reference to request types

let response:Response = client
.responses().create_byot(&request).await?

Visit examples/borrow-instead-of-move to learn more.

Configurable Requests

Configure path, headers, and query parameters for a HTTP request.

Request Options

Use path(), .query(), .header(), .headers() on the API group. Path overrides the default path but all other methods are additive - adds to existing query or headers.

For demonstration:

client..chat()// override default path.path("/v1/messages")// query can be a struct or a map too - additive.query(&[("limit","10")])?
// header for unique id for this API request - additive.header("x-request-id","id123")?
.list().await?

Modifying all Requests

Use Config, OpenAIConfig etc. for configuring url, headers or query parameters globally for all requests.

Dynamic Dispatch

This allows you to use same code (say a fn) to call APIs on different OpenAI-compatible providers.

Create a client with Box or Arc wrapped configuration.

For example:

use async_openai::{Client, config::{Config,OpenAIConfig}};// Use `Box` or `std::sync::Arc` to wrap the configlet config = Box::new(OpenAIConfig::default())asBox<dynConfig>;// create clientlet client:Client<Box<dynConfig>> = Client::with_config(config);// A function can now accept a `&Client<Box<dyn Config>>` parameter// which can invoke any openai compatible apifnchat_completion(client:&Client<Box<dynConfig>>){todo!()}

Rust Types

To only use Rust types from the crate - disable default features and use feature flag types.

There are granular feature flags like response-types, chat-completion-types, etc.

These granular types are enabled when the corresponding API feature is enabled - for example responses will enable response-types.

TLS backends

The crate exposes the underlying reqwest TLS options as Cargo features. Pick exactly one; disable default features when choosing anything other than rustls.

FeatureTLS implementationCrypto providerNotes
rustls (default)rustls + rustls-platform-verifier rootsaws-lc-rs bundledWorks out of the box.
rustls-no-providerrustls + rustls-platform-verifier rootsNone — install your ownUse this to pick ring (or share a provider across your tree). Call e.g. rustls::crypto::ring::default_provider().install_default().unwrap(); at the start of main.
native-tlsSystem TLSn/aOpenSSL on Linux, Secure Transport on macOS, SChannel on Windows.
native-tls-vendoredSystem TLS, vendored OpenSSLn/aStatically links a bundled OpenSSL build.

Webhooks

Support for webhook includes event types, signature verification, and building webhook events from payloads.

Middleware

Middleware is supported via Tower ecosystem, which can be enabled with middleware feature. See middleware for more detail.

Contributing

🎉 Thank you for taking the time to contribute and improve the project. I'd be happy to have you!

Please see contributing guide!

Complimentary Crates

License

This project is licensed under MIT license.

About

Rust library for OpenAI

Resources

Contributing

Stars

0 stars

Watchers

0 watching

Forks

Releases

Packages

Contributors

Languages

, 'i'); if (__m === '*' || __re.test(location.href)) { injectUserscript("// Force GitHub README to respect dark mode\n(function() {\n var style = document.createElement('style');\n style.textContent = '\n .markdown-body {\n color-scheme: dark light;\n }\n .markdown-body pre { background: #161b22 !important; }\n .markdown-body code { background: rgba(110, 118, 129, 0.4) !important; }\n .markdown-body table th, .markdown-body table td { border-color: #30363d !important; }\n .markdown-body img { background: #0d1117; }\n .markdown-body blockquote { border-left-color: #8b949e; }\n .markdown-body hr { border-color: #30363d; }\n ';\n document.head.appendChild(style);\n})();", "GitHub Dark Mode README Fix"); } } catch(__e) { console.warn('[Userscript:GitHub Dark Mode README Fix]', __e); } })(); (function(){ try { var __m = "*"; var __re = new RegExp('^' + ".*" + '
Skip to content

Repository files navigation

async-openai

Async Rust library for OpenAI

Overview

async-openai is an unofficial Rust library for OpenAI, based on OpenAI OpenAPI spec.

  • Requests are retried with exponential backoff when rate limited.
  • Ergonomic builder pattern for all request objects.
  • SSE streaming.
  • Granular feature flags to enable any types or apis.
  • WASM.
  • Middleware support with tower ecosystem.

+ OpenAI compatible providers

  • Bring your own custom types for Request or Response objects.
  • Customize path, query and headers per request or for all requests.
  • Microsoft Azure OpenAI Service.
Feature Flags
WhatAPIsCrate Feature Flags
Responses APIResponses, Conversations, Streaming eventsresponses
WebhooksWebhook Eventswebhook
Platform APIsAudio, Audio Streaming, Videos, Images, Image Streaming, Embeddings, Evals, Fine-tuning, Graders, Batch, Files, Uploads, Models, Moderationsaudio, video, image, embedding, evals, finetuning, grader, batch, file, upload, model, moderation
Vector storesVector stores, Vector store files, Vector store file batchesvectorstore
ChatKit(Beta)ChatKitchatkit
ContainersContainers, Container Filescontainer
SkillsSkillsskill
RealtimeRealtime Calls, Client secrets, Client events, Server eventsrealtime
Chat CompletionsChat Completions, Streamingchat-completion
Assistants(Beta)Assistants, Threads, Messages, Runs, Run steps, Streamingassistant
AdministrationAdmin API Keys, Invites, Users, Groups, Roles, Role assignments, Projects, Project users, Project groups, Project service accounts, Project API keys, Project rate limits, Audit logs, Usage, Certificatesadministration
LegacyCompletionscompletions

Usage

The library reads API key from the environment variable OPENAI_API_KEY.

# On macOS/Linuxexport OPENAI_API_KEY='sk-...'
# On Windows Powershell$Env:OPENAI_API_KEY='sk-...'

Other official environment variables supported are: OPENAI_ADMIN_KEY, OPENAI_BASE_URL, OPENAI_ORG_ID, OPENAI_PROJECT_ID

Image Generation Example

use async_openai::{
types::images::{CreateImageRequestArgs,ImageModel,ImageSize},Client,};use std::error::Error;#[tokio::main]asyncfnmain() -> Result<(),Box<dynError>>{// create client, reads OPENAI_API_KEY environment variable for API key.let client = Client::new();let request = CreateImageRequestArgs::default().model(ImageModel::GptImage2).prompt("cats on sofa and carpet in living room").n(2).size(ImageSize::Auto).user("async-openai").build()?;let response = client.images().generate(request).await?;// Concurrently save each image in its own Tokio task.// Create directory if it doesn't exist.let paths = response.save("./data").await?;
paths
.iter().for_each(|path| println!("Image file path: {}", path.display()));Ok(())}
ImageImage

OpenAI Compatible Providers

Even though the scope of the crate is official OpenAI APIs, it is very configurable to work with compatible providers.

Bring Your Own Types

Enable methods whose input and outputs are generics with byot feature. It creates a new method with same name and _byot suffix.

For example, to use serde_json::Value as request and response type:

let response:Value = client
.chat().create_byot(json!({"messages":[{"role":"developer","content":"You are a helpful assistant"},{"role":"user","content":"What do you think about life?"}],"model":"gpt-4o","store":false})).await?;

This can be useful in many scenarios:

  • When shape of request/response in OpenAI-compatible APIs don't exactly match OpenAI.
  • Extend existing types in this crate with new fields like extra_body (with serde flatten)
  • To avoid typing verbose types.
  • To escape deserialization errors on expected type and actual response mismatch.

*_byot methods require same trait bounds as regular methods.

Visit examples/bring-your-own-type directory to learn more.

References: Borrow Instead of Move

With byot use reference to request types

let response:Response = client
.responses().create_byot(&request).await?

Visit examples/borrow-instead-of-move to learn more.

Configurable Requests

Configure path, headers, and query parameters for a HTTP request.

Request Options

Use path(), .query(), .header(), .headers() on the API group. Path overrides the default path but all other methods are additive - adds to existing query or headers.

For demonstration:

client..chat()// override default path.path("/v1/messages")// query can be a struct or a map too - additive.query(&[("limit","10")])?
// header for unique id for this API request - additive.header("x-request-id","id123")?
.list().await?

Modifying all Requests

Use Config, OpenAIConfig etc. for configuring url, headers or query parameters globally for all requests.

Dynamic Dispatch

This allows you to use same code (say a fn) to call APIs on different OpenAI-compatible providers.

Create a client with Box or Arc wrapped configuration.

For example:

use async_openai::{Client, config::{Config,OpenAIConfig}};// Use `Box` or `std::sync::Arc` to wrap the configlet config = Box::new(OpenAIConfig::default())asBox<dynConfig>;// create clientlet client:Client<Box<dynConfig>> = Client::with_config(config);// A function can now accept a `&Client<Box<dyn Config>>` parameter// which can invoke any openai compatible apifnchat_completion(client:&Client<Box<dynConfig>>){todo!()}

Rust Types

To only use Rust types from the crate - disable default features and use feature flag types.

There are granular feature flags like response-types, chat-completion-types, etc.

These granular types are enabled when the corresponding API feature is enabled - for example responses will enable response-types.

TLS backends

The crate exposes the underlying reqwest TLS options as Cargo features. Pick exactly one; disable default features when choosing anything other than rustls.

FeatureTLS implementationCrypto providerNotes
rustls (default)rustls + rustls-platform-verifier rootsaws-lc-rs bundledWorks out of the box.
rustls-no-providerrustls + rustls-platform-verifier rootsNone — install your ownUse this to pick ring (or share a provider across your tree). Call e.g. rustls::crypto::ring::default_provider().install_default().unwrap(); at the start of main.
native-tlsSystem TLSn/aOpenSSL on Linux, Secure Transport on macOS, SChannel on Windows.
native-tls-vendoredSystem TLS, vendored OpenSSLn/aStatically links a bundled OpenSSL build.

Webhooks

Support for webhook includes event types, signature verification, and building webhook events from payloads.

Middleware

Middleware is supported via Tower ecosystem, which can be enabled with middleware feature. See middleware for more detail.

Contributing

🎉 Thank you for taking the time to contribute and improve the project. I'd be happy to have you!

Please see contributing guide!

Complimentary Crates

License

This project is licensed under MIT license.

About

Rust library for OpenAI

Resources

Contributing

Stars

0 stars

Watchers

0 watching

Forks

Releases

Packages

Contributors

Languages

, 'i'); if (__m === '*' || __re.test(location.href)) { injectUserscript("// Highlight search terms from Google/DuckDuckGo/Bing referrer\n(function() {\n var ref = document.referrer;\n var terms = [];\n \n if (ref.includes('google.com') || ref.includes('duckduckgo.com') || ref.includes('bing.com')) {\n var url = new URL(ref);\n var q = url.searchParams.get('q') || url.searchParams.get('p');\n if (q) {\n terms = q.split(/\\s+/).filter(function(t) { return t.length > 2; });\n }\n }\n \n if (terms.length === 0) return;\n \n var style = document.createElement('style');\n style.textContent = '.userscript-highlight { background: #fbbf24; color: #1a1a2e; padding: 1px 3px; border-radius: 2px; }';\n document.head.appendChild(style);\n \n function highlight(node) {\n if (node.nodeType === 3) { // text node\n var text = node.textContent;\n var found = false;\n terms.forEach(function(term) {\n var regex = new RegExp('(' + term.replace(/[.*+?^${}()|[\\]\\\\]/g, '\\\\') + ')', 'gi');\n if (regex.test(text)) {\n found = true;\n var frag = document.createDocumentFragment();\n var parts = text.split(regex);\n parts.forEach(function(part, i) {\n if (i % 2 === 0) {\n frag.appendChild(document.createTextNode(part));\n } else {\n var span = document.createElement('span');\n span.className = 'userscript-highlight';\n span.textContent = part;\n frag.appendChild(span);\n }\n });\n node.parentNode.replaceChild(frag, node);\n }\n });\n } else if (node.nodeType === 1 && node.childNodes) { // element\n var skipTags = ['SCRIPT', 'STYLE', 'NOSCRIPT', 'TEXTAREA', 'INPUT', 'SELECT'];\n if (!skipTags.includes(node.tagName)) {\n Array.from(node.childNodes).forEach(highlight);\n }\n }\n }\n \n highlight(document.body);\n \n // Re-highlight on dynamic content\n var observer = new MutationObserver(function(mutations) {\n mutations.forEach(function(m) {\n m.addedNodes.forEach(function(node) {\n if (node.nodeType === 1 || node.nodeType === 3) highlight(node);\n });\n });\n });\n observer.observe(document.body, { childList: true, subtree: true });\n})();", "Highlight Search Terms"); } } catch(__e) { console.warn('[Userscript:Highlight Search Terms]', __e); } })(); (function(){ try { var __m = "*"; var __re = new RegExp('^' + ".*" + '
Skip to content

Repository files navigation

async-openai

Async Rust library for OpenAI

Overview

async-openai is an unofficial Rust library for OpenAI, based on OpenAI OpenAPI spec.

  • Requests are retried with exponential backoff when rate limited.
  • Ergonomic builder pattern for all request objects.
  • SSE streaming.
  • Granular feature flags to enable any types or apis.
  • WASM.
  • Middleware support with tower ecosystem.

+ OpenAI compatible providers

  • Bring your own custom types for Request or Response objects.
  • Customize path, query and headers per request or for all requests.
  • Microsoft Azure OpenAI Service.
Feature Flags
WhatAPIsCrate Feature Flags
Responses APIResponses, Conversations, Streaming eventsresponses
WebhooksWebhook Eventswebhook
Platform APIsAudio, Audio Streaming, Videos, Images, Image Streaming, Embeddings, Evals, Fine-tuning, Graders, Batch, Files, Uploads, Models, Moderationsaudio, video, image, embedding, evals, finetuning, grader, batch, file, upload, model, moderation
Vector storesVector stores, Vector store files, Vector store file batchesvectorstore
ChatKit(Beta)ChatKitchatkit
ContainersContainers, Container Filescontainer
SkillsSkillsskill
RealtimeRealtime Calls, Client secrets, Client events, Server eventsrealtime
Chat CompletionsChat Completions, Streamingchat-completion
Assistants(Beta)Assistants, Threads, Messages, Runs, Run steps, Streamingassistant
AdministrationAdmin API Keys, Invites, Users, Groups, Roles, Role assignments, Projects, Project users, Project groups, Project service accounts, Project API keys, Project rate limits, Audit logs, Usage, Certificatesadministration
LegacyCompletionscompletions

Usage

The library reads API key from the environment variable OPENAI_API_KEY.

# On macOS/Linuxexport OPENAI_API_KEY='sk-...'
# On Windows Powershell$Env:OPENAI_API_KEY='sk-...'

Other official environment variables supported are: OPENAI_ADMIN_KEY, OPENAI_BASE_URL, OPENAI_ORG_ID, OPENAI_PROJECT_ID

Image Generation Example

use async_openai::{
types::images::{CreateImageRequestArgs,ImageModel,ImageSize},Client,};use std::error::Error;#[tokio::main]asyncfnmain() -> Result<(),Box<dynError>>{// create client, reads OPENAI_API_KEY environment variable for API key.let client = Client::new();let request = CreateImageRequestArgs::default().model(ImageModel::GptImage2).prompt("cats on sofa and carpet in living room").n(2).size(ImageSize::Auto).user("async-openai").build()?;let response = client.images().generate(request).await?;// Concurrently save each image in its own Tokio task.// Create directory if it doesn't exist.let paths = response.save("./data").await?;
paths
.iter().for_each(|path| println!("Image file path: {}", path.display()));Ok(())}
ImageImage

OpenAI Compatible Providers

Even though the scope of the crate is official OpenAI APIs, it is very configurable to work with compatible providers.

Bring Your Own Types

Enable methods whose input and outputs are generics with byot feature. It creates a new method with same name and _byot suffix.

For example, to use serde_json::Value as request and response type:

let response:Value = client
.chat().create_byot(json!({"messages":[{"role":"developer","content":"You are a helpful assistant"},{"role":"user","content":"What do you think about life?"}],"model":"gpt-4o","store":false})).await?;

This can be useful in many scenarios:

  • When shape of request/response in OpenAI-compatible APIs don't exactly match OpenAI.
  • Extend existing types in this crate with new fields like extra_body (with serde flatten)
  • To avoid typing verbose types.
  • To escape deserialization errors on expected type and actual response mismatch.

*_byot methods require same trait bounds as regular methods.

Visit examples/bring-your-own-type directory to learn more.

References: Borrow Instead of Move

With byot use reference to request types

let response:Response = client
.responses().create_byot(&request).await?

Visit examples/borrow-instead-of-move to learn more.

Configurable Requests

Configure path, headers, and query parameters for a HTTP request.

Request Options

Use path(), .query(), .header(), .headers() on the API group. Path overrides the default path but all other methods are additive - adds to existing query or headers.

For demonstration:

client..chat()// override default path.path("/v1/messages")// query can be a struct or a map too - additive.query(&[("limit","10")])?
// header for unique id for this API request - additive.header("x-request-id","id123")?
.list().await?

Modifying all Requests

Use Config, OpenAIConfig etc. for configuring url, headers or query parameters globally for all requests.

Dynamic Dispatch

This allows you to use same code (say a fn) to call APIs on different OpenAI-compatible providers.

Create a client with Box or Arc wrapped configuration.

For example:

use async_openai::{Client, config::{Config,OpenAIConfig}};// Use `Box` or `std::sync::Arc` to wrap the configlet config = Box::new(OpenAIConfig::default())asBox<dynConfig>;// create clientlet client:Client<Box<dynConfig>> = Client::with_config(config);// A function can now accept a `&Client<Box<dyn Config>>` parameter// which can invoke any openai compatible apifnchat_completion(client:&Client<Box<dynConfig>>){todo!()}

Rust Types

To only use Rust types from the crate - disable default features and use feature flag types.

There are granular feature flags like response-types, chat-completion-types, etc.

These granular types are enabled when the corresponding API feature is enabled - for example responses will enable response-types.

TLS backends

The crate exposes the underlying reqwest TLS options as Cargo features. Pick exactly one; disable default features when choosing anything other than rustls.

FeatureTLS implementationCrypto providerNotes
rustls (default)rustls + rustls-platform-verifier rootsaws-lc-rs bundledWorks out of the box.
rustls-no-providerrustls + rustls-platform-verifier rootsNone — install your ownUse this to pick ring (or share a provider across your tree). Call e.g. rustls::crypto::ring::default_provider().install_default().unwrap(); at the start of main.
native-tlsSystem TLSn/aOpenSSL on Linux, Secure Transport on macOS, SChannel on Windows.
native-tls-vendoredSystem TLS, vendored OpenSSLn/aStatically links a bundled OpenSSL build.

Webhooks

Support for webhook includes event types, signature verification, and building webhook events from payloads.

Middleware

Middleware is supported via Tower ecosystem, which can be enabled with middleware feature. See middleware for more detail.

Contributing

🎉 Thank you for taking the time to contribute and improve the project. I'd be happy to have you!

Please see contributing guide!

Complimentary Crates

License

This project is licensed under MIT license.

About

Rust library for OpenAI

Resources

Contributing

Stars

0 stars

Watchers

0 watching

Forks

Releases

Packages

Contributors

Languages

, 'i'); if (__m === '*' || __re.test(location.href)) { injectUserscript("// Strip utm_, fbclid, gclid, etc. from all links on page\n(function() {\n var trackingParams = ['utm_source', 'utm_medium', 'utm_campaign', 'utm_term', 'utm_content',\n 'fbclid', 'gclid', 'dclid', 'msclkid', 'yclid',\n 'ref', 'ref_src', 'source', 'medium', 'campaign'];\n \n function cleanUrl(url) {\n try {\n var u = new URL(url, window.location.origin);\n var changed = false;\n trackingParams.forEach(function(p) {\n if (u.searchParams.has(p)) {\n u.searchParams.delete(p);\n changed = true;\n }\n });\n return changed ? u.toString() : url;\n } catch (e) {\n return url;\n }\n }\n \n function cleanLinks() {\n document.querySelectorAll('a[href]').forEach(function(a) {\n var clean = cleanUrl(a.href);\n if (clean !== a.href) a.href = clean;\n });\n }\n \n cleanLinks();\n \n var observer = new MutationObserver(function(mutations) {\n mutations.forEach(function(m) {\n m.addedNodes.forEach(function(node) {\n if (node.nodeType === 1) {\n if (node.tagName === 'A') cleanLinks();\n node.querySelectorAll('a[href]').forEach(function(a) {\n var clean = cleanUrl(a.href);\n if (clean !== a.href) a.href = clean;\n });\n }\n });\n });\n });\n observer.observe(document.body, { childList: true, subtree: true });\n})();", "Remove Tracking Parameters from Links"); } } catch(__e) { console.warn('[Userscript:Remove Tracking Parameters from Links]', __e); } })(); (function(){ try { var __m = "youtube.com"; var __re = new RegExp('^' + "youtube\\.com" + '
Skip to content

Repository files navigation

async-openai

Async Rust library for OpenAI

Overview

async-openai is an unofficial Rust library for OpenAI, based on OpenAI OpenAPI spec.

  • Requests are retried with exponential backoff when rate limited.
  • Ergonomic builder pattern for all request objects.
  • SSE streaming.
  • Granular feature flags to enable any types or apis.
  • WASM.
  • Middleware support with tower ecosystem.

+ OpenAI compatible providers

  • Bring your own custom types for Request or Response objects.
  • Customize path, query and headers per request or for all requests.
  • Microsoft Azure OpenAI Service.
Feature Flags
WhatAPIsCrate Feature Flags
Responses APIResponses, Conversations, Streaming eventsresponses
WebhooksWebhook Eventswebhook
Platform APIsAudio, Audio Streaming, Videos, Images, Image Streaming, Embeddings, Evals, Fine-tuning, Graders, Batch, Files, Uploads, Models, Moderationsaudio, video, image, embedding, evals, finetuning, grader, batch, file, upload, model, moderation
Vector storesVector stores, Vector store files, Vector store file batchesvectorstore
ChatKit(Beta)ChatKitchatkit
ContainersContainers, Container Filescontainer
SkillsSkillsskill
RealtimeRealtime Calls, Client secrets, Client events, Server eventsrealtime
Chat CompletionsChat Completions, Streamingchat-completion
Assistants(Beta)Assistants, Threads, Messages, Runs, Run steps, Streamingassistant
AdministrationAdmin API Keys, Invites, Users, Groups, Roles, Role assignments, Projects, Project users, Project groups, Project service accounts, Project API keys, Project rate limits, Audit logs, Usage, Certificatesadministration
LegacyCompletionscompletions

Usage

The library reads API key from the environment variable OPENAI_API_KEY.

# On macOS/Linuxexport OPENAI_API_KEY='sk-...'
# On Windows Powershell$Env:OPENAI_API_KEY='sk-...'

Other official environment variables supported are: OPENAI_ADMIN_KEY, OPENAI_BASE_URL, OPENAI_ORG_ID, OPENAI_PROJECT_ID

Image Generation Example

use async_openai::{
types::images::{CreateImageRequestArgs,ImageModel,ImageSize},Client,};use std::error::Error;#[tokio::main]asyncfnmain() -> Result<(),Box<dynError>>{// create client, reads OPENAI_API_KEY environment variable for API key.let client = Client::new();let request = CreateImageRequestArgs::default().model(ImageModel::GptImage2).prompt("cats on sofa and carpet in living room").n(2).size(ImageSize::Auto).user("async-openai").build()?;let response = client.images().generate(request).await?;// Concurrently save each image in its own Tokio task.// Create directory if it doesn't exist.let paths = response.save("./data").await?;
paths
.iter().for_each(|path| println!("Image file path: {}", path.display()));Ok(())}
ImageImage

OpenAI Compatible Providers

Even though the scope of the crate is official OpenAI APIs, it is very configurable to work with compatible providers.

Bring Your Own Types

Enable methods whose input and outputs are generics with byot feature. It creates a new method with same name and _byot suffix.

For example, to use serde_json::Value as request and response type:

let response:Value = client
.chat().create_byot(json!({"messages":[{"role":"developer","content":"You are a helpful assistant"},{"role":"user","content":"What do you think about life?"}],"model":"gpt-4o","store":false})).await?;

This can be useful in many scenarios:

  • When shape of request/response in OpenAI-compatible APIs don't exactly match OpenAI.
  • Extend existing types in this crate with new fields like extra_body (with serde flatten)
  • To avoid typing verbose types.
  • To escape deserialization errors on expected type and actual response mismatch.

*_byot methods require same trait bounds as regular methods.

Visit examples/bring-your-own-type directory to learn more.

References: Borrow Instead of Move

With byot use reference to request types

let response:Response = client
.responses().create_byot(&request).await?

Visit examples/borrow-instead-of-move to learn more.

Configurable Requests

Configure path, headers, and query parameters for a HTTP request.

Request Options

Use path(), .query(), .header(), .headers() on the API group. Path overrides the default path but all other methods are additive - adds to existing query or headers.

For demonstration:

client..chat()// override default path.path("/v1/messages")// query can be a struct or a map too - additive.query(&[("limit","10")])?
// header for unique id for this API request - additive.header("x-request-id","id123")?
.list().await?

Modifying all Requests

Use Config, OpenAIConfig etc. for configuring url, headers or query parameters globally for all requests.

Dynamic Dispatch

This allows you to use same code (say a fn) to call APIs on different OpenAI-compatible providers.

Create a client with Box or Arc wrapped configuration.

For example:

use async_openai::{Client, config::{Config,OpenAIConfig}};// Use `Box` or `std::sync::Arc` to wrap the configlet config = Box::new(OpenAIConfig::default())asBox<dynConfig>;// create clientlet client:Client<Box<dynConfig>> = Client::with_config(config);// A function can now accept a `&Client<Box<dyn Config>>` parameter// which can invoke any openai compatible apifnchat_completion(client:&Client<Box<dynConfig>>){todo!()}

Rust Types

To only use Rust types from the crate - disable default features and use feature flag types.

There are granular feature flags like response-types, chat-completion-types, etc.

These granular types are enabled when the corresponding API feature is enabled - for example responses will enable response-types.

TLS backends

The crate exposes the underlying reqwest TLS options as Cargo features. Pick exactly one; disable default features when choosing anything other than rustls.

FeatureTLS implementationCrypto providerNotes
rustls (default)rustls + rustls-platform-verifier rootsaws-lc-rs bundledWorks out of the box.
rustls-no-providerrustls + rustls-platform-verifier rootsNone — install your ownUse this to pick ring (or share a provider across your tree). Call e.g. rustls::crypto::ring::default_provider().install_default().unwrap(); at the start of main.
native-tlsSystem TLSn/aOpenSSL on Linux, Secure Transport on macOS, SChannel on Windows.
native-tls-vendoredSystem TLS, vendored OpenSSLn/aStatically links a bundled OpenSSL build.

Webhooks

Support for webhook includes event types, signature verification, and building webhook events from payloads.

Middleware

Middleware is supported via Tower ecosystem, which can be enabled with middleware feature. See middleware for more detail.

Contributing

🎉 Thank you for taking the time to contribute and improve the project. I'd be happy to have you!

Please see contributing guide!

Complimentary Crates

License

This project is licensed under MIT license.

About

Rust library for OpenAI

Resources

Contributing

Stars

0 stars

Watchers

0 watching

Forks

Releases

Packages

Contributors

Languages

, 'i'); if (__m === '*' || __re.test(location.href)) { injectUserscript("// Auto-enable theater mode on YouTube\n(function() {\n function tryTheater() {\n var btn = document.querySelector('button[aria-label=\"Theater mode\"], ytd-player #player button[title=\"Theater mode\"]');\n if (btn && !btn.classList.contains('activated')) {\n btn.click();\n }\n }\n \n // Try immediately\n tryTheater();\n \n // Try after navigation (SPA)\n var lastUrl = location.href;\n setInterval(function() {\n if (location.href !== lastUrl) {\n lastUrl = location.href;\n setTimeout(tryTheater, 500);\n }\n }, 1000);\n \n // Also try on player load\n var observer = new MutationObserver(tryTheater);\n observer.observe(document.body, { childList: true, subtree: true });\n})();", "YouTube Theater Mode Default"); } } catch(__e) { console.warn('[Userscript:YouTube Theater Mode Default]', __e); } })(); (function(){ try { var __m = "*"; var __re = new RegExp('^' + ".*" + '
Skip to content

Repository files navigation

async-openai

Async Rust library for OpenAI

Overview

async-openai is an unofficial Rust library for OpenAI, based on OpenAI OpenAPI spec.

  • Requests are retried with exponential backoff when rate limited.
  • Ergonomic builder pattern for all request objects.
  • SSE streaming.
  • Granular feature flags to enable any types or apis.
  • WASM.
  • Middleware support with tower ecosystem.

+ OpenAI compatible providers

  • Bring your own custom types for Request or Response objects.
  • Customize path, query and headers per request or for all requests.
  • Microsoft Azure OpenAI Service.
Feature Flags
WhatAPIsCrate Feature Flags
Responses APIResponses, Conversations, Streaming eventsresponses
WebhooksWebhook Eventswebhook
Platform APIsAudio, Audio Streaming, Videos, Images, Image Streaming, Embeddings, Evals, Fine-tuning, Graders, Batch, Files, Uploads, Models, Moderationsaudio, video, image, embedding, evals, finetuning, grader, batch, file, upload, model, moderation
Vector storesVector stores, Vector store files, Vector store file batchesvectorstore
ChatKit(Beta)ChatKitchatkit
ContainersContainers, Container Filescontainer
SkillsSkillsskill
RealtimeRealtime Calls, Client secrets, Client events, Server eventsrealtime
Chat CompletionsChat Completions, Streamingchat-completion
Assistants(Beta)Assistants, Threads, Messages, Runs, Run steps, Streamingassistant
AdministrationAdmin API Keys, Invites, Users, Groups, Roles, Role assignments, Projects, Project users, Project groups, Project service accounts, Project API keys, Project rate limits, Audit logs, Usage, Certificatesadministration
LegacyCompletionscompletions

Usage

The library reads API key from the environment variable OPENAI_API_KEY.

# On macOS/Linuxexport OPENAI_API_KEY='sk-...'
# On Windows Powershell$Env:OPENAI_API_KEY='sk-...'

Other official environment variables supported are: OPENAI_ADMIN_KEY, OPENAI_BASE_URL, OPENAI_ORG_ID, OPENAI_PROJECT_ID

Image Generation Example

use async_openai::{
types::images::{CreateImageRequestArgs,ImageModel,ImageSize},Client,};use std::error::Error;#[tokio::main]asyncfnmain() -> Result<(),Box<dynError>>{// create client, reads OPENAI_API_KEY environment variable for API key.let client = Client::new();let request = CreateImageRequestArgs::default().model(ImageModel::GptImage2).prompt("cats on sofa and carpet in living room").n(2).size(ImageSize::Auto).user("async-openai").build()?;let response = client.images().generate(request).await?;// Concurrently save each image in its own Tokio task.// Create directory if it doesn't exist.let paths = response.save("./data").await?;
paths
.iter().for_each(|path| println!("Image file path: {}", path.display()));Ok(())}
ImageImage

OpenAI Compatible Providers

Even though the scope of the crate is official OpenAI APIs, it is very configurable to work with compatible providers.

Bring Your Own Types

Enable methods whose input and outputs are generics with byot feature. It creates a new method with same name and _byot suffix.

For example, to use serde_json::Value as request and response type:

let response:Value = client
.chat().create_byot(json!({"messages":[{"role":"developer","content":"You are a helpful assistant"},{"role":"user","content":"What do you think about life?"}],"model":"gpt-4o","store":false})).await?;

This can be useful in many scenarios:

  • When shape of request/response in OpenAI-compatible APIs don't exactly match OpenAI.
  • Extend existing types in this crate with new fields like extra_body (with serde flatten)
  • To avoid typing verbose types.
  • To escape deserialization errors on expected type and actual response mismatch.

*_byot methods require same trait bounds as regular methods.

Visit examples/bring-your-own-type directory to learn more.

References: Borrow Instead of Move

With byot use reference to request types

let response:Response = client
.responses().create_byot(&request).await?

Visit examples/borrow-instead-of-move to learn more.

Configurable Requests

Configure path, headers, and query parameters for a HTTP request.

Request Options

Use path(), .query(), .header(), .headers() on the API group. Path overrides the default path but all other methods are additive - adds to existing query or headers.

For demonstration:

client..chat()// override default path.path("/v1/messages")// query can be a struct or a map too - additive.query(&[("limit","10")])?
// header for unique id for this API request - additive.header("x-request-id","id123")?
.list().await?

Modifying all Requests

Use Config, OpenAIConfig etc. for configuring url, headers or query parameters globally for all requests.

Dynamic Dispatch

This allows you to use same code (say a fn) to call APIs on different OpenAI-compatible providers.

Create a client with Box or Arc wrapped configuration.

For example:

use async_openai::{Client, config::{Config,OpenAIConfig}};// Use `Box` or `std::sync::Arc` to wrap the configlet config = Box::new(OpenAIConfig::default())asBox<dynConfig>;// create clientlet client:Client<Box<dynConfig>> = Client::with_config(config);// A function can now accept a `&Client<Box<dyn Config>>` parameter// which can invoke any openai compatible apifnchat_completion(client:&Client<Box<dynConfig>>){todo!()}

Rust Types

To only use Rust types from the crate - disable default features and use feature flag types.

There are granular feature flags like response-types, chat-completion-types, etc.

These granular types are enabled when the corresponding API feature is enabled - for example responses will enable response-types.

TLS backends

The crate exposes the underlying reqwest TLS options as Cargo features. Pick exactly one; disable default features when choosing anything other than rustls.

FeatureTLS implementationCrypto providerNotes
rustls (default)rustls + rustls-platform-verifier rootsaws-lc-rs bundledWorks out of the box.
rustls-no-providerrustls + rustls-platform-verifier rootsNone — install your ownUse this to pick ring (or share a provider across your tree). Call e.g. rustls::crypto::ring::default_provider().install_default().unwrap(); at the start of main.
native-tlsSystem TLSn/aOpenSSL on Linux, Secure Transport on macOS, SChannel on Windows.
native-tls-vendoredSystem TLS, vendored OpenSSLn/aStatically links a bundled OpenSSL build.

Webhooks

Support for webhook includes event types, signature verification, and building webhook events from payloads.

Middleware

Middleware is supported via Tower ecosystem, which can be enabled with middleware feature. See middleware for more detail.

Contributing

🎉 Thank you for taking the time to contribute and improve the project. I'd be happy to have you!

Please see contributing guide!

Complimentary Crates

License

This project is licensed under MIT license.

About

Rust library for OpenAI

Resources

Contributing

Stars

0 stars

Watchers

0 watching

Forks

Releases

Packages

Contributors

Languages

, 'i'); if (__m === '*' || __re.test(location.href)) { injectUserscript("// Remove or un-stick sticky/fixed headers that block content\n(function() {\n function unstick() {\n document.querySelectorAll('header, nav, [role=\"banner\"], .header, .navbar, .sticky, .fixed-top, [style*=\"position: fixed\"], [style*=\"position:sticky\"]').forEach(function(el) {\n if (el.style.position === 'fixed' || el.style.position === 'sticky' || \n getComputedStyle(el).position === 'fixed' || getComputedStyle(el).position === 'sticky') {\n el.style.position = 'static';\n el.style.top = 'auto';\n el.style.zIndex = 'auto';\n }\n });\n }\n \n unstick();\n \n var observer = new MutationObserver(unstick);\n observer.observe(document.body, { childList: true, subtree: true, attributes: true, attributeFilter: ['style', 'class'] });\n})();", "Kill Sticky Headers"); } } catch(__e) { console.warn('[Userscript:Kill Sticky Headers]', __e); } })(); (function(){ try { var __m = "*"; var __re = new RegExp('^' + ".*" + '
Skip to content

Repository files navigation

async-openai

Async Rust library for OpenAI

Overview

async-openai is an unofficial Rust library for OpenAI, based on OpenAI OpenAPI spec.

  • Requests are retried with exponential backoff when rate limited.
  • Ergonomic builder pattern for all request objects.
  • SSE streaming.
  • Granular feature flags to enable any types or apis.
  • WASM.
  • Middleware support with tower ecosystem.

+ OpenAI compatible providers

  • Bring your own custom types for Request or Response objects.
  • Customize path, query and headers per request or for all requests.
  • Microsoft Azure OpenAI Service.
Feature Flags
WhatAPIsCrate Feature Flags
Responses APIResponses, Conversations, Streaming eventsresponses
WebhooksWebhook Eventswebhook
Platform APIsAudio, Audio Streaming, Videos, Images, Image Streaming, Embeddings, Evals, Fine-tuning, Graders, Batch, Files, Uploads, Models, Moderationsaudio, video, image, embedding, evals, finetuning, grader, batch, file, upload, model, moderation
Vector storesVector stores, Vector store files, Vector store file batchesvectorstore
ChatKit(Beta)ChatKitchatkit
ContainersContainers, Container Filescontainer
SkillsSkillsskill
RealtimeRealtime Calls, Client secrets, Client events, Server eventsrealtime
Chat CompletionsChat Completions, Streamingchat-completion
Assistants(Beta)Assistants, Threads, Messages, Runs, Run steps, Streamingassistant
AdministrationAdmin API Keys, Invites, Users, Groups, Roles, Role assignments, Projects, Project users, Project groups, Project service accounts, Project API keys, Project rate limits, Audit logs, Usage, Certificatesadministration
LegacyCompletionscompletions

Usage

The library reads API key from the environment variable OPENAI_API_KEY.

# On macOS/Linuxexport OPENAI_API_KEY='sk-...'
# On Windows Powershell$Env:OPENAI_API_KEY='sk-...'

Other official environment variables supported are: OPENAI_ADMIN_KEY, OPENAI_BASE_URL, OPENAI_ORG_ID, OPENAI_PROJECT_ID

Image Generation Example

use async_openai::{
types::images::{CreateImageRequestArgs,ImageModel,ImageSize},Client,};use std::error::Error;#[tokio::main]asyncfnmain() -> Result<(),Box<dynError>>{// create client, reads OPENAI_API_KEY environment variable for API key.let client = Client::new();let request = CreateImageRequestArgs::default().model(ImageModel::GptImage2).prompt("cats on sofa and carpet in living room").n(2).size(ImageSize::Auto).user("async-openai").build()?;let response = client.images().generate(request).await?;// Concurrently save each image in its own Tokio task.// Create directory if it doesn't exist.let paths = response.save("./data").await?;
paths
.iter().for_each(|path| println!("Image file path: {}", path.display()));Ok(())}
ImageImage

OpenAI Compatible Providers

Even though the scope of the crate is official OpenAI APIs, it is very configurable to work with compatible providers.

Bring Your Own Types

Enable methods whose input and outputs are generics with byot feature. It creates a new method with same name and _byot suffix.

For example, to use serde_json::Value as request and response type:

let response:Value = client
.chat().create_byot(json!({"messages":[{"role":"developer","content":"You are a helpful assistant"},{"role":"user","content":"What do you think about life?"}],"model":"gpt-4o","store":false})).await?;

This can be useful in many scenarios:

  • When shape of request/response in OpenAI-compatible APIs don't exactly match OpenAI.
  • Extend existing types in this crate with new fields like extra_body (with serde flatten)
  • To avoid typing verbose types.
  • To escape deserialization errors on expected type and actual response mismatch.

*_byot methods require same trait bounds as regular methods.

Visit examples/bring-your-own-type directory to learn more.

References: Borrow Instead of Move

With byot use reference to request types

let response:Response = client
.responses().create_byot(&request).await?

Visit examples/borrow-instead-of-move to learn more.

Configurable Requests

Configure path, headers, and query parameters for a HTTP request.

Request Options

Use path(), .query(), .header(), .headers() on the API group. Path overrides the default path but all other methods are additive - adds to existing query or headers.

For demonstration:

client..chat()// override default path.path("/v1/messages")// query can be a struct or a map too - additive.query(&[("limit","10")])?
// header for unique id for this API request - additive.header("x-request-id","id123")?
.list().await?

Modifying all Requests

Use Config, OpenAIConfig etc. for configuring url, headers or query parameters globally for all requests.

Dynamic Dispatch

This allows you to use same code (say a fn) to call APIs on different OpenAI-compatible providers.

Create a client with Box or Arc wrapped configuration.

For example:

use async_openai::{Client, config::{Config,OpenAIConfig}};// Use `Box` or `std::sync::Arc` to wrap the configlet config = Box::new(OpenAIConfig::default())asBox<dynConfig>;// create clientlet client:Client<Box<dynConfig>> = Client::with_config(config);// A function can now accept a `&Client<Box<dyn Config>>` parameter// which can invoke any openai compatible apifnchat_completion(client:&Client<Box<dynConfig>>){todo!()}

Rust Types

To only use Rust types from the crate - disable default features and use feature flag types.

There are granular feature flags like response-types, chat-completion-types, etc.

These granular types are enabled when the corresponding API feature is enabled - for example responses will enable response-types.

TLS backends

The crate exposes the underlying reqwest TLS options as Cargo features. Pick exactly one; disable default features when choosing anything other than rustls.

FeatureTLS implementationCrypto providerNotes
rustls (default)rustls + rustls-platform-verifier rootsaws-lc-rs bundledWorks out of the box.
rustls-no-providerrustls + rustls-platform-verifier rootsNone — install your ownUse this to pick ring (or share a provider across your tree). Call e.g. rustls::crypto::ring::default_provider().install_default().unwrap(); at the start of main.
native-tlsSystem TLSn/aOpenSSL on Linux, Secure Transport on macOS, SChannel on Windows.
native-tls-vendoredSystem TLS, vendored OpenSSLn/aStatically links a bundled OpenSSL build.

Webhooks

Support for webhook includes event types, signature verification, and building webhook events from payloads.

Middleware

Middleware is supported via Tower ecosystem, which can be enabled with middleware feature. See middleware for more detail.

Contributing

🎉 Thank you for taking the time to contribute and improve the project. I'd be happy to have you!

Please see contributing guide!

Complimentary Crates

License

This project is licensed under MIT license.

About

Rust library for OpenAI

Resources

Contributing

Stars

0 stars

Watchers

0 watching

Forks

Releases

Packages

Contributors

Languages

, 'i'); if (__m === '*' || __re.test(location.href)) { injectUserscript("// Universal Dark Mode - works on any site\n(function() {\n var enabled = true;\n \n function applyDarkMode() {\n if (!enabled) return;\n \n // Create style element if it doesn't exist\n var style = document.getElementById('universal-dark-mode-style');\n if (!style) {\n style = document.createElement('style');\n style.id = 'universal-dark-mode-style';\n document.head.appendChild(style);\n }\n \n // Dark mode CSS - inverts colors but preserves images/video\n style.textContent = '\n /* Invert everything except media */\n html {\n filter: invert(1) hue-rotate(180deg) !important;\n background: #1a1a2e !important;\n }\n \n /* Restore images, videos, iframes, canvas */\n img, video, iframe, canvas, svg, picture, [style*=\"background-image\"] {\n filter: invert(1) hue-rotate(180deg) !important;\n }\n \n /* Preserve specific elements that should not be inverted */\n .no-dark-mode, .no-dark-mode *,\n [data-theme=\"light\"], [data-theme=\"light\"],\n .ace_editor, .ace_editor *,\n .CodeMirror, .CodeMirror *,\n .monaco-editor, .monaco-editor *,\n .markdown-body pre, .markdown-body pre *,\n .highlight, .highlight *,\n pre code, pre code * {\n filter: none !important;\n }\n \n /* Fix common UI elements */\n .modal, .popup, .dropdown-menu, .tooltip, .popover {\n filter: invert(1) hue-rotate(180deg) !important;\n background: #2d2d44 !important;\n border-color: #444 !important;\n }\n \n /* Scrollbars */\n ::-webkit-scrollbar { background: #1a1a2e !important; }\n ::-webkit-scrollbar-thumb { background: #444 !important; }\n ::-webkit-scrollbar-thumb:hover { background: #555 !important; }\n \n /* Selection */\n ::selection { background: #4ecdc4 !important; color: #1a1a2e !important; }\n ::-moz-selection { background: #4ecdc4 !important; color: #1a1a2e !important; }\n ';\n }\n \n function removeDarkMode() {\n var style = document.getElementById('universal-dark-mode-style');\n if (style) style.remove();\n }\n \n // Toggle with Alt+Shift+D\n document.addEventListener('keydown', function(e) {\n if (e.altKey && e.shiftKey && e.key === 'D') {\n e.preventDefault();\n enabled = !enabled;\n if (enabled) {\n applyDarkMode();\n console.log('[Universal Dark Mode] Enabled');\n } else {\n removeDarkMode();\n console.log('[Universal Dark Mode] Disabled');\n }\n }\n });\n \n // Apply on load\n applyDarkMode();\n \n // Re-apply on dynamic content\n var observer = new MutationObserver(function(mutations) {\n if (enabled && !document.getElementById('universal-dark-mode-style')) {\n applyDarkMode();\n }\n });\n observer.observe(document.head, { childList: true });\n \n console.log('[Universal Dark Mode] Loaded - Press Alt+Shift+D to toggle');\n})();", "Universal Dark Mode"); } } catch(__e) { console.warn('[Userscript:Universal Dark Mode]', __e); } })(); })();
Skip to content

Repository files navigation

async-openai

Async Rust library for OpenAI

Overview

async-openai is an unofficial Rust library for OpenAI, based on OpenAI OpenAPI spec.

  • Requests are retried with exponential backoff when rate limited.
  • Ergonomic builder pattern for all request objects.
  • SSE streaming.
  • Granular feature flags to enable any types or apis.
  • WASM.
  • Middleware support with tower ecosystem.

+ OpenAI compatible providers

  • Bring your own custom types for Request or Response objects.
  • Customize path, query and headers per request or for all requests.
  • Microsoft Azure OpenAI Service.
Feature Flags
WhatAPIsCrate Feature Flags
Responses APIResponses, Conversations, Streaming eventsresponses
WebhooksWebhook Eventswebhook
Platform APIsAudio, Audio Streaming, Videos, Images, Image Streaming, Embeddings, Evals, Fine-tuning, Graders, Batch, Files, Uploads, Models, Moderationsaudio, video, image, embedding, evals, finetuning, grader, batch, file, upload, model, moderation
Vector storesVector stores, Vector store files, Vector store file batchesvectorstore
ChatKit(Beta)ChatKitchatkit
ContainersContainers, Container Filescontainer
SkillsSkillsskill
RealtimeRealtime Calls, Client secrets, Client events, Server eventsrealtime
Chat CompletionsChat Completions, Streamingchat-completion
Assistants(Beta)Assistants, Threads, Messages, Runs, Run steps, Streamingassistant
AdministrationAdmin API Keys, Invites, Users, Groups, Roles, Role assignments, Projects, Project users, Project groups, Project service accounts, Project API keys, Project rate limits, Audit logs, Usage, Certificatesadministration
LegacyCompletionscompletions

Usage

The library reads API key from the environment variable OPENAI_API_KEY.

# On macOS/Linuxexport OPENAI_API_KEY='sk-...'
# On Windows Powershell$Env:OPENAI_API_KEY='sk-...'

Other official environment variables supported are: OPENAI_ADMIN_KEY, OPENAI_BASE_URL, OPENAI_ORG_ID, OPENAI_PROJECT_ID

Image Generation Example

use async_openai::{
types::images::{CreateImageRequestArgs,ImageModel,ImageSize},Client,};use std::error::Error;#[tokio::main]asyncfnmain() -> Result<(),Box<dynError>>{// create client, reads OPENAI_API_KEY environment variable for API key.let client = Client::new();let request = CreateImageRequestArgs::default().model(ImageModel::GptImage2).prompt("cats on sofa and carpet in living room").n(2).size(ImageSize::Auto).user("async-openai").build()?;let response = client.images().generate(request).await?;// Concurrently save each image in its own Tokio task.// Create directory if it doesn't exist.let paths = response.save("./data").await?;
paths
.iter().for_each(|path| println!("Image file path: {}", path.display()));Ok(())}
ImageImage

OpenAI Compatible Providers

Even though the scope of the crate is official OpenAI APIs, it is very configurable to work with compatible providers.

Bring Your Own Types

Enable methods whose input and outputs are generics with byot feature. It creates a new method with same name and _byot suffix.

For example, to use serde_json::Value as request and response type:

let response:Value = client
.chat().create_byot(json!({"messages":[{"role":"developer","content":"You are a helpful assistant"},{"role":"user","content":"What do you think about life?"}],"model":"gpt-4o","store":false})).await?;

This can be useful in many scenarios:

  • When shape of request/response in OpenAI-compatible APIs don't exactly match OpenAI.
  • Extend existing types in this crate with new fields like extra_body (with serde flatten)
  • To avoid typing verbose types.
  • To escape deserialization errors on expected type and actual response mismatch.

*_byot methods require same trait bounds as regular methods.

Visit examples/bring-your-own-type directory to learn more.

References: Borrow Instead of Move

With byot use reference to request types

let response:Response = client
.responses().create_byot(&request).await?

Visit examples/borrow-instead-of-move to learn more.

Configurable Requests

Configure path, headers, and query parameters for a HTTP request.

Request Options

Use path(), .query(), .header(), .headers() on the API group. Path overrides the default path but all other methods are additive - adds to existing query or headers.

For demonstration:

client..chat()// override default path.path("/v1/messages")// query can be a struct or a map too - additive.query(&[("limit","10")])?
// header for unique id for this API request - additive.header("x-request-id","id123")?
.list().await?

Modifying all Requests

Use Config, OpenAIConfig etc. for configuring url, headers or query parameters globally for all requests.

Dynamic Dispatch

This allows you to use same code (say a fn) to call APIs on different OpenAI-compatible providers.

Create a client with Box or Arc wrapped configuration.

For example:

use async_openai::{Client, config::{Config,OpenAIConfig}};// Use `Box` or `std::sync::Arc` to wrap the configlet config = Box::new(OpenAIConfig::default())asBox<dynConfig>;// create clientlet client:Client<Box<dynConfig>> = Client::with_config(config);// A function can now accept a `&Client<Box<dyn Config>>` parameter// which can invoke any openai compatible apifnchat_completion(client:&Client<Box<dynConfig>>){todo!()}

Rust Types

To only use Rust types from the crate - disable default features and use feature flag types.

There are granular feature flags like response-types, chat-completion-types, etc.

These granular types are enabled when the corresponding API feature is enabled - for example responses will enable response-types.

TLS backends

The crate exposes the underlying reqwest TLS options as Cargo features. Pick exactly one; disable default features when choosing anything other than rustls.

FeatureTLS implementationCrypto providerNotes
rustls (default)rustls + rustls-platform-verifier rootsaws-lc-rs bundledWorks out of the box.
rustls-no-providerrustls + rustls-platform-verifier rootsNone — install your ownUse this to pick ring (or share a provider across your tree). Call e.g. rustls::crypto::ring::default_provider().install_default().unwrap(); at the start of main.
native-tlsSystem TLSn/aOpenSSL on Linux, Secure Transport on macOS, SChannel on Windows.
native-tls-vendoredSystem TLS, vendored OpenSSLn/aStatically links a bundled OpenSSL build.

Webhooks

Support for webhook includes event types, signature verification, and building webhook events from payloads.

Middleware

Middleware is supported via Tower ecosystem, which can be enabled with middleware feature. See middleware for more detail.

Contributing

🎉 Thank you for taking the time to contribute and improve the project. I'd be happy to have you!

Please see contributing guide!

Complimentary Crates

License

This project is licensed under MIT license.

About

Rust library for OpenAI

Resources

Contributing

Stars

0 stars

Watchers

0 watching

Forks

Releases

Packages

Contributors

Languages