By default, if you upload an object that has the same name as an existing object, the existing object is overwritten by the uploaded object. This topic describes how to configure the x-oss-forbid-overwrite request header to prevent existing objects from being overwritten by objects with the same names when you copy objects or perform simple upload or multipart upload.
Usage notes
In this topic, the public endpoint of the China (Hangzhou) region is used. If you want to access OSS from other Alibaba Cloud services in the same region as OSS, use an internal endpoint. For more information about OSS regions and endpoints, see Regions, endpoints and open ports.
In this topic, access credentials are obtained from environment variables. For more information about how to configure access credentials, see Configure access credentials.
In this topic, an OSSClient instance is created by using an OSS endpoint. If you want to create an OSSClient instance by using custom domain names or Security Token Service (STS), see Initialization.
Prevent overwrites in a simple upload task
The following sample code provides an example on how to prevent existing objects from being overwritten by objects that have the same names when you perform simple upload:
# -*- coding: utf-8 -*-
import oss2
from oss2.credentials import EnvironmentVariableCredentialsProvider
# Obtain access credentials from environment variables. Before you run the sample code, make sure that the OSS_ACCESS_KEY_ID and OSS_ACCESS_KEY_SECRET environment variables are configured.
auth = oss2.ProviderAuthV4(EnvironmentVariableCredentialsProvider())
# Specify the endpoint of the region in which the bucket is located. For example, if the bucket is located in the China (Hangzhou) region, set the endpoint to https://oss-cn-hangzhou.aliyuncs.com.
endpoint = "https://oss-cn-hangzhou.aliyuncs.com"
# Specify the ID of the region that maps to the endpoint. Example: cn-hangzhou. This parameter is required if you use the signature algorithm V4.
region = "cn-hangzhou"
# Specify the name of your bucket.
bucket = oss2.Bucket(auth, endpoint, "yourBucketName", region=region)
# Upload the object.
# Specify whether the object that is uploaded by calling the PutObject operation overwrites the existing object that has the same name.
# By default, if x-oss-forbid-overwrite is not specified, the object that is uploaded overwrites the existing object that has the same name.
# If x-oss-forbid-overwrite is set to false, the object that is uploaded overwrites the existing object that has the same name.
# If x-oss-forbid-overwrite is set to true, the object that is uploaded cannot overwrite the existing object that has the same name. If an object that has the same name exists in the bucket, OSS returns an error.
headers = {'x-oss-forbid-overwrite': 'true'}
result = bucket.put_object('yourObjectName', 'content of object', headers=headers)
# Display the returned HTTP status code.
print('http status: {0}'.format(result.status))
# Display the request ID. A request ID uniquely identifies a request. We recommend that you add this parameter to the logs.
print('request_id: {0}'.format(result.request_id))
# Display the ETag value returned by the put_object method.
print('ETag: {0}'.format(result.etag))
# Display the HTTP response headers.
print('date: {0}'.format(result.headers['date']))
Prevent overwrites in an object copy task
Copy a small object
The following sample code provides an example on how to copy a small object without overwriting the existing object that has the same name:
# -*- coding: utf-8 -*- import oss2 from oss2.credentials import EnvironmentVariableCredentialsProvider # Obtain access credentials from environment variables. Before you run the sample code, make sure that the OSS_ACCESS_KEY_ID and OSS_ACCESS_KEY_SECRET environment variables are configured. auth = oss2.ProviderAuth(EnvironmentVariableCredentialsProvider()) # Specify the endpoint of the region in which the bucket is located. For example, if the bucket is located in the China (Hangzhou) region, set the endpoint to https://oss-cn-hangzhou.aliyuncs.com. # Specify the name of your bucket. bucket = oss2.Bucket(auth, 'https://oss-cn-hangzhou.aliyuncs.com', 'yourBucketName') # Specify whether the object that is copied by calling the copy_object operation overwrites the existing object that has the same name. # By default, if x-oss-forbid-overwrite is not specified, an existing object is overwritten by a copied object with the same name. # If x-oss-forbid-overwrite is set to false, an existing object is overwritten by a copied object with the same name. # If x-oss-forbid-overwrite is set to true, an existing object is not overwritten by a copied object with the same name. If the existing object has the same name as the copied object, an error is reported. headers = dict() headers = {'x-oss-forbid-overwrite':'true'} bucket.copy_object('yourSourceBucketName', 'yourSourceObjectName', 'yourDestinationObjectName', headers=headers)
Copy a large object
The following sample code provides an example on how to prevent an existing object from being overwritten by a large object with the same name when you copy the large object by using multipart copy:
# -*- coding: utf-8 -*- import oss2 from oss2.credentials import EnvironmentVariableCredentialsProvider from oss2.models import PartInfo from oss2 import determine_part_size # Obtain access credentials from environment variables. Before you run the sample code, make sure that the OSS_ACCESS_KEY_ID and OSS_ACCESS_KEY_SECRET environment variables are configured. auth = oss2.ProviderAuthV4(EnvironmentVariableCredentialsProvider()) # Specify the endpoint of the region in which the bucket is located. For example, if the bucket is located in the China (Hangzhou) region, set the endpoint to https://oss-cn-hangzhou.aliyuncs.com. endpoint = "https://oss-cn-hangzhou.aliyuncs.com" # Specify the ID of the region that maps to the endpoint. Example: cn-hangzhou. This parameter is required if you use the signature algorithm V4. region = "cn-hangzhou" # Specify the name of your bucket. bucket = oss2.Bucket(auth, endpoint, "yourBucketName", region=region) src_object = 'yourSourceObjectName' dst_object = 'yourDestinationObjectName' total_size = bucket.head_object(src_object).content_length part_size = determine_part_size(total_size, preferred_size=100 * 1024) # Initiate a multipart upload task. # Specify whether to overwrite an object that has the same name when you copy an object. # By default, if x-oss-forbid-overwrite is not specified, the object that is copied overwrites the existing object that has the same name. # If x-oss-forbid-overwrite is set to false, the object that is copied overwrites the existing object that has the same name. # If x-oss-forbid-overwrite is set to true, an existing object is not overwritten by a copied object with the same name. If the existing object has the same name as the copied object, an error is reported. headers = dict() headers = {'x-oss-forbid-overwrite': 'true'} upload_id = bucket.init_multipart_upload(dst_object, headers=headers).upload_id parts = [] # Copy each part. part_number = 1 offset = 0 while offset < total_size: num_to_upload = min(part_size, total_size - offset) byte_range = (offset, offset + num_to_upload - 1) result = bucket.upload_part_copy(bucket.bucket_name, src_object, byte_range,dst_object, upload_id, part_number) parts.append(PartInfo(part_number, result.etag)) offset += num_to_upload part_number += 1 # Complete the multipart copy task. # Specify whether to overwrite an object that has the same name when you copy an object. # By default, if x-oss-forbid-overwrite is not specified, the object that is uploaded overwrites the existing object that has the same name. # If x-oss-forbid-overwrite is set to false, the object that is uploaded overwrites the existing object that has the same name. # If x-oss-forbid-overwrite is set to true, an existing object is not overwritten by a copied object with the same name. If the existing object has the same name as the copied object, an error is reported. headers = dict() headers = {'x-oss-forbid-overwrite':'true'} bucket.complete_multipart_upload(dst_object, upload_id, parts, headers=headers)
Prevent overwrites in a multipart upload task
The following sample code provides an example on how to prevent an existing object from being overwritten by an object with the same name when you use multipart upload to upload the object:
# -*- coding: utf-8 -*-
import os
from oss2 import SizedFileAdapter, determine_part_size
from oss2.models import PartInfo
import oss2
from oss2.credentials import EnvironmentVariableCredentialsProvider
# Obtain access credentials from environment variables. Before you run the sample code, make sure that the OSS_ACCESS_KEY_ID and OSS_ACCESS_KEY_SECRET environment variables are configured.
auth = oss2.ProviderAuthV4(EnvironmentVariableCredentialsProvider())
# Specify the endpoint of the region in which the bucket is located. For example, if the bucket is located in the China (Hangzhou) region, set the endpoint to https://oss-cn-hangzhou.aliyuncs.com.
endpoint = "https://oss-cn-hangzhou.aliyuncs.com"
# Specify the ID of the region that maps to the endpoint. Example: cn-hangzhou. This parameter is required if you use the signature algorithm V4.
region = "cn-hangzhou"
# Specify the name of your bucket.
bucket = oss2.Bucket(auth, endpoint, "yourBucketName", region=region)
key = 'yourObjectName'
filename = 'yourLocalFile'
total_size = os.path.getsize(filename)
# Specify the determine_part_size method to determine the part size.
part_size = determine_part_size(total_size, preferred_size=100 * 1024)
# Initiate a multipart upload task.
# Specify whether to overwrite the existing object that has the same name when you perform multipart upload.
# By default, if x-oss-forbid-overwrite is not specified, the object that is uploaded overwrites the existing object that has the same name.
# If x-oss-forbid-overwrite is set to false, the object that is uploaded overwrites the existing object that has the same name.
# If x-oss-forbid-overwrite is set to true, the object that is uploaded cannot overwrite the existing object that has the same name. If an object that has the same name exists in the bucket, OSS returns an error.
headers = {'x-oss-forbid-overwrite': 'true'}
upload_id = bucket.init_multipart_upload(key, headers=headers).upload_id
parts = []
# Upload the parts.
with open(filename, 'rb') as fileobj:
part_number = 1
offset = 0
while offset < total_size:
num_to_upload = min(part_size, total_size - offset)
# The SizedFileAdapter(fileobj, size) method generates a new object and recalculates the position from which the append operation starts.
result = bucket.upload_part(key, upload_id, part_number,
SizedFileAdapter(fileobj, num_to_upload))
parts.append(PartInfo(part_number, result.etag))
offset += num_to_upload
part_number += 1
# Complete the multipart upload task.
# Specify whether to overwrite the existing object that has the same name when you perform multipart upload.
# By default, if x-oss-forbid-overwrite is not specified, the object that is uploaded overwrites the existing object that has the same name.
# If x-oss-forbid-overwrite is set to false, the object that is uploaded overwrites the existing object that has the same name.
# If x-oss-forbid-overwrite is set to true, the object that is uploaded cannot overwrite the existing object that has the same name. If an object that has the same name exists in the bucket, OSS returns an error.
headers = {'x-oss-forbid-overwrite': 'true'}
bucket.complete_multipart_upload(key, upload_id, parts, headers=headers)
# Verify the result of the multipart upload task.
with open(filename, 'rb') as fileobj:
assert bucket.get_object(key).read() == fileobj.read()
References
For more information about the API operation that you can call to perform simple upload, see PutObject.
For more information about the API operation that you can call to copy an object, see CopyObject.
For more information about the API operations that you can call to perform multipart upload, see InitiateMultipartUpload and CompleteMultipartUpload.