use crate::client::OpenAI;
use crate::error::{OpenAIError, enum_to_string};
use crate::types::audio::{
SpeechRequest, Transcription, TranscriptionParams, Translation, TranslationParams,
};
pub struct Audio<'a> {
client: &'a OpenAI,
}
impl<'a> Audio<'a> {
pub(crate) fn new(client: &'a OpenAI) -> Self {
Self { client }
}
pub fn transcriptions(&self) -> Transcriptions<'_> {
Transcriptions {
client: self.client,
}
}
pub fn translations(&self) -> Translations<'_> {
Translations {
client: self.client,
}
}
pub fn speech(&self) -> Speech<'_> {
Speech {
client: self.client,
}
}
}
pub struct Transcriptions<'a> {
client: &'a OpenAI,
}
impl<'a> Transcriptions<'a> {
pub async fn create(&self, params: TranscriptionParams) -> Result<Transcription, OpenAIError> {
let mut form = reqwest::multipart::Form::new()
.part(
"file",
reqwest::multipart::Part::bytes(params.file).file_name(params.filename),
)
.text("model", params.model);
if let Some(lang) = params.language {
form = form.text("language", lang);
}
if let Some(prompt) = params.prompt {
form = form.text("prompt", prompt);
}
if let Some(fmt) = params.response_format {
form = form.text("response_format", enum_to_string(&fmt)?);
}
if let Some(temp) = params.temperature {
form = form.text("temperature", temp.to_string());
}
self.client
.post_multipart("/audio/transcriptions", form)
.await
}
}
pub struct Translations<'a> {
client: &'a OpenAI,
}
impl<'a> Translations<'a> {
pub async fn create(&self, params: TranslationParams) -> Result<Translation, OpenAIError> {
let mut form = reqwest::multipart::Form::new()
.part(
"file",
reqwest::multipart::Part::bytes(params.file).file_name(params.filename),
)
.text("model", params.model);
if let Some(prompt) = params.prompt {
form = form.text("prompt", prompt);
}
if let Some(fmt) = params.response_format {
form = form.text("response_format", enum_to_string(&fmt)?);
}
if let Some(temp) = params.temperature {
form = form.text("temperature", temp.to_string());
}
self.client
.post_multipart("/audio/translations", form)
.await
}
}
pub struct Speech<'a> {
client: &'a OpenAI,
}
impl<'a> Speech<'a> {
pub async fn create(&self, request: SpeechRequest) -> Result<bytes::Bytes, OpenAIError> {
self.client.post_raw("/audio/speech", &request).await
}
}
#[cfg(test)]
mod tests {
use crate::OpenAI;
use crate::config::ClientConfig;
use crate::types::audio::{SpeechRequest, TranscriptionParams, TranslationParams};
#[tokio::test]
async fn test_audio_transcription_create() {
let mut server = mockito::Server::new_async().await;
let mock = server
.mock("POST", "/audio/transcriptions")
.match_header("authorization", "Bearer sk-test")
.with_status(200)
.with_header("content-type", "application/json")
.with_body(r#"{"text": "Hello world from audio"}"#)
.create_async()
.await;
let client = OpenAI::with_config(ClientConfig::new("sk-test").base_url(server.url()));
let params = TranscriptionParams::new(
vec![0xFF, 0xFB, 0x90], "audio.mp3",
"whisper-1",
);
let response = client
.audio()
.transcriptions()
.create(params)
.await
.unwrap();
assert_eq!(response.text, "Hello world from audio");
mock.assert_async().await;
}
#[tokio::test]
async fn test_audio_translation_create() {
let mut server = mockito::Server::new_async().await;
let mock = server
.mock("POST", "/audio/translations")
.match_header("authorization", "Bearer sk-test")
.with_status(200)
.with_header("content-type", "application/json")
.with_body(r#"{"text": "Hello world in English"}"#)
.create_async()
.await;
let client = OpenAI::with_config(ClientConfig::new("sk-test").base_url(server.url()));
let params = TranslationParams::new(vec![0xFF, 0xFB, 0x90], "audio.mp3", "whisper-1");
let response = client.audio().translations().create(params).await.unwrap();
assert_eq!(response.text, "Hello world in English");
mock.assert_async().await;
}
#[tokio::test]
async fn test_audio_speech_create() {
let mut server = mockito::Server::new_async().await;
let audio_bytes = vec![0xFF, 0xFB, 0x90, 0x00]; let mock = server
.mock("POST", "/audio/speech")
.match_header("authorization", "Bearer sk-test")
.match_header("content-type", "application/json")
.with_status(200)
.with_header("content-type", "audio/mpeg")
.with_body(audio_bytes.clone())
.create_async()
.await;
let client = OpenAI::with_config(ClientConfig::new("sk-test").base_url(server.url()));
let request = SpeechRequest::new(
"Hello world",
"tts-1",
crate::types::audio::AudioVoice::Alloy,
);
let response = client.audio().speech().create(request).await.unwrap();
assert_eq!(response.as_ref(), audio_bytes.as_slice());
mock.assert_async().await;
}
}