コード例 #1
0
    def test_invalid_api_keys(self):
        fc = FullContact('')
        r = fc.api_get('person', **{'email': '*****@*****.**'})
        assert_equal(r.status_code, 403)

        test_batch = [
            ('person', {'email': '*****@*****.**'}),
            ('person', {'name': 'Bob Smith'})
        ]

        r = fc.api_batch(test_batch)
        assert_equal(r.status_code, 403)
コード例 #2
0
    def test_invalid_api_keys(self):
        fc = FullContact('')
        r = fc.api_get('person', **{'email': '*****@*****.**'})
        assert_equal(r.status_code, 403)

        test_batch = [('person', {
            'email': '*****@*****.**'
        }), ('person', {
            'name': 'Bob Smith'
        })]

        r = fc.api_batch(test_batch)
        assert_equal(r.status_code, 403)
コード例 #3
0
class FullContactEngager(Engager):

    #AYDRATE_KEY = "13edcff433f0c479"  # Aydrate
    #ACURATE_TRIAL_KEY = "2e7c73db16e677f8"  # AcureRate - Trial
    ACURATE_PRODUCTION_KEY = "401739667f580b02"  # AcureRate - Production

    THE_KEY = ACURATE_PRODUCTION_KEY  # Correct Key

    def __init__(self):
        super().__init__()
        self.fc = FullContact(self.THE_KEY)

    def __str__(self):
        return 'FullContact Engager'

    def __repr__(self):
        return 'FullContact Engager'

    def get_provider_name(self):
        return 'FullContact'

    def get_short_symbol(self):
        return 'fc'

    def get_api_key(self):
        return FullContactEngager.THE_KEY

    def set_enrich_key(self):
        t = self.enriched_entity.__class__.__name__
        if t == 'AcureRatePerson':
            email = self.get_pivot_email()
            if email is None:
                raise EngagementException(
                    "FullContacts - cannot engage. No email available as enrich key"
                )
            self.enrich_key = email
        elif t == 'AcureRateCompany':
            if C.DOMAIN not in self.enriched_entity.deduced:
                raise EngagementException(
                    "FullContacts - cannot engage - no domain property to use as key"
                )
            self.enrich_key = self.enriched_entity.deduced.get(C.DOMAIN)
        else:
            raise EngagementException(
                "FullContacts - cannot engage - cannot generate enrich key. Unknown entity type"
            )

    def enrich_person(self):

        result_obj = self._get_person_info()

        self.set_data("score", result_obj['likelihood'])

        contact_info = result_obj.get('contactInfo', None)
        if contact_info:
            if 'givenName' in contact_info:
                self.set_data(P.FIRST_NAME, contact_info['givenName'])
            if 'familyName' in contact_info:
                self.set_data(P.LAST_NAME, contact_info['familyName'])

        demographics = result_obj.get('demographics', None)
        if demographics:
            gender = demographics.get('gender', None)
            if gender:
                self.add_data(P.GENDER, gender.lower())
            loc = demographics.get('locationGeneral', None)
            if loc:
                self.add_data(P.LOCATIONS, loc)

        photos = result_obj.get('photos', None)
        if photos:
            for photo in photos:
                new_photo = {}
                m = {"url": P.PHOTO_URL, "typeName": P.PHOTO_SOURCE}
                AcureRateUtils.dict2dict(photo, new_photo, m)
                self.add_data(P.PHOTOS, new_photo)

        organizations = result_obj.get('organizations', None)
        if organizations:
            for org in organizations:
                new_job = {}
                m = {
                    "name": P.JOB_NAME,
                    "title": P.JOB_TITLE,
                    "current": P.JOB_CURRENT,
                    "isPrimary": P.JOB_PRIMARY
                }
                AcureRateUtils.dict2dict(org, new_job, m)
                # If there are start/end dates, grab them (year only - drop the month)
                if 'startDate' in org:
                    new_job[P.JOB_STARTED] = org['startDate'][0:4]
                if 'endDate' in org:
                    new_job[P.JOB_ENDED] = org['endDate'][0:4]
                self.add_data(P.JOBS, new_job)

        social_profiles = result_obj.get('socialProfiles', None)
        if social_profiles:
            for social_profile in social_profiles:
                if social_profile.get('typeName', '') == 'Twitter':
                    self.set_data(P.TWITTER_URL, social_profile['url'])
                elif social_profile.get('typeName', '') == 'LinkedIn':
                    self.set_data(P.LINKEDIN_URL, social_profile['url'])
                elif social_profile.get('typeName', '') == 'GooglePlus':
                    self.set_data(P.GOOGLEPLUS_URL, social_profile['url'])
                elif social_profile.get('typeName', '') == 'Facebook':
                    self.set_data(P.FACEBOOK_URL, social_profile['url'])
                elif social_profile.get('typeName', '') == 'Gravatar':
                    self.set_data(P.GRAVATAR_URL, social_profile['url'])
                elif social_profile.get('typeName', '') == 'Foursquare':
                    self.set_data(P.FOURSQUARE_URL, social_profile['url'])
                elif social_profile.get('typeName', '') == 'Pinterest':
                    self.set_data(P.PINTEREST_URL, social_profile['url'])
                elif social_profile.get('typeName', '') == 'Klout':
                    self.set_data(P.KLOUT_URL, social_profile['url'])
                elif social_profile.get('typeName', '') == 'AngelList':
                    self.set_data(P.ANGELLIST_URL, social_profile['url'])
                else:
                    print('Something else...')

        # TODO: add all other attributes received from FullContact

        return [P.JOBS]

    def enrich_company(self):

        domain = self.enriched_entity.deduced.get(C.DOMAIN, None)
        if domain is None:
            return []

        result_obj = self._get_company_info(domain)

        # Keep the logo url and website
        if 'logo' in result_obj:
            self.add_data(C.LOGOS, {
                C.LOGO_URL: result_obj['logo'],
                C.LOGO_SOURCE: 'fullcontact'
            })

        if 'website' in result_obj:
            self.set_data(C.WEBSITE, result_obj['website'])

        # Keep the founding year
        if 'founded' in result_obj['organization']:
            self.set_data(C.FOUNDING_YEAR,
                          result_obj['organization']['founded'])

        # Approximate Employees
        if 'approxEmployees' in result_obj['organization']:
            self.set_data(C.EMPLOYEES_NUMBER,
                          result_obj['organization']['approxEmployees'])

        # Keep keywords
        if 'keywords' in result_obj['organization']:
            self.set_data(C.KEYWORDS, result_obj['organization']['keywords'])

        # Keep name
        if 'name' in result_obj['organization']:
            self.set_data(C.NAME, result_obj['organization']['name'])

        # Keep social profiles URL
        # TODO: keep other social profiles...
        for profile in result_obj.get('socialProfiles', []):
            if profile['typeId'] == 'crunchbasecompany':
                self.set_data(C.CRUNCHBASE_URL, profile['url'])

        return [C.NAME]

    def _handle_fc_api_errors(self, response):
        if response.status_code == 200:  # All is ok.
            return
        # Handle different errors. Documentation - https://www.fullcontact.com/developer/docs/
        if response.status_code == 403:  # Quota exceeded - need special treatment
            raise EngagementException("403. Quota Exceeded.", True)
        elif response.status_code == 405 or response.status_code == 410 or response.status_code == 422:
            raise EngagementException(
                "%s. Invalid request sent to FC %s" %
                (response.status_code, response.text), True)
        elif response.status_code == 404:
            raise EngagementException(
                "404. Searched in the past 24 hours and nothing was found: %s"
                % response.text)
        elif response.status_code == 500 or response.status_code == 503:
            raise EngagementException(
                "%s. Transient errors in FC server. Possible maintenance/downtime. %s"
                % (response.status_code, response.text), True)
        elif response.status_code == 202:  # being processed...
            raise EngagementException(
                "202. Did not get info. Request is being processed. Return later."
            )
        else:
            raise EngagementException(
                "%s. Unknown error: %s" %
                (response.status_code, response.text), True)

    def _get_person_info(self):

        try:
            response = self.fc.api_get('person', **{'email': self.enrich_key})
            if hasattr(response, 'from_cache'):
                self.set_data("from_cache", response.from_cache)
            self._handle_fc_api_errors(response)
            # TODO: check if we can inspect the header and see our limit remaining...
            #r.headers['x-rate-limit-remaining']
        except EngagementException as e:
            raise e
        except Exception as e:
            raise EngagementException(e, True)

        json = response.json()
        return json

    def _get_company_info(self, domain):
        try:
            response = self.fc.api_get('company', **{'domain': domain})
            if hasattr(response, 'from_cache'):
                self.set_data("from_cache", response.from_cache)
            self._handle_fc_api_errors(response)
        except EngagementException as e:
            raise e
        except Exception as e:
            raise EngagementException(e, True)

        json = response.json()
        return json