use core::time::Duration;
use crate::error::Error;
use crate::models::{
GenerateContentRequest, GenerateContentResponse,
EmbedContentRequest, EmbedContentResponse,
ListModelsResponse, CreateCachedContentRequest, CachedContentResponse,
ListCachedContentsResponse, UpdateCachedContentRequest,
};
use super::Client;
#[ derive( Debug, Clone ) ]
pub struct SyncClientBuilder
{
api_key : Option< String >,
timeout : Option< Duration >,
}
impl SyncClientBuilder
{
#[ must_use ]
#[ inline ]
pub fn new() -> Self
{
Self {
api_key : None,
timeout : None,
}
}
#[ must_use ]
#[ inline ]
pub fn api_key< S : Into< String > >( mut self, api_key : S ) -> Self
{
self.api_key = Some( api_key.into() );
self
}
#[ must_use ]
#[ inline ]
pub fn timeout( mut self, timeout : Duration ) -> Self
{
self.timeout = Some( timeout );
self
}
#[ inline ]
pub fn build( self ) -> Result< SyncClient, Error >
{
let api_key = self.api_key.ok_or_else( || Error::AuthenticationError(
"API key is required for sync client".to_string()
) )?;
let rt = tokio::runtime::Runtime::new()
.map_err( |e| Error::NetworkError( format!( "Failed to create tokio runtime : {e}" ) ) )?;
let client = rt.block_on( async {
let mut builder = Client::builder().api_key( api_key );
if let Some( timeout ) = self.timeout
{
builder = builder.timeout( timeout );
}
builder.build()
} )?;
Ok( SyncClient {
client,
runtime : std::sync::Arc::new( rt ),
} )
}
}
impl Default for SyncClientBuilder
{
#[ inline ]
fn default() -> Self
{
Self::new()
}
}
#[ derive( Debug ) ]
pub struct SyncClient
{
client : Client,
runtime : std::sync::Arc< tokio::runtime::Runtime >,
}
impl SyncClient
{
#[ must_use ]
#[ inline ]
pub fn models( &self ) -> SyncModelsApi< '_ >
{
SyncModelsApi {
client : &self.client,
runtime : &self.runtime,
}
}
#[ must_use ]
#[ inline ]
pub fn cached_content( &self ) -> SyncCachedContentApi< '_ >
{
SyncCachedContentApi {
client : &self.client,
runtime : &self.runtime,
}
}
}
#[ derive( Debug ) ]
pub struct SyncModelsApi< 'a >
{
client : &'a Client,
runtime : &'a tokio::runtime::Runtime,
}
impl SyncModelsApi< '_ >
{
#[ inline ]
pub fn list( &self ) -> Result< ListModelsResponse, Error >
{
self.runtime.block_on( async {
self.client.models().list().await
} )
}
#[ inline ]
pub fn by_name< S : AsRef< str > >( &self, name : S ) -> Result< SyncModelApi< '_ >, Error >
{
let model_name = name.as_ref().to_string();
Ok( SyncModelApi {
client : self.client,
runtime : self.runtime,
model_name,
} )
}
}
#[ derive( Debug ) ]
pub struct SyncModelApi< 'a >
{
client : &'a Client,
runtime : &'a tokio::runtime::Runtime,
model_name : String,
}
impl SyncModelApi< '_ >
{
#[ inline ]
pub fn generate_content( &self, request : &GenerateContentRequest ) -> Result< GenerateContentResponse, Error >
{
self.runtime.block_on( async {
self.client.models().by_name( &self.model_name )
.generate_content( request ).await
} )
}
#[ cfg( feature = "streaming" ) ]
#[ inline ]
pub fn generate_content_stream( &self, request : &GenerateContentRequest ) -> Result< Vec< String >, Error >
{
use futures::StreamExt;
self.runtime.block_on( async {
let stream = self.client.models().by_name( &self.model_name )
.generate_content_stream( request ).await?;
let mut results = Vec::new();
tokio ::pin!( stream );
while let Some( response_result ) = stream.next().await
{
match response_result
{
Ok( response ) => {
if let Some( candidates ) = response.candidates
{
for candidate in candidates
{
for part in candidate.content.parts
{
if let Some( text ) = part.text
{
results.push( text );
}
}
}
}
},
Err( e ) => return Err( e ),
}
}
Ok( results )
} )
}
#[ inline ]
pub fn embed_content( &self, request : &EmbedContentRequest ) -> Result< EmbedContentResponse, Error >
{
self.runtime.block_on( async {
self.client.models().by_name( &self.model_name )
.embed_content( request ).await
} )
}
#[ inline ]
pub fn count_tokens( &self, request : &crate::models::CountTokensRequest ) -> Result< crate::models::CountTokensResponse, Error >
{
self.runtime.block_on( async {
self.client.models().by_name( &self.model_name )
.count_tokens( request ).await
} )
}
}
#[ derive( Debug ) ]
pub struct SyncCachedContentApi< 'a >
{
client : &'a Client,
runtime : &'a tokio::runtime::Runtime,
}
impl SyncCachedContentApi< '_ >
{
#[ inline ]
pub fn create( &self, request : &CreateCachedContentRequest ) -> Result< CachedContentResponse, Error >
{
self.runtime.block_on( async {
self.client.cached_content().create( request ).await
} )
}
#[ inline ]
pub fn list( &self, page_size : Option< i32 >, page_token : Option< &str > ) -> Result< ListCachedContentsResponse, Error >
{
self.runtime.block_on( async {
self.client.cached_content().list( page_size, page_token ).await
} )
}
#[ inline ]
pub fn get( &self, cache_id : &str ) -> Result< CachedContentResponse, Error >
{
self.runtime.block_on( async {
self.client.cached_content().get( cache_id ).await
} )
}
#[ inline ]
pub fn update( &self, cache_id : &str, request : &UpdateCachedContentRequest ) -> Result< CachedContentResponse, Error >
{
self.runtime.block_on( async {
self.client.cached_content().update( cache_id, request ).await
} )
}
#[ inline ]
pub fn delete( &self, cache_id : &str ) -> Result< (), Error >
{
self.runtime.block_on( async {
self.client.cached_content().delete( cache_id ).await
} )
}
}