Skip to content

Commit be84e02

Browse files
committed
restructure delete functionality in backend to handle directories
1 parent 8fa43e6 commit be84e02

File tree

2 files changed

+47
-36
lines changed

2 files changed

+47
-36
lines changed

jupyter_drives/manager.py

Lines changed: 46 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -399,8 +399,22 @@ async def delete_file(self, drive_name, path):
399399
try:
400400
# eliminate leading and trailing backslashes
401401
path = path.strip('/')
402-
await obs.delete_async(self._content_managers[drive_name]["store"], path)
403402

403+
# get list of contents with given prefix (path)
404+
stream = obs.list(self._content_managers[drive_name]["store"], path, chunk_size=100, return_arrow=True)
405+
async for batch in stream:
406+
contents_list = pyarrow.record_batch(batch).to_pylist()
407+
# delete each object within directory
408+
for object in contents_list:
409+
await obs.delete_async(self._content_managers[drive_name]["store"], object["path"])
410+
411+
# delete file
412+
await obs.delete_async(self._content_managers[drive_name]["store"], path)
413+
414+
# when dealing with S3 directory, use helping function to delete remaining directories
415+
if self._config.provider == 's3':
416+
await self._delete_directories(drive_name, path)
417+
404418
except Exception as e:
405419
raise tornado.web.HTTPError(
406420
status_code= httpx.codes.BAD_REQUEST,
@@ -507,7 +521,7 @@ def _check_object(self, drive_name, path):
507521

508522
def _create_empty_directory(self, drive_name, path):
509523
"""Helping function to create an empty directory, when dealing with S3 buckets.
510-
524+
511525
Args:
512526
drive_name: name of drive where to create object
513527
path: path of new object
@@ -524,6 +538,36 @@ def _create_empty_directory(self, drive_name, path):
524538
reason=f"The following error occured when creating the directory: {e}",
525539
)
526540

541+
return
542+
543+
async def _delete_directories(self, drive_name, path):
544+
"""Helping function to delete directories, when dealing with S3 buckets.
545+
546+
Args:
547+
drive_name: name of drive where to create object
548+
path: path of new object
549+
"""
550+
try:
551+
location = self._content_managers[drive_name]["location"]
552+
if location not in self._s3_clients:
553+
self._s3_clients[location] = self._s3_session.client('s3', location)
554+
555+
# delete remaining sub-directories
556+
stream = obs.list(self._content_managers[drive_name]["store"], path, chunk_size=100, return_arrow=True)
557+
async for batch in stream:
558+
contents_list = pyarrow.record_batch(batch).to_pylist()
559+
for object in contents_list:
560+
self._s3_clients[location].delete_object(Bucket=drive_name, Key=object["path"]+'/')
561+
562+
# delete main directory
563+
self._s3_clients[location].delete_object(Bucket=drive_name, Key=path+'/')
564+
565+
except Exception as e:
566+
raise tornado.web.HTTPError(
567+
status_code= httpx.codes.BAD_REQUEST,
568+
reason=f"The following error occured when deleting the directory: {e}",
569+
)
570+
527571
return
528572

529573
async def _call_provider(

src/requests.ts

Lines changed: 1 addition & 34 deletions
Original file line numberDiff line numberDiff line change
@@ -254,26 +254,7 @@ export async function deleteObjects(
254254
path: string;
255255
}
256256
) {
257-
// get list of contents with given prefix (path)
258-
const response = await requestAPI<any>(
259-
'drives/' + driveName + '/' + options.path,
260-
'GET'
261-
);
262-
263-
// deleting contents of a directory
264-
if (response.data.length !== undefined && response.data.length !== 0) {
265-
await Promise.all(
266-
response.data.map(async (c: any) => {
267-
return Private.deleteSingleObject(driveName, c.path);
268-
})
269-
);
270-
}
271-
try {
272-
// always deleting the object (file or main directory)
273-
return Private.deleteSingleObject(driveName, options.path);
274-
} catch (error) {
275-
// deleting failed if directory didn't exist and was only part of a path
276-
}
257+
await requestAPI<any>('drives/' + driveName + '/' + options.path, 'DELETE');
277258
}
278259

279260
/**
@@ -476,20 +457,6 @@ export const countObjectNameAppearances = async (
476457
};
477458

478459
namespace Private {
479-
/**
480-
* Helping function for deleting files inside
481-
* a directory, in the case of deleting the directory.
482-
*
483-
* @param driveName
484-
* @param objectPath complete path of object to delete
485-
*/
486-
export async function deleteSingleObject(
487-
driveName: string,
488-
objectPath: string
489-
) {
490-
await requestAPI<any>('drives/' + driveName + '/' + objectPath, 'DELETE');
491-
}
492-
493460
/**
494461
* Helping function for renaming files inside
495462
* a directory, in the case of deleting the directory.

0 commit comments

Comments
 (0)