Utilizzo dell'SDK IBM Cloud® Object Storage per Python

Utilizza l'SDK IBM Cloud® Object Storage per Python, un fork di boto3, per creare client, importare credenziali e gestire bucket, oggetti, Key Protect e Aspera.

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

Il codice sorgente è disponibile su 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 del servizio è noto anche come ID dell'istanza della 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 connettersi a Object Storage, viene creato e configurato un client utilizzando le credenziali (chiave API e ID dell'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 recupera automaticamente le credenziali da questo file, a meno che non vengano impostate esplicitamente 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 ~/.aws/credentials sono presenti sia che ~/.bluemix/cos_credentials, ha cos_credentials 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 per Object Storage. 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 per l'API Object Storage S3. Ciò consente di elaborare direttamente le risposte HTTP, anziché ricorrere a metodi e 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 tuo Object Storage cloud con prefisso dello schema ( https:// ) (disponibile dalla 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 (per gli esempi di creazione ed eliminazione è richiesto l'accesso in scrittura)
  • <service-instance-id>- ID della risorsa per il tuo Object Storage cloud (disponibile tramite la CLI di IBM Cloud o la dashboard di IBM Cloud)
  • <location>- posizione predefinita per il tuo Object Storage cloud (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 ciò sia utile per ridurre l'impatto sulle prestazioni per ogni richiesta, 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 rimangono riservati per 10-15 minuti dopo la cancellazione.

Esegui un caricamento in più parti

Carica un file binario (metodo preferito)

Il upload_fileobj metodo dell'oggetto S3 esegue automaticamente un caricamento in più parti quando necessario.

La classe <CODE_INLINE> TransferConfig </CODE_INLINE> viene utilizzata per determinare la soglia per l'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 lo si desidera, è possibile utilizzare la classe S3.Client 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 Object Storage con il blocco degli 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))

Applicare la configurazione del blocco degli oggetti con modalità di conformità al bucket Object Storage

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)

Applicare la configurazione del blocco degli oggetti con modalità di governance al bucket Object Storage

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)

Ottenere la configurazione del blocco degli oggetti sul bucket Object Storage

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)

Caricare un oggetto con modalità di governance nel bucket Object Storage

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

Per creare un bucket con Key-Protect abilitato sono necessari i seguenti elementi:

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 chiave radice 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, costituisce una dipendenza opzionale per l'SDK Object Storage (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 il AsperaTransferManager, assicurarsi di disporre di un oggetto funzionante ( client non un resource o un 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 più sessioni 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 nella 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 in cui è abilitata la funzionalità Aspera.
  • <absolute-path-to-file>- nome della directory e del file in cui salvare il file sul 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 in cui è abilitata la funzionalità Aspera
  • <absolute-path-to-directory>- directory locale contenente 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 archiviare 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 in cui è abilitata la funzionalità Aspera
  • <absolute-path-to-directory>- directory locale in cui salvare i file scaricati. È necessario che siano presenti la barra iniziale e quella finale ( / ovvero /Users/testuser/Downloads/)
  • <object prefix>- nome della directory nel bucket in cui archiviare 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 in cui è abilitata la funzionalità 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 archiviare 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 proprio ambiente sono installate diverse versioni di Python, potrebbero verificarsi errori di installazione quando si tenta di installare l' 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 ciò non risolve i problemi, è necessario aggiornare la versione di Python. Se non riesci a farlo, puoi utilizzare la distribuzione Intel® per Python * per l'installazione. 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 PUT sovrascrive il contenuto esistente dell'oggetto, pertanto è necessario prima scaricarlo e poi ricaricarlo 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 presenti nei bucket protetti che non sono più soggetti a conservazione (il periodo di conservazione è scaduto e l'oggetto non è soggetto ad alcun blocco legale), una volta sovrascritti, tornano ad essere soggetti a conservazione. Il nuovo periodo di conservazione può essere specificato nell’ambito della richiesta di sovrascrittura dell’oggetto oppure all’oggetto viene assegnato il tempo di conservazione predefinito del bucket.

I valori minimi e massimi supportati per le impostazioni del periodo di conservazione MinimumRetention, DefaultRetention, e sono MaximumRetention un minimo di 0 giorni e un massimo di 365.243 giorni (1.000 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 presenti nei bucket protetti che non sono più soggetti a conservazione (il periodo di conservazione è scaduto e l'oggetto non è soggetto ad alcun blocco legale), una volta sovrascritti, tornano ad essere soggetti a conservazione. Il nuovo periodo di conservazione può essere specificato nell’ambito della richiesta di sovrascrittura dell’oggetto oppure all’oggetto viene 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 dei due, viene 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 è consentito eliminare o modificare l'oggetto. Puoi specificare solo questo valore oppure l'intestazione Retention-Period. Se vengono specificati entrambi, viene restituito un errore 400. Se non viene specificato nessuno dei due, viene utilizzato il periodo di conservazione predefinito ( 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 presenti nei bucket protetti che non sono più soggetti a conservazione (il periodo di conservazione è scaduto e l'oggetto non è soggetto ad alcun blocco legale), una volta sovrascritti, tornano ad essere soggetti a conservazione. Il nuovo periodo di conservazione può essere specificato nell’ambito della richiesta di sovrascrittura dell’oggetto oppure all’oggetto viene 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.