Accessing tuned Gemini model in Flutter
Hi everyone! Myself Aayush Sharma, a fellow Flutter developer. In this article, I’ll demonstrate how you can access a tuned Gemini model in your Flutter app.
Overview
You must’ve used google_generative_ai
package if you tried integrating Gemini into your Flutter app. It lets you use the publicly available Gemini models like gemini-1.5-flash
easily.
But an error will be thrown if you tuned a model in the Google AI studio for your specific use case and tried connecting to it (given below).
Problem
The problem with accessing a tuned model is that it requires OAuth authentication, Only authenticating with the Gemini API key won't suffice. In the official documentation provided by Google, They provide a way to give this OAuth access using a Python client only for Desktops.
They don’t support OAuth yet for mobile devices but are working on it. So in the future, you might be able to access the model just by using their API key.
In the meantime, you can use my solution to access tuned models or even provide access to other people (email addresses).
Permissions/Roles
The tuned models in Gemini have permissions/roles assigned to those who want to access them. If you’ve got the READER role associated with your email address for a particular model then you can access it.
Initially, READER access is given to the owner of the model. You can access the model in your application if you somehow provide OAuth authentication with this account.
Authentication
The easiest way to provide Google OAuth is to implement Google Sign-in. Now, I won’t go into details of implementation. You can easily get CHAT-GPT to get it done in minutes.
Create a GoogleSignIn
object.
final googleSignIn = GoogleSignIn();
Note: You might have to specify scopes as well if it doesn’t work, Do it like given below.
final googleSignIn = GoogleSignIn(scopes: [
‘https://www.googleapis.com/auth/generative-language.retriever',
‘https://www.googleapis.com/auth/generative-language.tuning',
]);
now continue the normal flow for Google sign-in.
final googleAccount = await googleSignIn.signIn();
final googleAuthCreds = await googleAccount?.authentication;
The googleAuthCreds
have the required OAuth access token that will give us access to the tuned models. So, store that in a variable that will be used later.
_oauthAccessToken = googleAuthCreds?.accessToken;
Now we need to pass the access token to the GenerativeModel
object that actually connects to the model. It takes a Client
as a parameter which is an HTTP client from the HTTP package.
Extend the BaseClient
which is provided by default by http
package and override its send
method. This is where we’ll add the Authorization
header to each request that is made to Gemini API.
class OauthHttpClient extends http.BaseClient {
final String authorizationToken;
OauthHttpClient(this.authorizationToken);
@override
Future<http.StreamedResponse> send(http.BaseRequest request) {
request.headers['Authorization'] = 'Bearer $authorizationToken';
return http.Client().send(request);
}
}
Now pass an object of OauthHttpClient
to the Generative model you’re going to create.
final _tunedModel = GenerativeModel(
model: 'tunedModels/<yourModelId>',
apiKey: const String.fromEnvironment('GEMINI_API_KEY'),
httpClient: OauthHttpClient(AuthService().oathAccessToken ?? ''),
...
);
And it’s done, Now whenever you hit the Gemini API with this model it’ll automatically pass the OAuth Token and process the request normally.
Providing Access to other accounts
The above solution works as long as you have the READER permission for the respective model. To give access to others you have to follow a few steps below.
- Get the OAuth access token for the account through which you created the model
Just print the token you got above in the console
_oauthAccessToken = googleAuthCreds?.accessToken;
print(_oauthAccessToken)
- Hit the tuned model permissions API provided by Google, This API is still in beta.
curl --location 'https://generativelanguage.googleapis.com/v1beta/tunedModels/geminiscribblewordgen-m8ul77vifyl6/permissions' \
--header 'Authorization: Bearer oAuth token>' \
--header 'Content-Type: application/json' \
--data-raw '{
"granteeType": "USER",
"emailAddress": "<email address>",
"role": "READER"
}'
- You can also specify
granteeType
as EVERYONE then there is no need to specify email address.
That’s it now others can also access your tuned model after signing into Google.
Thanks for sticking to the end, I hope you learned something new. If you’ve any queries, reach out to me on LinkedIn or in the comments. Do visit my website made entirely in Flutter.