Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Text-to-speech synthesize response uses incorrect base64 encoding #422

Open
connorskees opened this issue Apr 4, 2023 · 9 comments
Open

Comments

@connorskees
Copy link

SynthesizeSpeechResponse uses urlsafe base64 during deserialization, where the API returns standard base64 (including / and +). Such a response can be found in the docs here. This prevents the API from being used at all.

#[serde_as(as = "Option<::client::serde::urlsafe_base64::Wrapper>")]

A minimal example demonstrating this:

let req = SynthesizeSpeechRequest {
    input: Some(SynthesisInput {
        text: Some("hello world".to_owned()),
        ssml: None,
    }),
    voice: Some(VoiceSelectionParams {
        language_code: Some("en-US".to_owned()),
        ..Default::default()
    }),
    audio_config: Some(AudioConfig {
        audio_encoding: Some("MP3".to_owned()),
        ..Default::default()
    }),
};

// will crash
let result = hub.text().synthesize(req).doit().await.unwrap();
@Byron
Copy link
Owner

Byron commented Apr 4, 2023

Thanks for reporting. Changing that for all APIs is easy, but I wonder if it would break others or most of them.

For those who want to tackle this I recommend to see if this encoding is in some way specified in the OpenAPI description so it could be used to make this decision.

If it it is implicit, it might be safest to implement a per-API override (as is present for the Youtube API for example) to turn a different encoding on only for the texttospeech API.

@tkrs
Copy link

tkrs commented Apr 20, 2023

Hi, I'm facing the same issue with google_datastore1 v5. It crashes when decoding blob_value.

#[serde_as(as = "Option<::client::serde::urlsafe_base64::Wrapper>")]
pub blob_value: Option<Vec<u8>>,

@Byron
Copy link
Owner

Byron commented Apr 20, 2023

As a workaround, it's probably easiest to vendor the Google API crate and patch it yourself. I presume without the urlsafe version of the wrapper it should work.

@connorskees
Copy link
Author

connorskees commented Apr 20, 2023

My workaround/hack has been to match on the error and decode as base64 a second time,

let result = match self.hub.text().synthesize(req).doit().await {
    Ok(v) => v.1,
    Err(e) => match e {
        Error::JsonDecodeError(s, _) => {
            let result = serde_json::from_str::<MySynthesizeSpeechResponse>(&s).unwrap();
            SynthesizeSpeechResponse {
                #[allow(deprecated)]
                audio_content: Some(base64::decode(result.audio_content.unwrap()).unwrap()),
            }
        }
        _ => todo!(),
    },
};

@Byron
Copy link
Owner

Byron commented Apr 20, 2023

Thanks for sharing!

@tkrs
Copy link

tkrs commented Nov 19, 2023

I'm thinking of using feature to be able to select whether URL-safe or not. What do you think?

@connorskees
Copy link
Author

I don't think feature is a good choice here. A feature is a crate-wide configuration, while this bug only impacts a particular Google API. If this issue is more widespread, then something else in the crate should change. Ideally a user shouldn't have to even know about the base64 encoding; it's an implementation detail of the API.

@tkrs
Copy link

tkrs commented Nov 19, 2023

I get it.

@Byron
Copy link
Owner

Byron commented Nov 19, 2023

I think cargo features could work if the whole crate either wants URL encoding or base64, and I don't know if that's the case consistently. Maybe it would also be possible to make it configurable at runtime on a per-field basis with a custom encoder/decoder, or better, with a switch for each callable method.

Definitely there are options, but it doesn't look like anybody will have the time to actually look into it.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

3 participants