3
3
import os
4
4
from pathlib import Path
5
5
from time import sleep , time
6
- from typing import List , Optional , Union
6
+ from typing import List , Literal , Optional , Union
7
7
8
8
from sqlalchemy import func
9
9
from sqlalchemy .orm import Session
10
10
11
+ from ._exceptions import NoFpathError , RnameExistsError , RpathTimeoutError
11
12
from .db import create_schema
12
13
from .db .schema import Resource
13
14
from .utils import copy_or_move , create_tmp_dir , generate_id
14
- from ._exceptions import NoFpathError , RnameExistsError , RpathTimeoutError
15
15
16
- __author__ = "jkanche "
16
+ __author__ = "Jayaram Kancherla "
17
17
__copyright__ = "jkanche"
18
18
__license__ = "MIT"
19
19
@@ -25,8 +25,10 @@ def __init__(self, cacheDirOrPath: Union[str, Path] = create_tmp_dir()):
25
25
"""Initialize BiocFileCache.
26
26
27
27
Args:
28
- cacheDirOrPath (Union[str, Path], optional): Path to cache.
29
- directory. Defaults to tmp location, `create_tmp_dir()`.
28
+ cacheDirOrPath:
29
+ Path to cache directory.
30
+
31
+ Defaults to tmp location, :py:func:`~.utils.create_tmp_dir`.
30
32
31
33
Raises:
32
34
Exception: Failed to initialize cache.
@@ -51,38 +53,54 @@ def add(
51
53
self ,
52
54
rname : str ,
53
55
fpath : Union [str , Path ],
54
- rtype : str = "local" ,
55
- action : str = "copy" ,
56
+ rtype : Literal [ "local" , "web" , "relative" ] = "local" ,
57
+ action : Literal [ "copy" , "move" , "asis" ] = "copy" ,
56
58
ext : bool = False ,
57
59
) -> Resource :
58
60
"""Add a resource from the provided `fpath` to cache as `rname`.
59
61
60
62
Args:
61
- rname (str): Name of the resource to add to cache.
62
- fpath (Union[str, Path]): Location of the resource.
63
- rtype (str, optional): One of `"local"`, `"web"`, or `"relative"`.
64
- Defaults to `"local"`.
65
- action (str, optional): Either `"copy"`, `"move"` or `"asis"`.
66
- Defaults to `"copy"`.
67
- ext (bool, optional): Use filepath extension when storing in cache.
68
- Defaults to `False`.
63
+ rname:
64
+ Name of the resource to add to cache.
69
65
70
- Returns:
71
- Resource: Database record of the new resource in cache.
66
+ fpath:
67
+ Location of the resource.
68
+
69
+ rtype:
70
+ One of ``local``, ``web``, or ``relative``.
71
+ Defaults to ``local``.
72
+
73
+ action:
74
+ Either ``copy``, ``move`` or ``asis``.
75
+ Defaults to ``copy``.
76
+
77
+ ext:
78
+ Whether to use filepath extension when storing in cache.
79
+ Defaults to `False`.
72
80
73
81
Raises:
74
- NoFpathError: When the `fpath` does not exist.
75
- RnameExistsError: When the `rname` already exists in the cache.
76
- sqlalchemy exceptions: When something is up with the cache.
82
+ NoFpathError:
83
+ When the `fpath` does not exist.
84
+
85
+ RnameExistsError:
86
+ When the `rname` already exists in the cache.
87
+ sqlalchemy exceptions: When something is up with the cache.
88
+
89
+ Returns:
90
+ Database record of the new resource in cache.
77
91
"""
78
92
if isinstance (fpath , str ):
79
93
fpath = Path (fpath )
80
94
81
95
if not fpath .exists ():
82
- raise NoFpathError (f"Resource at { fpath } does not exist." )
96
+ raise NoFpathError (f"Resource at ' { fpath } ' does not exist." )
83
97
84
98
rid = generate_id ()
85
- rpath = f"{ self .cache } /{ rid } " + (f".{ fpath .suffix } " if ext else "" )
99
+ rpath = (
100
+ f"{ self .cache } /{ rid } " + (f".{ fpath .suffix } " if ext else "" )
101
+ if action != "asis"
102
+ else str (fpath )
103
+ )
86
104
87
105
# create new record in the database
88
106
res = Resource (
@@ -123,11 +141,15 @@ def query(self, query: str, field: str = "rname") -> List[Resource]:
123
141
"""Search cache for a resource.
124
142
125
143
Args:
126
- query (str): query or keywords to search.
127
- field (str, optional): Field to search. Defaults to "rname".
144
+ query:
145
+ Query string or keywords to search.
146
+
147
+ field:
148
+ Field to search.
149
+ Defaults to "rname".
128
150
129
151
Returns:
130
- List[Resource]: list of matching resources from cache.
152
+ List of matching resources from cache.
131
153
"""
132
154
with self .sessionLocal () as session :
133
155
return (
@@ -140,11 +162,14 @@ def _get(self, session: Session, rname: str) -> Optional[Resource]:
140
162
"""Get a resource with `rname` from given `Session`.
141
163
142
164
Args:
143
- session (Session): The `Session` object to use.
144
- rname (str): The `rname` of the `Resource` to get.
165
+ session:
166
+ The `Session` object to use.
167
+
168
+ rname:
169
+ The `rname` of the `Resource` to get.
145
170
146
171
Returns:
147
- (Resource, optional): The `Resource` for the `rname` if any .
172
+ The `Resource` for the `rname` if available .
148
173
"""
149
174
resource : Optional [Resource ] = (
150
175
session .query (Resource ).filter (Resource .rname == rname ).first ()
@@ -169,18 +194,20 @@ def get(self, rname: str) -> Optional[Resource]:
169
194
"""Get resource by name from cache.
170
195
171
196
Args:
172
- rname (str): Name of the file to search.
197
+ rname:
198
+ Name of the file to search.
173
199
174
200
Returns:
175
- Optional[Resource]: matched resource from cache if exists.
201
+ Matched `Resource` from cache if exists.
176
202
"""
177
203
return self ._get (self .sessionLocal (), rname )
178
204
179
205
def remove (self , rname : str ) -> None :
180
206
"""Remove a resource from cache by name.
181
207
182
208
Args:
183
- rname (str): Name of the resource to remove.
209
+ rname:
210
+ Name of the resource to remove.
184
211
"""
185
212
with self .sessionLocal () as session :
186
213
res : Optional [Resource ] = self ._get (session , rname )
@@ -196,18 +223,30 @@ def purge(self):
196
223
for file in os .scandir (self .cache ):
197
224
os .remove (file .path )
198
225
226
+ return True
227
+
199
228
def update (
200
- self , rname : str , fpath : Union [str , Path ], action : str = "copy"
229
+ self ,
230
+ rname : str ,
231
+ fpath : Union [str , Path ],
232
+ action : Literal ["copy" , "move" , "asis" ] = "copy" ,
201
233
) -> Resource :
202
234
"""Update a resource in cache.
203
235
204
236
Args:
205
- rname (str): name of the resource in cache.
206
- fpath (Union[str, Path]): new resource to replace existing file in cache.
207
- action (str, optional): either copy of move. defaults to copy.
237
+ rname:
238
+ Name of the resource in cache.
239
+
240
+ fpath:
241
+ New resource to replace existing file in cache.
242
+
243
+ action:
244
+ Either ``copy``, ``move`` or ``asis``.
245
+
246
+ Defaults to ``copy``.
208
247
209
248
Returns:
210
- Resource: Updated resource record in cache.
249
+ Updated resource record in cache.
211
250
"""
212
251
213
252
if isinstance (fpath , str ):
@@ -220,8 +259,12 @@ def update(
220
259
res = self ._get (session , rname )
221
260
222
261
if res is not None :
223
- # copy the file to cache
224
- copy_or_move (str (fpath ), str (res .rpath ), rname , action )
262
+ if action != "asis" :
263
+ # copy the file to cache
264
+ copy_or_move (str (fpath ), str (res .rpath ), rname , action )
265
+ else :
266
+ res .rpath = str (fpath )
267
+
225
268
res .access_time = res .last_modified_time = func .now ()
226
269
session .merge (res )
227
270
session .commit ()
0 commit comments