Skip to content

Commit

Permalink
fix: add method to delete a folder and all its content (#793)
Browse files Browse the repository at this point in the history
  • Loading branch information
12rambau committed Jun 20, 2023
2 parents 2fd367f + 29389fc commit 12e7388
Show file tree
Hide file tree
Showing 4 changed files with 68 additions and 17 deletions.
74 changes: 64 additions & 10 deletions sepal_ui/scripts/gee.py
Original file line number Diff line number Diff line change
Expand Up @@ -84,28 +84,30 @@ def is_running(task_descripsion: str) -> ee.batch.Task:


@sd.need_ee
def get_assets(folder: Union[str, Path] = "", asset_list: List[str] = []) -> List[str]:
def get_assets(folder: Union[str, Path] = "") -> List[dict]:
"""Get all the assets from the parameter folder. every nested asset will be displayed.
Args:
folder: the initial GEE folder
asset_list: extra element that you would like to add to the asset list
Returns:
the asset list. each asset is a dict with 3 keys: 'type', 'name' and 'id'
"""
# set the folder
# set the folder and init the list
asset_list = []
folder = str(folder) or ee.data.getAssetRoots()[0]["id"]

# loop in the assets
for asset in ee.data.listAssets({"parent": folder})["assets"]:
if asset["type"] == "FOLDER":
asset_list += [asset]
asset_list = get_assets(asset["name"], asset_list)
else:
def _recursive_get(folder, asset_list):

# loop in the assets
for asset in ee.data.listAssets({"parent": folder})["assets"]:
asset_list += [asset]
if asset["type"] == "FOLDER":
asset_list = _recursive_get(asset["name"], asset_list)

return asset_list
return asset_list

return _recursive_get(folder, asset_list)


@sd.need_ee
Expand Down Expand Up @@ -133,3 +135,55 @@ def is_asset(asset_name: str, folder: Union[str, Path] = "") -> bool:
break

return exist


@sd.need_ee
def delete_assets(asset_id: str, dry_run: bool = True) -> None:
"""Delete the selected asset and all its content.
This method will delete all the files and folders existing in an asset folder. By default a dry run will be launched and if you are satisfyed with the displayed names, change the ``dry_run`` variable to ``False``. No other warnng will be displayed.
.. warning::
If this method is used on the root directory you will loose all your data, it's highly recommended to use a dry run first and carefully review the destroyed files.
Args:
asset_id: the Id of the asset or a folder
dry_run: whether or not a dry run should be launched. dry run will only display the files name without deleting them.
"""
# define the action to execute for each asset based on the dry run mode
def delete(id: str) -> None:
if dry_run is True:
print(f"to be deleted: {id}")
else:
print(f"deleting: {id}")
ee.data.deleteAsset(id)

return

# identify the type of asset
asset_info = ee.data.getAsset(asset_id)

if asset_info["type"] == "FOLDER":

# get all the assets
asset_list = get_assets(folder=asset_id)

# split the files by nesting levels
# we will need to delete the more nested files first
assets_ordered = {}
for asset in asset_list:
lvl = len(asset["id"].split("/"))
assets_ordered.setdefault(lvl, [])
assets_ordered[lvl].append(asset)

# delete all items starting from the more nested one but not folders
assets_ordered = dict(sorted(assets_ordered.items(), reverse=True))
for lvl in assets_ordered:
for i in assets_ordered[lvl]:
delete(i["name"])

# delete the initial folder/asset
delete(asset_id)

return
6 changes: 1 addition & 5 deletions tests/conftest.py
Original file line number Diff line number Diff line change
Expand Up @@ -181,11 +181,7 @@ def gee_dir(_hash: str) -> Optional[Path]:
yield gee_dir

# flush the directory and it's content
ee.data.deleteAsset(str(subfolder / subfolder_fc))
ee.data.deleteAsset(str(subfolder))
ee.data.deleteAsset(str(gee_dir / fc))
ee.data.deleteAsset(str(gee_dir / rand_image))
ee.data.deleteAsset(str(gee_dir))
gee.delete_assets(str(gee_dir), False)

return

Expand Down
3 changes: 2 additions & 1 deletion tests/test_mapping/test_SepalMap.py
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@

import ee
import pytest
from ee.ee_exception import EEException
from ipyleaflet import GeoJSON

from sepal_ui import mapping as sm
Expand Down Expand Up @@ -190,7 +191,7 @@ def test_add_ee_layer_exceptions() -> None:
)
)

with pytest.raises(AttributeError):
with pytest.raises(EEException):
map_.addLayer(geometry, {"invalid_propery": "red", "fillColor": None})

return
Expand Down
2 changes: 1 addition & 1 deletion tests/test_scripts/test_gee.py
Original file line number Diff line number Diff line change
Expand Up @@ -152,6 +152,6 @@ def fake_task(gee_dir: Path, _hash: str, alert: sw.Alert) -> str:

# delete the task asset
gee.wait_for_completion(name, alert)
ee.data.deleteAsset(asset_id)
gee.delete_assets(asset_id, False)

return

0 comments on commit 12e7388

Please sign in to comment.