1616// under the License.
1717
1818use std:: sync:: Arc ;
19+ use std:: time:: Duration ;
1920
2021use pyo3:: prelude:: * ;
2122
@@ -24,6 +25,7 @@ use object_store::azure::{MicrosoftAzure, MicrosoftAzureBuilder};
2425use object_store:: gcp:: { GoogleCloudStorage , GoogleCloudStorageBuilder } ;
2526use object_store:: http:: { HttpBuilder , HttpStore } ;
2627use object_store:: local:: LocalFileSystem ;
28+ use object_store:: ClientOptions ;
2729use pyo3:: exceptions:: PyValueError ;
2830use url:: Url ;
2931
@@ -164,6 +166,36 @@ impl PyGoogleCloudContext {
164166 }
165167}
166168
169+ #[ pyclass( name = "ClientOptions" , module = "datafusion.store" , subclass) ]
170+ #[ derive( Debug , Clone ) ]
171+ pub struct PyClientOptions {
172+ pub inner : ClientOptions ,
173+ }
174+
175+ #[ pymethods]
176+ impl PyClientOptions {
177+
178+ #[ pyo3( signature=( ) ) ]
179+ #[ new]
180+ pub fn new ( ) -> Self {
181+ Self {
182+ inner : ClientOptions :: new ( )
183+ }
184+ }
185+
186+ #[ pyo3( signature = ( timeout) ) ]
187+ pub fn with_timeout ( & mut self , timeout : Duration ) -> Self {
188+ self . inner = self . inner . clone ( ) . with_timeout ( timeout) ;
189+ return self . clone ( ) ;
190+ }
191+
192+ #[ pyo3( signature = ( timeout) ) ]
193+ pub fn with_connect_timeout ( & mut self , timeout : Duration ) -> Self {
194+ self . inner = self . inner . clone ( ) . with_connect_timeout ( timeout) ;
195+ return self . clone ( ) ;
196+ }
197+ }
198+
167199#[ pyclass( name = "AmazonS3" , module = "datafusion.store" , subclass) ]
168200#[ derive( Debug , Clone ) ]
169201pub struct PyAmazonS3Context {
@@ -174,14 +206,15 @@ pub struct PyAmazonS3Context {
174206#[ pymethods]
175207impl PyAmazonS3Context {
176208 #[ allow( clippy:: too_many_arguments) ]
177- #[ pyo3( signature = ( bucket_name, region=None , access_key_id=None , secret_access_key=None , endpoint=None , allow_http=false , imdsv1_fallback=false ) ) ]
209+ #[ pyo3( signature = ( bucket_name, region=None , access_key_id=None , secret_access_key=None , endpoint=None , client_options= None , allow_http=false , imdsv1_fallback=false ) ) ]
178210 #[ new]
179211 fn new (
180212 bucket_name : String ,
181213 region : Option < String > ,
182214 access_key_id : Option < String > ,
183215 secret_access_key : Option < String > ,
184216 endpoint : Option < String > ,
217+ client_options : Option < PyClientOptions > ,
185218 //retry_config: RetryConfig,
186219 allow_http : bool ,
187220 imdsv1_fallback : bool ,
@@ -209,6 +242,10 @@ impl PyAmazonS3Context {
209242 builder = builder. with_imdsv1_fallback ( ) ;
210243 } ;
211244
245+ if let Some ( client_options) = client_options {
246+ builder = builder. with_client_options ( client_options. inner ) ;
247+ } ;
248+
212249 let store = builder
213250 . with_bucket_name ( bucket_name. clone ( ) )
214251 //.with_retry_config(retry_config) #TODO: add later
@@ -250,6 +287,7 @@ impl PyHttpContext {
250287}
251288
252289pub ( crate ) fn init_module ( m : & Bound < ' _ , PyModule > ) -> PyResult < ( ) > {
290+ m. add_class :: < PyClientOptions > ( ) ?;
253291 m. add_class :: < PyAmazonS3Context > ( ) ?;
254292 m. add_class :: < PyMicrosoftAzureContext > ( ) ?;
255293 m. add_class :: < PyGoogleCloudContext > ( ) ?;
0 commit comments