Utilizzo di Python

Il supporto Python viene fornito tramite un duplicato della libreria boto3 con funzioni che utilizzano in modo ottimale IBM Cloud® Object Storage.

Può essere installato dal Python Package Index tramite pip install ibm-cos-sdk.

Il codice sorgente è disponibile all'indirizzo GitHub.

La libreria ibm_boto3 fornisce l'accesso completo all'API IBM Cloud® Object Storage. Devono essere specificati gli endpoint, una chiave API e l'ID istanza durante la creazione di una risorsa del servizio o del client di basso livello come mostrato nei seguenti esempi di base.

L'ID dell'istanza di servizio viene anche chiamato ID dell'istanza di risorsa. Il valore può essere trovato creando una credenziale di servizio o tramite la CLI.

La documentazione dettagliata è disponibile qui.

Creazione di un client e derivazione delle credenziali

Per stabilire una connessione a COS, un client viene creato e configurato utilizzando le informazioni delle credenziali (chiave API e ID istanza del servizio). Questi valori possono anche essere derivati automaticamente da un file di credenziali o dalle variabili di ambiente.

Dopo aver generato una credenziale del servizio, il documento JSON risultante può essere salvato in ~/.bluemix/cos_credentials. L'SDK deriverà automaticamente le credenziali da questo file a meno che non vengano esplicitamente impostate altre credenziali durante la creazione del client. Se il file cos_credentials contiene chiavi HMAC che il client autentica con una firma, altrimenti il client utilizza la chiave API fornita per eseguire l'autenticazione utilizzando un token di connessione (l'uso di una chiave API richiede ancora che config=Config(signature_version="oauth") sia incluso durante la creazione del client).

Se si esegue la migrazione da AWS S3, puoi anche derivare i dati delle credenziali da ~/.aws/credentials nel formato:

[default]
aws_access_key_id = {API_KEY}
aws_secret_access_key = {SERVICE_INSTANCE_ID}

Nota: Se esistono sia ~/.bluemix/cos_credentials che ~/.aws/credentials, cos_credentials ha la precedenza.

Raccogli le informazioni richieste

Le seguenti variabili vengono visualizzate negli esempi:

Esempi di codici

Gli esempi di codice vengono verificati sulle versioni di release supportate di Python.

Nel codice, è necessario rimuovere le parentesi angolari o qualsiasi altro carattere in eccesso fornito qui come illustrazione.

Inizializzazione della configurazione

Questo esempio crea un oggetto resource. Una risorsa fornisce un'interfaccia orientata agli oggetti a COS. Ciò consente un livello di astrazione superiore rispetto alle chiamate di livello inferiore fornite da un oggetto client.

Si noti che alcune operazioni (come il trasferimento ad alta velocità dell' Aspera ) richiedono un client oggetto. Aspera richiede una version Python e di 3.6.

Avviso relativo alle versioni precedenti: il supporto per Aspera è considerato obsoleto. Utilizza invece il Aspera Transfer SDK.

import ibm_boto3
from ibm_botocore.client import Config, ClientError

# Constants for IBM COS values
COS_ENDPOINT = "<endpoint>" # Current list avaiable at https://control.cloud-object-storage.cloud.ibm.com/v2/endpoints
COS_API_KEY_ID = "<api-key>" # eg "W00YixxxxxxxxxxMB-odB-2ySfTrFBIQQWanc--P3byk"
COS_INSTANCE_CRN = "<service-instance-id>" # eg "crn:v1:bluemix:public:cloud-object-storage:global:a/3bf0d9003xxxxxxxxxx1c3e97696b71c:d6f04d83-6c4f-4a62-a165-696756d63903::"

# Create resource
cos_resource = ibm_boto3.resource("s3",
    ibm_api_key_id=COS_API_KEY_ID,
    ibm_service_instance_id=COS_INSTANCE_CRN,
    config=Config(signature_version="oauth"),
    endpoint_url=COS_ENDPOINT
)

Un client fornisce un'interfaccia di basso livello all'API COS S3. Ciò consente di elaborare direttamente le risposte di HTTP, anziché utilizzare i metodi e gli attributi astratti forniti da una risorsa per accedere alle informazioni contenute nelle intestazioni o nei payload delle risposte XML.


import ibm_boto3
from ibm_botocore.client import Config, ClientError

# Constants for IBM COS values
COS_ENDPOINT = "<endpoint>" # Current list avaiable at https://control.cloud-object-storage.cloud.ibm.com/v2/endpoints
COS_API_KEY_ID = "<api-key>" # eg "W00YixxxxxxxxxxMB-odB-2ySfTrFBIQQWanc--P3byk"
COS_INSTANCE_CRN = "<service-instance-id>" # eg "crn:v1:bluemix:public:cloud-object-storage:global:a/3bf0d9003xxxxxxxxxx1c3e97696b71c:d6f04d83-6c4f-4a62-a165-696756d63903::"

# Create client
cos_client = ibm_boto3.client("s3",
    ibm_api_key_id=COS_API_KEY_ID,
    ibm_service_instance_id=COS_INSTANCE_CRN,
    config=Config(signature_version="oauth"),
    endpoint_url=COS_ENDPOINT
)

Valori chiave

  • <endpoint>- endpoint pubblico per il vostro cloud Object Storage con schema preceduto da (' https:// ') (disponibile nella Dashboard di IBM Cloud ). Per ulteriori informazioni sugli endpoint, vedi Endpoint e ubicazioni di archiviazione.
  • <api-key>- chiave api generata durante la creazione delle credenziali del servizio (è richiesto l'accesso in scrittura per gli esempi di creazione e cancellazione)
  • <service-instance-id>- ID risorsa per il cloud Object Storage (disponibile tramite IBM Cloud CLI o IBM Cloud Dashboard )
  • <location>- posizione predefinita per il cloud Object Storage (deve corrispondere alla regione utilizzata per <endpoint>)

Riferimenti SDK

Creazione di un nuovo bucket

Gli esempi seguenti utilizzano il client che è un'interfaccia di basso livello.

È possibile che si faccia riferimento a un elenco di codici di provisioning validi per LocationConstraint nella guida alle classi di archiviazione.

def create_bucket(bucket_name):
    print("Creating new bucket: {0}".format(bucket_name))
    try:
        cos_client.create_bucket(
            Bucket=bucket_name,
            CreateBucketConfiguration={
                "LocationConstraint":COS_BUCKET_LOCATION
            }
        )
        print("Bucket: {0} created!".format(bucket_name))
    except ClientError as be:
        print("CLIENT ERROR: {0}\n".format(be))
    except Exception as e:
        print("Unable to create bucket: {0}".format(e))

Riferimenti SDK

Metodi

Creazione di un nuovo file di testo

def create_text_file(bucket_name, item_name, file_text):
    print("Creating new item: {0}".format(item_name))
    try:
        cos_client.put_object(
            Bucket=bucket_name,
            Key=item_name,
            Body=file_text
        )
        print("Item: {0} created!".format(item_name))
    except ClientError as be:
        print("CLIENT ERROR: {0}\n".format(be))
    except Exception as e:
        print("Unable to create text file: {0}".format(e))

Riferimenti SDK

Metodi

Elenca i bucket disponibili

def get_buckets():
    print("Retrieving list of buckets")
    try:
        buckets = cos_client.list_buckets()
        for bucket in buckets["Buckets"]:
            print("Bucket Name: {0}".format(bucket["Name"]))
    except ClientError as be:
        print("CLIENT ERROR: {0}\n".format(be))
    except Exception as e:
        print("Unable to retrieve list buckets: {0}".format(e))

Riferimenti SDK

Metodi

Elenca gli elementi in un bucket

def get_bucket_contents(bucket_name):
    print("Retrieving bucket contents from: {0}".format(bucket_name))
    try:
        files = cos_client.list_objects(Bucket=bucket_name)
        for file in files.get("Contents", []):
            print("Item: {0} ({1} bytes).".format(file["Key"], file["Size"]))
    except ClientError as be:
        print("CLIENT ERROR: {0}\n".format(be))
    except Exception as e:
        print("Unable to retrieve bucket contents: {0}".format(e))

Riferimenti SDK

Metodi

Ottieni il contenuto del file di uno specifico elemento

def get_item(bucket_name, item_name):
    print("Retrieving item from bucket: {0}, key: {1}".format(bucket_name, item_name))
    try:
        file = cos_client.get_object(Bucket=bucket_name, Key=item_name)
        print("File Contents: {0}".format(file["Body"].read()))
    except ClientError as be:
        print("CLIENT ERROR: {0}\n".format(be))
    except Exception as e:
        print("Unable to retrieve file contents: {0}".format(e))

Riferimenti SDK

Metodi

Elimina un elemento da un bucket

def delete_item(bucket_name, object_name):
    try:
        cos_client.delete_object(Bucket=bucket_name, Key=object_name)
        print("Item: {0} deleted!\n".format(object_name))
    except ClientError as be:
        print("CLIENT ERROR: {0}\n".format(be))
    except Exception as e:
        print("Unable to delete object: {0}".format(e))

Riferimenti SDK

Metodi

Elimina più elementi da un bucket

La richiesta di eliminazione può contenere un massimo di 1000 chiavi che vuoi eliminare. Sebbene sia utile per ridurre le prestazioni per richiesta, occorre prestare attenzione quando si eliminano molte chiavi. Inoltre, prendi in considerazione anche le dimensioni degli oggetti per garantire delle prestazioni adeguate.

def delete_items(bucket_name):
    try:
        delete_request = {
            "Objects": [
                { "Key": "deletetest/testfile1.txt" },
                { "Key": "deletetest/testfile2.txt" },
                { "Key": "deletetest/testfile3.txt" },
                { "Key": "deletetest/testfile4.txt" },
                { "Key": "deletetest/testfile5.txt" }
            ]
        }

        response = cos_client.delete_objects(
            Bucket=bucket_name,
            Delete=delete_request
        )

        print("Deleted items for {0}\n".format(bucket_name))
        print(json.dumps(response.get("Deleted"), indent=4))
    except ClientError as be:
        print("CLIENT ERROR: {0}\n".format(be))
    except Exception as e:
        print("Unable to copy item: {0}".format(e))

Riferimenti SDK

Metodi

Elimina un bucket

def delete_bucket(bucket_name):
    print("Deleting bucket: {0}".format(bucket_name))
    try:
        cos_client.delete_bucket(Bucket=bucket_name)
        print("Bucket: {0} deleted!".format(bucket_name))
    except ClientError as be:
        print("CLIENT ERROR: {0}\n".format(be))
    except Exception as e:
        print("Unable to delete bucket: {0}".format(e))

Riferimenti SDK

Metodi

I nomi dei bucket sono riservati per 10-15 minuti dopo l'eliminazione.

Esegui un caricamento in più parti

Carica un file binario (metodo preferito)

Il metodo upload_fileobj dell'oggetto S3 esegue automaticamente un caricamento in più parti, se necessario. La classe TransferConfig viene utilizzata per determinare la soglia di utilizzo del caricamento in più parti.

def multi_part_upload(bucket_name, item_name, file_path):
    try:
        print("Starting file transfer for {0} to bucket: {1}\n".format(item_name, bucket_name))
        # set 5 MB chunks
        part_size = 1024 * 1024 * 5

        # set threadhold to 15 MB
        file_threshold = 1024 * 1024 * 15

        # set the transfer threshold and chunk size
        transfer_config = ibm_boto3.s3.transfer.TransferConfig(
            multipart_threshold=file_threshold,
            multipart_chunksize=part_size
        )

        # the upload_fileobj method will automatically execute a multi-part upload
        # in 5 MB chunks for all files over 15 MB
        with open(file_path, "rb") as file_data:
            cos_client.upload_fileobj(
                Bucket=bucket_name,
                Key=item_name,
                Fileobj=file_data,
                Config=transfer_config
            )

        print("Transfer for {0} Complete!\n".format(item_name))
    except ClientError as be:
        print("CLIENT ERROR: {0}\n".format(be))
    except Exception as e:
        print("Unable to complete multi-part upload: {0}".format(e))

Riferimenti SDK

Metodi

Esegui manualmente un caricamento in più parti

Se si desidera, la classe S3.Client può essere usata per eseguire un caricamento in più parti. Questo può essere utile se è necessario maggiore controllo sul processo di caricamento.

def multi_part_upload_manual(bucket_name, item_name, file_path):
    try:
        # create client object
        cos_client = ibm_boto3.client("s3",
            ibm_api_key_id=COS_API_KEY_ID,
            ibm_service_instance_id=COS_SERVICE_CRN,
            config=Config(signature_version="oauth"),
            endpoint_url=COS_ENDPOINT
        )

        print("Starting multi-part upload for {0} to bucket: {1}\n".format(item_name, bucket_name))

        # initiate the multi-part upload
        mp = cos_client.create_multipart_upload(
            Bucket=bucket_name,
            Key=item_name
        )

        upload_id = mp["UploadId"]

        # min 20MB part size
        part_size = 1024 * 1024 * 20
        file_size = os.stat(file_path).st_size
        part_count = int(math.ceil(file_size / float(part_size)))
        data_packs = []
        position = 0
        part_num = 0

        # begin uploading the parts
        with open(file_path, "rb") as file:
            for i in range(part_count):
                part_num = i + 1
                part_size = min(part_size, (file_size - position))

                print("Uploading to {0} (part {1} of {2})".format(item_name, part_num, part_count))

                file_data = file.read(part_size)

                mp_part = cos_client.upload_part(
                    Bucket=bucket_name,
                    Key=item_name,
                    PartNumber=part_num,
                    Body=file_data,
                    ContentLength=part_size,
                    UploadId=upload_id
                )

                data_packs.append({
                    "ETag":mp_part["ETag"],
                    "PartNumber":part_num
                })

                position += part_size

        # complete upload
        cos_client.complete_multipart_upload(
            Bucket=bucket_name,
            Key=item_name,
            UploadId=upload_id,
            MultipartUpload={
                "Parts": data_packs
            }
        )
        print("Upload for {0} Complete!\n".format(item_name))
    except ClientError as be:
        # abort the upload
        cos_client.abort_multipart_upload(
            Bucket=bucket_name,
            Key=item_name,
            UploadId=upload_id
        )
        print("Multi-part upload aborted for {0}\n".format(item_name))
        print("CLIENT ERROR: {0}\n".format(be))
    except Exception as e:
        print("Unable to complete multi-part upload: {0}".format(e))

Riferimenti SDK continuati

Classi

Metodi

Caricamento di grandi oggetti tramite TransferManager

TransferManager fornisce un altro modo di eseguire trasferimenti di grandi file incorporando automaticamente i caricamenti in più parti quando necessario impostando dei parametri di configurazione.

def upload_large_file(bucket_name, item_name, file_path):
    print("Starting large file upload for {0} to bucket: {1}".format(item_name, bucket_name))

    # set the chunk size to 5 MB
    part_size = 1024 * 1024 * 5

    # set threadhold to 5 MB
    file_threshold = 1024 * 1024 * 5

    # Create client connection
    cos_client = ibm_boto3.client("s3",
        ibm_api_key_id=COS_API_KEY_ID,
        ibm_service_instance_id=COS_SERVICE_CRN,
        config=Config(signature_version="oauth"),
        endpoint_url=COS_ENDPOINT
    )

    # set the transfer threshold and chunk size in config settings
    transfer_config = ibm_boto3.s3.transfer.TransferConfig(
        multipart_threshold=file_threshold,
        multipart_chunksize=part_size
    )

    # create transfer manager
    transfer_mgr = ibm_boto3.s3.transfer.TransferManager(cos_client, config=transfer_config)

    try:
        # initiate file upload
        future = transfer_mgr.upload(file_path, bucket_name, item_name)

        # wait for upload to complete
        future.result()

        print ("Large file upload complete!")
    except Exception as e:
        print("Unable to complete large file upload: {0}".format(e))
    finally:
        transfer_mgr.shutdown()

Elenca gli elementi in un bucket (v2)

S3.Client client ha un metodo aggiornato per elencare il contenuto (list_objects_v2). Questo metodo ti consente di limitare il numero di record restituiti e di richiamare i record in batch. Questo potrebbe essere utile per la paginazione dei tuoi risultati all'interno di un'applicazione e per migliorare le prestazioni.

def get_bucket_contents_v2(bucket_name, max_keys):
    print("Retrieving bucket contents from: {0}".format(bucket_name))
    try:
        # create client object
        cos_client = ibm_boto3.client("s3",
            ibm_api_key_id=COS_API_KEY_ID,
            ibm_service_instance_id=COS_SERVICE_CRN,
            config=Config(signature_version="oauth"),
            endpoint_url=COS_ENDPOINT)

        more_results = True
        next_token = ""

        while (more_results):
            response = cos_client.list_objects_v2(Bucket=bucket_name, MaxKeys=max_keys, ContinuationToken=next_token)
            files = response["Contents"]
            for file in files:
                print("Item: {0} ({1} bytes).".format(file["Key"], file["Size"]))

            if (response["IsTruncated"]):
                next_token = response["NextContinuationToken"]
                print("...More results in next batch!\n")
            else:
                more_results = False
                next_token = ""

    except ClientError as be:
        print("CLIENT ERROR: {0}\n".format(be))
    except Exception as e:
        print("Unable to retrieve bucket contents: {0}".format(e))

Riferimenti SDK

Metodi

Creazione di un criterio di backup

# Config values
api_key = "<API_KEY>"
vault_crn = "<SERVICE_INSTANCE_ID>"
source_bucket_name = "<BACKUP_VAULT_NAME>"
policy_name = "<POLICY_NAME>"

# Authenticator and client setup
authenticator = IAMAuthenticator(apikey=api_key)
rc_client = ResourceConfigurationV1(authenticator=authenticator)

# Create policy
create_backup_policy = rc_client.create_backup_policy(
        bucket=source_bucket_name,
        policy_name=policy_name,
        target_backup_vault_crn=vault_crn,
        backup_type="continuous",
        initial_retention={"delete_after_days": 1}
    )

# Print response
print(f" Policy created: { create_backup_policy }")

Elencare un criterio di backup

# Config values
api_key = "<API_KEY>"
source_bucket_name = "<BACKUP_VAULT_NAME>"

# Authenticator and client setup
authenticator = IAMAuthenticator(apikey=api_key)
rc_client = ResourceConfigurationV1(authenticator=authenticator)

# List all backup policies
list_response = rc_client.list_backup_policies(bucket=source_bucket_name)

print("\nList of backup policies:")
for policy in list_response.result.get("backup_policies", []):
    print(policy)

Ottenere una politica di backup

# Config
api_key = "<API_KEY>"
source_bucket_name = "<SOURCE_BUCKET_NAME>"
backup_vault_crn = "<BACKUP_VAULT_CRN>"
policy_name = "<POLICY_NAME>"

# Setup authenticator and client
authenticator = IAMAuthenticator(apikey=api_key)
rc_client = ResourceConfigurationV1(authenticator=authenticator)

# Create backup policy
create_backup_policy_response = rc_client.create_backup_policy(
    bucket=source_bucket_name,
    policy_name=policy_name,
    target_backup_vault_crn=backup_vault_crn,
    backup_type="continuous",
    initial_retention={"delete_after_days": 1}
)

# Extract policy ID
policy_id = create_backup_policy_response.result.get("policy_id")

get_backup_policy_response = rc_client.get_backup_policy(
    bucket=source_bucket_name,
    policy_id=policy_id
)

print("\nFetched Backup Policy Details:")
print(get_backup_policy_response.result)

Eliminare un criterio di backup

# Config
api_key = "<API_KEY>"
source_bucket_name = "<SOURCE_BUCKET_NAME>"
policy_id = "<POLICY_ID>"

# Setup authenticator and client
authenticator = IAMAuthenticator(apikey=api_key)
rc_client = ResourceConfigurationV1(authenticator=authenticator)

# Delete the backup policy
delete_backup_policy_response = rc_client.delete_backup_policy(
    bucket=source_bucket_name,
    policy_id=policy_id
)

print(f"Backup policy '{policy_id}' deleted successfully.")

Creazione di un vault di backup

# Config
api_key = "<API_KEY>"
service_instance_id = "<SERVICE_INSTANCE_ID>"
backup_vault_name = "<BACKUP_VAULT_NAME>"
region = "<REGION>"

# Setup authenticator and client
authenticator = IAMAuthenticator(apikey=api_key)
rc_client = ResourceConfigurationV1(authenticator=authenticator)

# Create a backup vault
create_backup_vault_response = rc_client.create_backup_vault(
    service_instance_id=service_instance_id,
    backup_vault_name=backup_vault_name,
    region=region
)

# Output result
print("Backup vault created:")
print(create_backup_vault_response.result)

Elenco delle camere blindate di backup

# Config
api_key = "<API_KEY>"
service_instance_id = "<SERVICE_INSTANCE_ID>"

# Setup authenticator and client
authenticator = IAMAuthenticator(apikey=api_key)
rc_client = ResourceConfigurationV1(authenticator=authenticator)

# List backup vaults
list_backup_vaults_response = rc_client.list_backup_vaults(
    service_instance_id=service_instance_id
)

print("List of backup vaults:")
print(list_backup_vaults_response.result)

Ottenere i vault di backup

# Config
api_key = "<API_KEY>"
backup_vault_name = "<BACKUP_VAULT_NAME>"

# Setup authenticator and client
authenticator = IAMAuthenticator(apikey=api_key)
rc_client = ResourceConfigurationV1(authenticator=authenticator)

# Get backup vault
get_backup_vault = rc_client.get_backup_vault(
    backup_vault_name=backup_vault_name
)

# Output result
print("Backup vault details:")
print(get_backup_vault.result)

Aggiornare i vault di backup

# Config
api_key = "<API_KEY>"
backup_vault_name = "<BACKUP_VAULT_NAME>"

# Setup authenticator and client
authenticator = IAMAuthenticator(apikey=api_key)
rc_client = ResourceConfigurationV1(authenticator=authenticator)

# Update backup vault settings (disable activity tracking and metrics monitoring)
backup_vault_patch = {
    "activity_tracking": {"management_events": True},
    "metrics_monitoring": {"usage_metrics_enabled": True},
}

update_backup_vault_response = rc_client.update_backup_vault(
    backup_vault_name=backup_vault_name,
    backup_vault_patch=backup_vault_patch
)

# Output result
print("Backup vault updated successfully.")
print(update_backup_vault_response)

Eliminare un vault di backup

# Config
api_key = "<API_KEY>"
backup_vault_name = "<BACKUP_VAULT_NAME>"

# Setup authenticator and client
authenticator = IAMAuthenticator(apikey=api_key)
rc_client = ResourceConfigurationV1(authenticator=authenticator)

# Delete the backup vault
delete_vault_response = rc_client.delete_backup_vault(
    backup_vault_name=backup_vault_name
)

# Output result
print(f"Successfully deleted backup vault '{delete_vault_response}'.")

Elenco Gamme di recupero

# Config
api_key = "<API_KEY>"
backup_vault_name = "<BACKUP_VAULT_NAME>"

# Setup authenticator and client
authenticator = IAMAuthenticator(apikey=api_key)
rc_client = ResourceConfigurationV1(authenticator=authenticator)

# List recovery ranges
recovery_ranges_response = rc_client.list_recovery_ranges(
    backup_vault_name=backup_vault_name
)

# Output recovery range results
print("Recovery Ranges:")
print(recovery_ranges_response.result)

Ottenere l'intervallo di recupero

# Config
api_key = "<API_KEY>"
backup_vault_name = "<BACKUP_VAULT_NAME>"
recovery_range_id = "<RECOVERY_RANGE_ID>"

# Setup authenticator and client
authenticator = IAMAuthenticator(apikey=api_key)
rc_client = ResourceConfigurationV1(authenticator=authenticator)

get_recovery_range_response = rc_client.get_source_resource_recovery_range(
    backup_vault_name=backup_vault_name,
    recovery_range_id=recovery_range_id
)
print("Recovery Range Details:")
print(get_recovery_range_response.result)

Aggiornamento dell'intervallo di recupero

# Config
api_key = "<API_KEY>"
backup_vault_name = "<BACKUP_VAULT_NAME>"
recovery_range_id = "<RECOVERY_RANGE_ID>"

# Setup authenticator and client
authenticator = IAMAuthenticator(apikey=api_key)
rc_client = ResourceConfigurationV1(authenticator=authenticator)

recovery_range_patch_model = {}
recovery_range_patch_model['retention'] = {"delete_after_days": 99}

patch_response = rc_client.patch_source_resource_recovery_range(
    backup_vault_name=backup_vault_name,
    recovery_range_id=recovery_range_id,
    recovery_range_patch=recovery_range_patch_model
)
print("Patch Response Details:")
print(patch_response)

Avvio di un ripristino

# Configuration
api_key = "<API_KEY>"
backup_vault_name = "<BACKUP_VAULT_NAME>"
target_bucket_crn = "<TARGET_BUCKET_CRN>"
recovery_range_id = "<RECOVERY_RANGE_ID>"
restore_point_in_time = "<RESTORE_POINT_IN_TIME>"

# Setup authenticator and clients
authenticator = IAMAuthenticator(apikey=api_key)
rc_client = ResourceConfigurationV1(authenticator=authenticator)

# Initiate restore
create_restore = rc_client.create_restore(
    backup_vault_name=backup_vault_name,
    recovery_range_id=recovery_range_id,
    restore_type="in_place",
    restore_point_in_time=restore_point_in_time,
    target_resource_crn=target_bucket_crn
)
print(f"Restore initiated : {create_restore}")

Ripristino dell'elenco

# Config
api_key = "<API_KEY>"
backup_vault_name = "<BACKUP_VAULT_NAME>"

# Setup authenticator and clients
authenticator = IAMAuthenticator(apikey=api_key)
rc_client = ResourceConfigurationV1(authenticator=authenticator)

# List restore operations
get_store = rc_client.get_restore(
    backup_vault_name=backup_vault_name)

print("Restore response:")
print(get_store.result)

Ottenere i dettagli del ripristino

# Config
api_key = "<API_KEY>"
source_bucket_name = "<SOURCE_BUCKET_NAME>"
backup_vault_crn = "<BACKUP_VAULT_CRN>"
backup_vault_name = "<BACKUP_VAULT_NAME>"
target_bucket_crn = "<TARGET_BUCKET_CRN>"
recovery_range_id = "<RECOVERY_RANGE_ID>"
restore_point_in_time = "<RESTORE_POINT_IN_TIME>"

# Setup authenticator and clients
authenticator = IAMAuthenticator(apikey=api_key)
rc_client = ResourceConfigurationV1(authenticator=authenticator)

# Create restore
create_restore = rc_client.create_restore(
    backup_vault_name=backup_vault_name,
    recovery_range_id=recovery_range_id,
    restore_type="in_place",
    restore_point_in_time=restore_point_in_time,
    target_resource_crn=target_bucket_crn
)

restore_id = create_restore.result["restore_id"]

# List restore operations
get_store = rc_client.get_restore(
    backup_vault_name=backup_vault_name, restore_id=restore_id)

print("Restore response:")
print(get_store.result)

Crea un nuovo bucket COS con blocco oggetti abilitato

 def create_bucket_with_objectlock(bucket_name):
         cos_cli.create_bucket(
             Bucket=bucket_name,
             ObjectLockEnabledForBucket=True,
         )
         print("Bucket: {0} created with objectlock enabled".format(bucket_name))

Imposta la configurazione del blocco oggetti con modalità di conformità sul bucket COS

def objectlock_configuration_on_bucket(bucket_name):

    # Putting default retenion on the COS bucket.
    default_retention_rule = {'DefaultRetention': {'Mode': 'COMPLIANCE', 'Years': 1}}
    object_lock_config = {'ObjectLockEnabled': 'Enabled', 'Rule': default_retention_rule}
    cos_cli.put_object_lock_configuration(Bucket=bucket_name, ObjectLockConfiguration=object_lock_config)

Imposta la configurazione del blocco degli oggetti con modalità di governance sul bucket COS

def objectlock_configuration_with_governance_mode_on_bucket(bucket_name):

    # Putting default retenion on the COS bucket with governance mode.
    default_retention_rule = {'DefaultRetention': {'Mode': 'GOVERNANCE', 'Years': 1}}
    object_lock_config = {'ObjectLockEnabled': 'Enabled', 'Rule': default_retention_rule}
    cos_cli.put_object_lock_configuration(Bucket=bucket_name, ObjectLockConfiguration=object_lock_config)

Ottieni la configurazione del blocco oggetti sul bucket COS

def objectlock_configuration_with_governance_mode_on_bucket(bucket_name):

    # Reading the objectlock configuration set on the bucket.
    response = cos_cli.get_object_lock_configuration(Bucket=bucket_name)
    print("Objectlock Configuration for {0} =>".format(bucket_name))
    print(response.ObjectLockConfiguration)

Carica un oggetto con modalità di governance nel bucket COS

def upload_object_with_governance_mode(bucket_name,object_name,object_content):
        cos_cli.put_object(
            Bucket=bucket_name,
            Key=object_name,
            Body=object_content,
            ObjectLockMode='GOVERNANCE',
            ObjectLockRetainUntilDate=datetime(2025, 11, 15)
        )
        print("Object: {0} uploaded!".format(object_name))

Attiva la conservazione del blocco dell'oggetto con modalità di conformità sull'oggetto

def objectlock_retention(bucket_name,object_name):
        # Put objectlock retenion on the  object uploaded to the bucket.
        date = datetime.now()+timedelta(seconds=5)
        retention_rule = {'Mode': 'COMPLIANCE', 'RetainUntilDate': date}
        cos_cli.put_object_retention(Bucket=bucket_name, Key=object_name, Retention=retention_rule)

Attiva la conservazione del blocco dell'oggetto con modalità di governance sull'oggetto

def objectlock_retention_with_governance_mode(bucket_name,object_name):
        # Put objectlock retenion with governance mode on the  object uploaded to the bucket.
        date = datetime.now()+timedelta(seconds=5)
        retention_rule = {'Mode': 'GOVERNANCE', 'RetainUntilDate': date}
        cos_cli.put_object_retention(Bucket=bucket_name, Key=object_name, Retention=retention_rule)

Ottieni il mantenimento del blocco dell'oggetto

def objectlock_retention_with_governance_mode(bucket_name,object_name):
        # Get objectlock retention of the above object.
        response = cos_cli.get_object_retention(Bucket=bucket_name, Key=object_name)
        print("Objectlock Retention for {0}=>".format(object_name))
        print(response.Retention)

Eliminazione di un oggetto con modalità di governance del blocco oggetti utilizzando la governance di bypass

def delete_object_with_bypass_governance(bucket_name,object_name):
        # Deleting an object with retention using bypass governance
        cos_cli.delete_object(Bucket=bucket_name, Key=object_name, BypassGovernanceRetention=True)

Utilizzo di Key Protect

Key Protect può essere aggiunto a un bucket di archiviazione per crittografare dati sensibili inattivi nel cloud.

Prima di cominciare

I seguenti elementi sono necessari per creare un bucket con Key-Protect abilitato:

Richiamo del CRN di chiave root

  1. Richiama l'ID istanza per il tuo servizio Key Protect
  2. Utilizza l'API Key Protect per richiamare tutte le tue chiavi disponibili
  3. Richiama il CRN della chiave root che utilizzi per abilitare Key Protect sul tuo bucket. Il CRN è simile al seguente:

crn:v1:bluemix:public:kms:us-south:a/3d624cd74a0dea86ed8efe3101341742:90b6a1db-0fe1-4fe9-b91e-962c327df531:key:0bg3e33e-a866-50f2-b715-5cba2bc93234

Creazione di un bucket con Key Protect abilitato

COS_KP_ALGORITHM = "<algorithm>"
COS_KP_ROOTKEY_CRN = "<root-key-crn>"

# Create a new bucket with key protect (encryption)
def create_bucket_kp(bucket_name):
    print("Creating new encrypted bucket: {0}".format(bucket_name))
    try:
        cos_client.create_bucket(
            Bucket=bucket_name,
            CreateBucketConfiguration={
                "LocationConstraint":COS_BUCKET_LOCATION
            },
            IBMSSEKPEncryptionAlgorithm=COS_KP_ALGORITHM,
            IBMSSEKPCustomerRootKeyCrn=COS_KP_ROOTKEY_CRN
        )
        print("Encrypted Bucket: {0} created!".format(bucket_name))
    except ClientError as be:
        print("CLIENT ERROR: {0}\n".format(be))
    except Exception as e:
        print("Unable to create encrypted bucket: {0}".format(e))

Valori chiave

  • <algorithm>- L'algoritmo di crittografia utilizzato per i nuovi oggetti aggiunti al bucket (l'impostazione predefinita è AES256 ).
  • <root-key-crn>- CRN della Root Key ottenuta dal servizio Key Protect.

Riferimenti SDK

Metodi

Utilizzo del trasferimento ad alta velocità Aspera

Avviso relativo alle versioni precedenti: il supporto per Aspera è considerato obsoleto. Si consiglia agli utenti di utilizzare Aspera Transfer SDK[https://developer.ibm.com/apis/catalog/aspera--aspera-transfer-sdk/API Reference].

Avviso relativo alle versioni precedenti: il supporto per Aspera è considerato obsoleto. Si consiglia agli utenti di utilizzare Aspera Transfer SDK.

Installando la Libreria del trasferimento ad alta velocità Aspera, puoi utilizzare trasferimenti file ad alta velocità all'interno della tua applicazione. La libreria Aspera è closed-source e, pertanto, una dipendenza facoltativa per l'SDK COS (che utilizza una licenza Apache).

Ogni sessione Aspera crea un singolo processo ascp eseguito sulla macchina client per eseguire il trasferimento. Assicurati che il tuo ambiente di calcolo possa consentire l'esecuzione di questo processo.

Inizializzazione di AsperaTransferManager

Prima di inizializzare AsperaTransferManager, assicurarsi di avere un oggetto funzionante (non un oggetto o ). client (non un oggetto resource o session).

import ibm_boto3
from ibm_botocore.client import Config
from ibm_s3transfer.aspera.manager import AsperaTransferManager

COS_ENDPOINT = "<endpoint>" # Current list avaiable at https://control.cloud-object-storage.cloud.ibm.com/v2/endpoints
COS_API_KEY_ID = "<api-key>"
COS_RESOURCE_CRN = "<resource-instance-id>"
COS_BUCKET_LOCATION = "<location>"

# Create resource
cos_client = ibm_boto3.client("s3",
    ibm_api_key_id=COS_API_KEY_ID,
    ibm_service_instance_id=COS_RESOURCE_CRN,
    config=Config(signature_version="oauth"),
    endpoint_url=COS_ENDPOINT
)

transfer_manager = AsperaTransferManager(cos)

Devi fornire una chiave API IAM per i trasferimenti ad alta velocità Aspera. Le credenziali HMAC NON sono attualmente supportate. Per ulteriori informazioni su IAM, fai clic qui.

Per ottenere una velocità effettiva più elevata, suddividi il trasferimento in un numero specificato di sessioni parallele che inviano blocchi di dati la cui dimensione è definita dal valore threshold.

La tipica configurazione per l'utilizzo di più sessioni dovrebbe essere:

  • Velocità di destinazione di 2500 MBps
  • Soglia di 100 MB (questo è il valore consigliato per la maggior parte delle applicazioni)
ms_transfer_config = AsperaConfig(multi_session="all",
                                  target_rate_mbps=2500,
                                  multi_session_threshold_mb=100)

Nell'esempio sopra riportato, l'SDK genera un numero sufficiente di sessioni per provare a raggiungere la velocità di destinazione di 2500 MBps.

La gestione delle sessioni può anche essere configurata esplicitamente nell'SDK. Ciò è utile nei casi in cui si voglia un controllo più preciso sull'utilizzo della rete.

La tipica configurazione per l'utilizzo di più sessioni esplicito dovrebbe essere:

  • 2 o 10 sessioni
  • Soglia di 100 MB (questo è il valore consigliato per la maggior parte delle applicazioni)
from ibm_s3transfer.aspera.manager import AsperaConfig
# Configure 2 sessions for transfer
ms_transfer_config = AsperaConfig(multi_session=2,
                                  multi_session_threshold_mb=100)

# Create the Aspera Transfer Manager
transfer_manager = AsperaTransferManager(client=client,
                                         transfer_config=ms_transfer_config)

Per ottenere le migliori prestazioni nella maggior parte degli scenari, utilizzare sempre sessioni multiple per ridurre al minimo l'elaborazione associata all'istanziazione di un trasferimento ad alta velocità Aspera. Se la tua capacità di rete è di almeno 1 Gbps, devi utilizzare 10 sessioni. Reti con una larghezza di banda inferiore devono utilizzare due sessioni.

Caricamento file

bucket_name = "<bucket-name>"
upload_filename = "<absolute-path-to-file>"
object_name = "<item-name>"

# Create Transfer manager
with AsperaTransferManager(client) as transfer_manager:

    # Perform upload
    future = transfer_manager.upload(upload_filename, bucket_name, object_name)

    # Wait for upload to complete
    future.result()

Valori chiave

  • <bucket-name>- nome del bucket di destinazione
  • <absolute-path-to-file>- percorso della directory e nome del file da caricare
  • <item-name>- nome del nuovo file aggiunto al bucket

Scarica file

bucket_name = "<bucket-name>"
download_filename = "<absolute-path-to-file>"
object_name = "<object-to-download>"

# Create Transfer manager
with AsperaTransferManager(client) as transfer_manager:

    # Get object with Aspera
    future = transfer_manager.download(bucket_name, object_name, download_filename)

    # Wait for download to complete
    future.result()

Valori chiave

  • <bucket-name>- nome del bucket nell'istanza del servizio Object Storage che ha abilitato Aspera.
  • <absolute-path-to-file>- e il nome del file in cui salvare il file nel sistema locale.
  • <object-to-download>- nome del file nel bucket da scaricare.

Caricamento directory

bucket_name = "<bucket-name>"
# THIS DIRECTORY MUST EXIST LOCALLY, and have objects in it.
local_upload_directory = "<absolute-path-to-directory>"
# THIS SHOULD NOT HAVE A LEADING "/"
remote_directory = "<object prefix>"

# Create Transfer manager
with AsperaTransferManager(client) as transfer_manager:

    # Perform upload
    future = transfer_manager.upload_directory(local_upload_directory, bucket_name, remote_directory)

    # Wait for upload to complete
    future.result()

Valori chiave

  • <bucket-name>- nome del bucket nell'istanza del servizio Object Storage che ha abilitato Aspera
  • <absolute-path-to-directory>- directory locale che contiene i file da caricare. Deve avere una / di inizio e di fine (ossia /Users/testuser/Documents/Upload/)
  • <object prefix>- nome della directory nel bucket in cui memorizzare i file. Non deve avere una barra / iniziale (ossia newuploads/)

Scaricamento directory

bucket_name = "<bucket-name>"
# THIS DIRECTORY MUST EXIST LOCALLY
local_download_directory = "<absolute-path-to-directory>"
remote_directory = "<object prefix>"

# Create Transfer manager
with AsperaTransferManager(client) as transfer_manager:

    # Get object with Aspera
    future = transfer_manager.download_directory(bucket_name, remote_directory, local_download_directory)

    # Wait for download to complete
    future.result()

Valori chiave

  • <bucket-name>- nome del bucket nell'istanza del servizio Object Storage che ha abilitato Aspera
  • <absolute-path-to-directory>- directory locale in cui salvare i file scaricati. Deve avere una barra di separazione e un'altra di separazione / (cioè /Users/testuser/Downloads/)
  • <object prefix>- nome della directory nel bucket in cui memorizzare i file. Non deve avere una barra / iniziale (ossia todownload/)

Utilizzo dei sottoscrittori

I sottoscrittori forniscono l'osservabilità nei trasferimenti collegando dei metodi di callback personalizzati. Tutte le transizioni dei trasferimenti tra le seguenti fasi:

Queued - In Progress - Done

Esistono tre sottoscrittori disponibili per ogni fase:

  • CallbackOnQueued() - richiamato quando è stato aggiunto un nuovo trasferimento a AsperaTransferManager
  • CallbackOnProgress() - richiamato quando un trasferimento ha trasmesso i dati (attivato ripetutamente mentre il trasferimento è in corso).
  • CallbackOnDone() - richiamato quando il trasferimento è stato completato
bucket_name = "<bucket-name>"
local_download_directory = "<absolute-path-to-directory>"
remote_directory = "<object prefix>"

# Subscriber callbacks
class CallbackOnQueued(AsperaBaseSubscriber):
    def __init__(self):
        pass

    def on_queued(self, future, **kwargs):
        print("Directory download queued.")

class CallbackOnProgress(AsperaBaseSubscriber):
    def __init__(self):
        pass

    def on_progress(self, future, bytes_transferred, **kwargs):
        print("Directory download in progress: %s bytes transferred" % bytes_transferred)

class CallbackOnDone(AsperaBaseSubscriber):
    def __init__(self):
        pass

    def on_done(self, future, **kwargs):
        print("Downloads complete!")

# Create Transfer manager
transfer_manager = AsperaTransferManager(client)

# Attach subscribers
subscribers = [CallbackOnQueued(), CallbackOnProgress(), CallbackOnDone()]

# Get object with Aspera
future = transfer_manager.download_directory(bucket_name, remote_directory, local_download_directory, None, subscribers)

# Wait for download to complete
future.result()

Valori chiave

  • <bucket-name>- nome del bucket nell'istanza del servizio Object Storage che ha abilitato Aspera
  • <absolute-path-to-directory>- directory locale in cui salvare i file scaricati. Deve avere una barra / di inizio e di fine (ossia /Users/testuser/Downloads/)
  • <object prefix>- nome della directory nel bucket in cui memorizzare i file. Non deve avere una barra / iniziale (ossia todownload/)

Il codice di esempio produce il seguente output:

Directory download queued.
Directory download in progress: 5632 bytes transferred
Directory download in progress: 1047552 bytes transferred
...
Directory download in progress: 53295130 bytes transferred
Directory download in progress: 62106855 bytes transferred
Download complete!

Metti in pausa/Riprendi/Annulla

L'SDK consente di gestire l'avanzamento dei trasferimenti di file/directory mediante i seguenti metodi dell'oggetto AsperaTransferFuture:

  • pause()
  • resume()
  • cancel()

Il richiamo dei metodi sopra indicati non ha alcun effetto collaterale. Adeguate attività di ripulitura e manutenzione sono gestite dall'SDK.

# Create Transfer manager
bucket_name = "<bucket-name>"
local_download_directory = "<absolute-path-to-directory>"
remote_directory = "<object prefix>"

with AsperaTransferManager(client) as transfer_manager:

    # download a directory with Aspera
    future = transfer_manager.download_directory(bucket_name, remote_directory, local_download_directory, None, None)

    # pause the transfer
    future.pause()

    # resume the transfer
    future.resume()

    # cancel the transfer
    future.cancel()

Risoluzione dei problemi di Aspera

Problema: gli sviluppatori che utilizzano qualsiasi versione di Python oltre a 3.6 potrebbero riscontrare degli errori durante l'installazione o l'utilizzo di Aspera SDK.

Causa: Se nel vostro ambiente sono installate diverse versioni di Python, è possibile che si verifichino errori di installazione quando si tenta di installare Aspera SDK. Questo può essere causato dalla mancanza di file DLL o di una DLL non corretta nel percorso.

Soluzione: il primo passo nella risoluzione di questo problema consiste nel reinstallare le librerie Aspera. Potrebbe essersi verificato un errore durante l'installazione. Di conseguenza, questo errore potrebbe avere interessato i file DLL. Se questo non risolve i problemi, ti verrà richiesto di aggiornare la tua versione di Python. Se non è possibile farlo, è possibile utilizzare l'installazione di Intel® Distribution per Python *. Ciò ti dovrebbe consentire di installare Aspera SDK su Python 3.6.x senza alcun problema.

Aggiornamento dei metadati

Esistono due modi per aggiornare i metadati in un oggetto esistente:

  • Una richiesta PUT con i nuovi metadati e il contenuto dell'oggetto originale
  • L'esecuzione di una richiesta COPY con i nuovi metadati che specifica l'oggetto originale come origine della copia

Utilizzo di PUT per aggiornare i metadati

Nota: la richiesta di PUT sovrascrive il contenuto esistente dell'oggetto, che deve quindi essere prima scaricato e ricaricato con i nuovi metadati.

def update_metadata_put(bucket_name, item_name, key, value):
    try:
        # retrieve the existing item to reload the contents
        response = cos_client.get_object(Bucket=bucket_name, Key=item_name)
        existing_body = response.get("Body").read()

        # set the new metadata
        new_metadata = {
            key: value
        }

        cos_client.put_object(Bucket=bucket_name, Key=item_name, Body=existing_body, Metadata=new_metadata)

        print("Metadata update (PUT) for {0} Complete!\n".format(item_name))
    except ClientError as be:
        print("CLIENT ERROR: {0}\n".format(be))
    except Exception as e:
        log_error("Unable to update metadata: {0}".format(e))

Utilizzo di COPY per aggiornare i metadati

def update_metadata_copy(bucket_name, item_name, key, value):
    try:
        # set the new metadata
        new_metadata = {
            key: value
        }

        # set the copy source to itself
        copy_source = {
            "Bucket": bucket_name,
            "Key": item_name
        }

        cos_client.copy_object(Bucket=bucket_name, Key=item_name, CopySource=copy_source, Metadata=new_metadata, MetadataDirective="REPLACE")

        print("Metadata update (COPY) for {0} Complete!\n".format(item_name))
    except ClientError as be:
        print("CLIENT ERROR: {0}\n".format(be))
    except Exception as e:
        log_error("Unable to update metadata: {0}".format(e))

Utilizzo di Immutable Object Storage

Aggiunta di una configurazione di protezione ad un bucket esistente

Gli oggetti scritti in un bucket protetto non possono essere eliminati fino a quando il periodo di protezione non è scaduto e tutte le conservazioni a fini legali sull'oggetto non sono stati rimosse. A un oggetto viene dato il valore di conservazione predefinito del bucket, a meno che non venga fornito un valore specifico per l'oggetto quando l'oggetto viene creato. Gli oggetti nei bucket protetti che non sono più sottoposti a conservazione (il periodo di conservazione è scaduto e l'oggetto non ha alcuna conservazione a fini legali), quando vengono sovrascritti sono di nuovo sottoposti a conservazione. Il nuovo periodo di conservazione può essere fornito come parte della richiesta di sovrascrittura dell'oggetto, altrimenti all'oggetto verrà assegnato il tempo di conservazione predefinito del bucket.

I valori minimi e massimi supportati per le impostazioni del periodo di conservazione MinimumRetention, DefaultRetention e MaximumRetention sono un minimo di 0 giorni e un massimo di 365243 giorni (1000 anni).

def add_protection_configuration_to_bucket(bucket_name):
    try:
        new_protection_config = {
            "Status": "Retention",
            "MinimumRetention": {"Days": 10},
            "DefaultRetention": {"Days": 100},
            "MaximumRetention": {"Days": 1000}
        }

        cos_client.put_bucket_protection_configuration(Bucket=bucket_name, ProtectionConfiguration=new_protection_config)

        print("Protection added to bucket {0}\n".format(bucket_name))
    except ClientError as be:
        print("CLIENT ERROR: {0}\n".format(be))
    except Exception as e:
        print("Unable to set bucket protection config: {0}".format(e))

Controlla la protezione su un bucket

def get_protection_configuration_on_bucket(bucket_name):
    try:
        response = cos_client.get_bucket_protection_configuration(Bucket=bucket_name)
        protection_config = response.get("ProtectionConfiguration")

        print("Bucket protection config for {0}\n".format(bucket_name))
        print(protection_config)
        print("\n")
    except ClientError as be:
        print("CLIENT ERROR: {0}\n".format(be))
    except Exception as e:
        print("Unable to get bucket protection config: {0}".format(e))

Carica un oggetto protetto

Gli oggetti nei bucket protetti che non sono più sottoposti a conservazione (il periodo di conservazione è scaduto e l'oggetto non ha alcuna conservazione a fini legali), quando vengono sovrascritti sono di nuovo sottoposti a conservazione. Il nuovo periodo di conservazione può essere fornito come parte della richiesta di sovrascrittura dell'oggetto, altrimenti all'oggetto verrà assegnato il tempo di conservazione predefinito del bucket.

Valore Immettere Descrizione
Retention-Period Numero intero non negativo (secondi) Il periodo di conservazione da memorizzare sull'oggetto, in secondi. L'oggetto non può essere sovrascritto o eliminato finché l'intervallo di tempo specificato nel periodo di conservazione non è trascorso. Se vengono specificati questi campo e Retention-Expiration-Date, viene restituito un errore 400. Se non viene specificato nessuno di questi due valori, verrà utilizzato il periodo DefaultRetention del bucket. Zero (0) è un valore consentito, presumendo che il periodo di conservazione minimo del bucket sia anch'esso 0.
Retention-expiration-date Data (formato ISO 8601) Data in cui sarà consentito eliminare o modificare l'oggetto. Puoi specificare solo questo valore oppure l'intestazione Retention-Period. Se vengono specificati entrambi, verrà restituito un errore 400. Se non viene specificato nessuno di questi due valori, verrà utilizzato il periodo DefaultRetention del bucket.
Retention-legal-hold-id stringa Una singola conservazione a fini legali da applicare all'oggetto. Una conservazione a fini legali è una stringa di caratteri di lunghezza Y. L'oggetto non può essere sovrascritto o eliminato finché non sono state rimosse tutte le conservazioni a fini legali a esso associate.
def put_object_add_legal_hold(bucket_name, object_name, file_text, legal_hold_id):
    print("Add legal hold {0} to {1} in bucket {2} with a putObject operation.\n".format(legal_hold_id, object_name, bucket_name))
    cos_client.put_object(
        Bucket=bucket_name,
        Key=object_name,
        Body=file_text,
        RetentionLegalHoldId=legal_hold_id)
    print("Legal hold {0} added to object {1} in bucket {2}\n".format(legal_hold_id, object_name, bucket_name))

def copy_protected_object(source_bucket_name, source_object_name, destination_bucket_name, new_object_name):
    print("Copy protected object {0} from bucket {1} to {2}/{3}.\n".format(source_object_name, source_bucket_name, destination_bucket_name, new_object_name))

    copy_source = {
        "Bucket": source_bucket_name,
        "Key": source_object_name
    }

    cos_client.copy_object(
        Bucket=destination_bucket_name,
        Key=new_object_name,
        CopySource=copy_source,
        RetentionDirective="Copy"
    )

    print("Protected object copied from {0}/{1} to {2}/{3}\n".format(source_bucket_name, source_object_name, destination_bucket_name, new_object_name));

def complete_multipart_upload_with_retention(bucket_name, object_name, upload_id, retention_period):
    print("Completing multi-part upload for object {0} in bucket {1}\n".format(object_name, bucket_name))
    cos_client.complete_multipart_upload(
        Bucket=bucket_name,
        Key=object_name,
        MultipartUpload={
            "Parts":[{
                "ETag": part["ETag"],
                "PartNumber": 1
            }]
        },
        UploadId=upload_id,
        RetentionPeriod=retention_period
    )

    print("Multi-part upload completed for object {0} in bucket {1}\n".format(object_name, bucket_name))

def upload_file_with_retention(bucket_name, object_name, path_to_file, retention_period):
    print("Uploading file {0} to object {1} in bucket {2}\n".format(path_to_file, object_name, bucket_name))

    args = {
        "RetentionPeriod": retention_period
    }

    cos_client.upload_file(
        Filename=path_to_file,
        Bucket=bucket_name,
        Key=object_name,
        ExtraArgs=args
    )

    print("File upload complete to object {0} in bucket {1}\n".format(object_name, bucket_name))

Estendi il periodo di conservazione di un oggetto protetto

Il periodo di conservazione di un oggetto può solo essere esteso. Non può essere ridotto rispetto al valore attualmente configurato.

Il valore di espansione della conservazione è impostato in uno di tre possibili modi:

  • ulteriore tempo dal valore corrente (Additional-Retention-Period o metodo simile)
  • nuovo periodo di estensione in secondi (Extend-Retention-From-Current-Time o metodo simile)
  • nuova data di scadenza della conservazione dell'oggetto (New-Retention-Expiration-Date o metodo simile)

Il periodo di conservazione attuale memorizzato nei metadati dell'oggetto viene aumentato in misura equivalente al tempo aggiuntivo indicato oppure sostituito con il nuovo valore, a seconda del parametro impostato nella richiesta extendRetention. In tutti i casi, il parametro di estensione della conservazione viene controllato rispetto al periodo di conservazione attuale e il parametro esteso viene accettato solo se il periodo di conservazione aggiornato è più grande del periodo di conservazione attuale.

Gli oggetti nei bucket protetti che non sono più sottoposti a conservazione (il periodo di conservazione è scaduto e l'oggetto non ha alcuna conservazione a fini legali), quando vengono sovrascritti sono di nuovo sottoposti a conservazione. Il nuovo periodo di conservazione può essere fornito come parte della richiesta di sovrascrittura dell'oggetto, altrimenti all'oggetto verrà assegnato il tempo di conservazione predefinito del bucket.

def extend_retention_period_on_object(bucket_name, object_name, additional_seconds):
    print("Extend the retention period on {0} in bucket {1} by {2} seconds.\n".format(object_name, bucket_name, additional_seconds))

    cos_client.extend_object_retention(
        Bucket=bucket_ame,
        Key=object_name,
        AdditionalRetentionPeriod=additional_seconds
    )

    print("New retention period on {0} is {1}\n".format(object_name, additional_seconds))

Elenca le conservazioni a fini legali su un oggetto protetto

Questa operazione restituisce:

  • La data di creazione dell'oggetto
  • Il periodo di conservazione dell'oggetto in secondi
  • Data di scadenza della conservazione calcolata sulla base del periodo e della data di creazione
  • Elenco delle conservazioni a fini legali
  • Identificativo della conservazione a fini legali
  • Data/ora di quando è stata applicata la conservazione a fini legali

Se non ci sono conservazioni a fini legali sull'oggetto, viene restituito un LegalHoldSet vuoto. Se non c'è alcun periodo di conservazione specificato sull'oggetto, viene restituito un errore 404.

def list_legal_holds_on_object(bucket_name, object_name):
    print("List all legal holds on object {0} in bucket {1}\n".format(object_name, bucket_name));

    response = cos_client.list_legal_holds(
        Bucket=bucket_name,
        Key=object_name
    )

    print("Legal holds on bucket {0}: {1}\n".format(bucket_name, response))

Crea un sito web statico ospitato

Questa operazione richiede le autorizzazioni, poiché solo al proprietario del bucket è generalmente consentito configurare un bucket per ospitare un sito web statico. I parametri determinano il suffisso predefinito per i visitatori del sito e un documento di errore facoltativo.

def putBucketWebsiteConfiguration(bucket_name):
    website_defaults = {
        'ErrorDocument': {'Key': 'error.html'},
        'IndexDocument': {'Suffix': 'index.html'},
    }
    cos_client.put_bucket_website(Bucket=bucket_name, WebsiteConfiguration=website_defaults)
    print("Website configuration set on bucket {0}\n".format(bucket_name))

Passi successivi

Per ulteriori informazioni, il codice sorgente può essere trovato all'indirizzo GitHub.