python - Boto3, पायथन और त्रुटियों को कैसे संभालें




amazon-web-services (5)

मैंने अभी अपनी स्क्रिप्टिंग भाषा के रूप में पायथन उठाया है और मैं यह समझने की कोशिश कर रहा हूं कि boto3 के साथ उचित त्रुटि कैसे करें।

मैं एक आईएएम उपयोगकर्ता बनाने की कोशिश कर रहा हूं:

def create_user(username, iam_conn):
    try:
        user = iam_conn.create_user(UserName=username)
        return user
    except Exception as e:
        return e

जब create_user को कॉल सफल होता है, तो मुझे एक साफ ऑब्जेक्ट मिलता है जिसमें API कॉल का http स्थिति कोड और नव निर्मित उपयोगकर्ता का डेटा होता है।

उदाहरण:

{'ResponseMetadata': 
      {'HTTPStatusCode': 200, 
       'RequestId': 'omitted'
      },
 u'User': {u'Arn': 'arn:aws:iam::omitted:user/omitted',
           u'CreateDate': datetime.datetime(2015, 10, 11, 17, 13, 5, 882000, tzinfo=tzutc()),
           u'Path': '/',
           u'UserId': 'omitted',
           u'UserName': 'omitted'
          }
}

यह बहुत अच्छा काम करता है। लेकिन जब यह विफल हो जाता है (जैसे कि उपयोगकर्ता पहले से मौजूद है), तो मुझे बस botocore.exceptions.bientError का एक ऑब्जेक्ट मिलता है जो मुझे बताता है कि क्या गलत हुआ।

उदाहरण: क्लाइंट एरर ('एक त्रुटि हुई (EntityAlreadyExists) CreateUser ऑपरेशन को कॉल करते समय: छोड़ा गया नाम वाला उपयोगकर्ता पहले से मौजूद है।',)

यह (AFAIK) त्रुटि को बहुत कठिन बनाता है क्योंकि मैं केवल परिणामी http स्थिति कोड पर स्विच नहीं कर सकता (उपयोगकर्ता के लिए 40 9 आईएएम के लिए एडब्ल्यूएस एपीआई दस्तावेज़ों के अनुसार पहले से मौजूद है)। इससे मुझे लगता है कि मुझे कुछ गलत तरीके से करना होगा। इष्टतम तरीका boto3 के लिए कभी अपवाद नहीं फेंकने के लिए होगा, लेकिन juts हमेशा एक ऑब्जेक्ट लौटाता है जो दर्शाता है कि एपीआई कॉल कैसे चला गया।

क्या कोई मुझे इस मुद्दे पर उजागर कर सकता है या मुझे सही दिशा में इंगित कर सकता है?

आपका बहुत बहुत धन्यवाद!


Answers

या वर्ग नाम जैसे तुलना

except ClientError as e:
    if 'EntityAlreadyExistsException' == e.__class__.__name__:
        # handle specific error

क्योंकि वे गतिशील रूप से बनाए गए हैं, आप कक्षा को कभी भी आयात नहीं कर सकते हैं और वास्तविक पायथन का उपयोग करके इसे पकड़ सकते हैं।


@jarmod द्वारा इंगित किए गए 'संसाधनों पर कोई अपवाद नहीं' के लिए बस एक अपडेट (कृपया नीचे दिए गए अगर आपका उत्तर अपडेट करने के लिए स्वतंत्र महसूस करें)

मैंने नीचे दिए गए कोड का परीक्षण किया है और यह ठीक चलता है। यह चीजों को करने के लिए 'संसाधन' का उपयोग करता है, लेकिन client.exceptions पकड़ता है। अपवाद - हालांकि यह कुछ हद तक गलत लगता है ... यह अच्छा परीक्षण करता है, अपवाद समय अपवाद समय पर डीबगर का उपयोग करते समय दिखाए जा रहे हैं ...

यह सभी संसाधनों और ग्राहकों पर लागू नहीं हो सकता है, लेकिन डेटा फ़ोल्डर्स (उर्फ एस 3 बाल्टी) के लिए काम करता है।

lab_session = boto3.Session() 
c = lab_session.client('s3') #this client is only for exception catching

try:
    b = s3.Bucket(bucket)
    b.delete()
except c.exceptions.NoSuchBucket as e:
    #ignoring no such bucket exceptions
    logger.debug("Failed deleting bucket. Continuing. {}".format(e))
except Exception as e:
    #logging all the others as warning
    logger.warning("Failed deleting bucket. Continuing. {}".format(e))

उम्मीद है की यह मदद करेगा...


अपवाद के भीतर निहित प्रतिक्रिया का प्रयोग करें। यहाँ एक उदाहरण है:

import boto3
from botocore.exceptions import ClientError

try:
    iam = boto3.client('iam')
    user = iam.create_user(UserName='fred')
    print "Created user: %s" % user
except ClientError as e:
    if e.response['Error']['Code'] == 'EntityAlreadyExists':
        print "User already exists"
    else:
        print "Unexpected error: %s" % e

अपवाद में प्रतिक्रिया निर्देश में निम्न शामिल होंगे:

  • ['Error']['Code'] जैसे 'EntityAlreadyExists' या 'प्रमाणीकरण ['Error']['Code'] '
  • ['ResponseMetadata']['HTTPStatusCode'] उदाहरण के लिए 400
  • ['ResponseMetadata']['RequestId'] जैसे 'd2b06652-88d7-11e5-99d0-812348583a35'
  • ['Error']['Message'] उदाहरण के लिए "एक त्रुटि हुई (EntityAlreadyExists) ..."
  • ['Error']['Type'] जैसे 'प्रेषक'

अधिक जानकारी के लिए botocore.readthedocs.io/en/latest/… देखें।

[अपडेटेडः 2018-03-07]

एडब्ल्यूएस पायथन एसडीके ने clients पर सेवा अपवादों का खुलासा करना शुरू कर दिया clients (हालांकि resources पर नहीं) जिन्हें आप स्पष्ट रूप से पकड़ सकते हैं, इसलिए अब इस कोड को कुछ लिखना संभव है:

import boto3
from botocore.exceptions import ClientError, ParamValidationError

try:
    iam = boto3.client('iam')
    user = iam.create_user(UserName='fred')
    print "Created user: %s" % user
except iam.exceptions.EntityAlreadyExistsException:
    print "User already exists"
except ParamValidationError as e:
    print "Parameter validation error: %s" % e
except ClientError as e:
    print "Unexpected error: %s" % e

दुर्भाग्यवश, वर्तमान में इन अपवादों के लिए कोई दस्तावेज़ीकरण नहीं है।


जब आप इस मुद्दे को संभालने में विफल रहते हैं तो आपको कुछ करने की आवश्यकता होती है। अभी आप वास्तविक अपवाद लौट रहे हैं। उदाहरण के लिए, यदि यह कोई समस्या नहीं है कि उपयोगकर्ता पहले से मौजूद है और आप इसे get_or_create फ़ंक्शन के रूप में उपयोग करना चाहते हैं, तो हो सकता है कि आप मौजूदा उपयोगकर्ता ऑब्जेक्ट को वापस कर समस्या को संभाल लें।

try:
    user = iam_conn.create_user(UserName=username)
    return user
except botocore.exceptions.ClientError as e:

    #this exception could actually be other things other than exists, so you want to evaluate it further in your real code.
    if e.message.startswith(
        'enough of the exception message to identify it as the one you want')

        print('that user already exists.')
        user = iam_conn.get_user(UserName=username)
        return user

    elif e.message.some_other_condition:

         #something else
    else:
         #unhandled ClientError
         raise(e)
except SomeOtherExceptionTypeYouCareAbout as e:
    #handle it

# any unhandled exception will raise here at this point.
# if you want a general handler

except Exception as e:
    #handle it.

ऐसा कहा जाता है, हो सकता है कि यह आपके ऐप के लिए एक समस्या है, इस मामले में आप उस कोड के आस-पास अपवाद हैंडलर रखना चाहते हैं जिसे आपके उपयोगकर्ता उपयोगकर्ता फ़ंक्शन कहा जाता है और कॉलिंग फ़ंक्शन को यह निर्धारित करने दें कि इसके साथ कैसे निपटें, उदाहरण के लिए, पूछकर उपयोगकर्ता को अन्य उपयोगकर्ता नाम इनपुट करने के लिए, या जो भी आपके आवेदन के लिए समझ में आता है।


import datetime
date_time = datetime.datetime.now()

date = date_time.date()  # Gives the date
time = date_time.time()  # Gives the time

print date.year, date.month, date.day
print time.hour, time.minute, time.second, time.microsecond

पैकेज सहित dir(date) या किसी भी चर। आप चर के साथ जुड़े सभी विशेषताओं और विधियों को प्राप्त कर सकते हैं।





python amazon-web-services boto boto3