Delete one or more objects, or all objects with a given key prefix, from a versioning-enabled bucket using OSS SDK for Python 1.0.
Prerequisites
Before you begin, ensure that you have:
A versioning-enabled OSS bucket
The
oss:DeleteObjectVersionpermission. For details, see Attach a custom policy to a RAM userThe
OSS_ACCESS_KEY_IDandOSS_ACCESS_KEY_SECRETenvironment variables set. For details, see Configure access credentials using OSS SDK for Python 1.0An OSSClient instance initialized with an OSS endpoint. For alternative configurations such as using a custom domain or authenticating with Security Token Service (STS) credentials, see Initialization
How it works
In a versioning-enabled bucket, OSS offers two deletion modes depending on whether you specify a versionId:
| Mode | How to trigger | What happens |
|---|---|---|
| Soft delete | Call delete without a versionId | OSS inserts a delete marker for the object's current version. The object data is preserved. Subsequent GetObject calls return 404 Not Found with the x-oss-delete-marker: true header and the new delete marker's version ID in x-oss-version-id. |
| Permanent delete | Call delete with a versionId | OSS permanently removes that specific object version. To delete a version with ID "null", set params['versionId'] = "null" — OSS treats the string "null" as the version ID null. |
The examples in this topic use the public endpoint for the China (Hangzhou) region (https://oss-cn-hangzhou.aliyuncs.com). To access OSS from other Alibaba Cloud services in the same region, use an internal endpoint instead. For a full list of endpoints, see Regions and endpoints.Delete a single object
Both examples use bucket.delete_object(). Pass a params dict with versionId for a permanent delete; omit params for a soft delete.
Permanent delete
# -*- coding: utf-8 -*-
import oss2
from oss2.credentials import EnvironmentVariableCredentialsProvider
# Load credentials from environment variables.
# Set OSS_ACCESS_KEY_ID and OSS_ACCESS_KEY_SECRET before running this example.
auth = oss2.ProviderAuthV4(EnvironmentVariableCredentialsProvider())
# Replace with the endpoint for your bucket's region.
endpoint = "https://oss-cn-hangzhou.aliyuncs.com"
# Required for V4 signatures.
region = "cn-hangzhou"
bucket = oss2.Bucket(auth, endpoint, "<your-bucket-name>", region=region)
object_name = "<your-object-name>"
# Specify the versionId to permanently delete that version.
# This also works with delete marker versionIds.
params = {"versionId": "<your-version-id>"}
result = bucket.delete_object(object_name, params=params)
print("Deleted object:", object_name)
# If versionId belongs to an object version: delete_marker is None, versionid is the object's version ID.
# If versionId belongs to a delete marker: delete_marker is True, versionid is the delete marker's version ID.
if result.delete_marker:
print("Deleted delete marker, version ID:", result.versionid)
else:
print("Deleted object version ID:", result.versionid)Soft delete
# -*- coding: utf-8 -*-
import oss2
from oss2.credentials import EnvironmentVariableCredentialsProvider
auth = oss2.ProviderAuthV4(EnvironmentVariableCredentialsProvider())
endpoint = "https://oss-cn-hangzhou.aliyuncs.com"
region = "cn-hangzhou"
bucket = oss2.Bucket(auth, endpoint, "<your-bucket-name>", region=region)
object_name = "<your-object-name>"
# No versionId — OSS inserts a delete marker instead of removing the object.
result = bucket.delete_object(object_name)
# result.delete_marker is True; result.versionid is the new delete marker's version ID.
print("Delete marker:", result.delete_marker)
print("Delete marker version ID:", result.versionid)Response fields
| Field | Type | Description |
|---|---|---|
delete_marker | bool or None | True if the deleted version was a delete marker; None if it was an object version. |
versionid | string | Version ID of the deleted entry (object version or delete marker). |
Delete multiple objects
Both examples use oss2.models.BatchDeleteObjectVersion and oss2.models.BatchDeleteObjectVersionList. To permanently delete, build a version list with explicit versionIds. To soft delete, call bucket.batch_delete_objects() with a list of object keys.
Permanent delete
# -*- coding: utf-8 -*-
import oss2
from oss2.credentials import EnvironmentVariableCredentialsProvider
from oss2.models import BatchDeleteObjectVersion, BatchDeleteObjectVersionList
auth = oss2.ProviderAuthV4(EnvironmentVariableCredentialsProvider())
endpoint = "https://oss-cn-hangzhou.aliyuncs.com"
region = "cn-hangzhou"
bucket = oss2.Bucket(auth, endpoint, "<your-bucket-name>", region=region)
# Build a list of (key, versionId) pairs to delete.
# Each entry can be an object version or a delete marker version.
version_list = BatchDeleteObjectVersionList()
version_list.append(BatchDeleteObjectVersion(key="<object-1-name>", versionid="<object-1-version-id>"))
version_list.append(BatchDeleteObjectVersion(key="<object-1-name>", versionid="<object-1-delete-marker-version-id>"))
version_list.append(BatchDeleteObjectVersion(key="<object-2-name>", versionid="<object-2-version-id>"))
version_list.append(BatchDeleteObjectVersion(key="<object-2-name>", versionid="<object-2-delete-marker-version-id>"))
result = bucket.delete_object_versions(version_list)
# result.delete_versions: list of deleted entries.
# Each entry has: .key, .delete_marker (bool), .versionid, .delete_marker_versionid.
for entry in result.delete_versions:
print("Key:", entry.key)
if entry.delete_marker:
print(" Deleted delete marker, version ID:", entry.delete_marker_versionid)
else:
print(" Deleted object version ID:", entry.versionid)Soft delete
# -*- coding: utf-8 -*-
import oss2
from oss2.credentials import EnvironmentVariableCredentialsProvider
auth = oss2.ProviderAuthV4(EnvironmentVariableCredentialsProvider())
endpoint = "https://oss-cn-hangzhou.aliyuncs.com"
region = "cn-hangzhou"
bucket = oss2.Bucket(auth, endpoint, "<your-bucket-name>", region=region)
# Pass a list of object keys without versionIds.
# OSS adds a delete marker to each object; no versions are permanently removed.
key_list = ["<object-1-name>", "<object-2-name>"]
result = bucket.batch_delete_objects(key_list)
# result.delete_versions: list of inserted delete markers.
# Each entry has: .key, .delete_marker (True), .delete_marker_versionid.
for entry in result.delete_versions:
print("Key:", entry.key)
print(" Delete marker:", entry.delete_marker)
print(" Delete marker version ID:", entry.delete_marker_versionid)Response fields (`result.delete_versions` entries)
| Field | Type | Description |
|---|---|---|
key | string | Object key. |
delete_marker | bool | True if the entry is a delete marker; False if it is an object version. |
versionid | string | Version ID of the deleted object version. Empty if a delete marker was deleted. |
delete_marker_versionid | string | Version ID of the deleted (or newly created) delete marker. |
Delete objects by prefix
To delete all object versions and delete markers under a given prefix, list all versions with bucket.list_object_versions() and call bucket.delete_object() for each. The listing is paginated — the loop continues until result.is_truncated is False.
This operation permanently deletes all versions and delete markers for objects under the specified prefix. It cannot be undone.
# -*- coding: utf-8 -*-
import oss2
from oss2.credentials import EnvironmentVariableCredentialsProvider
auth = oss2.ProviderAuth(EnvironmentVariableCredentialsProvider())
bucket = oss2.Bucket(auth, "https://oss-cn-hangzhou.aliyuncs.com", "<your-bucket-name>")
prefix = "<your-key-prefix>"
# Paginate through all versions and delete markers under the prefix.
next_key_marker = None
next_versionid_marker = None
while True:
result = bucket.list_object_versions(
prefix=prefix,
key_marker=next_key_marker,
versionid_marker=next_versionid_marker,
)
# Permanently delete each object version.
for version_info in result.versions:
bucket.delete_object(version_info.key, params={"versionId": version_info.versionid})
# Permanently delete each delete marker.
for del_marker_info in result.delete_marker:
bucket.delete_object(del_marker_info.key, params={"versionId": del_marker_info.versionid})
if result.is_truncated:
next_key_marker = result.next_key_marker
next_versionid_marker = result.next_versionid_marker
else:
breakReplace the following placeholders before running the code:
| Placeholder | Description | Example |
|---|---|---|
<your-bucket-name> | Name of the versioning-enabled bucket | my-bucket |
<your-key-prefix> | Key prefix shared by the objects to delete | logs/2024/ |