All Products
Search
Document Center

Object Storage Service:Use a presigned URL to download an object with OSS SDK for Python 2.0

Last Updated:Sep 24, 2026

By default, the access control list (ACL) of an object in an Object Storage Service (OSS) bucket is private. Only the object owner has the permissions to access the object. This topic describes how to use OSS SDK for Python to generate a presigned URL that allows a user to download a specific object within the specified period by using the HTTP GET method. Within the validity period, the user can repeatedly access the object by using the presigned URL. If the presigned URL expires, you can regenerate a presigned URL to prolong access for the user.

Usage notes

  • The sample code in this topic uses the region ID cn-hangzhou of the China (Hangzhou) region. By default, the 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 in which the bucket is located, use the internal endpoint. For more information about OSS regions and endpoints, see Regions and endpoints.

  • You do not need permissions to generate a presigned URL. However, for a third party to download the object using the presigned URL, the user who generates the URL must have the oss:GetObject permission. For more information about how to grant permissions, see Grant custom permissions to a RAM user.

  • In this topic, the signature algorithm V4 is used to generate presigned URLs with a validity period of up to 7 days. For more information, see (Recommended) V4 signatures in presigned URLs.

Procedure

The following procedure describes how to download an object using a presigned URL:

image

Method definition

You can call the presign method to generate a presigned URL that grants time-limited access to an OSS object. The presigned URL can be used multiple times before it expires.

The following line shows the syntax of the presign method:

presign(request: GetObjectRequest, **kwargs) → PresignResult

Request parameters

Parameter

Type

Description

request

GetObjectRequest

The API operation that you want the presigned URL to support. For more information, see Client.presign.

expires

datetime.timedelta

The validity period of the presigned URL starting from the current time. This is an optional parameter. For example, if you want to set the validity period to 30 minutes, set expires to 30 * time.Minute. If you do not specify this parameter, the presigned URL will have a default validity period of 15 minutes.

expiration

datetime.datetime

The absolute expiration date and time of the presigned URL. This is an optional parameter.

Important

If you use the V4 signature algorithm, the validity period can be up to seven days. If you specify both expiration and expires, expiration takes precedence.

Response parameters

Type

Description

PresignResult

The returned results, including the presigned URL, HTTP method, expiration time, and request headers specified in the request. For more information, see PresignResult.

Content of PresignResult

Parameter

Type

Description

method

str

The HTTP method, which corresponds to the API operation specified in the presign request. For example, the HTTP method of the GetObject operation is GET.

url

str

The presigned URL.

expiration

datetime

The expiration time of the presigned URL.

signed_headers

MutableMapping

The signed headers specified in the request. For example, if content_type is specified, content_type is returned.

For the more information about the presign method, see presign.

Sample code

  1. Generate a presigned URL that allows HTTP GET requests:

    import argparse
    import alibabacloud_oss_v2 as oss
    
    # Create a command-line parameter parser and describe the purpose of the script.
    parser = argparse.ArgumentParser(description="presign get object sample")
    
    # Specify the --region parameter to indicate the region in which the bucket is located. This parameter is required.
    parser.add_argument('--region', help='The region in which the bucket is located.', required=True)
    # Specify the --bucket parameter to indicate the name of the bucket in which the object is stored. This parameter is required.
    parser.add_argument('--bucket', help='The name of the bucket.', required=True)
    # Specify the --endpoint parameter to indicate the endpoint of the region in which the bucket is located. This parameter is optional.
    parser.add_argument('--endpoint', help='The domain names that other services can use to access OSS')
    # Specify the --key parameter to indicate the name of the object. This parameter is required.
    parser.add_argument('--key', help='The name of the object.', required=True)
    
    def main():
        # Parse the command-line parameters to obtain the specified values.
        args = parser.parse_args()
    
        # From the environment variables, load the authentication information required to access OSS.
        credentials_provider = oss.credentials.EnvironmentVariableCredentialsProvider()
    
        # Use the default configuration to create a cfg object and specify the credential provider.
        cfg = oss.config.load_default()
        cfg.credentials_provider = credentials_provider
        
        # Set the region attribute of the cfg object to the region provided in the command line.
        cfg.region = args.region
    
        # If a custom endpoint is provided, update the endpoint attribute of the cfg object with the provided endpoint.
        if args.endpoint is not None:
            cfg.endpoint = args.endpoint
    
        # Use the preceding settings to initialize the OSSClient instance.
        client = oss.Client(cfg)
    
        # Initiate a request to generate a presigned URL.
        pre_result = client.presign(
            oss.GetObjectRequest(
                bucket=args.bucket,  # Specify the bucket name.
                key=args.key,        # Specify the object key.
            )
        )
    
        # Display the HTTP method, expiration time, and presigned URL.
        print(f'method: {pre_result.method},'
              f' expiration: {pre_result.expiration.strftime("%Y-%m-%dT%H:%M:%S.000Z")},'
              f' url: {pre_result.url}'
        )
    
        # Display the signed headers.
        for key, value in pre_result.signed_headers.items():
            print(f'signed headers key: {key}, signed headers value: {value}')
    
    # Call the main function to start the processing logic when the script is directly run.
    if __name__ == "__main__":
        main()  # Specify the entry point of the script. The control flow starts here.
  2. Use the presigned URL to download the object.

    curl

    curl -SO "https://examplebucket.oss-cn-hangzhou.aliyuncs.com/exampleobject.txt?x-oss-date=20241112T092756Z&x-oss-expires=3599&x-oss-signature-version=OSS4-HMAC-SHA256&x-oss-credential=LTAI****************/20241112/cn-hangzhou/oss/aliyun_v4_request&x-oss-signature=ed5a******************************************************"

    Java

    import java.io.BufferedInputStream;
    import java.io.FileOutputStream;
    import java.io.IOException;
    import java.io.InputStream;
    import java.net.HttpURLConnection;
    import java.net.URL;
    
    public class Demo {
        public static void main(String[] args) {
            // Replace with the generated presigned URL for the GET request.
            String fileURL = "https://examplebucket.oss-cn-hangzhou.aliyuncs.com/exampleobject.txt?x-oss-date=20241112T092756Z&x-oss-expires=3599&x-oss-signature-version=OSS4-HMAC-SHA256&x-oss-credential=LTAI****************/20241112/cn-hangzhou/oss/aliyun_v4_request&x-oss-signature=ed5a******************************************************";
            // Enter the destination path to save the file, including the file name and extension.
            String savePath = "C:/downloads/myfile.txt";
    
            try {
                downloadFile(fileURL, savePath);
                System.out.println("Download completed!");
            } catch (IOException e) {
                System.err.println("Error during download: " + e.getMessage());
            }
        }
    
        private static void downloadFile(String fileURL, String savePath) throws IOException {
            URL url = new URL(fileURL);
            HttpURLConnection httpConn = (HttpURLConnection) url.openConnection();
            httpConn.setRequestMethod("GET");
    
            // Check the response code.
            int responseCode = httpConn.getResponseCode();
            if (responseCode == HttpURLConnection.HTTP_OK) {
                // Input stream.
                InputStream inputStream = new BufferedInputStream(httpConn.getInputStream());
                // Output stream.
                FileOutputStream outputStream = new FileOutputStream(savePath);
    
                byte[] buffer = new byte[4096]; // Buffer.
                int bytesRead;
                while ((bytesRead = inputStream.read(buffer)) != -1) {
                    outputStream.write(buffer, 0, bytesRead);
                }
    
                outputStream.close();
                inputStream.close();
            } else {
                System.out.println("No file to download. Server replied HTTP code: " + responseCode);
            }
            httpConn.disconnect();
        }
    }

    Node.js

    const https = require('https');
    const fs = require('fs');
    
    const fileURL = "https://examplebucket.oss-cn-hangzhou.aliyuncs.com/exampleobject.txt?x-oss-date=20241112T092756Z&x-oss-expires=3599&x-oss-signature-version=OSS4-HMAC-SHA256&x-oss-credential=LTAI****************/20241112/cn-hangzhou/oss/aliyun_v4_request&x-oss-signature=ed5a******************************************************";
    const savePath = "C:/downloads/myfile.txt";
    
    https.get(fileURL, (response) => {
        if (response.statusCode === 200) {
            const fileStream = fs.createWriteStream(savePath);
            response.pipe(fileStream);
            
            fileStream.on('finish', () => {
                fileStream.close();
                console.log("Download completed!");
            });
        } else {
            console.error(`Download failed. Server responded with code: ${response.statusCode}`);
        }
    }).on('error', (err) => {
        console.error("Error during download:", err.message);
    });

    Python

    import requests
    
    file_url = "https://examplebucket.oss-cn-hangzhou.aliyuncs.com/exampleobject.txt?x-oss-date=20241112T092756Z&x-oss-expires=3599&x-oss-signature-version=OSS4-HMAC-SHA256&x-oss-credential=LTAI****************/20241112/cn-hangzhou/oss/aliyun_v4_request&x-oss-signature=ed5a******************************************************"
    save_path = "C:/downloads/myfile.txt"
    
    try:
        response = requests.get(file_url, stream=True)
        if response.status_code == 200:
            with open(save_path, 'wb') as f:
                for chunk in response.iter_content(4096):
                    f.write(chunk)
            print("Download completed!")
        else:
            print(f"No file to download. Server replied HTTP code: {response.status_code}")
    except Exception as e:
        print("Error during download:", e)

    Go

    package main
    
    import (
        "io"
        "net/http"
        "os"
    )
    
    func main() {
        fileURL := "https://examplebucket.oss-cn-hangzhou.aliyuncs.com/exampleobject.txt?x-oss-date=20241112T092756Z&x-oss-expires=3599&x-oss-signature-version=OSS4-HMAC-SHA256&x-oss-credential=LTAI****************/20241112/cn-hangzhou/oss/aliyun_v4_request&x-oss-signature=ed5a******************************************************"
        savePath := "C:/downloads/myfile.txt"
    
        response, err := http.Get(fileURL)
        if err != nil {
            panic(err)
        }
        defer response.Body.Close()
    
        if response.StatusCode == http.StatusOK {
            outFile, err := os.Create(savePath)
            if err != nil {
                panic(err)
            }
            defer outFile.Close()
    
            _, err = io.Copy(outFile, response.Body)
            if err != nil {
                panic(err)
            }
            println("Download completed!")
        } else {
            println("No file to download. Server replied HTTP code:", response.StatusCode)
        }
    }

    JavaScript

    const fileURL = "https://examplebucket.oss-cn-hangzhou.aliyuncs.com/exampleobject.txt?x-oss-date=20241112T092756Z&x-oss-expires=3599&x-oss-signature-version=OSS4-HMAC-SHA256&x-oss-credential=LTAI****************/20241112/cn-hangzhou/oss/aliyun_v4_request&x-oss-signature=ed5a******************************************************";
    const savePath = "C:/downloads/myfile.txt"; // The file name to use for the download.
    
    fetch(fileURL)
        .then(response => {
            if (!response.ok) {
                throw new Error(`Server replied HTTP code: ${response.status}`);
            }
            return response.blob(); // Convert the response to a blob.
        })
        .then(blob => {
            const link = document.createElement('a');
            link.href = window.URL.createObjectURL(blob);
            link.download = savePath; // Set the name of the downloaded file.
            document.body.appendChild(link); // This step ensures that the link exists in the document.
            link.click(); // Simulate a click on the download link.
            link.remove(); // Remove the link after completion.
            console.log("Download completed!");
        })
        .catch(error => {
            console.error("Error during download:", error);
        });

    Android-Java

    import android.os.AsyncTask;
    import android.os.Environment;
    import java.io.BufferedInputStream;
    import java.io.FileOutputStream;
    import java.io.InputStream;
    import java.net.HttpURLConnection;
    import java.net.URL;
    
    public class DownloadTask extends AsyncTask<String, String, String> {
        @Override
        protected String doInBackground(String... params) {
            String fileURL = params[0];
            String savePath = Environment.getExternalStoragePublicDirectory(Environment.DIRECTORY_DOWNLOADS) + "/myfile.txt"; // The modified save path.
            try {
                URL url = new URL(fileURL);
                HttpURLConnection httpConn = (HttpURLConnection) url.openConnection();
                httpConn.setRequestMethod("GET");
                int responseCode = httpConn.getResponseCode();
                if (responseCode == HttpURLConnection.HTTP_OK) {
                    InputStream inputStream = new BufferedInputStream(httpConn.getInputStream());
                    FileOutputStream outputStream = new FileOutputStream(savePath);
                    byte[] buffer = new byte[4096];
                    int bytesRead;
                    while ((bytesRead = inputStream.read(buffer)) != -1) {
                        outputStream.write(buffer, 0, bytesRead);
                    }
                    outputStream.close();
                    inputStream.close();
                    return "Download completed!";
                } else {
                    return "No file to download. Server replied HTTP code: " + responseCode;
                }
            } catch (Exception e) {
                return "Error during download: " + e.getMessage();
            }
        }
    }

    Objective-C

    #import <Foundation/Foundation.h>
    
    int main(int argc, const char * argv[]) {
        @autoreleasepool {
            // Define the file URL and save path (change to a valid path).
            NSString *fileURL = @"https://examplebucket.oss-cn-hangzhou.aliyuncs.com/exampleobject.txt?x-oss-date=20241112T092756Z&x-oss-expires=3599&x-oss-signature-version=OSS4-HMAC-SHA256&x-oss-credential=LTAI****************/20241112/cn-hangzhou/oss/aliyun_v4_request&x-oss-signature=ed5a******************************************************";
            NSString *savePath = @"/Users/your_username/Desktop/myfile.txt"; // Replace with your username.
            
            // Create a URL object.
            NSURL *url = [NSURL URLWithString:fileURL];
            
            // Create a download task.
            NSURLSessionDataTask *task = [[NSURLSession sharedSession] dataTaskWithURL:url completionHandler:^(NSData *data, NSURLResponse *response, NSError *error) {
                // Error handling.
                if (error) {
                    NSLog(@"Error during download: %@", error.localizedDescription);
                    return;
                }
                
                // Check the data.
                if (!data) {
                    NSLog(@"No data received.");
                    return;
                }
                
                // Save the file.
                NSError *writeError = nil;
                BOOL success = [data writeToURL:[NSURL fileURLWithPath:savePath] options:NSDataWritingAtomic error:&writeError];
                if (success) {
                    NSLog(@"Download completed!");
                } else {
                    NSLog(@"Error saving file: %@", writeError.localizedDescription);
                }
            }];
            
            // Start the task.
            [task resume];
            
            // Keep the main thread running so that the asynchronous request can be completed.
            [[NSRunLoop currentRunLoop] run];
        }
        return 0;
    }

Common scenarios

Generate a presigned URL that allows HTTP GET requests for a specific version of an object

The following sample code generates a presigned URL that allows HTTP GET requests for a specific version of an object:

import argparse
import alibabacloud_oss_v2 as oss

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

# Specify the --region parameter to indicate the region in which the bucket is located. This parameter is required.
parser.add_argument('--region', help='The region in which the bucket is located.', required=True)
# Specify the --bucket parameter to indicate the name of the bucket in which the object is stored. This parameter is required.
parser.add_argument('--bucket', help='The name of the bucket.', required=True)
# Specify the --endpoint parameter to indicate the endpoint of the region in which the bucket is located. This parameter is optional.
parser.add_argument('--endpoint', help='The domain names that other services can use to access OSS')
# Specify the --key parameter to indicate the name of the object. This parameter is required.
parser.add_argument('--key', help='The name of the object.', required=True)

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

    # From the environment variables, load the authentication information required to access OSS.
    credentials_provider = oss.credentials.EnvironmentVariableCredentialsProvider()

    # Use the default configuration to create a cfg object and specify the credential provider.
    cfg = oss.config.load_default()
    cfg.credentials_provider = credentials_provider
    
    # Specify the region attribute of the configuration object based on the command line parameters specified by the user.
    cfg.region = args.region

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

    # Use the preceding settings to initialize the OSSClient instance.
    client = oss.Client(cfg)

    # Initiate a request to generate a presigned URL.
    # The version_id parameter is optional. You need to specify this parameter only when the bucket that contains the object is versioned.
    pre_result = client.presign(
        oss.GetObjectRequest(
            bucket=args.bucket,  # Specify the bucket name.
            key=args.key,        # Specify the object key.
            version_id='yourVersionId'  # If applicable, specify the version ID of the object.
        )
    )

    # Display the HTTP method, expiration time, and presigned URL.
    print(f'method: {pre_result.method},'
          f' expiration: {pre_result.expiration.strftime("%Y-%m-%dT%H:%M:%S.000Z")},'
          f' url: {pre_result.url}'
    )

    # Display the signed headers.
    for key, value in pre_result.signed_headers.items():
        print(f'signed headers key: {key}, signed headers value: {value}')

# Call the main function to start the processing logic when the script is directly run.
if __name__ == "__main__":
    main()  # Specify the entry point of the script. The control flow starts here.

Download an object by using a presigned URL that contains specified request headers

If you specify request headers when you generate a presigned URL that allows HTTP GET requests, make sure that the request headers are included in the GET request initiated by using the presigned URL. This prevents request failures and signature errors.

  1. Generate a presigned URL that contains specific request headers and allows HTTP GET requests.

    import argparse
    import alibabacloud_oss_v2 as oss
    
    # Create a command-line argument parser and describe the purpose of the script.
    parser = argparse.ArgumentParser(description="presign get object sample")
    
    # Specify the --region parameter to indicate the region in which the bucket is located. This parameter is required.
    parser.add_argument('--region', help='The region in which the bucket is located.', required=True)
    # Specify the --bucket parameter to indicate the name of the bucket in which the object is stored. This parameter is required.
    parser.add_argument('--bucket', help='The name of the bucket.', required=True)
    # Specify the --endpoint parameter to indicate the endpoint of the region in which the bucket is located. This parameter is optional.
    parser.add_argument('--endpoint', help='The domain names that other services can use to access OSS')
    # Specify the --key parameter to indicate the name of the object. This parameter is required.
    parser.add_argument('--key', help='The name of the object.', required=True)
    
    def main():
        # Parse the command-line parameters.
        args = parser.parse_args()
    
        # Obtain access credentials from environment variables for authentication.
        credentials_provider = oss.credentials.EnvironmentVariableCredentialsProvider()
    
        # Use the default configuration to create a configuration object (cfg) and specify the credential provider.
        cfg = oss.config.load_default()
        cfg.credentials_provider = credentials_provider
    
        # Set the region attribute of the cfg object to the region in the parser.
        cfg.region = args.region
    
        # # Specify a custom domain name.
        # cfg.endpoint = "http://ossv2.wangpeiyu.com"
        # # Enable CNAME record resolution.
        # cfg.use_cname = True
    
        # If a custom endpoint is provided, update the endpoint attribute of the cfg object with the provided endpoint.
        if args.endpoint is not None:
            cfg.endpoint = args.endpoint
    
        # Use the preceding configuration to initialize the OSSClient instance.
        client = oss.Client(cfg)
    
        # Initiate a request to generate a presigned URL.
        pre_result = client.presign(
            oss.GetObjectRequest(
                bucket=args.bucket,  # Specify the bucket name.
                key=args.key,        # Specify the object key.
                range_behavior="standard", # Specify a request header.
                request_payer="requester", # Specify a request header.
            )
        )
    
        # Display the HTTP method, expiration time, and presigned URL.
        print(f'method: {pre_result.method},'
              f' expiration: {pre_result.expiration.strftime("%Y-%m-%dT%H:%M:%S.000Z")},'
              f' url: {pre_result.url}'
        )
    
        # Display the signed headers.
        for key, value in pre_result.signed_headers.items():
            print(f'signed headers key: {key}, signed headers value: {value}')
    
    # Call the main function to start the processing logic when the script is directly run.
    if __name__ == "__main__":
        main()  # Specify the entry point of the script. The control flow starts here.
  2. Download the object by using the presigned URL and specifying the request headers:

    curl -X GET "https://examplebucket.oss-cn-hangzhou.aliyuncs.com/exampleobject.txt?x-oss-date=20241113T093321Z&x-oss-expires=3599&x-oss-signature-version=OSS4-HMAC-SHA256&x-oss-credential=LTAI****************&x-oss-signature=ed5a******************************************************" \
    -H "x-oss-range-behavior: standard" \
    -H "x-oss-request-payer: requester" \
    -o "myfile.txt"
    import requests
    
    def download_file(signed_url, file_path, headers=None, metadata=None):
        """
        Use a presigned URL to download an object. 
    
        :param signed_url: A pre-signed URL. 
        param file_path: The full local path to which you want to download the object. 
        : param headers: The request headers. This parameter is optional. 
        : param metadata: The custom metadata. This parameter is not needed by GET requests. 
        :return: None
        """
        if not headers:
            headers = {}
    
        try:
            response = requests.get(signed_url, headers=headers, stream=True)
            print(f"HTTP status code: {response.status_code}")
    
            if response.status_code == 200:
                with open(file_path, 'wb') as file:
                    for chunk in response.iter_content(chunk_size=8192):
                        if chunk:
                            file.write(chunk)
                print("The object was downloaded.")
            else:
                print("The object failed to be downloaded.")
                print(response.text)
        except Exception as e:
            print(f"An error occurred: {e}")
    
    if __name__ == "__main__":
        # Replace <signedUrl> with the presigned URL. 
        signed_url = "<signedUrl>"
        file_path = "/Users/<yourLocalPath>/Downloads/downloadedFile.txt" # The local path to which you want to download the object.
    
        headers = {
            "X-Oss-Range-Behavior":"standard",
            "X-Oss-Request-Payer":"requester",
        }
    
        download_file(signed_url, file_path, headers=headers)

Forcibly download an object by using a presigned URL

  1. Generate a URL that contains the response-content-disposition parameter.

    import argparse
    import alibabacloud_oss_v2 as oss
    
    # Create a command-line argument parser and describe the purpose of the script.
    parser = argparse.ArgumentParser(description="presign get object sample")
    
    # Specify the --region parameter to indicate the region in which the bucket is located. This parameter is required.
    parser.add_argument('--region', help='The region in which the bucket is located.', required=True)
    # Specify the --bucket parameter to indicate the name of the bucket in which the object is stored. This parameter is required.
    parser.add_argument('--bucket', help='The name of the bucket.', required=True)
    # Specify the --endpoint parameter to indicate the endpoint of the region in which the bucket is located. This parameter is optional.
    parser.add_argument('--endpoint', help='The domain names that other services can use to access OSS')
    # Specify the --key parameter to indicate the name of the object. This parameter is required.
    parser.add_argument('--key', help='The name of the object.', required=True)
    
    def main():
        # Parse the command-line parameters.
        args = parser.parse_args()
    
        # Obtain access credentials from environment variables for authentication.
        credentials_provider = oss.credentials.EnvironmentVariableCredentialsProvider()
    
        # Use the default configuration to create a configuration object (cfg) and specify the credential provider.
        cfg = oss.config.load_default()
        cfg.credentials_provider = credentials_provider
    
        # Set the region attribute of the cfg object to the region in the parser.
        cfg.region = args.region
    
        # If a custom endpoint is provided, update the endpoint attribute of the cfg object with the provided endpoint.
        if args.endpoint is not None:
            cfg.endpoint = args.endpoint
    
        # Use the preceding configuration to initialize the OSSClient instance.
        client = oss.Client(cfg)
    
        # Initiate a request to generate a presigned URL.
        pre_result = client.presign(
            oss.GetObjectRequest(
                bucket=args.bucket,  # Specify the bucket name.
                key=args.key,        # Specify the object key.
                response_content_disposition="attachment;filename=test.txt",
            )
        )
    
        # Display the HTTP method, expiration time, and presigned URL.
        print(f'method: {pre_result.method},'
              f' expiration: {pre_result.expiration.strftime("%Y-%m-%dT%H:%M:%S.000Z")},'
              f' url: {pre_result.url}'
        )
    
        # Display the signed headers.
        for key, value in pre_result.signed_headers.items():
            print(f'signed headers key: {key}, signed headers value: {value}')
    
    # Call the main function to start the processing logic when the script is directly run.
    if __name__ == "__main__":
        main()  # Specify the entry point of the script. The control flow starts here.

  2. Use the presigned URL to download the specified object.

    curl -X GET "https://examplebucket.oss-cn-hangzhou.aliyuncs.com/exampleobject.txt?response-content-disposition=attachment%3B%20filename%3Dtest.txt&x-oss-date=20241113T093321Z&x-oss-expires=3599&x-oss-signature-version=OSS4-HMAC-SHA256&x-oss-credential=LTAI****************&x-oss-signature=ed5a******************************************************" \
    -o "myfile.txt"
    import requests
    
    def download_file(signed_url, file_path):
        """
        Use a presigned URL to download an object. 
    
        :param signed_url: A pre-signed URL. 
        param file_path: The full local path to which you want to download the object. 
        : param headers: The request headers. This parameter is optional. 
        : param metadata: The custom metadata. This parameter is not needed by GET requests. 
        :return: None
        """
    
        try:
            response = requests.get(signed_url, stream=True)
            print(f"HTTP status code: {response.status_code}")
    
            if response.status_code == 200:
                with open(file_path, 'wb') as file:
                    for chunk in response.iter_content(chunk_size=8192):
                        if chunk:
                            file.write(chunk)
                print("The object was downloaded.")
            else:
                print("The object failed to be downloaded.")
                print(response.text)
        except Exception as e:
            print(f"An error occurred: {e}")
    
    if __name__ == "__main__":
        # Replace <signedUrl> with the presigned URL. 
        signed_url = "<signedUrl>"
        file_path = "/Users/<yourLocalPath>/Downloads/downloadedFile.txt" # The local path to which you want to download the object.
    
        download_file(signed_url, file_path)

Generate a presigned URL that allows object downloads by using a custom endpoint

The following sample code uses a custom endpoint to generate a presigned URL that allows HTTP GET requests:

import argparse
import alibabacloud_oss_v2 as oss

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

# Specify the --region parameter to indicate the region in which the bucket is located. This parameter is required.
parser.add_argument('--region', help='The region in which the bucket is located.', required=True)
# Specify the --bucket parameter to indicate the name of the bucket in which the object is stored. This parameter is required.
parser.add_argument('--bucket', help='The name of the bucket.', required=True)
# Specify the --endpoint parameter to indicate the endpoint of the region in which the bucket is located. This parameter is optional.
parser.add_argument('--endpoint', help='The domain names that other services can use to access OSS')
# Specify the --key parameter to indicate the name of the object. This parameter is required.
parser.add_argument('--key', help='The name of the object.', required=True)

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

    # From the environment variables, load the authentication information required to access OSS.
    credentials_provider = oss.credentials.EnvironmentVariableCredentialsProvider()

    # Use the default configuration to create a cfg object and specify the credential provider.
    cfg = oss.config.load_default()
    cfg.credentials_provider = credentials_provider
    
    # Specify the region attribute of the configuration object based on the command line parameters specified by the user.
    cfg.region = args.region

    # Specify the custom endpoint. Example: http://static.example.com
    cfg.endpoint = "http://static.example.com"
    
    # Enable CNAME record resolution.
    cfg.use_cname = True

    # Use the preceding settings to initialize the OSSClient instance.
    client = oss.Client(cfg)

    # Initiate a request to generate a presigned URL.
    pre_result = client.presign(
        oss.GetObjectRequest(
            bucket=args.bucket,  # Specify the bucket name.
            key=args.key,        # Specify the object key.
        )
    )

    # Display the HTTP method, expiration time, and presigned URL.
    print(f'method: {pre_result.method},'
          f' expiration: {pre_result.expiration.strftime("%Y-%m-%dT%H:%M:%S.000Z")},'
          f' url: {pre_result.url}'
    )

    # Display the signed headers.
    for key, value in pre_result.signed_headers.items():
        print(f'signed headers key: {key}, signed headers value: {value}')

# Call the main function to start the processing logic when the script is directly run.
if __name__ == "__main__":
    main()  # Specify the entry point of the script. The control flow starts here.

References