python - जाँच करें कि क्या कोई कुंजी s3 में बोटो 3 का उपयोग कर बाल्टी में मौजूद है




amazon-s3 boto3 (12)

मैं जानना चाहूंगा कि क्या कोई कुंजी boto3 में मौजूद है। मैं बकेट सामग्री को लूप कर सकता हूं और कुंजी की जांच कर सकता हूं यदि यह मेल खाता है।

लेकिन यह लंबे समय तक और एक overkill लगता है। Boto3 आधिकारिक डॉक्स स्पष्ट रूप से बताता है कि यह कैसे करना है।

हो सकता है मैं स्पष्ट याद कर रहा हूँ। क्या कोई मुझे बता सकता है कि मैं इसे कैसे प्राप्त कर सकता हूं।


Boto 2 के boto.s3.key.Key ऑब्जेक्ट में एक exists पद्धति होती थी जो यह boto.s3.key.Key कि कुंजी S3 में HEAD अनुरोध करके और परिणाम को देखते हुए अस्तित्व में है, लेकिन ऐसा लगता है कि अब मौजूद नहीं है। आपको इसे स्वयं करना होगा:

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() एक एकल कुंजी के लिए एक HEAD अनुरोध करता है, जो तेज है, भले ही प्रश्न में ऑब्जेक्ट बड़ा हो या आपकी बाल्टी में कई ऑब्जेक्ट हों।

बेशक, आप जाँच सकते हैं कि क्या वस्तु मौजूद है क्योंकि आप इसका उपयोग करने की योजना बना रहे हैं। यदि ऐसा है, तो आप केवल load() बारे में भूल सकते हैं load() और सीधे एक get() या download_file() कर सकते हैं, फिर वहां त्रुटि मामले को संभाल लें।


Boto3 के लिए, ObjectSummary का उपयोग यह जांचने के लिए किया जा सकता है कि कोई वस्तु मौजूद है या नहीं।

अमेज़ॅन S3 बाल्टी में संग्रहीत ऑब्जेक्ट का सारांश समाहित करता है। इस ऑब्जेक्ट में ऑब्जेक्ट का पूरा मेटाडेटा या उसकी कोई सामग्री शामिल नहीं है

import boto3
from botocore.errorfactory import ClientError
def path_exists(path, bucket_name):
    """Check to see if an object exists on S3"""
    s3 = boto3.resource('s3')
    try:
        s3.ObjectSummary(bucket_name=bucket_name, key=path).load()
    except ClientError as e:
        if e.response['Error']['Code'] == "404":
            return False
        else:
            raise e
    return True

path_exists('path/to/file.html')

ObjectSummary.load

ऑब्जेक्ट Summary संसाधन की विशेषताओं को अद्यतन करने के लिए s3.Client.head_object को कॉल करता है।

इससे पता चलता है कि आप Object बजाय ObjectSummary उपयोग कर सकते हैं यदि आप get() का उपयोग नहीं करने पर योजना बना रहे हैं। load() फ़ंक्शन ऑब्जेक्ट को पुनर्प्राप्त नहीं करता है जो केवल सारांश प्राप्त करता है।


आप S3Fs उपयोग कर सकते हैं, जो अनिवार्य रूप से boto3 के आसपास एक आवरण है जो विशिष्ट फाइल-सिस्टम शैली संचालन को उजागर करता है:

import s3fs
s3 = s3fs.S3FileSystem()
s3.exists('myfile.txt')

आप इसके लिए Boto3 का उपयोग कर सकते हैं।

 import boto3 s3 = boto3.resource('s3') bucket = s3.Bucket('my-bucket') objs = list(bucket.objects.filter(Prefix=key)) if(len(objs)>0): print("key exists!!") else: print("key doesn't exist!") 

यहां कुंजी वह पथ है जिसे आप जांचना चाहते हैं कि मौजूद है या नहीं


एक सरल तरीका है जिसके द्वारा हम जांच सकते हैं कि फ़ाइल मौजूद है या नहीं S3 बाल्टी में। हमें इसके लिए अपवाद का उपयोग करने की आवश्यकता नहीं है

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

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

न केवल client बल्कि bucket भी:

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')

मैं नियंत्रण प्रवाह के अपवादों का उपयोग करने का एक बड़ा प्रशंसक नहीं हूं। यह एक वैकल्पिक दृष्टिकोण है जो बोटो 3 में काम करता है:

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")

यदि आप एक ऐसी कुंजी की तलाश करते हैं जो एक निर्देशिका के बराबर है तो आप इस दृष्टिकोण को चाह सकते हैं

session = boto3.session.Session()
resource = session.resource("s3")
bucket = resource.Bucket('mybucket')

key = 'dir-like-or-file-like-key'
objects = [o for o in bucket.objects.filter(Prefix=key).limit(1)]    
has_key = len(objects) > 0

यह एक पैरेंट कुंजी या एक कुंजी के लिए काम करता है जो फाइल या एक ऐसी कुंजी के बराबर है जो मौजूद नहीं है। मैंने ऊपर दिए गए पसंदीदा दृष्टिकोण की कोशिश की और माता-पिता की चाबियों पर विफल रहा।


यदि आपके पास एक निर्देशिका या बाल्टी में 1000 से कम है, तो आप उनमें से सेट कर सकते हैं और चेक कर सकते हैं कि क्या इस सेट में ऐसी कुंजी है:

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

अगर my/dir मौजूद नहीं है तो भी ऐसा कोड काम करता है।

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


सबसे आसान तरीका मुझे मिला (और शायद सबसे कुशल) यह है:

import boto3
from botocore.errorfactory import ClientError

s3 = boto3.client('s3')
try:
    s3.head_object(Bucket='bucket_name', Key='file_path')
except ClientError:
    # Not found
    pass

import boto3
client = boto3.client('s3')
s3_key = 'Your file without bucket name e.g. 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)




boto3