Make the OpenAiAudioApi return ResponseEntity<value>

This commit is contained in:
Christian Tzolov
2024-03-03 10:49:09 +01:00
parent 5e6815863c
commit 54930af220
2 changed files with 44 additions and 24 deletions

View File

@@ -24,6 +24,7 @@ import com.fasterxml.jackson.annotation.JsonProperty;
import org.springframework.ai.openai.api.common.ApiUtils; import org.springframework.ai.openai.api.common.ApiUtils;
import org.springframework.core.io.ByteArrayResource; import org.springframework.core.io.ByteArrayResource;
import org.springframework.http.ResponseEntity;
import org.springframework.util.Assert; import org.springframework.util.Assert;
import org.springframework.util.LinkedMultiValueMap; import org.springframework.util.LinkedMultiValueMap;
import org.springframework.util.MultiValueMap; import org.springframework.util.MultiValueMap;
@@ -561,18 +562,19 @@ public class OpenAiAudioApi {
/** /**
* Request to generates audio from the input text. * Request to generates audio from the input text.
* @param requestBody The request body. * @param requestBody The request body.
* @return The audio file in bytes. * @return Response entity containing the audio binary.
*/ */
public byte[] createSpeech(SpeechRequest requestBody) { public ResponseEntity<byte[]> createSpeech(SpeechRequest requestBody) {
return this.restClient.post().uri("/v1/audio/speech").body(requestBody).retrieve().body(byte[].class); return this.restClient.post().uri("/v1/audio/speech").body(requestBody).retrieve().toEntity(byte[].class);
} }
/** /**
* Transcribes audio into the input language. * Transcribes audio into the input language.
* @param requestBody The request body. * @param requestBody The request body.
* @return The transcribed text. * @return Response entity containing the transcribed text in either json or text
* format.
*/ */
public Object createTranscription(TranscriptionRequest requestBody) { public ResponseEntity<?> createTranscription(TranscriptionRequest requestBody) {
return createTranscription(requestBody, requestBody.responseFormat().getResponseType()); return createTranscription(requestBody, requestBody.responseFormat().getResponseType());
} }
@@ -582,9 +584,9 @@ public class OpenAiAudioApi {
* @param <T> The response type. * @param <T> The response type.
* @param requestBody The request body. * @param requestBody The request body.
* @param responseType The response type class. * @param responseType The response type class.
* @return The transcribed text. * @return Response entity containing the transcribed text in the responseType format.
*/ */
public <T> T createTranscription(TranscriptionRequest requestBody, Class<T> responseType) { public <T> ResponseEntity<T> createTranscription(TranscriptionRequest requestBody, Class<T> responseType) {
MultiValueMap<String, Object> multipartBody = new LinkedMultiValueMap<>(); MultiValueMap<String, Object> multipartBody = new LinkedMultiValueMap<>();
multipartBody.add("file", new ByteArrayResource(requestBody.file()) { multipartBody.add("file", new ByteArrayResource(requestBody.file()) {
@@ -604,15 +606,20 @@ public class OpenAiAudioApi {
multipartBody.add("timestamp_granularities[]", requestBody.granularityType().getValue()); multipartBody.add("timestamp_granularities[]", requestBody.granularityType().getValue());
} }
return this.restClient.post().uri("/v1/audio/transcriptions").body(multipartBody).retrieve().body(responseType); return this.restClient.post()
.uri("/v1/audio/transcriptions")
.body(multipartBody)
.retrieve()
.toEntity(responseType);
} }
/** /**
* Translates audio into English. * Translates audio into English.
* @param requestBody The request body. * @param requestBody The request body.
* @return The transcribed text. * @return Response entity containing the transcribed text in either json or text
* format.
*/ */
public Object createTranslation(TranslationRequest requestBody) { public ResponseEntity<?> createTranslation(TranslationRequest requestBody) {
return createTranslation(requestBody, requestBody.responseFormat().getResponseType()); return createTranslation(requestBody, requestBody.responseFormat().getResponseType());
} }
@@ -622,9 +629,9 @@ public class OpenAiAudioApi {
* @param <T> The response type. * @param <T> The response type.
* @param requestBody The request body. * @param requestBody The request body.
* @param responseType The response type class. * @param responseType The response type class.
* @return The transcribed text. * @return Response entity containing the transcribed text in the responseType format.
*/ */
public <T> T createTranslation(TranslationRequest requestBody, Class<T> responseType) { public <T> ResponseEntity<T> createTranslation(TranslationRequest requestBody, Class<T> responseType) {
MultiValueMap<String, Object> multipartBody = new LinkedMultiValueMap<>(); MultiValueMap<String, Object> multipartBody = new LinkedMultiValueMap<>();
multipartBody.add("file", new ByteArrayResource(requestBody.file()) { multipartBody.add("file", new ByteArrayResource(requestBody.file()) {
@@ -638,7 +645,11 @@ public class OpenAiAudioApi {
multipartBody.add("response_format", requestBody.responseFormat().getValue()); multipartBody.add("response_format", requestBody.responseFormat().getValue());
multipartBody.add("temperature", requestBody.temperature()); multipartBody.add("temperature", requestBody.temperature());
return this.restClient.post().uri("/v1/audio/translations").body(multipartBody).retrieve().body(responseType); return this.restClient.post()
.uri("/v1/audio/translations")
.body(multipartBody)
.retrieve()
.toEntity(responseType);
} }
} }

View File

@@ -28,6 +28,7 @@ import org.springframework.ai.openai.api.OpenAiAudioApi.TranscriptionRequest;
import org.springframework.ai.openai.api.OpenAiAudioApi.StructuredResponse; import org.springframework.ai.openai.api.OpenAiAudioApi.StructuredResponse;
import org.springframework.ai.openai.api.OpenAiAudioApi.TranslationRequest; import org.springframework.ai.openai.api.OpenAiAudioApi.TranslationRequest;
import org.springframework.ai.openai.api.OpenAiAudioApi.SpeechRequest.Voice; import org.springframework.ai.openai.api.OpenAiAudioApi.SpeechRequest.Voice;
import org.springframework.lang.NonNull;
import org.springframework.ai.openai.api.OpenAiAudioApi.TtsModel; import org.springframework.ai.openai.api.OpenAiAudioApi.TtsModel;
import org.springframework.ai.openai.api.OpenAiAudioApi.WhisperModel; import org.springframework.ai.openai.api.OpenAiAudioApi.WhisperModel;
import org.springframework.util.FileCopyUtils; import org.springframework.util.FileCopyUtils;
@@ -42,34 +43,42 @@ public class OpenAiAudioApiIT {
OpenAiAudioApi audioApi = new OpenAiAudioApi(System.getenv("OPENAI_API_KEY")); OpenAiAudioApi audioApi = new OpenAiAudioApi(System.getenv("OPENAI_API_KEY"));
@SuppressWarnings("null")
@Test @Test
void speechTranscriptionAndTranslation() throws IOException { void speechTranscriptionAndTranslation() throws IOException {
byte[] speech = audioApi.createSpeech(SpeechRequest.builder() byte[] speech = audioApi
.withModel(TtsModel.TTS_1_HD.getValue()) .createSpeech(SpeechRequest.builder()
.withInput("Hello, my name is Chris and I love Spring A.I.") .withModel(TtsModel.TTS_1_HD.getValue())
.withVoice(Voice.ONYX) .withInput("Hello, my name is Chris and I love Spring A.I.")
.build()); .withVoice(Voice.ONYX)
.build())
.getBody();
assertThat(speech).isNotEmpty(); assertThat(speech).isNotEmpty();
FileCopyUtils.copy(speech, new File("target/speech.mp3")); FileCopyUtils.copy(speech, new File("target/speech.mp3"));
StructuredResponse translation = audioApi.createTranslation( StructuredResponse translation = audioApi
TranslationRequest.builder().withModel(WhisperModel.WHISPER_1.getValue()).withFile(speech).build(), .createTranslation(
StructuredResponse.class); TranslationRequest.builder().withModel(WhisperModel.WHISPER_1.getValue()).withFile(speech).build(),
StructuredResponse.class)
.getBody();
assertThat(translation.text().replaceAll(",", "")).isEqualTo("Hello my name is Chris and I love Spring AI."); assertThat(translation.text().replaceAll(",", "")).isEqualTo("Hello my name is Chris and I love Spring AI.");
StructuredResponse transcriptionEnglish = audioApi.createTranscription( StructuredResponse transcriptionEnglish = audioApi.createTranscription(
TranscriptionRequest.builder().withModel(WhisperModel.WHISPER_1.getValue()).withFile(speech).build(), TranscriptionRequest.builder().withModel(WhisperModel.WHISPER_1.getValue()).withFile(speech).build(),
StructuredResponse.class); StructuredResponse.class)
.getBody();
assertThat(transcriptionEnglish.text().replaceAll(",", "")) assertThat(transcriptionEnglish.text().replaceAll(",", ""))
.isEqualTo("Hello my name is Chris and I love Spring AI."); .isEqualTo("Hello my name is Chris and I love Spring AI.");
StructuredResponse transcriptionDutch = audioApi.createTranscription( StructuredResponse transcriptionDutch = audioApi
TranscriptionRequest.builder().withFile(speech).withLanguage("nl").build(), StructuredResponse.class); .createTranscription(TranscriptionRequest.builder().withFile(speech).withLanguage("nl").build(),
StructuredResponse.class)
.getBody();
assertThat(transcriptionDutch.text()).isEqualTo("Hallo, mijn naam is Chris en ik hou van Spring AI."); assertThat(transcriptionDutch.text()).isEqualTo("Hallo, mijn naam is Chris en ik hou van Spring AI.");
} }