Skip to content

Commit 5c6a43e

Browse files
committed
Simplify implementation and reduce code duplication
1 parent 29f7dd8 commit 5c6a43e

File tree

3 files changed

+31
-48
lines changed

3 files changed

+31
-48
lines changed

gen3workflow/aws_utils.py

Lines changed: 27 additions & 44 deletions
Original file line numberDiff line numberDiff line change
@@ -409,26 +409,6 @@ def create_user_bucket(user_id: str) -> Tuple[str, str, str]:
409409
return user_bucket_name, "ga4gh-tes", config["USER_BUCKETS_REGION"], kms_key_arn
410410

411411

412-
def _get_user_bucket_if_present(user_id: str) -> Optional[str]:
413-
"""
414-
Return the user's bucket name if it exists in S3, else None.
415-
416-
Derives the bucket name from the user_id and checks its existence
417-
using a HeadBucket call. Raises for any AWS errors other than
418-
bucket-not-found.
419-
"""
420-
bucket = get_bucket_name_from_user_id(user_id)
421-
try:
422-
s3_client.head_bucket(Bucket=bucket)
423-
return bucket
424-
except ClientError as e:
425-
code = e.response.get("Error", {}).get("Code")
426-
if code == "404":
427-
logger.warning(f"Bucket '{bucket}' not found for user '{user_id}'.")
428-
return None
429-
raise
430-
431-
432412
def get_all_bucket_objects(user_bucket_name: str) -> list:
433413
"""
434414
Get all objects from the specified S3 bucket.
@@ -492,41 +472,44 @@ def delete_all_bucket_objects(user_id: str, user_bucket_name: str) -> None:
492472
raise Exception(response)
493473

494474

495-
def empty_user_bucket(user_id: str) -> Optional[str]:
496-
bucket = _get_user_bucket_if_present(user_id)
497-
if not bucket:
498-
return None
499-
try:
500-
delete_all_bucket_objects(user_id, bucket)
501-
except Exception as e:
502-
logger.error(
503-
f"Failed to empty the bucket: '{bucket}' for user '{user_id}': {e}"
504-
)
505-
raise
506-
return bucket
507-
508-
509-
def delete_user_bucket(user_id: str) -> Union[str, None]:
475+
def cleanup_user_bucket(user_id: str, delete_bucket: bool = False) -> Union[str, None]:
510476
"""
511-
Deletes all objects from a user's S3 bucket before deleting the bucket itself.
477+
Empty a user's S3 bucket and optionally delete the bucket.
512478
513479
Args:
514-
user_id (str): The user's unique Gen3 ID
480+
user_id: User identifier used to derive the bucket name.
481+
delete_bucket: If True, delete the bucket after removing all objects.
482+
Defaults to False (only objects are removed).
483+
484+
Returns:
485+
Bucket name if it exists and cleanup was performed, otherwise None
486+
if the bucket does not exist.
515487
516488
Raises:
517-
Exception: If there is an error during the deletion process.
489+
Exception: Propagates unexpected errors during cleanup or deletion.
518490
"""
519-
user_bucket_name = _get_user_bucket_if_present(user_id)
520-
logger.info(f"Deleting bucket '{user_bucket_name}' for user '{user_id}'")
521-
if not user_bucket_name:
522-
return None
491+
user_bucket_name = get_bucket_name_from_user_id(user_id)
492+
493+
try:
494+
s3_client.head_bucket(Bucket=user_bucket_name)
495+
except ClientError as e:
496+
error_code = e.response["Error"]["Code"]
497+
if error_code == "404":
498+
logger.warning(
499+
f"Bucket '{user_bucket_name}' not found for user '{user_id}'."
500+
)
501+
return None
523502
try:
524503
delete_all_bucket_objects(user_id, user_bucket_name)
525-
s3_client.delete_bucket(Bucket=user_bucket_name)
504+
if delete_bucket:
505+
logger.info(
506+
f"Initializing delete for bucket '{user_bucket_name}' for user '{user_id}'"
507+
)
508+
s3_client.delete_bucket(Bucket=user_bucket_name)
526509
return user_bucket_name
527510

528511
except Exception as e:
529512
logger.error(
530-
f"Failed to delete bucket '{user_bucket_name}' for user '{user_id}': {e}"
513+
f"Failed to cleanup bucket '{user_bucket_name}' for user '{user_id}': {e}"
531514
)
532515
raise

gen3workflow/routes/storage.py

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -50,7 +50,7 @@ async def delete_user_bucket(request: Request, auth=Depends(Auth)) -> None:
5050
token_claims = await auth.get_token_claims()
5151
user_id = token_claims.get("sub")
5252
logger.info(f"User '{user_id}' deleting their storage bucket")
53-
deleted_bucket_name = aws_utils.delete_user_bucket(user_id)
53+
deleted_bucket_name = aws_utils.cleanup_user_bucket(user_id, delete_bucket=True)
5454

5555
if not deleted_bucket_name:
5656
raise HTTPException(
@@ -85,7 +85,7 @@ async def empty_user_bucket(request: Request, auth=Depends(Auth)) -> None:
8585
token_claims = await auth.get_token_claims()
8686
user_id = token_claims.get("sub")
8787
logger.info(f"User '{user_id}' emptying their storage bucket")
88-
deleted_bucket_name = aws_utils.empty_user_bucket(user_id)
88+
deleted_bucket_name = aws_utils.cleanup_user_bucket(user_id)
8989

9090
if not deleted_bucket_name:
9191
raise HTTPException(

tests/test_misc.py

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -324,7 +324,7 @@ async def test_delete_user_bucket_no_token(client, mock_aws_services):
324324
"""
325325
mock_delete_bucket = MagicMock()
326326
# Delete the bucket
327-
with patch("gen3workflow.aws_utils.delete_user_bucket", mock_delete_bucket):
327+
with patch("gen3workflow.aws_utils.cleanup_user_bucket", mock_delete_bucket):
328328
res = await client.delete("/storage/user-bucket")
329329
assert res.status_code == 401, res.text
330330
assert res.json() == {"detail": "Must provide an access token"}
@@ -346,7 +346,7 @@ async def test_delete_user_bucket_unauthorized(
346346
"""
347347
mock_delete_bucket = MagicMock()
348348
# Delete the bucket
349-
with patch("gen3workflow.aws_utils.delete_user_bucket", mock_delete_bucket):
349+
with patch("gen3workflow.aws_utils.cleanup_user_bucket", mock_delete_bucket):
350350
res = await client.delete(
351351
"/storage/user-bucket",
352352
headers={"Authorization": f"bearer {TEST_USER_TOKEN}"},

0 commit comments

Comments
 (0)