All Products
Search
Document Center

Object Storage Service:Range download (Python SDK V2)

Last Updated:Jul 31, 2025

This topic describes how to use range download to efficiently download a specific range of data from an object.

Usage notes

  • The sample code in this topic uses the region ID cn-hangzhou for the China (Hangzhou) region. By default, a public endpoint is used to access resources in a bucket. If you want to access resources in the bucket from other Alibaba Cloud services in the same region, use an internal endpoint. For more information about the regions and endpoints that OSS supports, see OSS regions and endpoints.

  • To use range download, you must have the oss:GetObject permission. For more information, see Grant custom policy to RAM users.

Method definition

get_object(request: GetObjectRequest, **kwargs) → GetObjectResult

Request parameters

Parameter

Type

Description

request

*GetObjectRequest

Set the request parameters for the specific interface, such as setting range_header to specify the download range, and setting range_behavior to specify the standard behavior for range download. For more information, see GetObjectRequest

Response parameters

Type

Description

GetObjectResult

The response to the operation. This parameter is available when the value of err is nil. For more information, see GetObjectResult

Important
  • For an object that is 1,000 bytes in size, the valid range is from byte 0 to byte 999. If the specified range is outside of 0 to 999, the range does not take effect. In this case, OSS returns HTTP status code 200 and the entire object. The following examples show invalid requests and their returned results:

    • If you set Range: bytes to 500-2000, the end of the range is invalid. In this case, OSS returns HTTP status code 200 and the entire object.

    • If you set Range: bytes to 1000-2000, the start of the range is invalid. In this case, OSS returns HTTP status code 200 and the entire object.

  • You can add the x-oss-range-behavior:standard header to the request to modify the download behavior when the specified range is invalid. For an object that is 1,000 bytes in size:

    • If you set Range: bytes to 500-2000, the end of the range is invalid. In this case, OSS returns HTTP status code 206 and the data from byte 500 to byte 999.

    • If you set Range: bytes to 1000-2000, the start of the range is invalid. In this case, OSS returns HTTP status code 416 and the InvalidRange error code.

Sample code

The following code shows how to add the RangeBehavior:standard request header to a request. This header specifies the standard download behavior, which downloads file data within a specified range.

import argparse
import alibabacloud_oss_v2 as oss

# Create a command-line parameter parser.
parser = argparse.ArgumentParser(description="Get object range sample")
# Add necessary command line parameters.
parser.add_argument('--region', help='The region in which the bucket is located.', required=True)
parser.add_argument('--bucket', help='The name of the bucket.', required=True)
parser.add_argument('--endpoint', help='The domain names that other services can use to access OSS')
parser.add_argument('--key', help='The name of the object.', required=True)
parser.add_argument('--range', help='Specify the scope of file transfer. Example value: bytes=0-9', required=True)
parser.add_argument('--range_behavior', help='Standard for downloading behavior within a specified range. Example value: standard.')

def main():
    # Parse the command-line parameters.
    args = parser.parse_args()

    # Load access credentials from environment variables.
    credentials_provider = oss.credentials.EnvironmentVariableCredentialsProvider()

    # Use the default configuration of the SDK.
    cfg = oss.config.load_default()
    # Specify the credential provider.
    cfg.credentials_provider = credentials_provider
    # Specify the region.
    cfg.region = args.region
    # If an endpoint is provided from the command line, update the endpoint in the configuration with the provided endpoint.
    if args.endpoint is not None:
        cfg.endpoint = args.endpoint

    # Create an OSS client.
    client = oss.Client(cfg)

    # Initiate a request to get an object.
    result = client.get_object(oss.GetObjectRequest(
        bucket=args.bucket,  # Specify the name of the bucket
        key=args.key,  # Specify the key name of the object
        range_header=args.range,  # Specify the range header
        range_behavior=args.range_behavior,  # Specify the download behavior within the range
    ))

    # Print multiple attributes in the response.
    print(f'status code: {result.status_code},'
          f' request id: {result.request_id},'
          f' content length: {result.content_length},'
          f' content range: {result.content_range},'
          f' content type: {result.content_type},'
          f' etag: {result.etag},'
          f' last modified: {result.last_modified},'
          f' content md5: {result.content_md5},'
          f' cache control: {result.cache_control},'
          f' content disposition: {result.content_disposition},'
          f' content encoding: {result.content_encoding},'
          f' expires: {result.expires},'
          f' hash crc64: {result.hash_crc64},'
          f' storage class: {result.storage_class},'
          f' object type: {result.object_type},'
          f' version id: {result.version_id},'
          f' tagging count: {result.tagging_count},'
          f' server side encryption: {result.server_side_encryption},'
          f' server side data encryption: {result.server_side_data_encryption},'
          f' next append position: {result.next_append_position},'
          f' expiration: {result.expiration},'
          f' restore: {result.restore},'
          f' process status: {result.process_status},'
          f' delete marker: {result.delete_marker},'
    )

    # ========== Method 1: Read completely ==========
    # Use a context manager to ensure resource release.
    with result.body as body_stream:
        data = body_stream.read()
        print(f"File read completed, data length: {len(data)} bytes")

        path = "./get-object-sample.txt"
        with open(path, 'wb') as f:
            f.write(data)
        print(f"File download completed, saved to path: {path}")

    # # ========== Method 2: Read in chunks ==========
    # # Use a context manager to ensure resource release.
    # with result.body as body_stream:
    #     chunk_path = "./get-object-sample-chunks.txt"
    #     total_size = 0

    #     with open(chunk_path, 'wb') as f:
    #         # Use a block size of 256 KB (adjust block_size parameter as needed).
    #         for chunk in body_stream.iter_bytes(block_size=256 * 1024):
    #             f.write(chunk)
    #             total_size += len(chunk)
    #             print(f"Received data block: {len(chunk)} bytes | Total: {total_size} bytes")

    #     print(f"File download completed, saved to path: {chunk_path}")

# Call the main function when the script runs as the main program.
if __name__ == "__main__":
    main()

References