0

I am working with ExactTarget FUEL SDK to retrieve data from the SalesForce Marketing Cloud. More specifically I working on calling "Unsub Events"(https://github.com/salesforce-marketingcloud/FuelSDK-Python/blob/master/objsamples/sample_unsubevent.py#L15) but the structure of the SOAP response has couple of deeper nested dictionary objects, which I need to iterate over and place into dataframes. Here is what the response looks like and I need to place each of the variables into seperate dataframe.

(UnsubEvent){
   Client = 
      (ClientID){
         ID = 11111111
      }
   PartnerKey = None
   CreatedDate = 2016-07-13 13:37:46.000663
   ModifiedDate = 2016-07-13 13:37:46.000663
   ID = 11111111
   ObjectID = "11111111"
   SendID = 11111111
   SubscriberKey = "[email protected]"
   EventDate = 2016-07-13 13:37:46.000663
   EventType = "Unsubscribe"
   TriggeredSendDefinitionObjectID = None
   BatchID = 1
   List = 
      (List){
         PartnerKey = None
         ID = 11111111
         ObjectID = None
         Type = "aaaa"
         ListClassification = "aaa"
      }
   IsMasterUnsubscribed = False
 }]

I have successfully placed all variables in data frames except one "ListClassification". I am getting the error "List instance has no attribute 'ListClassification', my question is why is this happening if I can see the attribute in the response? and is there a fix for the issue?

My Code:

    import ET_Client
    import pandas as pd



    try:
        debug = False
        stubObj = ET_Client.ET_Client(False, debug)

        print '>>>UnsubEvents'
        getUnsubEvent = ET_Client.ET_UnsubEvent()
        getUnsubEvent.auth_stub = stubObj
        getResponse3 = getUnsubEvent.get()
        ResponseResultsUnsubEvent = getResponse3.results
        #print ResponseResultsUnsubEvent

        ClientIDUnsubEvents = []
        partner_keys3 = []
        created_dates3 = []
        modified_date3 = []
        ID3 = []
        ObjectID3 = []
        SendID3 = []
        SubscriberKey3 = []
        EventDate3 = []
        EventType3 = []
        TriggeredSendDefinitionObjectID3 = []
        BatchID3 = []
        IsMasterUnsubscribed = []
        ListPartnerKey = [] 
        ListID = []
        ListObjectID = []
        ListType = []
        ListClassification = []


        for UnsubEvent in ResponseResultsUnsubEvent:
            ClientIDUnsubEvents.append(str(UnsubEvent['Client']['ID']))
            partner_keys3.append(UnsubEvent['PartnerKey'])
            created_dates3.append(UnsubEvent['CreatedDate'])
            modified_date3.append(UnsubEvent['ModifiedDate'])
            ID3.append(UnsubEvent['ID'])
            ObjectID3.append(UnsubEvent['ObjectID'])
            SendID3.append(UnsubEvent['SendID'])
            SubscriberKey3.append(UnsubEvent['SubscriberKey'])
            EventDate3.append(UnsubEvent['EventDate'])
            EventType3.append(UnsubEvent['EventType'])
            if hasattr(UnsubEvent['List'], 'ListClassification'):
                         ListClassification.append(str(UnsubEvent['List'['ListClassification']))
            TriggeredSendDefinitionObjectID3.append(UnsubEvent['TriggeredSendDefinitionObjectID'])
            BatchID3.append(UnsubEvent['BatchID'])
            IsMasterUnsubscribed.append(UnsubEvent['IsMasterUnsubscribed'])

            ListPartnerKey.append(str(UnsubEvent['List']['PartnerKey']))
            ListID.append(str(UnsubEvent['List']['ID']))
            ListObjectID.append(str(UnsubEvent['List']['ObjectID']))
            ListType.append(str(UnsubEvent['List']['Type']))
            ListClassification.append(str(UnsubEvent['List']['ListClassification']))

        df3 = pd.DataFrame({'ListPartnerKey':ListPartnerKey,'ListID':ListID,'ListObjectID':ListObjectID,'ListType':ListType,
                            'ClientID':ClientIDUnsubEvents,'PartnerKey':partner_keys3,'CreatedDate':created_dates3,
                            'ModifiedDate':modified_date3,'ID':ID3,'ObjectID':ObjectID3,'SendID':SendID3,'SubscriberKey':SubscriberKey3,
                            'EventDate':EventDate3,'EventType':EventType3,'TriggeredSendDefinitionObjectID':TriggeredSendDefinitionObjectID3,
                            'BatchID':BatchID3,'ListClassification':ListClassification,'IsMasterUnsubscribed':IsMasterUnsubscribed})

        print df3

Literally all other attributes are going into the dataframe but not sure why "ListClassification" is not being picked up on.

Thank you in advance for you help!

2
  • 1
    What is the value being returned for ListClassification? Is it somehow outside of the values expected by the enumeration (ExactTargetList, PublicationList, and PublicationList)?
    – Mac
    Commented Jul 15, 2016 at 19:21
  • The value is "PublicationList" but I think I may have found something else. The "ListClassification" seems to be optional when i print the "UnsubEvent" in the "for" loop. So i am thinking I need to write a logic statement where "if "ListClassification" present then populate dataframe "ListClassification" column" But I am not sure how to write this while iterating over the SOAP responses. Would you know how to do this? Commented Jul 15, 2016 at 20:15

1 Answer 1

1

Since it is an optional property, you should be able to use hasattr to check for it before attempting to read it

if hasattr(UnsubEvent['List'], 'ListClassification'):
    ListClassification.append(str(UnsubEvent['List']['ListClassification']))
else:
    ListClassification.append('')
4
  • Thank you for the response, I tried the above line but I am getting error " arrays must all be same length". Not sure why. Would you know why? Code edited above with your line and added needed variables. Please let me know if I placed it correctly. Commented Jul 18, 2016 at 12:27
  • I think the error "arrays must all be same length" is being caused by the boolean function you told me above. I see in the dataframe that the number of columns is 17, but it should be 18, since the "ListClassification" column is optional I believe the dataframe is getting confused on how to handle this. Just my 2cents. Commented Jul 18, 2016 at 13:19
  • Sorry for the third comment but, I am separately testing out iterating over individual attributes. Your above code for the "ListClassification" is working well but as i test out the other attributes along side your line of code, I am getting the error "arrays must all be same length" so not sure how your line is affecting the size of the other arrays. But it is working just for one attribute. Tried adding the "IF" statement for the other attributes still getting same error. Commented Jul 18, 2016 at 14:25
  • 1
    Sounds like you will need to specify a blank string if no ListClassification is available so that it doesn't mess with your dataframe. I have updated the code example above with what I think might work.
    – Mac
    Commented Jul 18, 2016 at 16:08

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .