Пример #1
0
    def get_distribution(self, survey, distribution):
        ''' This method gives users the ability to get a specific distribution corresponding with a given survey. Given that
        distributions are specific to individual surveys, we must pass the SurveyID as an arguement into the survey parameter for
        this method to work appropriately. This method will return a Pandas DataFrame consisting of multiple variables associated
        with the specified distirbution.

        :param survey: The Survey ID corresponding with the Survey that the distribution is to be sent to.
        :type survey: str
        :param distribution: A specific Distribution ID associated with the given survey.
        :type distribution: str
        :return: A Pandas DataFrame
        '''

        assert survey[:
                      3] == 'SV_', 'Hey there! It looks like your SurveyID is incorrect. You can find the SurveyID on the Qualtrics site under your account settings. It will begin with "SV_". Please try again.'
        assert len(
            survey
        ) == 18, 'Hey, the parameter for "survey" that was passed is the wrong length. It should have 18 characters.'
        assert len(
            distribution
        ) == 19, 'Hey, the parameter for "distribution" that was passed is the wrong length. It should have 19 characters.'
        assert distribution[:
                            4] == 'EMD_', 'Hey there! It looks like your distributionID is incorrect. You can find the distributionID by using the list_distributions method in this module. It will begin with "UMD_". Please try again.'

        headers, base_url = self.header_setup(xm=False, path='distributions')
        url = f'{base_url}/{distribution}?surveyId={survey}'
        request = r.get(url, headers=headers)
        try:
            response = request.json()
            keys = [
                'id', 'parentDistributionId', 'ownerId', 'organizationId',
                'requestStatus', 'requestType', 'sendDate', 'createdDate',
                'modifiedDate', 'headers', 'fromEmail', 'replyToEmail',
                'fromName', 'subject', 'recipients', 'mailingListId',
                'contactId', 'sampleId', 'message', 'messageId', 'messageText',
                'surveyLink', 'surveyId', 'expirationDate', 'linkType',
                'stats', 'sent', 'failed', 'started', 'bounced', 'opened',
                'skipped', 'finished', 'complaints', 'blocked'
            ]
            dists = Parser().json_parser(response=response,
                                         keys=keys,
                                         arr=False)
            dist_df = pd.DataFrame(dists)
            dist_df.index = keys
            library_ids = Parser().json_parser(response=response,
                                               keys=['libraryId'],
                                               arr=False)
            lib = pd.DataFrame(
                library_ids[0],
                index=['mailing_list_library_id', 'message_library_id'])
            dist_df = dist_df.append(lib)
            return dist_df
        except:
            print(
                f"\nServerError: QualtricsAPI Error Code: {response['meta']['error']['errorCode']}\nQualtricsAPI Error Message: {response['meta']['error']['errorMessage']}"
            )
Пример #2
0
    def get_contact_additional_info(self, contact_id=None, content=None):
        ''' This method will return the additional "nested" information associated with a contact in the XMDirectory.
        To get these different nested pieces of infomation you can pass one of three arguements to the 'content' parameter. If you
        pass 'mailinglistmembership', you will return the different Mailing Lists that the contact is associated with in the form of a
        pandas DataFrame. If you pass 'stats', you will return the response statistics associated with the contact, again in the form
        of a Pandas DataFrame. Finally, if you pass the 'embeddedData' argument, you will return any emmbedded data associated with
        the given contact, and as you guessed it, in the form of a Pandas DataFrame.

        :param contact_id: The unique id associated with each contact in the XM Directory.
        :type contact_id: str
        :param content: A string representing either 'mailingListMembership', 'stats', 'embeddedData'
        :type content: str
        :return: A Pandas DataFrame
        '''
        assert contact_id != None, 'Hey, the contact_id parameter cannot be None. You need to pass in a XM Directory Contact ID as a string into the contact_id parameter.'
        assert isinstance(contact_id, str) == True, 'Hey there, the contact_id parameter must be of type string.'
        assert len(contact_id) == 19, 'Hey, the parameter for "contact_id" that was passed is the wrong length. It should have 19 characters.'
        assert contact_id[:4] == 'CID_', 'Hey there! It looks like the Contact ID that was entered is incorrect. It should begin with "CID_". Please try again.'
        assert content != None, 'Hey there, you need to pass an argument ("embeddedData", or "mailingListMembership") to the "content" parameter.'

        try:
            primary = self.get_contact(contact_id=contact_id)
            keys = Parser().extract_keys(primary[content][0])
            data = pd.DataFrame.from_dict(primary[content][0], orient='index').transpose()
            return data
        except:
            print('Hey there! Something went wrong please try again.')
Пример #3
0
 def extract_page(url=url, master=master, page_size=page_size):
     ''' This is a method that extracts a single page of contacts in a mailing list.'''
     try:
         request = r.get(url, headers=headers)
         response = request.json()
         if response['meta']['httpStatus'] == '500 - Internal Server Error':
             raise Qualtrics500Error('500 - Internal Server Error')
         elif response['meta']['httpStatus'] == '503 - Temporary Internal Server Error':
             raise Qualtrics503Error('503 - Temporary Internal Server Error')
         elif response['meta']['httpStatus'] == '504 - Gateway Timeout':
             raise Qualtrics504Error('504 - Gateway Timeout')
     except (Qualtrics500Error, Qualtrics503Error):
         t.sleep(0.25)
         extract_page(url=url, master=master)
     except Qualtrics504Error:
         t.sleep(5)
         extract_page(url=url, master=master)
     except:
         t.sleep(10)
         extract_page(url=url, master=master)
     else:
         keys = ['contactId','firstName', 'lastName', 'email', 'phone','unsubscribed', 'language', 'extRef']
         contact_lists = Parser().json_parser(response=response, keys=keys, arr=False)
         next_page = response['result']['nextPage']
         single_contact_list = pd.DataFrame(contact_lists).transpose()
         single_contact_list.columns = keys
         master = pd.concat([master, single_contact_list]).reset_index(drop=True)
         return master, next_page
Пример #4
0
 def extract_distributions(url=url, master=master):
     request = r.get(url, headers=headers)
     response = request.json()
     if response['meta']['httpStatus'] == '200 - OK':
         keys = columns[:-2]
         dists = Parser().json_parser(response=response, keys=keys, arr=False)
         dist_df = pd.DataFrame(dists).transpose()
         dist_df.columns = keys
         library_ids = Parser().json_parser(response=response, keys=['libraryId'], arr=False)
         dist_df['mailing_list_library_id'] = library_ids[0][:len(dist_df)]
         dist_df['message_library_id'] = library_ids[0][len(dist_df):]
         master = pd.concat([master, dist_df], sort=False).reset_index(drop=True)
         next_page = response['result']['nextPage']
         return master, next_page
     else:
         print(response['meta'])
         master, next_page = extract_distributions(url=url, master=master)
Пример #5
0
 def get_page(mailing_list=mailing_list, contact_list=contact_list, url=url):
   request = r.get(url, headers=headers)
   response = request.json()
   keys = ['contactId','firstName','lastName','email','phone','extRef','language','unsubscribed']
   contact_lists = Parser().json_parser(response=response, keys=keys, arr=False)
   single_page = pd.DataFrame(contact_lists).transpose()
   single_page.columns = keys
   single_page['mailing_list'] = mailing_list
   contact_list = pd.concat([contact_list, single_page]).reset_index(drop=True)
   next_page = str(response['result']['nextPage'])
   return contact_list, next_page, response
Пример #6
0
 def extract_page(surveys=surveys, url=url):
     ''' This method is a nested method that extracts a single page of surveys. '''
     try:
         request = r.get(url, headers=headers)
         response = request.json()
         if response['meta'][
                 'httpStatus'] == '500 - Internal Server Error':
             raise Qualtrics500Error('500 - Internal Server Error')
         elif response['meta'][
                 'httpStatus'] == '503 - Temporary Internal Server Error':
             raise Qualtrics503Error(
                 '503 - Temporary Internal Server Error')
         elif response['meta']['httpStatus'] == '504 - Gateway Timeout':
             raise Qualtrics504Error('504 - Gateway Timeout')
         elif response['meta']['httpStatus'] == '400 - Bad Request':
             raise Qualtrics400Error(
                 'Qualtrics Error\n(Http Error: 400 - Bad Request): There was something invalid about the request.'
             )
         elif response['meta']['httpStatus'] == '401 - Unauthorized':
             raise Qualtrics401Error(
                 'Qualtrics Error\n(Http Error: 401 - Unauthorized): The Qualtrics API user could not be authenticated or does not have authorization to access the requested resource.'
             )
         elif response['meta']['httpStatus'] == '403 - Forbidden':
             raise Qualtrics403Error(
                 'Qualtrics Error\n(Http Error: 403 - Forbidden): The Qualtrics API user was authenticated and made a valid request, but is not authorized to access this requested resource.'
             )
     except (Qualtrics500Error, Qualtrics503Error):
         t.sleep(0.25)
         extract_page(surveys=surveys, url=url)
     except Qualtrics504Error:
         t.sleep(5)
         extract_page(surveys=surveys, url=url)
     except (Qualtrics400Error, Qualtrics401Error,
             Qualtrics403Error) as e:
         print(e)
     except:
         t.sleep(10)
         extract_page(surveys=surveys, url=url)
     else:
         keys = [
             'id', 'name', 'ownerId', 'lastModified', 'creationDate',
             'isActive'
         ]
         lists = Parser().json_parser(response=response,
                                      keys=keys,
                                      arr=False)
         single_page = pd.DataFrame(lists).transpose()
         single_page.columns = keys
         surveys = pd.concat([surveys,
                              single_page]).reset_index(drop=True)
         next_page = response['result']['nextPage']
         return surveys, next_page
Пример #7
0
 def get_page(mailing_lists=mailing_lists, url=url):
   ''' This method is a nested method that extracts a single page of mailing lists. '''
   request = r.get(url, headers=headers)
   response = request.json()
   keys = ['mailingListId', 'name', 'ownerId', 'lastModifiedDate', 'creationDate','contactCount', 'nextPage']
   lists = Parser().json_parser(response=response, keys=keys, arr=False)
   single_page = pd.DataFrame(lists).transpose()
   single_page.columns = keys
   single_page['creationDate'] = pd.to_datetime(single_page['creationDate'], unit='ms')
   single_page['lastModifiedDate'] = pd.to_datetime(single_page['lastModifiedDate'], unit='ms')
   mailing_lists = pd.concat([mailing_lists, single_page]).reset_index(drop=True)
   next_page = str(response['result']['nextPage'])
   return mailing_lists, next_page, response
Пример #8
0
    def create_list(self, name=None):
        '''This method will create a mailing list in the XM Directory for the your specified user's account.

        :param list_name: the name of the list to be created.
        :return: tuple containing the Mailing List's and the Mailing List's new id.
        '''
        assert name != None, 'Hey there! The name parameter cannot be None. You need to pass in a new Mailing List name as a string into the name parameter.'
        assert isinstance(name, str) == True, 'Hey there! The name parameter must be of type string.'

        headers, base_url = self.header_setup(content_type=True, xm=True)
        url = f"{base_url}/mailinglists"
        data = {"name": "{0}".format(name)}
        request = r.post(url, json=data, headers=headers)
        response = request.json()
        try:
            list_id = Parser().json_parser(response=response, keys=['id'], arr=False)[0][0]
            return name, list_id
        except:
            print(f"ServerError: {response['meta']['httpStatus']}\nError Code: {response['meta']['error']['errorCode']}\nError Message: {response['meta']['error']['errorMessage']}")
Пример #9
0
    def list_messages(self, library=None):
        '''This method gets the all of the messages available to a user in a given library. Messages are defined based on
        the library (User-Deifined or Global) that they exist within. Thus, in order to list the messages availble to your
        user account, you need to specify the library that the api must look within. There can exist several different
        categories of messages. These include, 'invite', 'inactiveSurvey', 'reminder', 'thankYou', 'smsInvite', 'validation',
        'emailSubject', 'general', 'lookAndFeel', and 'endOfSurvey'. This method returns all the types of these, if they exist.

        :param library: The (Global or User) Library ID which the messages are located within.
        :type library: str
        :return: A Pandas DataFrame
        '''

        assert len(
            library
        ) == 18, 'Hey, the parameter for the Libary ID that was passed is the wrong length. It should have 18 characters.'
        assert library[:3] == 'UR_' or library[:3] == 'GR_', 'Hey there! It looks like your Library ID is incorrect. You can find the Library ID on the Qualtrics site under your account settings. It will begin with "UR_" or "GR_". Please try again.'

        # Need Recursion to handle nextPage Errors
        headers, base_url = self.header_setup(xm=False, path='libraries')
        url = base_url + f"/{library}/messages/"
        request = r.get(url, headers=headers)
        response = request.json()
        try:
            keys = ['id', 'description', 'category']
            messages = Parser().json_parser(response=response['result'],
                                            keys=keys,
                                            arr=False)
            msg_df = pd.DataFrame(messages).transpose()
            msg_df.columns = [
                'MessageID', 'MessageDescription', 'MessageCategory'
            ]
            msg_df['LibraryID'] = library
        except:
            print(
                f"\nServerError: QualtricsAPI Error Code: {response['meta']['error']['errorCode']}\nQualtricsAPI Error Message: {response['meta']['error']['errorMessage']}"
            )
        return msg_df