Tous les produits
Search
Centre de documentation

Object Storage Service:Téléchargement simple (SDK Python V2)

Dernière mise à jour :Aug 25, 2026

Cette rubrique explique comment utiliser la méthode de téléchargement simple pour télécharger un objet d'un compartiment vers un fichier local. Cette méthode est simple et idéale pour télécharger rapidement des fichiers depuis le cloud vers un appareil local.

Remarques sur l'utilisation

L'exemple de code de cette rubrique utilise cn-hangzhou, l'ID de région de Chine (Hangzhou), à titre d'exemple. Par défaut, un endpoint public est utilisé. Si vous souhaitez accéder à OSS depuis d'autres produits Alibaba Cloud dans la même région, utilisez un endpoint interne. Pour plus d'informations sur les régions et les endpoints pris en charge par OSS, consultez Régions et endpoints.

Autorisations

Par défaut, un compte Alibaba Cloud dispose de toutes les autorisations. Les utilisateurs RAM ou les rôles RAM associés à un compte Alibaba Cloud ne disposent d'aucune autorisation par défaut. Le compte Alibaba Cloud ou l'administrateur du compte doit accorder les autorisations d'opération via stratégies RAM ou Bucket Policy.

API

Action

Description

GetObject

oss:GetObject

Télécharge un objet.

oss:GetObjectVersion

Lors du téléchargement d'un objet, si vous spécifiez la version de l'objet via versionId, cette autorisation est requise.

kms:Decrypt

Lors du téléchargement d'un objet, si les métadonnées de l'objet contiennent X-Oss-Server-Side-Encryption: KMS, cette autorisation est requise.

Définition de la méthode

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

Paramètres de requête

Paramètre

Type

Description

request

GetObjectRequest

Les paramètres de la requête. Pour plus d'informations, consultez GetObjectRequest

Valeurs de retour

Type

Description

GetObjectResult

La valeur de retour. Pour plus d'informations, consultez GetObjectResult

Pour la définition complète de la méthode de téléchargement simple, consultez get_object.

Exemple de code

Utilisez le code suivant pour télécharger un objet d'un compartiment vers un fichier local.

import argparse
import alibabacloud_oss_v2 as oss
import os

# Create a command-line argument parser.
parser = argparse.ArgumentParser(description="get object sample")

# Add the --region command-line argument to specify the region in which the bucket is located. This argument is required.
parser.add_argument('--region', help='The region in which the bucket is located.', required=True)
# Add the --bucket command-line argument to specify the name of the bucket. This argument is required.
parser.add_argument('--bucket', help='The name of the bucket.', required=True)
# Add the --endpoint command-line argument to specify the domain name that other services can use to access OSS. This argument is not required.
parser.add_argument('--endpoint', help='The domain names that other services can use to access OSS')
# Add the --key command-line argument to specify the name of the object. This argument is required.
parser.add_argument('--key', help='The name of the object.', required=True)

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

    # Load credentials from environment variables for identity verification.
    credentials_provider = oss.credentials.EnvironmentVariableCredentialsProvider()

    # Load the default configurations of the SDK and set the credentials provider.
    cfg = oss.config.load_default()
    cfg.credentials_provider = credentials_provider

    # Set the region in the configuration.
    cfg.region = args.region

    # If an endpoint is provided, set the endpoint in the configuration.
    if args.endpoint is not None:
        cfg.endpoint = args.endpoint

    # Use the configured information to create an OSS client.
    client = oss.Client(cfg)

    # Execute a request to get the object. Specify the bucket name and object name.
    result = client.get_object(oss.GetObjectRequest(
        bucket=args.bucket,  # Specify the bucket name.
        key=args.key,  # Specify the object key.
    ))

    # Print the result of getting the object to check whether the request is successful.
    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 the entire object ==========
    with result.body as body_stream:
        data = body_stream.read()
        print(f"The file is read. Data length: {len(data)} bytes")

        path = "./get-object-sample.txt"
        with open(path, 'wb') as f:
            f.write(data)
        print(f"The file is downloaded and saved to the path: {path}")

    # # ========== Method 2: Read in chunks ==========
    # 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 256 KB block size. You can change the block_size parameter based on your needs.
    #         for chunk in body_stream.iter_bytes(block_size=256 * 1024):
    #             f.write(chunk)
    #             total_size += len(chunk)
    #             print(f"Data block received: {len(chunk)} bytes | Total: {total_size} bytes")

    #     print(f"The file is downloaded and saved to the path: {chunk_path}")

# When this script is run directly, the main function is called.
if __name__ == "__main__":
    main()  # The entry point of the script. When the file is run directly, the main function is called.

Scénarios

Téléchargement conditionnel

Lorsque vous téléchargez un seul objet depuis un compartiment, vous pouvez spécifier des conditions basées sur la date de dernière modification ou sur l'ETag de l'objet. L'objet n'est téléchargé que si ces conditions sont remplies. Dans le cas contraire, une erreur est renvoyée et l'opération de téléchargement n'est pas déclenchée. Cela réduit les transmissions réseau et la consommation de ressources inutiles, et améliore l'efficacité du téléchargement.

Le tableau suivant décrit les conditions disponibles.

Remarque
  • if_modified_since et if_unmodified_since peuvent coexister. if_match et if_none_match peuvent également coexister.

  • Vous pouvez utiliser la méthode client.get_object_meta pour obtenir l'ETag.

Paramètre

Description

if_modified_since

Si l'heure spécifiée est antérieure à l'heure de la dernière modification d'un objet, l'objet peut être téléchargé. Sinon, 304 Not modified est renvoyé.

if_unmodified_since

Si l'heure spécifiée est postérieure ou égale à l'heure de la dernière modification d'un objet, l'objet peut être téléchargé. Sinon, 412 Precondition failed est renvoyé.

if_match

Si l'ETag spécifié correspond à celui d'un objet, l'objet peut être téléchargé. Sinon, 412 Precondition failed est renvoyé.

if_none_match

Si l'ETag spécifié ne correspond pas à celui d'un objet, l'objet peut être téléchargé. Sinon, 304 Not modified est renvoyé.

L'exemple de code suivant montre comment utiliser le téléchargement conditionnel.

import argparse
import alibabacloud_oss_v2 as oss
from datetime import datetime, timezone

# Create a command-line argument parser and describe the purpose of the script: get object and save to file sample.
parser = argparse.ArgumentParser(description="get object to file sample")

# Add the --region command-line argument to specify the region in which the bucket is located. This argument is required.
parser.add_argument('--region', help='The region in which the bucket is located.', required=True)
# Add the --bucket command-line argument to specify the name of the bucket from which to get the object. This argument is required.
parser.add_argument('--bucket', help='The name of the bucket.', required=True)
# Add the --endpoint command-line argument to specify the domain name that other services can use to access OSS. This argument is not required.
parser.add_argument('--endpoint', help='The domain names that other services can use to access OSS')
# Add the --key command-line argument to specify the key of the object (file) in OSS. This argument is required.
parser.add_argument('--key', help='The name of the object.', required=True)
# Add the --file_path command-line argument to specify the local path of the downloaded file. This argument is required.
parser.add_argument('--file_path', help='The path of the file to save the downloaded content.', required=True)

def main():
    # Parse the command-line arguments to get the user-input values.
    args = parser.parse_args()

    # Load the credentials required to access OSS from environment variables for identity verification.
    credentials_provider = oss.credentials.EnvironmentVariableCredentialsProvider()

    # Use the default configurations of the SDK to create a configuration object and set the credentials provider.
    cfg = oss.config.load_default()
    cfg.credentials_provider = credentials_provider
    
    # Set the region property of the configuration object based on the command-line arguments.
    cfg.region = args.region

    # If a custom endpoint is provided, update the endpoint property of the configuration object.
    if args.endpoint is not None:
        cfg.endpoint = args.endpoint

    # Use the preceding configurations to initialize the OSS client to interact with OSS.
    client = oss.Client(cfg)

    # Define the if_modified_since time.
    # Only objects modified after this time are returned.
    if_modified_since = datetime(2024, 10, 1, 12, 0, 0, tzinfo=timezone.utc)

    # Assume that the ETag is DA5223EFCD7E0353BE08866700000000. If the specified ETag is the same as the ETag of the object, the IfMatch condition is met and the download is triggered.
    etag = "\"DA5223EFCD7E0353BE08866700000000\""

    # Execute the request to get the object and save it to a local file.
    result = client.get_object_to_file(
        oss.GetObjectRequest(
            bucket=args.bucket,  # Specify the bucket name.
            key=args.key,        # Specify the object key.
            if_modified_since=if_modified_since,  # Only objects modified after the specified time are returned.
            if_match=etag,       # Only objects with a matching ETag are returned.
        ),
        args.file_path  # Specify the local path to which the file is downloaded.
    )

    # Print the result of getting the object, including the status code and request ID.
    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},'
          f' server time: {result.headers.get("x-oss-server-time")},'
    )

# When this script is run directly, call the main function to start the processing logic.
if __name__ == "__main__":
    main()  # The entry point of the script. The program flow starts from here.

Afficher une barre de progression pour le téléchargement de fichiers

Lorsque vous téléchargez un fichier, vous pouvez utiliser une barre de progression pour surveiller la progression du téléchargement en temps réel. Cela vous aide à suivre l'état du téléchargement et à confirmer que la tâche se déroule comme prévu, ce qui est particulièrement utile pour les téléchargements de longue durée.

L'exemple de code suivant montre comment afficher une barre de progression lors du téléchargement d'un objet vers un fichier local. La méthode get_object_to_file est utilisée à titre d'exemple.

import argparse
import alibabacloud_oss_v2 as oss

# Create a command-line argument parser and describe the purpose of the script: get object sample.
parser = argparse.ArgumentParser(description="get object sample")

# Add the --region command-line argument to specify the region in which the bucket is located. This argument is required.
parser.add_argument('--region', help='The region in which the bucket is located.', required=True)
# Add the --bucket command-line argument to specify the name of the bucket from which to get the object. This argument is required.
parser.add_argument('--bucket', help='The name of the bucket.', required=True)
# Add the --endpoint command-line argument to specify the domain name that other services can use to access OSS. This argument is not required.
parser.add_argument('--endpoint', help='The domain names that other services can use to access OSS')
# Add the --key command-line argument to specify the key of the object (file) in OSS. This argument is required.
parser.add_argument('--key', help='The name of the object.', required=True)

def main():
    # Parse the command-line arguments to get the user-input values.
    args = parser.parse_args()

    # Load the credentials required to access OSS from environment variables for identity verification.
    credentials_provider = oss.credentials.EnvironmentVariableCredentialsProvider()

    # Use the default configurations of the SDK to create a configuration object and set the credentials provider.
    cfg = oss.config.load_default()
    cfg.credentials_provider = credentials_provider

    # Set the region property of the configuration object based on the command-line arguments.
    cfg.region = args.region

    # If a custom endpoint is provided, update the endpoint property of the configuration object.
    if args.endpoint is not None:
        cfg.endpoint = args.endpoint

    # Use the preceding configurations to initialize the OSS client to interact with OSS.
    client = oss.Client(cfg)

    # Define a dictionary variable progress_state to save the download progress status. The initial value is 0.
    progress_state = {'saved': 0}
    
    # Define the progress callback function _progress_fn.
    def _progress_fn(n, written, total):
        # Use a dictionary to store the accumulated number of written bytes.
        progress_state['saved'] += n

        # Calculate the current download percentage. Divide the number of written bytes by the total number of bytes and round down the result to an integer.
        rate = int(100 * (float(written) / float(total)))

        # Print the current download progress. \r indicates returning to the beginning of the line to implement real-time refresh in the command line.
        # end='' indicates no line break, so that the next print overwrites the current line.
        print(f'\r{rate}% ', end='')

    # Execute the request to get the object. Specify the bucket name, object name, and progress callback function.
    result = client.get_object_to_file(
        oss.GetObjectRequest(
            bucket=args.bucket,  # Specify the bucket name.
            key=args.key,        # Specify the object key.
            progress_fn=_progress_fn, # Specify the progress callback function.
        ),
        "/local/dir/example", # Specify the local path to which the file is saved.
    )

    # Print the result of getting the object.
    print(vars(result))

# When this script is run directly, call the main function to start the processing logic.
if __name__ == "__main__":
    main()  # The entry point of the script. The program flow starts from here.

L'exemple de code suivant montre comment afficher une barre de progression pour un téléchargement en flux continu. La méthode get_object est utilisée à titre d'exemple.

import argparse
import alibabacloud_oss_v2 as oss
import os

# Create a command-line argument parser.
parser = argparse.ArgumentParser(description="get object sample")

# Add the --region command-line argument to specify the region in which the bucket is located. This argument is required.
parser.add_argument('--region', help='The region in which the bucket is located.', required=True)
# Add the --bucket command-line argument to specify the name of the bucket. This argument is required.
parser.add_argument('--bucket', help='The name of the bucket.', required=True)
# Add the --endpoint command-line argument to specify the domain name that other services can use to access OSS. This argument is not required.
parser.add_argument('--endpoint', help='The domain names that other services can use to access OSS')
# Add the --key command-line argument to specify the name of the object. This argument is required.
parser.add_argument('--key', help='The name of the object.', required=True)

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

    # Load the credentials required to access OSS from environment variables for identity verification.
    credentials_provider = oss.credentials.EnvironmentVariableCredentialsProvider()

    # Load the default configurations of the SDK and set the credentials provider.
    cfg = oss.config.load_default()
    cfg.credentials_provider = credentials_provider

    # Set the region in the configuration.
    cfg.region = args.region

    # If an endpoint is provided, set the endpoint in the configuration.
    if args.endpoint is not None:
        cfg.endpoint = args.endpoint

    # Use the configured information to create an OSS client.
    client = oss.Client(cfg)

    # Execute a request to get the object. Specify the bucket name and object name.
    result = client.get_object(oss.GetObjectRequest(
        bucket=args.bucket,  # Specify the bucket name.
        key=args.key,  # Specify the object key.
    ))

    # The result returned for getting the object contains the total size of the file in bytes.
    total_size = result.content_length

    # Initialize the progress counter to 0 to record the amount of downloaded data.
    progress_save_n = 0

    # Traverse the data blocks in the response body to read data block by block.
    for d in result.body.iter_bytes():
        # Add the length of the current data block to the total downloaded amount.
        progress_save_n += len(d)

        # Calculate the current download percentage. Convert the ratio of the downloaded amount to the total size to a percentage and round it down to an integer.
        rate = int(100 * (float(progress_save_n) / float(total_size)))

        # Print the current download progress. \r indicates returning to the beginning of the line to implement real-time refresh in the command line.
        # end='' indicates no line break, so that the next print overwrites the current line.
        print(f'\r{rate}% ', end='')

    # Print all property information of the result object for debugging or viewing the complete response content.
    print(vars(result))

# When this script is run directly, the main function is called.
if __name__ == "__main__":
    main()  # The entry point of the script. When the file is run directly, the main function is called.

Télécharger des fichiers par lots vers un appareil local

#!/usr/bin/env python3
# -*- coding: utf-8 -*-

import argparse
import alibabacloud_oss_v2 as oss
import os
import sys
import threading
import time
from concurrent.futures import ThreadPoolExecutor, as_completed
from pathlib import Path
from typing import List, Tuple, Optional
import signal

class DownloadTask:
    """Download task class"""
    def __init__(self, object_key: str, local_path: str, size: int):
        self.object_key = object_key
        self.local_path = local_path
        self.size = size

class DownloadResult:
    """Download result class"""
    def __init__(self, object_key: str, success: bool = False, error: Optional[str] = None, size: int = 0):
        self.object_key = object_key
        self.success = success
        self.error = error
        self.size = size

class BatchDownloader:
    """Batch downloader"""

    def __init__(self, client: oss.Client, bucket: str, max_workers: int = 5):
        self.client = client
        self.bucket = bucket
        self.max_workers = max_workers
        self.stop_event = threading.Event()

    def list_objects(self, prefix: str = "", max_keys: int = 1000) -> List[DownloadTask]:
        """List all objects that have the specified prefix in the bucket."""
        tasks = []
        continuation_token = None

        print(f"Scanning files in the bucket...")

        while not self.stop_event.is_set():
            try:
                # Create a request to list objects.
                request = oss.ListObjectsV2Request(
                    bucket=self.bucket,
                    prefix=prefix,
                    max_keys=max_keys,
                    continuation_token=continuation_token
                )

                # Execute the list operation.
                result = self.client.list_objects_v2(request)

                # Process the list result.
                for obj in result.contents:
                    # Skip folder objects, which end with a forward slash (/) and have a size of 0.
                    if obj.key.endswith('/') and obj.size == 0:
                        continue

                    # Calculate the local file path.
                    relative_path = obj.key[len(prefix):] if prefix else obj.key

                    tasks.append(DownloadTask(
                        object_key=obj.key,
                        local_path=relative_path,
                        size=obj.size
                    ))

                # Check whether there are more objects.
                if not result.next_continuation_token:
                    break
                continuation_token = result.next_continuation_token

            except Exception as e:
                raise Exception(f"Failed to list objects: {str(e)}")

        return tasks

    def download_file(self, task: DownloadTask, local_dir: str) -> DownloadResult:
        """Download a single file."""
        result = DownloadResult(task.object_key, size=task.size)

        try:
            # Calculate the full local file path.
            full_local_path = os.path.join(local_dir, task.local_path)

            # Create the local file directory.
            os.makedirs(os.path.dirname(full_local_path), exist_ok=True)

            # Check whether the file exists and has the same size for resumable download.
            if os.path.exists(full_local_path):
                local_size = os.path.getsize(full_local_path)
                if local_size == task.size:
                    result.success = True
                    return result

            # Create a download request.
            get_request = oss.GetObjectRequest(
                bucket=self.bucket,
                key=task.object_key
            )

            # Execute the download.
            response = self.client.get_object(get_request)

            # Save the file.
            with open(full_local_path, 'wb') as f:
                with response.body as body_stream:
                    # Read and write in chunks.
                    for chunk in body_stream.iter_bytes(block_size=1024 * 1024):  # 1 MB chunks
                        if self.stop_event.is_set():
                            raise Exception("Download interrupted")
                        f.write(chunk)

            result.success = True

        except Exception as e:
            result.error = str(e)
            # If the download fails, delete the incomplete file.
            try:
                if os.path.exists(full_local_path):
                    os.remove(full_local_path)
            except:
                pass

        return result

    def batch_download(self, tasks: List[DownloadTask], local_dir: str) -> List[DownloadResult]:
        """Execute batch download."""
        results = []
        completed = 0
        total = len(tasks)

        print(f"Start to download {total} files using {self.max_workers} concurrent threads...")

        with ThreadPoolExecutor(max_workers=self.max_workers) as executor:
            # Submit all download tasks.
            future_to_task = {
                executor.submit(self.download_file, task, local_dir): task
                for task in tasks
            }

            # Process completed tasks.
            for future in as_completed(future_to_task):
                if self.stop_event.is_set():
                    break

                task = future_to_task[future]
                try:
                    result = future.result()
                    results.append(result)
                    completed += 1

                    # Display the progress.
                    if result.success:
                        print(f"✓ [{completed}/{total}] {result.object_key} ({self.format_bytes(result.size)})")
                    else:
                        print(f"✗ [{completed}/{total}] {result.object_key} - Error: {result.error}")

                except Exception as e:
                    result = DownloadResult(task.object_key, error=str(e), size=task.size)
                    results.append(result)
                    completed += 1
                    print(f"✗ [{completed}/{total}]

Exemples d'utilisation

# Download all files with the prefix images/2024/ from the my-bucket bucket.
python batch_download.py --region cn-hangzhou --bucket my-bucket --prefix images/2024/

# Download files to a specified local directory.
python batch_download.py --region cn-hangzhou --bucket my-bucket --prefix documents/ --local-dir ./my-downloads

# Use more concurrent workers for the download.
python batch_download.py --region cn-hangzhou --bucket my-bucket --prefix videos/ --workers 10

# Download all files in the bucket by either omitting the prefix parameter or specifying an empty string as the prefix.
python batch_download.py --region cn-hangzhou --bucket my-bucket

# Alternatively, explicitly specify an empty prefix.
python batch_download.py --region cn-hangzhou --bucket my-bucket --prefix ""

Exemple de sortie

Le programme affiche la progression détaillée du téléchargement au moment de l'exécution :

Starting batch download
Bucket: my-bucket
Prefix: 'images/2024/'
Local directory: ./downloads
Concurrency: 5
--------------------------------------------------
Scanning files in the bucket...
Found 150 files to download
--------------------------------------------------
Starting to download 150 files using 5 concurrent threads...
✓ [1/150] images/2024/photo1.jpg (2.3 MB)
✓ [2/150] images/2024/photo2.png (1.8 MB)
✗ [3/150] images/2024/photo3.gif - Error: Request timeout
✓ [4/150] images/2024/subfolder/photo4.jpg (3.1 MB)
...
✓ [150/150] images/2024/thumbnails/thumb150.jpg (256.0 KB)
--------------------------------------------------
Download complete!
Success: 148
Failed: 2
Total size: 1.2 GB
Duration: 45.67 seconds

Failed files:
  - images/2024/photo3.gif: Request timeout
  - images/2024/corrupted.jpg: Invalid response

Références