Skip to content

Commit 54134ba

Browse files
64bitifsheldon
authored andcommitted
feat: docs + dependency updates (64bit#494)
* full feature flag * github action full feature flag * fix docs warnings * expanded types for docs.rs * types docs * updated README * add docs on scope * add CONTRIBUTING.md * 🎉 * updated readm * doc comment * updated lib.rs for docs.rs * updated doc tests in lib.rs * cleanup * update feature flags * borrow-instead-of-move example * updated example * References in README * Using References * simplify cargo.toml * dependency version to allow patch or minor updates * allow minor or patch updates in example dependencies * add language to code blocks in README for syntax colors * unittests: add missing feature flags in all mod tests {} * fix feature flags required for tests * update embedding tests to use latest small model * fix ser_de test * fix vector_store_files tests * fix assistants examples to include required beta header * fix example responses-images-and-vision * fix responses-structured-outputs example * fix for video-types (cherry picked from commit bcf808a)
1 parent 3af9504 commit 54134ba

File tree

30 files changed

+353
-130
lines changed

30 files changed

+353
-130
lines changed

CONTRIBUTING.md

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,18 @@
1+
## Contributing to async-openai
2+
3+
Thank you for taking the time to contribute and improve the project. I'd be happy to have you!
4+
5+
All forms of contributions, such as new features requests, bug fixes, issues, documentation, testing, comments, [examples](https://github.com/64bit/async-openai/tree/main/examples) etc. are welcome.
6+
7+
A good starting point would be to look at existing [open issues](https://github.com/64bit/async-openai/issues).
8+
9+
To maintain quality of the project, a minimum of the following is a must for code contribution:
10+
11+
- **Names & Documentation**: All struct names, field names and doc comments are from OpenAPI spec. Nested objects in spec without names leaves room for making appropriate name.
12+
- **Tested**: For changes supporting test(s) and/or example is required. Existing examples, doc tests, unit tests, and integration tests should be made to work with the changes if applicable.
13+
- **Scope**: Keep scope limited to APIs available in official documents such as [API Reference](https://platform.openai.com/docs/api-reference) or [OpenAPI spec](https://github.com/openai/openai-openapi/). Other LLMs or AI Providers offer OpenAI-compatible APIs, yet they may not always have full parity - for those use `byot` feature.
14+
- **Consistency**: Keep code style consistent across all the "APIs" that library exposes; it creates a great developer experience.
15+
16+
This project adheres to [Rust Code of Conduct](https://www.rust-lang.org/policies/code-of-conduct)
17+
18+
Unless you explicitly state otherwise, any contribution intentionally submitted for inclusion in async-openai by you, shall be licensed as MIT, without any additional terms or conditions.

async-openai/Cargo.toml

Lines changed: 48 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -16,15 +16,15 @@ homepage = "https://github.com/ifsheldon/async-openai-wasm"
1616
repository = "https://github.com/ifsheldon/async-openai-wasm"
1717

1818
[features]
19-
default = []
19+
default = ["rustls"]
2020
# Enable rustls for TLS support
21-
rustls = ["_api", "dep:reqwest", "reqwest/rustls-tls-native-roots"]
21+
rustls = ["dep:reqwest", "reqwest/rustls-tls-native-roots"]
2222
# Enable rustls and webpki-roots
23-
rustls-webpki-roots = ["_api", "dep:reqwest", "reqwest/rustls-tls-webpki-roots"]
23+
rustls-webpki-roots = ["dep:reqwest", "reqwest/rustls-tls-webpki-roots"]
2424
# Enable native-tls for TLS support
25-
native-tls = ["_api","dep:reqwest", "reqwest/native-tls"]
25+
native-tls = ["dep:reqwest", "reqwest/native-tls"]
2626
# Remove dependency on OpenSSL
27-
native-tls-vendored = ["_api", "dep:reqwest", "reqwest/native-tls-vendored"]
27+
native-tls-vendored = ["dep:reqwest", "reqwest/native-tls-vendored"]
2828
# Bring your own types
2929
byot = ["dep:async-openai-macros"]
3030

@@ -104,6 +104,33 @@ types = [
104104
"completion-types",
105105
]
106106

107+
# Enable all features
108+
full = [
109+
"responses",
110+
"webhook",
111+
"audio",
112+
"video",
113+
"image",
114+
"embedding",
115+
"evals",
116+
"finetuning",
117+
"batch",
118+
"file",
119+
"upload",
120+
"model",
121+
"moderation",
122+
"vectorstore",
123+
"chatkit",
124+
"container",
125+
"realtime",
126+
"chat-completion",
127+
"assistant",
128+
"administration",
129+
"completions",
130+
"types",
131+
"byot",
132+
]
133+
107134
# Internal feature to enable API dependencies
108135
_api = [
109136
"dep:async-openai-macros",
@@ -125,27 +152,27 @@ _api = [
125152

126153
[dependencies]
127154
# Core dependencies - always needed for types
128-
serde = { version = "1.0", features = ["derive", "rc"] }
129-
serde_json = "1.0"
130-
derive_builder = { version = "0.20.2", optional = true }
131-
bytes = { version = "1.9.0", optional = true }
155+
serde = { version = "1", features = ["derive", "rc"] }
156+
serde_json = "1"
157+
derive_builder = { version = "0.20", optional = true }
158+
bytes = { version = "1.11", optional = true }
132159

133160
# API dependencies - only needed when API features are enabled
134161
# We use a feature gate to enable these when any API feature is enabled
135162
async-openai-macros = { path = "../async-openai-macros", version = "0.1.0", optional = true }
136-
base64 = { version = "0.22.1", optional = true }
137-
futures = { version = "0.3.31", optional = true }
138-
reqwest = { version = "0.12.12", features = [
163+
base64 = { version = "0.22", optional = true }
164+
futures = { version = "0.3", optional = true }
165+
reqwest = { version = "0.12", features = [
139166
"json",
140167
"stream",
141168
"multipart",
142169
], default-features = false, optional = true }
143170
reqwest-eventsource = { version = "0.6.0", optional = true }
144-
thiserror = { version = "2.0.11", optional = true }
145-
tracing = { version = "0.1.41", optional = true }
146-
secrecy = { version = "0.10.3", features = ["serde"], optional = true }
147-
eventsource-stream = { version = "0.2.3", optional = true }
148-
serde_urlencoded = { version = "0.7.1", optional = true }
171+
thiserror = { version = "2.0", optional = true }
172+
tracing = { version = "0.1", optional = true }
173+
secrecy = { version = "0.10", features = ["serde"], optional = true }
174+
eventsource-stream = { version = "0.2", optional = true }
175+
serde_urlencoded = { version = "0.7", optional = true }
149176
url = { version = "2.5", optional = true }
150177
pin-project = { version= "1.1", optional = true }
151178
# For Webhook signature verification
@@ -155,7 +182,7 @@ hex = { version = "0.4", optional = true, default-features = false }
155182

156183

157184
[target.'cfg(target_arch = "wasm32")'.dependencies]
158-
rand = { version = "0.9.0", optional = true }
185+
rand = { version = "0.9", optional = true }
159186
getrandom = { version = "0.3", features = ["wasm_js"]}
160187

161188

@@ -166,23 +193,23 @@ serde_json = "1.0"
166193

167194
[[test]]
168195
name = "bring_your_own_type"
169-
required-features = ["byot", "file", "assistant", "model", "moderation", "image", "chat-completion", "completions", "audio", "embedding", "finetuning", "batch", "administration", "upload", "vectorstore", "responses", "chatkit", "container", "evals", "video"]
196+
required-features = ["full"]
170197

171198
[[test]]
172199
name = "chat_completion"
173200
required-features = ["chat-completion-types"]
174201

175202
[[test]]
176203
name = "embeddings"
177-
required-features = ["embedding-types", "chat-completion-types"]
204+
required-features = ["embedding-types"]
178205

179206
[[test]]
180207
name = "ser_de"
181208
required-features = ["chat-completion-types"]
182209

183210
[[test]]
184211
name = "whisper"
185-
required-features = ["audio", "file-types"]
212+
required-features = ["audio"]
186213

187214
[package.metadata.docs.rs]
188215
all-features = true

async-openai/README.md

Lines changed: 43 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -132,7 +132,7 @@ async fn main() -> Result<(), Box<dyn Error>> {
132132

133133
## Webhooks
134134

135-
Support for webhook event types, signature verification, and building webhook events from payloads can be enabled by using the `webhook` feature flag.
135+
Support for webhook includes event types, signature verification, and building webhook events from payloads.
136136

137137
## Bring Your Own Types
138138

@@ -172,26 +172,62 @@ This can be useful in many scenarios:
172172
Visit [examples/bring-your-own-type](https://github.com/64bit/async-openai/tree/main/examples/bring-your-own-type)
173173
directory to learn more.
174174

175+
### References: Borrow Instead of Move
176+
177+
With `byot` use reference to request types
178+
179+
```rust
180+
let response: Response = client
181+
.responses()
182+
.create_byot(&request).await?
183+
```
184+
185+
Visit [examples/borrow-instead-of-move](https://github.com/64bit/async-openai/tree/main/examples/borrow-instead-of-move) to learn more.
186+
187+
175188
## Rust Types
176189

177-
To only use Rust types from the crate - use feature flag `types`.
190+
To only use Rust types from the crate - disable default features and use feature flag `types`.
178191

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

194+
These granular types are enabled when the corresponding API feature is enabled - for example `response` will enable `response-types`.
195+
196+
## Configurable Requests
197+
198+
### Individual Request
199+
Certain individual APIs that need additional query or header parameters - these can be provided by chaining `.query()`, `.header()`, `.headers()` on the API group.
200+
201+
For example:
202+
```rust
203+
client.
204+
.chat()
205+
// query can be a struct or a map too.
206+
.query(&[("limit", "10")])?
207+
// header for demo
208+
.header("key", "value")?
209+
.list()
210+
.await?
211+
```
212+
213+
### All Requests
214+
215+
Use `Config`, `OpenAIConfig` etc. for configuring url, headers or query parameters globally for all requests.
216+
181217
## OpenAI-compatible Providers
182218

183-
### Configurable Request
219+
Even though the scope of the crate is official OpenAI APIs, it is very configurable to work with compatible providers.
220+
221+
### Configurable Path
184222

185-
To change path, query or headers of individual request use the `.path()`, `.query()`, `.header()`, `.headers()` method on the API group.
223+
In addition to `.query()`, `.header()`, `.headers()` a path for individual request can be changed by using `.path()`, method on the API group.
186224

187225
For example:
188226

189-
```
227+
```rust
190228
client
191229
.chat()
192230
.path("/v1/messages")?
193-
.query(&[("role", "user")])?
194-
.header("key", "value")?
195231
.create(request)
196232
.await?
197233
```
@@ -225,9 +261,6 @@ fn chat_completion(client: &Client<Box<dyn Config>>) {
225261
This repo will only accept issues and PRs related to WASM support. For other issues and PRs, please visit the original
226262
project [async-openai](https://github.com/64bit/async-openai).
227263

228-
This project adheres to [Rust Code of Conduct](https://www.rust-lang.org/policies/code-of-conduct)
229-
230-
Unless you explicitly state otherwise, any contribution intentionally submitted for inclusion in async-openai by you, shall be licensed as MIT, without any additional terms or conditions.
231264

232265
## Why `async-openai-wasm`
233266

async-openai/src/assistants/threads.rs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -24,12 +24,12 @@ impl<'c, C: Config> Threads<'c, C> {
2424
}
2525
}
2626

27-
/// Call [Messages] group API to manage message in [thread_id] thread.
27+
/// Call [Messages] group API to manage message in `thread_id` thread.
2828
pub fn messages(&self, thread_id: &str) -> Messages<'_, C> {
2929
Messages::new(self.client, thread_id)
3030
}
3131

32-
/// Call [Runs] group API to manage runs in [thread_id] thread.
32+
/// Call [Runs] group API to manage runs in `thread_id` thread.
3333
pub fn runs(&self, thread_id: &str) -> Runs<'_, C> {
3434
Runs::new(self.client, thread_id)
3535
}

async-openai/src/embedding.rs

Lines changed: 8 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -72,7 +72,7 @@ impl<'c, C: Config> Embeddings<'c, C> {
7272
}
7373
}
7474

75-
#[cfg(test)]
75+
#[cfg(all(test, feature = "embedding"))]
7676
mod tests {
7777
use crate::types::embeddings::{CreateEmbeddingResponse, Embedding, EncodingFormat};
7878
use crate::{Client, types::embeddings::CreateEmbeddingRequestArgs};
@@ -82,7 +82,7 @@ mod tests {
8282
let client = Client::new();
8383

8484
let request = CreateEmbeddingRequestArgs::default()
85-
.model("text-embedding-ada-002")
85+
.model("text-embedding-3-small")
8686
.input("The food was delicious and the waiter...")
8787
.build()
8888
.unwrap();
@@ -97,7 +97,7 @@ mod tests {
9797
let client = Client::new();
9898

9999
let request = CreateEmbeddingRequestArgs::default()
100-
.model("text-embedding-ada-002")
100+
.model("text-embedding-3-small")
101101
.input(["The food was delicious", "The waiter was good"])
102102
.build()
103103
.unwrap();
@@ -112,7 +112,7 @@ mod tests {
112112
let client = Client::new();
113113

114114
let request = CreateEmbeddingRequestArgs::default()
115-
.model("text-embedding-ada-002")
115+
.model("text-embedding-3-small")
116116
.input([1, 2, 3])
117117
.build()
118118
.unwrap();
@@ -127,7 +127,7 @@ mod tests {
127127
let client = Client::new();
128128

129129
let request = CreateEmbeddingRequestArgs::default()
130-
.model("text-embedding-ada-002")
130+
.model("text-embedding-3-small")
131131
.input([[1, 2, 3], [4, 5, 6], [7, 8, 10]])
132132
.build()
133133
.unwrap();
@@ -142,7 +142,7 @@ mod tests {
142142
let client = Client::new();
143143

144144
let request = CreateEmbeddingRequestArgs::default()
145-
.model("text-embedding-ada-002")
145+
.model("text-embedding-3-small")
146146
.input([vec![1, 2, 3], vec![4, 5, 6, 7], vec![7, 8, 10, 11, 100257]])
147147
.build()
148148
.unwrap();
@@ -178,7 +178,7 @@ mod tests {
178178
use crate::error::OpenAIError;
179179
let client = Client::new();
180180

181-
const MODEL: &str = "text-embedding-ada-002";
181+
const MODEL: &str = "text-embedding-3-small";
182182
const INPUT: &str = "You shall not pass.";
183183

184184
let b64_request = CreateEmbeddingRequestArgs::default()
@@ -195,7 +195,7 @@ mod tests {
195195
async fn test_embedding_create_base64() {
196196
let client = Client::new();
197197

198-
const MODEL: &str = "text-embedding-ada-002";
198+
const MODEL: &str = "text-embedding-3-small";
199199
const INPUT: &str = "a head full of dreams";
200200

201201
let b64_request = CreateEmbeddingRequestArgs::default()
@@ -221,8 +221,5 @@ mod tests {
221221
let embedding = response.data.into_iter().next().unwrap().embedding;
222222

223223
assert_eq!(b64_embedding.len(), embedding.len());
224-
for (b64, normal) in b64_embedding.iter().zip(embedding.iter()) {
225-
assert!((b64 - normal).abs() < 1e-6);
226-
}
227224
}
228225
}

0 commit comments

Comments
 (0)