Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 2 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -7,3 +7,5 @@ Cargo.lock
data

*.mp3

*.py
2 changes: 2 additions & 0 deletions async-openai/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -50,6 +50,8 @@ derive_builder = "0.20.2"
secrecy = { version = "0.10.3", features = ["serde"] }
bytes = "1.9.0"
eventsource-stream = "0.2.3"
serde_urlencoded = "0.7.1"
url = "2.5"
tokio-tungstenite = { version = "0.26.1", optional = true, default-features = false }
hmac = { version = "0.12", optional = true, default-features = false}
sha2 = { version = "0.10", optional = true, default-features = false }
Expand Down
9 changes: 5 additions & 4 deletions async-openai/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@
</a>
</div>
<div align="center">
<sub>Logo created by this <a href="https://github.com/64bit/async-openai/tree/main/examples/create-image-b64-json">repo itself</a></sub>
<sub>Logo created by this <a href="https://github.com/64bit/async-openai/tree/main/examples/image-generate-b64-json">repo itself</a></sub>
</div>

## Overview
Expand All @@ -32,15 +32,16 @@
| **Realtime** | Realtime Calls, Client secrets, Client events, Server events |
| **Chat Completions** | Chat Completions, Streaming |
| **Assistants** <sub>(Beta)</sub> | Assistants, Threads, Messages, Runs, Run steps, Streaming |
| **Administration** | Administration, Admin API Keys, Invites, Users, Projects, Project users, Project service accounts, Project API keys, Project rate limits, Audit logs, Usage, Certificates |
| **Administration** | Admin API Keys, Invites, Users, Projects, Project users, Project service accounts, Project API keys, Project rate limits, Audit logs, Usage, Certificates |
| **Legacy** | Completions |

Features that makes `async-openai` unique:
- Bring your own custom types for Request or Response objects.
- SSE streaming on available APIs
- SSE streaming on available APIs.
- Customize query and headers per request, customize headers globally.
- Requests (except SSE streaming) including form submissions are retried with exponential backoff when [rate limited](https://platform.openai.com/docs/guides/rate-limits).
- Ergonomic builder pattern for all request objects.
- Microsoft Azure OpenAI Service (only for APIs matching OpenAI spec)
- Microsoft Azure OpenAI Service (only for APIs matching OpenAI spec).

## Usage

Expand Down
35 changes: 22 additions & 13 deletions async-openai/src/admin_api_keys.rs
Original file line number Diff line number Diff line change
@@ -1,34 +1,33 @@
use serde::Serialize;

use crate::{
config::Config,
error::OpenAIError,
types::admin::api_keys::{
AdminApiKey, AdminApiKeyDeleteResponse, ApiKeyList, CreateAdminApiKeyRequest,
},
Client,
Client, RequestOptions,
};

/// Admin API keys enable Organization Owners to programmatically manage various aspects of their
/// organization, including users, projects, and API keys. These keys provide administrative capabilities,
/// allowing you to automate organization management tasks.
pub struct AdminAPIKeys<'c, C: Config> {
client: &'c Client<C>,
pub(crate) request_options: RequestOptions,
}

impl<'c, C: Config> AdminAPIKeys<'c, C> {
pub fn new(client: &'c Client<C>) -> Self {
Self { client }
Self {
client,
request_options: RequestOptions::new(),
}
}

/// List all organization and project API keys.
#[crate::byot(T0 = serde::Serialize, R = serde::de::DeserializeOwned)]
pub async fn list<Q>(&self, query: &Q) -> Result<ApiKeyList, OpenAIError>
where
Q: Serialize + ?Sized,
{
#[crate::byot(R = serde::de::DeserializeOwned)]
pub async fn list(&self) -> Result<ApiKeyList, OpenAIError> {
self.client
.get_with_query("/organization/admin_api_keys", &query)
.get("/organization/admin_api_keys", &self.request_options)
.await
}

Expand All @@ -38,23 +37,33 @@ impl<'c, C: Config> AdminAPIKeys<'c, C> {
request: CreateAdminApiKeyRequest,
) -> Result<AdminApiKey, OpenAIError> {
self.client
.post("/organization/admin_api_keys", request)
.post(
"/organization/admin_api_keys",
request,
&self.request_options,
)
.await
}

/// Retrieve a single organization API key.
#[crate::byot(T0 = std::fmt::Display, R = serde::de::DeserializeOwned)]
pub async fn retrieve(&self, key_id: &str) -> Result<AdminApiKey, OpenAIError> {
self.client
.get(format!("/organization/admin_api_keys/{key_id}").as_str())
.get(
format!("/organization/admin_api_keys/{key_id}").as_str(),
&self.request_options,
)
.await
}

/// Delete an organization admin API key.
#[crate::byot(T0 = std::fmt::Display, R = serde::de::DeserializeOwned)]
pub async fn delete(&self, key_id: &str) -> Result<AdminApiKeyDeleteResponse, OpenAIError> {
self.client
.delete(format!("/organization/admin_api_keys/{key_id}").as_str())
.delete(
format!("/organization/admin_api_keys/{key_id}").as_str(),
&self.request_options,
)
.await
}
}
39 changes: 25 additions & 14 deletions async-openai/src/assistants.rs
Original file line number Diff line number Diff line change
@@ -1,25 +1,27 @@
use serde::Serialize;

use crate::{
config::Config,
error::OpenAIError,
types::assistants::{
AssistantObject, CreateAssistantRequest, DeleteAssistantResponse, ListAssistantsResponse,
ModifyAssistantRequest,
},
Client,
Client, RequestOptions,
};

/// Build assistants that can call models and use tools to perform tasks.
///
/// [Get started with the Assistants API](https://platform.openai.com/docs/assistants)
pub struct Assistants<'c, C: Config> {
client: &'c Client<C>,
pub(crate) request_options: RequestOptions,
}

impl<'c, C: Config> Assistants<'c, C> {
pub fn new(client: &'c Client<C>) -> Self {
Self { client }
Self {
client,
request_options: RequestOptions::new(),
}
}

/// Create an assistant with a model and instructions.
Expand All @@ -28,14 +30,19 @@ impl<'c, C: Config> Assistants<'c, C> {
&self,
request: CreateAssistantRequest,
) -> Result<AssistantObject, OpenAIError> {
self.client.post("/assistants", request).await
self.client
.post("/assistants", request, &self.request_options)
.await
}

/// Retrieves an assistant.
#[crate::byot(T0 = std::fmt::Display, R = serde::de::DeserializeOwned)]
pub async fn retrieve(&self, assistant_id: &str) -> Result<AssistantObject, OpenAIError> {
self.client
.get(&format!("/assistants/{assistant_id}"))
.get(
&format!("/assistants/{assistant_id}"),
&self.request_options,
)
.await
}

Expand All @@ -47,24 +54,28 @@ impl<'c, C: Config> Assistants<'c, C> {
request: ModifyAssistantRequest,
) -> Result<AssistantObject, OpenAIError> {
self.client
.post(&format!("/assistants/{assistant_id}"), request)
.post(
&format!("/assistants/{assistant_id}"),
request,
&self.request_options,
)
.await
}

/// Delete an assistant.
#[crate::byot(T0 = std::fmt::Display, R = serde::de::DeserializeOwned)]
pub async fn delete(&self, assistant_id: &str) -> Result<DeleteAssistantResponse, OpenAIError> {
self.client
.delete(&format!("/assistants/{assistant_id}"))
.delete(
&format!("/assistants/{assistant_id}"),
&self.request_options,
)
.await
}

/// Returns a list of assistants.
#[crate::byot(T0 = serde::Serialize, R = serde::de::DeserializeOwned)]
pub async fn list<Q>(&self, query: &Q) -> Result<ListAssistantsResponse, OpenAIError>
where
Q: Serialize + ?Sized,
{
self.client.get_with_query("/assistants", &query).await
#[crate::byot(R = serde::de::DeserializeOwned)]
pub async fn list(&self) -> Result<ListAssistantsResponse, OpenAIError> {
self.client.get("/assistants", &self.request_options).await
}
}
8 changes: 6 additions & 2 deletions async-openai/src/audio.rs
Original file line number Diff line number Diff line change
@@ -1,14 +1,18 @@
use crate::{config::Config, Client, Speech, Transcriptions, Translations};
use crate::{config::Config, Client, RequestOptions, Speech, Transcriptions, Translations};

/// Turn audio into text or text into audio.
/// Related guide: [Speech to text](https://platform.openai.com/docs/guides/speech-to-text)
pub struct Audio<'c, C: Config> {
client: &'c Client<C>,
pub(crate) request_options: RequestOptions,
}

impl<'c, C: Config> Audio<'c, C> {
pub fn new(client: &'c Client<C>) -> Self {
Self { client }
Self {
client,
request_options: RequestOptions::new(),
}
}

/// APIs in Speech group.
Expand Down
18 changes: 9 additions & 9 deletions async-openai/src/audit_logs.rs
Original file line number Diff line number Diff line change
@@ -1,29 +1,29 @@
use serde::Serialize;

use crate::{
config::Config, error::OpenAIError, types::admin::audit_logs::ListAuditLogsResponse, Client,
RequestOptions,
};

/// Logs of user actions and configuration changes within this organization.
/// To log events, you must activate logging in the [Organization Settings](https://platform.openai.com/settings/organization/general).
/// Once activated, for security reasons, logging cannot be deactivated.
pub struct AuditLogs<'c, C: Config> {
client: &'c Client<C>,
pub(crate) request_options: RequestOptions,
}

impl<'c, C: Config> AuditLogs<'c, C> {
pub fn new(client: &'c Client<C>) -> Self {
Self { client }
Self {
client,
request_options: RequestOptions::new(),
}
}

/// List user actions and configuration changes within this organization.
#[crate::byot(T0 = serde::Serialize, R = serde::de::DeserializeOwned)]
pub async fn get<Q>(&self, query: &Q) -> Result<ListAuditLogsResponse, OpenAIError>
where
Q: Serialize + ?Sized,
{
#[crate::byot(R = serde::de::DeserializeOwned)]
pub async fn get(&self) -> Result<ListAuditLogsResponse, OpenAIError> {
self.client
.get_with_query("/organization/audit_logs", &query)
.get("/organization/audit_logs", &self.request_options)
.await
}
}
28 changes: 16 additions & 12 deletions async-openai/src/batches.rs
Original file line number Diff line number Diff line change
@@ -1,43 +1,46 @@
use serde::Serialize;

use crate::{
config::Config,
error::OpenAIError,
types::batches::{Batch, BatchRequest, ListBatchesResponse},
Client,
Client, RequestOptions,
};

/// Create large batches of API requests for asynchronous processing. The Batch API returns completions within 24 hours for a 50% discount.
///
/// Related guide: [Batch](https://platform.openai.com/docs/guides/batch)
pub struct Batches<'c, C: Config> {
client: &'c Client<C>,
pub(crate) request_options: RequestOptions,
}

impl<'c, C: Config> Batches<'c, C> {
pub fn new(client: &'c Client<C>) -> Self {
Self { client }
Self {
client,
request_options: RequestOptions::new(),
}
}

/// Creates and executes a batch from an uploaded file of requests
#[crate::byot(T0 = serde::Serialize, R = serde::de::DeserializeOwned)]
pub async fn create(&self, request: BatchRequest) -> Result<Batch, OpenAIError> {
self.client.post("/batches", request).await
self.client
.post("/batches", request, &self.request_options)
.await
}

/// List your organization's batches.
#[crate::byot(T0 = serde::Serialize, R = serde::de::DeserializeOwned)]
pub async fn list<Q>(&self, query: &Q) -> Result<ListBatchesResponse, OpenAIError>
where
Q: Serialize + ?Sized,
{
self.client.get_with_query("/batches", &query).await
#[crate::byot(R = serde::de::DeserializeOwned)]
pub async fn list(&self) -> Result<ListBatchesResponse, OpenAIError> {
self.client.get("/batches", &self.request_options).await
}

/// Retrieves a batch.
#[crate::byot(T0 = std::fmt::Display, R = serde::de::DeserializeOwned)]
pub async fn retrieve(&self, batch_id: &str) -> Result<Batch, OpenAIError> {
self.client.get(&format!("/batches/{batch_id}")).await
self.client
.get(&format!("/batches/{batch_id}"), &self.request_options)
.await
}

/// Cancels an in-progress batch. The batch will be in status `cancelling` for up to 10 minutes, before changing to `cancelled`, where it will have partial results (if any) available in the output file.
Expand All @@ -47,6 +50,7 @@ impl<'c, C: Config> Batches<'c, C> {
.post(
&format!("/batches/{batch_id}/cancel"),
serde_json::json!({}),
&self.request_options,
)
.await
}
Expand Down
Loading
Loading