33import os
44from pathlib import Path
55from time import sleep , time
6- from typing import List , Optional , Union
6+ from typing import List , Literal , Optional , Union
77
88from sqlalchemy import func
99from sqlalchemy .orm import Session
1010
11+ from ._exceptions import NoFpathError , RnameExistsError , RpathTimeoutError
1112from .db import create_schema
1213from .db .schema import Resource
1314from .utils import copy_or_move , create_tmp_dir , generate_id
14- from ._exceptions import NoFpathError , RnameExistsError , RpathTimeoutError
1515
16- __author__ = "jkanche "
16+ __author__ = "Jayaram Kancherla "
1717__copyright__ = "jkanche"
1818__license__ = "MIT"
1919
@@ -25,8 +25,10 @@ def __init__(self, cacheDirOrPath: Union[str, Path] = create_tmp_dir()):
2525 """Initialize BiocFileCache.
2626
2727 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`.
3032
3133 Raises:
3234 Exception: Failed to initialize cache.
@@ -51,38 +53,54 @@ def add(
5153 self ,
5254 rname : str ,
5355 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" ,
5658 ext : bool = False ,
5759 ) -> Resource :
5860 """Add a resource from the provided `fpath` to cache as `rname`.
5961
6062 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.
6965
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`.
7280
7381 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.
7791 """
7892 if isinstance (fpath , str ):
7993 fpath = Path (fpath )
8094
8195 if not fpath .exists ():
82- raise NoFpathError (f"Resource at { fpath } does not exist." )
96+ raise NoFpathError (f"Resource at ' { fpath } ' does not exist." )
8397
8498 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+ )
86104
87105 # create new record in the database
88106 res = Resource (
@@ -123,11 +141,15 @@ def query(self, query: str, field: str = "rname") -> List[Resource]:
123141 """Search cache for a resource.
124142
125143 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".
128150
129151 Returns:
130- List[Resource]: list of matching resources from cache.
152+ List of matching resources from cache.
131153 """
132154 with self .sessionLocal () as session :
133155 return (
@@ -140,11 +162,14 @@ def _get(self, session: Session, rname: str) -> Optional[Resource]:
140162 """Get a resource with `rname` from given `Session`.
141163
142164 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.
145170
146171 Returns:
147- (Resource, optional): The `Resource` for the `rname` if any .
172+ The `Resource` for the `rname` if available .
148173 """
149174 resource : Optional [Resource ] = (
150175 session .query (Resource ).filter (Resource .rname == rname ).first ()
@@ -169,18 +194,20 @@ def get(self, rname: str) -> Optional[Resource]:
169194 """Get resource by name from cache.
170195
171196 Args:
172- rname (str): Name of the file to search.
197+ rname:
198+ Name of the file to search.
173199
174200 Returns:
175- Optional[Resource]: matched resource from cache if exists.
201+ Matched `Resource` from cache if exists.
176202 """
177203 return self ._get (self .sessionLocal (), rname )
178204
179205 def remove (self , rname : str ) -> None :
180206 """Remove a resource from cache by name.
181207
182208 Args:
183- rname (str): Name of the resource to remove.
209+ rname:
210+ Name of the resource to remove.
184211 """
185212 with self .sessionLocal () as session :
186213 res : Optional [Resource ] = self ._get (session , rname )
@@ -196,18 +223,30 @@ def purge(self):
196223 for file in os .scandir (self .cache ):
197224 os .remove (file .path )
198225
226+ return True
227+
199228 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" ,
201233 ) -> Resource :
202234 """Update a resource in cache.
203235
204236 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``.
208247
209248 Returns:
210- Resource: Updated resource record in cache.
249+ Updated resource record in cache.
211250 """
212251
213252 if isinstance (fpath , str ):
@@ -220,8 +259,12 @@ def update(
220259 res = self ._get (session , rname )
221260
222261 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+
225268 res .access_time = res .last_modified_time = func .now ()
226269 session .merge (res )
227270 session .commit ()
0 commit comments