vérifier si une clé existe dans un compartiment dans s3 en utilisant boto3

Je voudrais savoir si une clé existe dans boto3. Je peux boucler le contenu du seau et vérifier la clé si elle correspond.

Mais cela semble plus long et excessif. Les documents officiels de Boto3 expliquent explicitement comment procéder.

Peut-être que je manque l’évidence. Quelqu’un peut-il me montrer comment je peux y arriver?

L’object boto.s3.key.Key Boto 2 utilisait une méthode boto.s3.key.Key qui vérifiait si la clé existait sur S3 en effectuant une requête HEAD et en examinant le résultat, mais il semble que cela n’existe plus. Vous devez le faire vous-même:

 import boto3 import botocore s3 = boto3.resource('s3') try: s3.Object('my-bucket', 'dootdoot.jpg').load() except botocore.exceptions.ClientError as e: if e.response['Error']['Code'] == "404": # The object does not exist. ... else: # Something else has gone wrong. raise else: # The object does exist. ... 

load() effectue une requête HEAD pour une seule clé, ce qui est rapide, même si l’object en question est volumineux ou si de nombreux objects se trouvent dans votre compartiment.

Bien sûr, vous pouvez vérifier si l’object existe parce que vous prévoyez de l’utiliser. Si tel est le cas, vous pouvez simplement oublier le load() et faire directement un get() ou un download_file() , puis gérer le cas d’erreur.

Je ne suis pas un grand fan de l’utilisation des exceptions pour le stream de contrôle. Ceci est une approche alternative qui fonctionne dans boto3:

 import boto3 s3 = boto3.resource('s3') bucket = s3.Bucket('my-bucket') key = 'dootdoot.jpg' objs = list(bucket.objects.filter(Prefix=key)) if len(objs) > 0 and objs[0].key == key: print("Exists!") else: print("Doesn't exist") 

La manière la plus simple que j’ai trouvée (et probablement la plus efficace) est la suivante:

 import boto3 from botocore.errorfactory import ClientError s3 = boto3.client('s3', aws_access_key_id='aws_key', aws_secret_access_key='aws_secret') try: s3.head_object(Bucket='bucket_name', Key='file_path') except ClientError: # Not found pass 

Dans Boto3, si vous recherchez un dossier (préfixe) ou un fichier utilisant list_objects. Vous pouvez utiliser l’existence de «Contents» dans le dict de réponse pour vérifier si l’object existe. C’est une autre façon d’éviter les captures try / except que suggère @EvilPuppetMaster

 import boto3 client = boto3.client('s3') results = client.list_objects(Bucket='my-bucket', Prefix='dootdoot.jpg') return 'Contents' in results 

Non seulement le client mais le bucket aussi:

 import boto3 import botocore bucket = boto3.resource('s3', region_name='eu-west-1').Bucket('my-bucket') try: bucket.Object('my-file').get() except botocore.exceptions.ClientError as ex: if ex.response['Error']['Code'] == 'NoSuchKey': print('NoSuchKey') 

C’est la technique la plus simple que j’ai trouvée:

 response = s3_client.list_objects_v2( Bucket=bucket_name, MaxKeys=1, Prefix=key_name ) file_exists = response['KeyCount'] > 0: 

Il existe un moyen simple de vérifier si le fichier existe ou non dans le compartiment S3. Nous n’avons pas besoin d’utiliser l’exception pour cela

 sesssion = boto3.Session(aws_access_key_id, aws_secret_access_key) s3 = session.client('s3') object_name = 'filename' bucket = 'bucketname' obj_status = s3.list_objects(Bucket = bucket, Prefix = object_name) if obj_status.get('Contents'): print("File exists") else: print("File does not exists") 
 import boto3 client = boto3.client('s3') s3_key = 'Your file without bucket name eg abc/bcd.txt' bucket = 'your bucket name' content = client.head_object(Bucket=bucket,Key=s3_key) if content.get('ResponseMetadata',None) is not None: print "File exists - s3://%s/%s " %(bucket,s3_key) else: print "File does not exist - s3://%s/%s " %(bucket,s3_key) 

Si vous avez moins de 1000 dans un répertoire ou un compartiment, vous pouvez en obtenir un ensemble et après avoir vérifié si cette clé dans cet ensemble:

 files_in_dir = {d['Key'].split('/')[-1] for d in s3_client.list_objects_v2( Bucket='mybucket', Prefix='my/dir').get('Contents') or []} 

Un tel code fonctionne même si my/dir n’existe pas.

http://boto3.readthedocs.io/en/latest/reference/services/s3.html#S3.Client.list_objects_v2

 S3_REGION="eu-central-1" bucket="mybucket1" name="objectname" import boto3 from botocore.client import Config client = boto3.client('s3',region_name=S3_REGION,config=Config(signature_version='s3v4')) list = client.list_objects_v2(Bucket=bucket,Prefix=name) for obj in list.get('Contents', []): if obj['Key'] == name: return True return False 

FWIW, voici les fonctions très simples que j’utilise

 import boto3 def get_resource(config: dict={}): """Loads the s3 resource. Expects AWS_ACCESS_KEY_ID and AWS_SECRET_ACCESS_KEY to be in the environment or in a config dictionary. Looks in the environment first.""" s3 = boto3.resource('s3', aws_access_key_id=os.environ.get( "AWS_ACCESS_KEY_ID", config.get("AWS_ACCESS_KEY_ID")), aws_secret_access_key=os.environ.get("AWS_SECRET_ACCESS_KEY", config.get("AWS_SECRET_ACCESS_KEY"))) return s3 def get_bucket(s3, s3_uri: str): """Get the bucket from the resource. A thin wrapper, use with caution. Example usage: >> bucket = get_bucket(get_resource(), s3_uri_prod)""" return s3.Bucket(s3_uri) def isfile_s3(bucket, key: str) -> bool: """Returns T/F whether the file exists.""" objs = list(bucket.objects.filter(Prefix=key)) return len(objs) == 1 and objs[0].key == key def isdir_s3(bucket, key: str) -> bool: """Returns T/F whether the directory exists.""" objs = list(bucket.objects.filter(Prefix=key)) return len(objs) > 1 

Check-out

 bucket.get_key( key_name, headers=None, version_id=None, response_headers=None, validate=True ) 

Vérifiez si une clé particulière existe dans le compartiment. Cette méthode utilise une requête HEAD pour vérifier l’existence de la clé. Retourne: une instance d’un object clé ou aucun

de Boto S3 Docs

Vous pouvez simplement appeler bucket.get_key (nom de fichier) et vérifier si l’object renvoyé est Aucun.