openai_dive/v1/endpoints/
audio.rs1use crate::v1::api::Client;
2use crate::v1::error::APIError;
3use crate::v1::resources::audio::AudioSpeechParameters;
4use crate::v1::resources::audio::AudioSpeechResponse;
5#[cfg(feature = "stream")]
6use crate::v1::resources::audio::AudioSpeechResponseChunkResponse;
7use crate::v1::resources::audio::{AudioTranscriptionParameters, AudioTranslationParameters};
8#[cfg(feature = "stream")]
9use futures::Stream;
10#[cfg(feature = "stream")]
11use futures::StreamExt;
12use serde_json::Value;
13#[cfg(feature = "stream")]
14use std::pin::Pin;
15
16pub struct Audio<'a> {
17 pub client: &'a Client,
18}
19
20impl Client {
21 pub fn audio(&self) -> Audio<'_> {
23 Audio { client: self }
24 }
25}
26
27impl Audio<'_> {
28 pub async fn create_speech(
30 &self,
31 parameters: AudioSpeechParameters,
32 ) -> Result<AudioSpeechResponse, APIError> {
33 let bytes = self.client.post_raw("/audio/speech", ¶meters).await?;
34
35 Ok(AudioSpeechResponse { bytes })
36 }
37
38 pub async fn create_transcription(
40 &self,
41 parameters: AudioTranscriptionParameters,
42 ) -> Result<String, APIError> {
43 let mut form = reqwest::multipart::Form::new();
44
45 let file = parameters.file.into_part().await?;
46
47 form = form.part("file", file);
48
49 form = form.text("model", parameters.model);
50
51 if let Some(prompt) = parameters.prompt {
52 form = form.text("prompt", prompt);
53 }
54
55 if let Some(language) = parameters.language {
56 form = form.text("language", language.to_string());
57 }
58
59 if let Some(chunking_strategy) = parameters.chunking_strategy {
60 form = form.text("chunking_strategy", chunking_strategy.to_string());
61 }
62
63 if let Some(response_format) = parameters.response_format {
64 form = form.text("response_format", response_format.to_string());
65 }
66
67 if let Some(stream) = parameters.stream {
68 form = form.text("stream", stream.to_string());
69 }
70
71 if let Some(temperature) = parameters.temperature {
72 form = form.text("temperature", temperature.to_string());
73 }
74
75 if let Some(timestamp_granularities) = parameters.timestamp_granularities {
76 form = form.text(
77 "timestamp_granularities",
78 timestamp_granularities
79 .iter()
80 .map(|t| t.to_string())
81 .collect::<Vec<String>>()
82 .join(","),
83 );
84 }
85
86 if let Some(extra_body) = parameters.extra_body {
87 match extra_body {
88 Value::Object(map) => {
89 for (key, value) in map {
90 form = form.text(key, value.to_string());
91 }
92 }
93 _ => {
94 return Err(APIError::BadRequestError(
95 "extra_body must be formatted as a map of key: value".to_string(),
96 ));
97 }
98 }
99 }
100
101 let response = self
102 .client
103 .post_with_form("/audio/transcriptions", form)
104 .await?;
105
106 Ok(response)
107 }
108
109 pub async fn create_translation(
111 &self,
112 parameters: AudioTranslationParameters,
113 ) -> Result<String, APIError> {
114 let mut form = reqwest::multipart::Form::new();
115
116 let file = parameters.file.into_part().await?;
117 form = form.part("file", file);
118
119 form = form.text("model", parameters.model);
120
121 if let Some(prompt) = parameters.prompt {
122 form = form.text("prompt", prompt);
123 }
124
125 if let Some(response_format) = parameters.response_format {
126 form = form.text("response_format", response_format.to_string());
127 }
128
129 if let Some(temperature) = parameters.temperature {
130 form = form.text("temperature", temperature.to_string());
131 }
132
133 let response = self
134 .client
135 .post_with_form("/audio/translations", form)
136 .await?;
137
138 Ok(response)
139 }
140
141 #[cfg(feature = "stream")]
142 pub async fn create_speech_stream(
144 &self,
145 parameters: AudioSpeechParameters,
146 ) -> Result<
147 Pin<Box<dyn Stream<Item = Result<AudioSpeechResponseChunkResponse, APIError>> + Send>>,
148 APIError,
149 > {
150 use crate::v1::resources::audio::StreamAudioSpeechParameters;
151
152 let stream_parameters = StreamAudioSpeechParameters {
153 model: parameters.model,
154 input: parameters.input,
155 voice: parameters.voice,
156 response_format: parameters.response_format,
157 speed: parameters.speed,
158 stream: true,
159 };
160
161 let stream = Box::pin(
162 self.client
163 .post_stream_raw("/audio/speech", &stream_parameters)
164 .await
165 .unwrap()
166 .map(|item| item.map(|bytes| AudioSpeechResponseChunkResponse { bytes })),
167 );
168
169 Ok(stream)
170 }
171}