Skip to content

Commit f41d168

Browse files
authored
feat: Add delete_images method to Project class and tests (#424)
Add `delete_images` method to the Project class, allowing users to remove images from a project. Corresponding unit tests have been added to tests/test_project.py to ensure the method functions correctly for both successful deletions and error scenarios.
1 parent 07b639a commit f41d168

File tree

2 files changed

+71
-0
lines changed

2 files changed

+71
-0
lines changed

roboflow/core/project.py

Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -969,3 +969,31 @@ def get_batch(self, batch_id: str) -> Dict:
969969
raise RuntimeError(f"Failed to get batch {batch_id}: {response.text}")
970970

971971
return response.json()
972+
973+
def delete_images(self, image_ids: List[str]):
974+
"""
975+
Delete images from a project.
976+
977+
Args:
978+
image_ids (List[str]): A list of image IDs to delete.
979+
980+
Example:
981+
>>> import roboflow
982+
>>> rf = roboflow.Roboflow(api_key="")
983+
>>> project = rf.workspace().project("PROJECT_ID")
984+
>>> project.delete_images(image_ids=["image_id_1", "image_id_2"])
985+
"""
986+
url = f"{API_URL}/{self.__workspace}/{self.__project_name}/images?api_key={self.__api_key}"
987+
988+
payload = {"images": image_ids}
989+
990+
response = requests.delete(url, headers={"Content-Type": "application/json"}, json=payload)
991+
992+
if response.status_code != 204:
993+
try:
994+
error_data = response.json()
995+
if "error" in error_data:
996+
raise RuntimeError(error_data["error"])
997+
raise RuntimeError(response.text)
998+
except ValueError:
999+
raise RuntimeError(f"Failed to delete images: {response.text}")

tests/test_project.py

Lines changed: 43 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -591,6 +591,49 @@ def test_get_batch_error(self):
591591

592592
self.assertEqual(str(context.exception), "Batch not found")
593593

594+
def test_delete_images_success(self):
595+
image_ids = ["image1.jpg", "image2.jpg"]
596+
expected_url = f"{API_URL}/{WORKSPACE_NAME}/{PROJECT_NAME}/images?api_key={ROBOFLOW_API_KEY}"
597+
598+
responses.add(
599+
responses.DELETE,
600+
expected_url,
601+
status=204,
602+
match=[
603+
json_params_matcher(
604+
{
605+
"images": image_ids,
606+
}
607+
)
608+
],
609+
)
610+
611+
self.project.delete_images(image_ids=image_ids)
612+
613+
def test_delete_images_error(self):
614+
image_ids = ["image1.jpg", "image2.jpg"]
615+
expected_url = f"{API_URL}/{WORKSPACE_NAME}/{PROJECT_NAME}/images?api_key={ROBOFLOW_API_KEY}"
616+
error_response = {"error": "Failed to delete images"}
617+
618+
responses.add(
619+
responses.DELETE,
620+
expected_url,
621+
json=error_response,
622+
status=400,
623+
match=[
624+
json_params_matcher(
625+
{
626+
"images": image_ids,
627+
}
628+
)
629+
],
630+
)
631+
632+
with self.assertRaises(RuntimeError) as context:
633+
self.project.delete_images(image_ids=image_ids)
634+
635+
self.assertEqual(str(context.exception), "Failed to delete images")
636+
594637
def test_classification_dataset_upload(self):
595638
from roboflow.util import folderparser
596639

0 commit comments

Comments
 (0)