20
20
class Client (object ):
21
21
"""The main filetracker client class.
22
22
23
- The client instance can be built is one of several ways. The easiest
24
- one is to just call the constructor without arguments. In this case
25
- the configuration is taken from the environment variables:
26
-
27
- ``FILETRACKER_DIR``
28
- the folder to use as the local cache; if not specified,
29
- ``~/.filetracker-store`` is used.
30
-
31
- ``FILETRACKER_URL``
32
- the URL of the filetracker server; if not present, the constructed
33
- client is a stand-alone local client, which stores the files and
34
- metadata locally --- this can be safely used by multiple processes
35
- on the same machine, too.
36
-
37
- Another way to create a client is to pass these values as constructor
38
- arguments --- ``remote_url`` and ``cache_dir``.
39
-
40
- If you are the power-user, you may create the client by manually passing
41
- ``local_store`` and ``remote_store`` to the constructor (see
42
- :ref:`filetracker_api`).
23
+ The client instance can be built is one of several ways. The easiest
24
+ one is to just call the constructor without arguments. In this case
25
+ the configuration is taken from the environment variables:
26
+
27
+ ``FILETRACKER_DIR``
28
+ the folder to use as the local cache; if not specified,
29
+ ``~/.filetracker-store`` is used.
30
+
31
+ ``FILETRACKER_URL``
32
+ the URL of the filetracker server; if not present, the constructed
33
+ client is a stand-alone local client, which stores the files and
34
+ metadata locally --- this can be safely used by multiple processes
35
+ on the same machine, too.
36
+
37
+ Another way to create a client is to pass these values as constructor
38
+ arguments --- ``remote_url`` and ``cache_dir``.
39
+
40
+ If you are the power-user, you may create the client by manually passing
41
+ ``local_store`` and ``remote_store`` to the constructor (see
42
+ :ref:`filetracker_api`).
43
43
"""
44
44
45
- DEFAULT_CACHE_DIR = os .path .expanduser (
46
- os .path .join ('~' , '.filetracker-store' ))
47
-
48
- def __init__ (self , local_store = 'auto' , remote_store = 'auto' ,
49
- lock_manager = 'auto' , cache_dir = None , remote_url = None ,
50
- locks_dir = None ):
45
+ DEFAULT_CACHE_DIR = os .path .expanduser (os .path .join ('~' , '.filetracker-store' ))
46
+
47
+ def __init__ (
48
+ self ,
49
+ local_store = 'auto' ,
50
+ remote_store = 'auto' ,
51
+ lock_manager = 'auto' ,
52
+ cache_dir = None ,
53
+ remote_url = None ,
54
+ locks_dir = None ,
55
+ ):
51
56
if cache_dir is None :
52
57
cache_dir = os .environ .get ('FILETRACKER_DIR' )
53
58
if cache_dir is None :
@@ -73,8 +78,9 @@ def __init__(self, local_store='auto', remote_store='auto',
73
78
lock_manager = NoOpLockManager ()
74
79
75
80
if not local_store and not remote_store :
76
- raise ValueError ("Neither local nor remote Filetracker store "
77
- "has been configured" )
81
+ raise ValueError (
82
+ "Neither local nor remote Filetracker store " "has been configured"
83
+ )
78
84
79
85
self .local_store = local_store
80
86
self .remote_store = remote_store
@@ -85,28 +91,36 @@ def _add_to_cache(self, name, filename):
85
91
if self .local_store :
86
92
self .local_store .add_file (name , filename )
87
93
except Exception :
88
- logger .warning ("Error adding '%s' to cache (from file '%s')"
89
- % (name , filename ), exc_info = True )
90
-
91
- def get_file (self , name , save_to , add_to_cache = True ,
92
- force_refresh = False , _lock_exclusive = False ):
94
+ logger .warning (
95
+ "Error adding '%s' to cache (from file '%s')" % (name , filename ),
96
+ exc_info = True ,
97
+ )
98
+
99
+ def get_file (
100
+ self ,
101
+ name ,
102
+ save_to ,
103
+ add_to_cache = True ,
104
+ force_refresh = False ,
105
+ _lock_exclusive = False ,
106
+ ):
93
107
"""Retrieves file identified by ``name``.
94
108
95
- The file is saved as ``save_to``. If ``add_to_cache`` is ``True``,
96
- the file is added to the local store. If ``force_refresh`` is
97
- ``True``, local cache is not examined if a remote store is
98
- configured.
109
+ The file is saved as ``save_to``. If ``add_to_cache`` is ``True``,
110
+ the file is added to the local store. If ``force_refresh`` is
111
+ ``True``, local cache is not examined if a remote store is
112
+ configured.
99
113
100
- If a remote store is configured, but ``name`` does not contain a
101
- version, the local data store is not used, as we cannot guarantee
102
- that the version there is fresh.
114
+ If a remote store is configured, but ``name`` does not contain a
115
+ version, the local data store is not used, as we cannot guarantee
116
+ that the version there is fresh.
103
117
104
- Local data store implemented in :class:`LocalDataStore` tries to not
105
- copy the entire file to ``save_to`` if possible, but instead uses
106
- hardlinking. Therefore you should not modify the file if you don't
107
- want to totally blow something.
118
+ Local data store implemented in :class:`LocalDataStore` tries to not
119
+ copy the entire file to ``save_to`` if possible, but instead uses
120
+ hardlinking. Therefore you should not modify the file if you don't
121
+ want to totally blow something.
108
122
109
- This method returns the full versioned name of the retrieved file.
123
+ This method returns the full versioned name of the retrieved file.
110
124
"""
111
125
112
126
uname , version = split_name (name )
@@ -124,23 +138,24 @@ def get_file(self, name, save_to, add_to_cache=True,
124
138
t = time .time ()
125
139
logger .debug (' downloading %s' , name )
126
140
try :
127
- if not self .remote_store or (version is not None
128
- and not force_refresh ):
141
+ if not self .remote_store or (version is not None and not force_refresh ):
129
142
try :
130
143
if self .local_store and self .local_store .exists (name ):
131
144
return self .local_store .get_file (name , save_to )
132
145
except Exception :
133
146
if self .remote_store :
134
- logger .warning ("Error getting '%s' from local store" ,
135
- name , exc_info = True )
147
+ logger .warning (
148
+ "Error getting '%s' from local store" , name , exc_info = True
149
+ )
136
150
else :
137
151
raise
138
152
if self .remote_store :
139
153
if not _lock_exclusive and add_to_cache :
140
154
if lock :
141
155
lock .unlock ()
142
- return self .get_file (name , save_to , add_to_cache ,
143
- _lock_exclusive = True )
156
+ return self .get_file (
157
+ name , save_to , add_to_cache , _lock_exclusive = True
158
+ )
144
159
vname = self .remote_store .get_file (name , save_to )
145
160
if add_to_cache :
146
161
self ._add_to_cache (vname , save_to )
@@ -154,13 +169,13 @@ def get_file(self, name, save_to, add_to_cache=True,
154
169
def get_stream (self , name , force_refresh = False , serve_from_cache = False ):
155
170
"""Retrieves file identified by ``name`` in streaming mode.
156
171
157
- Works like :meth:`get_file`, except that returns a tuple
158
- (file-like object, versioned name).
172
+ Works like :meth:`get_file`, except that returns a tuple
173
+ (file-like object, versioned name).
159
174
160
- When both remote_store and local_store are present, serve_from_cache
161
- can be used to ensure that the file will be downloaded and served
162
- from a local cache. If a full version is specified and the file
163
- exists in the cache a file will be always served locally.
175
+ When both remote_store and local_store are present, serve_from_cache
176
+ can be used to ensure that the file will be downloaded and served
177
+ from a local cache. If a full version is specified and the file
178
+ exists in the cache a file will be always served locally.
164
179
"""
165
180
166
181
uname , version = split_name (name )
@@ -171,15 +186,15 @@ def get_stream(self, name, force_refresh=False, serve_from_cache=False):
171
186
lock .lock_shared ()
172
187
173
188
try :
174
- if not self .remote_store or (version is not None
175
- and not force_refresh ):
189
+ if not self .remote_store or (version is not None and not force_refresh ):
176
190
try :
177
191
if self .local_store and self .local_store .exists (name ):
178
192
return self .local_store .get_stream (name )
179
193
except Exception :
180
194
if self .remote_store :
181
- logger .warning ("Error getting '%s' from local store" ,
182
- name , exc_info = True )
195
+ logger .warning (
196
+ "Error getting '%s' from local store" , name , exc_info = True
197
+ )
183
198
else :
184
199
raise
185
200
if self .remote_store :
@@ -201,11 +216,11 @@ def get_stream(self, name, force_refresh=False, serve_from_cache=False):
201
216
def file_version (self , name ):
202
217
"""Returns the newest available version number of the file.
203
218
204
- If the remote store is configured, it is queried, otherwise
205
- the local version is returned. It is assumed that the remote store
206
- always has the newest version of the file.
219
+ If the remote store is configured, it is queried, otherwise
220
+ the local version is returned. It is assumed that the remote store
221
+ always has the newest version of the file.
207
222
208
- If version is a part of ``name``, it is ignored.
223
+ If version is a part of ``name``, it is ignored.
209
224
"""
210
225
211
226
if self .remote_store :
@@ -216,24 +231,24 @@ def file_version(self, name):
216
231
def file_size (self , name , force_refresh = False ):
217
232
"""Returns the size of the file.
218
233
219
- For efficiency this operation does not use locking, so may return
220
- inconsistent data. Use it for informational purposes.
234
+ For efficiency this operation does not use locking, so may return
235
+ inconsistent data. Use it for informational purposes.
221
236
"""
222
237
223
238
uname , version = split_name (name )
224
239
225
240
t = time .time ()
226
241
logger .debug (' querying size of %s' , name )
227
242
try :
228
- if not self .remote_store or (version is not None
229
- and not force_refresh ):
243
+ if not self .remote_store or (version is not None and not force_refresh ):
230
244
try :
231
245
if self .local_store and self .local_store .exists (name ):
232
246
return self .local_store .file_size (name )
233
247
except Exception :
234
248
if self .remote_store :
235
- logger .warning ("Error getting '%s' from local store" ,
236
- name , exc_info = True )
249
+ logger .warning (
250
+ "Error getting '%s' from local store" , name , exc_info = True
251
+ )
237
252
else :
238
253
raise
239
254
if self .remote_store :
@@ -242,35 +257,39 @@ def file_size(self, name, force_refresh=False):
242
257
finally :
243
258
logger .debug (' processed %s in %.2fs' , name , time .time () - t )
244
259
245
- def put_file (self ,
246
- name ,
247
- filename ,
248
- to_local_store = True ,
249
- to_remote_store = True ,
250
- compress_hint = True ):
260
+ def put_file (
261
+ self ,
262
+ name ,
263
+ filename ,
264
+ to_local_store = True ,
265
+ to_remote_store = True ,
266
+ compress_hint = True ,
267
+ ):
251
268
"""Adds file ``filename`` to the filetracker under the name ``name``.
252
269
253
- If the file already exists, a new version is created. In practice
254
- if the store does not support versioning, the file is overwritten.
270
+ If the file already exists, a new version is created. In practice
271
+ if the store does not support versioning, the file is overwritten.
255
272
256
- The file may be added to local store only (if ``to_remote_store`` is
257
- ``False``), to remote store only (if ``to_local_store`` is
258
- ``False``) or both. If only one store is configured, the values of
259
- ``to_local_store`` and ``to_remote_store`` are ignored.
273
+ The file may be added to local store only (if ``to_remote_store`` is
274
+ ``False``), to remote store only (if ``to_local_store`` is
275
+ ``False``) or both. If only one store is configured, the values of
276
+ ``to_local_store`` and ``to_remote_store`` are ignored.
260
277
261
- Local data store implemented in :class:`LocalDataStore` tries to not
262
- directly copy the data to the final cache destination, but uses
263
- hardlinking. Therefore you should not modify the file in-place
264
- later as this would be disastrous.
278
+ Local data store implemented in :class:`LocalDataStore` tries to not
279
+ directly copy the data to the final cache destination, but uses
280
+ hardlinking. Therefore you should not modify the file in-place
281
+ later as this would be disastrous.
265
282
266
- If ``compress_hint`` is set to False, file is compressed on
267
- the server, instead of the client. This is generally not
268
- recommended, unless you know what you're doing.
283
+ If ``compress_hint`` is set to False, file is compressed on
284
+ the server, instead of the client. This is generally not
285
+ recommended, unless you know what you're doing.
269
286
"""
270
287
271
288
if not to_local_store and not to_remote_store :
272
- raise ValueError ("Neither to_local_store nor to_remote_store set "
273
- "in a call to filetracker.Client.put_file" )
289
+ raise ValueError (
290
+ "Neither to_local_store nor to_remote_store set "
291
+ "in a call to filetracker.Client.put_file"
292
+ )
274
293
275
294
check_name (name )
276
295
@@ -284,7 +303,8 @@ def put_file(self,
284
303
versioned_name = self .local_store .add_file (name , filename )
285
304
if (to_remote_store or not self .local_store ) and self .remote_store :
286
305
versioned_name = self .remote_store .add_file (
287
- name , filename , compress_hint = compress_hint )
306
+ name , filename , compress_hint = compress_hint
307
+ )
288
308
finally :
289
309
if lock :
290
310
lock .close ()
@@ -294,7 +314,7 @@ def put_file(self,
294
314
def delete_file (self , name ):
295
315
"""Deletes the file identified by ``name`` along with its metadata.
296
316
297
- The file is removed from both the local store and the remote store.
317
+ The file is removed from both the local store and the remote store.
298
318
"""
299
319
if self .local_store :
300
320
lock = self .lock_manager .lock_for (name )
@@ -311,8 +331,8 @@ def delete_file(self, name):
311
331
def list_local_files (self ):
312
332
"""Returns list of all stored local files.
313
333
314
- Each element of this list is of :class:`DataStore.FileInfoEntry`
315
- type.
334
+ Each element of this list is of :class:`DataStore.FileInfoEntry`
335
+ type.
316
336
"""
317
337
result = []
318
338
if self .local_store :
0 commit comments