Skip to content

Commit 06baee9

Browse files
64bitifsheldon
authored andcommitted
feat: RequestOptions for individual requests (64bit#476)
* feat: RequestOptions * cargo fmt * cargo clippy fix * make RequestOptions methods as pub(crate) * remove query parameters from individual methods * update tests and examples to use RequestOptionsBuilder trait * cargo fmt * remove query params from all other methods * update examples to use query chain method * cargo clippy fix * cargo fmt * handle query properly * fix bring-your-own-type tests * query parameters for all APIs * updated README * fix example: * cargo fmt * namespaced query param types * fix example * update * fix link * only initialize request options vector when needed (cherry picked from commit 8b33483)
1 parent 4d3f4d2 commit 06baee9

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

91 files changed

+2716
-811
lines changed

.gitignore

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -9,3 +9,5 @@ data
99
*.mp3
1010

1111
.idea
12+
13+
*.py

async-openai/README.md

Lines changed: 5 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -30,15 +30,16 @@ a `x.y.z` version.
3030
| **Realtime** | Realtime Calls, Client secrets, Client events, Server events |
3131
| **Chat Completions** | Chat Completions, Streaming |
3232
| **Assistants** <sub>(Beta)</sub> | Assistants, Threads, Messages, Runs, Run steps, Streaming |
33-
| **Administration** | Administration, Admin API Keys, Invites, Users, Projects, Project users, Project service accounts, Project API keys, Project rate limits, Audit logs, Usage, Certificates |
33+
| **Administration** | Admin API Keys, Invites, Users, Projects, Project users, Project service accounts, Project API keys, Project rate limits, Audit logs, Usage, Certificates |
3434
| **Legacy** | Completions |
3535

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

4344
More on `async-openai-wasm`:
4445
- **WASM support**

async-openai/src/admin_api_keys.rs

Lines changed: 22 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -1,34 +1,34 @@
1-
use serde::Serialize;
2-
31
use crate::{
42
Client,
53
config::Config,
64
error::OpenAIError,
75
types::admin::api_keys::{
86
AdminApiKey, AdminApiKeyDeleteResponse, ApiKeyList, CreateAdminApiKeyRequest,
97
},
8+
Client, RequestOptions,
109
};
1110

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

1919
impl<'c, C: Config> AdminAPIKeys<'c, C> {
2020
pub fn new(client: &'c Client<C>) -> Self {
21-
Self { client }
21+
Self {
22+
client,
23+
request_options: RequestOptions::new(),
24+
}
2225
}
2326

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

@@ -38,23 +38,33 @@ impl<'c, C: Config> AdminAPIKeys<'c, C> {
3838
request: CreateAdminApiKeyRequest,
3939
) -> Result<AdminApiKey, OpenAIError> {
4040
self.client
41-
.post("/organization/admin_api_keys", request)
41+
.post(
42+
"/organization/admin_api_keys",
43+
request,
44+
&self.request_options,
45+
)
4246
.await
4347
}
4448

4549
/// Retrieve a single organization API key.
4650
#[crate::byot(T0 = std::fmt::Display, R = serde::de::DeserializeOwned)]
4751
pub async fn retrieve(&self, key_id: &str) -> Result<AdminApiKey, OpenAIError> {
4852
self.client
49-
.get(format!("/organization/admin_api_keys/{key_id}").as_str())
53+
.get(
54+
format!("/organization/admin_api_keys/{key_id}").as_str(),
55+
&self.request_options,
56+
)
5057
.await
5158
}
5259

5360
/// Delete an organization admin API key.
5461
#[crate::byot(T0 = std::fmt::Display, R = serde::de::DeserializeOwned)]
5562
pub async fn delete(&self, key_id: &str) -> Result<AdminApiKeyDeleteResponse, OpenAIError> {
5663
self.client
57-
.delete(format!("/organization/admin_api_keys/{key_id}").as_str())
64+
.delete(
65+
format!("/organization/admin_api_keys/{key_id}").as_str(),
66+
&self.request_options,
67+
)
5868
.await
5969
}
6070
}

async-openai/src/assistants.rs

Lines changed: 25 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,3 @@
1-
use serde::Serialize;
2-
31
use crate::{
42
Client,
53
config::Config,
@@ -8,18 +6,23 @@ use crate::{
86
AssistantObject, CreateAssistantRequest, DeleteAssistantResponse, ListAssistantsResponse,
97
ModifyAssistantRequest,
108
},
9+
Client, RequestOptions,
1110
};
1211

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

2020
impl<'c, C: Config> Assistants<'c, C> {
2121
pub fn new(client: &'c Client<C>) -> Self {
22-
Self { client }
22+
Self {
23+
client,
24+
request_options: RequestOptions::new(),
25+
}
2326
}
2427

2528
/// Create an assistant with a model and instructions.
@@ -28,14 +31,19 @@ impl<'c, C: Config> Assistants<'c, C> {
2831
&self,
2932
request: CreateAssistantRequest,
3033
) -> Result<AssistantObject, OpenAIError> {
31-
self.client.post("/assistants", request).await
34+
self.client
35+
.post("/assistants", request, &self.request_options)
36+
.await
3237
}
3338

3439
/// Retrieves an assistant.
3540
#[crate::byot(T0 = std::fmt::Display, R = serde::de::DeserializeOwned)]
3641
pub async fn retrieve(&self, assistant_id: &str) -> Result<AssistantObject, OpenAIError> {
3742
self.client
38-
.get(&format!("/assistants/{assistant_id}"))
43+
.get(
44+
&format!("/assistants/{assistant_id}"),
45+
&self.request_options,
46+
)
3947
.await
4048
}
4149

@@ -47,24 +55,28 @@ impl<'c, C: Config> Assistants<'c, C> {
4755
request: ModifyAssistantRequest,
4856
) -> Result<AssistantObject, OpenAIError> {
4957
self.client
50-
.post(&format!("/assistants/{assistant_id}"), request)
58+
.post(
59+
&format!("/assistants/{assistant_id}"),
60+
request,
61+
&self.request_options,
62+
)
5163
.await
5264
}
5365

5466
/// Delete an assistant.
5567
#[crate::byot(T0 = std::fmt::Display, R = serde::de::DeserializeOwned)]
5668
pub async fn delete(&self, assistant_id: &str) -> Result<DeleteAssistantResponse, OpenAIError> {
5769
self.client
58-
.delete(&format!("/assistants/{assistant_id}"))
70+
.delete(
71+
&format!("/assistants/{assistant_id}"),
72+
&self.request_options,
73+
)
5974
.await
6075
}
6176

6277
/// Returns a list of assistants.
63-
#[crate::byot(T0 = serde::Serialize, R = serde::de::DeserializeOwned)]
64-
pub async fn list<Q>(&self, query: &Q) -> Result<ListAssistantsResponse, OpenAIError>
65-
where
66-
Q: Serialize + ?Sized,
67-
{
68-
self.client.get_with_query("/assistants", &query).await
78+
#[crate::byot(R = serde::de::DeserializeOwned)]
79+
pub async fn list(&self) -> Result<ListAssistantsResponse, OpenAIError> {
80+
self.client.get("/assistants", &self.request_options).await
6981
}
7082
}

async-openai/src/audio.rs

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,14 +1,18 @@
1-
use crate::{Client, Speech, Transcriptions, Translations, config::Config};
1+
use crate::{Client, RequestOptions, Speech, Transcriptions, Translations, config::Config};
22

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

910
impl<'c, C: Config> Audio<'c, C> {
1011
pub fn new(client: &'c Client<C>) -> Self {
11-
Self { client }
12+
Self {
13+
client,
14+
request_options: RequestOptions::new(),
15+
}
1216
}
1317

1418
/// APIs in Speech group.

async-openai/src/audit_logs.rs

Lines changed: 10 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -1,29 +1,29 @@
1-
use serde::Serialize;
2-
31
use crate::{
4-
Client, config::Config, error::OpenAIError, types::admin::audit_logs::ListAuditLogsResponse,
2+
config::Config, error::OpenAIError, types::admin::audit_logs::ListAuditLogsResponse, Client,
3+
RequestOptions,
54
};
65

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

1414
impl<'c, C: Config> AuditLogs<'c, C> {
1515
pub fn new(client: &'c Client<C>) -> Self {
16-
Self { client }
16+
Self {
17+
client,
18+
request_options: RequestOptions::new(),
19+
}
1720
}
1821

1922
/// List user actions and configuration changes within this organization.
20-
#[crate::byot(T0 = serde::Serialize, R = serde::de::DeserializeOwned)]
21-
pub async fn get<Q>(&self, query: &Q) -> Result<ListAuditLogsResponse, OpenAIError>
22-
where
23-
Q: Serialize + ?Sized,
24-
{
23+
#[crate::byot(R = serde::de::DeserializeOwned)]
24+
pub async fn get(&self) -> Result<ListAuditLogsResponse, OpenAIError> {
2525
self.client
26-
.get_with_query("/organization/audit_logs", &query)
26+
.get("/organization/audit_logs", &self.request_options)
2727
.await
2828
}
2929
}

async-openai/src/batches.rs

Lines changed: 16 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -1,43 +1,47 @@
1-
use serde::Serialize;
2-
31
use crate::{
42
Client,
53
config::Config,
64
error::OpenAIError,
75
types::batches::{Batch, BatchRequest, ListBatchesResponse},
6+
Client, RequestOptions,
87
};
98

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

1717
impl<'c, C: Config> Batches<'c, C> {
1818
pub fn new(client: &'c Client<C>) -> Self {
19-
Self { client }
19+
Self {
20+
client,
21+
request_options: RequestOptions::new(),
22+
}
2023
}
2124

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

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

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

4347
/// 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.
@@ -47,6 +51,7 @@ impl<'c, C: Config> Batches<'c, C> {
4751
.post(
4852
&format!("/batches/{batch_id}/cancel"),
4953
serde_json::json!({}),
54+
&self.request_options,
5055
)
5156
.await
5257
}

0 commit comments

Comments
 (0)