def person_lookup(self, service): if service == 'fullcontact': fullcontact_key = '50bd8e5a1133dd29' #context = ssl._create_unverified_context() try: email = self.query_object.emails[0].address.encode("utf-8") except IndexError: return None try: url = "https://api.fullcontact.com/v2/person.json?email=" + email + "&apiKey=" + fullcontact_key #response = urllib2.urlopen(url, context=context) response = urllib2.urlopen(url) data_obj = response.read() json_obj = json.loads(data_obj) return json_obj except urllib2.HTTPError as err: if err.code == 404: return elif service == 'pipl': pipl_api_key ='wzcdrge37w2ktmrcnvy8gs8c' request = SearchAPIRequest(api_key=pipl_api_key, person=self.query_object) response = request.send() data = response.to_dict() return data else: return "Service not supported. Please Try Again"
def test_response_class_custom(self): custom_response_class = type('CustomResponseClass', (SearchAPIResponse, ), {}) request = SearchAPIRequest(email="*****@*****.**", response_class=custom_response_class) response = request.send() self.assertIsInstance(response, custom_response_class)
def selftest_function(opts): """ Placeholder for selftest function. An example use would be to test package api connectivity. Suggested return values are be unimplemented, success, or failure. """ options = opts.get("fn_pipl", {}) # Read configuration settings: if "pipl_api_key" in options: pipl_api_key = options["pipl_api_key"] else: log.error(u"Mandatory config setting 'pipl_api_key' not set.") raise ValueError("Mandatory config setting 'pipl_api_key' not set.") state, reason = "", "" try: request = SearchAPIRequest(email=u'*****@*****.**', first_name=u'Clark', last_name=u'Kent', api_key=pipl_api_key) response = request.send() if response and response.http_status_code == 200: state = "success" else: state = "failure" reason = response.error except Exception as ex: state = "failure" reason = str(ex) result = {"state": state, "reason": reason} log.info(result) return result
def query(query_username): request = SearchAPIRequest(api_key=u'COMMUNITY-s20idwagbdiijrrjsmzhq320', username=unicode(query_username)) try: response = request.send() print response.to_dict() except SearchAPIError as e: print e
def test_make_sure_insufficient_search_isnt_sent(self): request = SearchAPIRequest(first_name="brian") try: request.send() failed = False except Exception as e: failed = True self.assertTrue(failed)
def run_request(data): request = SearchAPIRequest(**data, api_key=PIPL_KEY) try: response = request.send() return response except SearchAPIError as e: print(e.http_status_code, e) return None
def getName(emailAddress): request = SearchAPIRequest(email=emailAddress) try: response = request.send() except SearchAPIError as e: print e.http_status_code, e return response.person.names[0]
def search_object(person): request = SearchAPIRequest(person=bind_pipl_object(read_the_files())) try: response = request.send() print(response.image.get_thumbnail_url(500, 500, zoom_face=True, favicon=False)) print response.name print response.address print response.job except SearchAPIError as e: print e.http_status_code, e
def search_object(name): user = name + '@twitter' try: request = SearchAPIRequest(username=user, country='US') response = request.send() if response.person != None and response.person.addresses != None: print response.person.names #print response.person.addresses output.write(str(response.person.names)+ "\t" + str(response.person.addresses)+ "\n") except SearchAPIError as e: print e.http_status_code, e
def __init__(self): super().__init__() # Set configuration settings for the Pipl search queries # TODO: infer_persons - what's the default? Should we turn off? # TODO: match_requirements -- ! SearchAPIRequest.set_default_settings(api_key=self.THE_KEY, minimum_probability=None, show_sources=None, minimum_match=None, hide_sponsored=None, live_feeds=None, use_https=False)
def test_make_sure_deserialization_works(self): response = SearchAPIRequest(email="*****@*****.**").send() self.assertEquals(response.person.names[0].display, "Clark Joseph Kent") self.assertEquals(response.person.emails[1].address_md5, "999e509752141a0ee42ff455529c10fc") self.assertEquals(response.person.usernames[0].content, "superman@facebook") self.assertEquals(response.person.addresses[1].display, "1000-355 Broadway, Metropolis, Kansas") self.assertEquals(response.person.jobs[0].display, "Field Reporter at The Daily Planet (2000-2012)") self.assertEquals(response.person.educations[0].degree, "B.Sc Advanced Science")
def call_pipl(profile=None, search_pointer=None): api_key = os.environ.get("PIPL_API_KEY") if not api_key: print("call_pipl(): Warning: Missing API Key.") params = {'api_key': api_key, 'hide_sponsored': True, 'use_https': True} if search_pointer: params["search_pointer"] = search_pointer elif profile: # TODO: Look into using advanced search: # https://docs.pipl.com/reference/#using-search-parameters # TODO: look this up from the profile params['country'] = 'US' email = ProfileEmail.to_reach(profile.id, strict=True) if email: params["email"] = email.value if profile.state_id: params["state"] = profile.state.state_code if profile.city: params["city"] = profile.city if profile.first_name: params["first_name"] = profile.first_name if profile.last_name: params["last_name"] = profile.last_name else: print("Abiguous Lookup: Not enough information to make a PIPL query.") raise AmbiguousLookupException() try: response = SearchAPIRequest(**params).send() except ValueError: # ValueError's get raised when there's not enough information in the query print("Sparse PIPL query.") raise AmbiguousLookupException() if response and response.http_status_code == 200: if response.persons_count > 1: print("Ambiguous Lookup: Too many results") raise AmbiguousLookupException() # NS 11.13.18 - disable because search pointer logic is FUBAR # search_pointer = get_valid_search_pointer_from_pipl_response(response, job=profile.job) # if search_pointer: # return call_pipl(search_pointer=search_pointer) return json.loads(response.raw_json.replace('\n', '')) else: print("Bad HTTP response.") raise LookupFailedException() return None
def search(row): fields = [Name(first=unicode(row['FIRST NAME'], "utf-8"), middle= unicode(row['MI'], "utf-8"), last=unicode(row['LAST NAME'], "utf-8")), Address(country=u'US', state=unicode(row['STATE'], "utf-8"), city=unicode(row['CITY'], "utf-8"), zip_code=unicode(row['ZIP5'], "utf-8"))] request = SearchAPIRequest(person=Person(fields)) try: response = request.send() print response.name #print response.address #print response.job if(response.email != None): email = response.email print email.username if(response.person != None): print response.sources[0].origin_url if(response.person.user_ids != None): print response.person.user_ids except SearchAPIError as e: print e.http_status_code, e
class SocialSearch(object): def __init__(self, name): self.request = SearchAPIRequest( raw_name=name, api_key='SOCIAL-PREMIUM-DEMO-vllok8b97jwjpygr3p6mnx1x') def search(self): try: return self.request.send() except SearchAPIError as e: print(e.http_status_code, e) return None
def check_pipl(self, email, password, elastic=False): print("---" + Fore.CYAN + "Pipl" + Fore.RESET + '---') request = SearchAPIRequest(email=email, show_sources=True, use_https=True, api_key=conf['keys']['pipl']) to_elastic = {"email": email, "password": password, "name": [], "dob": "", 'jobs': [], 'addresses': [], "images": [], "urls": []} try: response = request.send() if response.person: if response.person.names: print("Name: " + response.person.names[0].display) for name in response.person.names: to_elastic['name'].append(name.display) if response.person.dob: print(response.person.dob.display) to_elastic['dob'].append(str(response.person.dob.display)) if response.person.jobs: print("Jobs:") for job in response.person.jobs: # if "Director" in job.display or "CEO" in job.display # self.send_push("Found big fish " + email + password) print(job.display) if response.person.urls: for url in response.person.urls: print(url.display) to_elastic['urls'].append(url.display) for address in response.person.addresses: to_elastic['addresses'].append(address.display) for image in response.person.images: to_elastic['images'].append(image.display) if elastic: self.put_elastic('pipl', 'email', to_elastic) else: print("Nothing was found :(") except Exception as e: print(Fore.RED + str(e) + Fore.RESET)
def set_default(): SearchAPIRequest.set_default_settings(api_key=u'9ztqbp5mxbuqdc3z6g6nckdy', minimum_probability=None, show_sources="all", minimum_match=None, hide_sponsored=None, live_feeds=None, use_https=True)
from piplapis.data import Person, Name, Address, Job, DOB, DateRange from piplapis.search import SearchAPIRequest from piplapis.search import SearchAPIError import json import datetime # Test for DOB parsing. The DOB provided below does not appear in the "parsed data" in the pipl API console query view # I believe therefore it is not being included in the filtering logic, and there are too many returned responses # Please change the name and DOB range below to something useful for your tests. fields = [ Name(first=u'Clark', last=u'Kent'), DOB(date_range=DateRange(datetime.date(1975, 1, 1), datetime.date(1980, 1, 1))) ] request = SearchAPIRequest(person=Person(fields=fields), api_key='YOUR_KEY') try: response = request.send() except SearchAPIError as e: print(e.http_status_code, e) exit(1) exit(0)
def enhance_segment_user(user): resp = SearchAPIRequest(email=user.email, first_name=user.first_name, last_name=user.last_name, show_sources='matching').send() if resp.warnings: logger.warning("Got {} warnings for Pipl enhancement".format(len(resp.warnings))) for warning in resp.warnings: logger.warning(warning) if resp.person: traits = {} if person.dob: traits['age'] = person.dob.age if person.educations: traits['degree'] = person.educations[0]._display if person.languages: traits['language'] = person.languages[0]._display if person.gender: traits['gender'] = person.gender.display for p in person.phones: if p.type == 'work_phone': traits['phone'] = p.display_international if person.names and (not user.first_name or not user.last_name): name = person.names[0] traits['firstName'] = name.first traits['lastName'] = name.last if person.jobs: job = person.jobs[0] traits['Job Title'] = job.title traits['Organization'] = job.organization traits['Industry'] = job.industry if person.emails: query_md5 = resp.query.emails[0].address_md5 match_email = ([e for e in person.emails if e.address_md5 == query_md5] or [None])[0] if match_email: traits['Disposable Email'] = 'Yes' if match_email.disposable else 'No' traits['Email Provider'] = 'Public' if match_email.email_provider else 'Work' domain_names = [ ('linkedin.com', 'LinkedIn'), ('facebook.com', 'Facebook'), ('plus.google.com', 'G+'), ('twitter.com', 'Twitter'), ('pinterest.com', 'Pinterest'), ('reddit.com', 'Reddit'), ] sources_by_domain = resp.group_sources_by_domain() for domain, name in domain_names: sources = sources_by_domain.get(domain, []) for src in sources: if src.usernames: traits['{} Username'.format(name)] = src.usernames[0].content if src.user_ids: traits['{} User ID'.format(name)] = src.user_ids[0].content.split('@')[0] break for src in sources: if 'avatar' not in traits and src.images: traits['avatar'] = src.images[0].url if 'avatar' not in traits and person.images: traits['avatar'] = person.images[0].url analytics.identify(user.email, traits)
def test_response_class_default(self): request = SearchAPIRequest(email="*****@*****.**") response = request.send() self.assertIsInstance(response, SearchAPIResponse)
def __init__(self, name): self.request = SearchAPIRequest( raw_name=name, api_key='SOCIAL-PREMIUM-DEMO-vllok8b97jwjpygr3p6mnx1x')
from piplapis.search import SearchAPIRequest file = None if sys.argv.__len__() > 1: file = open(sys.argv[1]) inputsource = file or sys.stdin for line in inputsource: whatToCheck = line.strip() if whatToCheck.count('@') == 0: continue print "Checking Information for Email: (%s) " % whatToCheck Piplrequest = SearchAPIRequest(api_key=UserApiKey, email=whatToCheck) response = Piplrequest.send() Collection = response.group_records_by_domain() print Collection for Domain in Collection: print print for item in Collection[Domain]: print "%s %s \n%s" % (Domain , item, item.to_dict()) print ("") """
def index(request): latest_testresult_list = "test" if request.method == 'POST': # create a form instance and populate it with data from the request: form = PIPLSearch(request.POST) # check whether it's valid: if form.is_valid(): #print(form.cleaned_data) # get rid of elements in form that are emtpy newDict = {} for element, value in form.cleaned_data.items(): if value != "": newDict[element] = value # loop through form and organize it into a query for the PIPL Api piplQuery = {} for element, value in newDict.items(): piplQuery[element] = value ## UNCOMMENT HERE TO GET OUT OF TESTING piplQuery["api_key"] = api_key #pprint.pprint(piplQuery) request2 = SearchAPIRequest(**literal_eval(str(piplQuery))) #request2 = SearchAPIRequest(first_name=u'Caleb', last_name=u'Lawrence', api_key='vqnx9j3dfjxyq5sgmnspgvij') search_response = request2.send() json_response = search_response.to_dict() #pprint.pprint(json_response) ### UNCOMMENT HERE TO LOAD JSON TO FILE FOR FUTURE TESTING # with open('multiplepeople.json', 'w') as outfile: # json.dump(json_response, outfile) context = {} # with open("multiplepeople.json") as json_data: # json_response = json.load(json_data) # json_data.close() if "possible_persons" in json_response: # more than one person found # collection of person objects context = {} context['people'] = {} totalPeople = 0 # loop through possible persons for person in json_response["possible_persons"]: totalPeople += 1 #print "printing person" #pprint.pprint(person) unique_name = person["@search_pointer"] context["people"][unique_name] = {} if "names" in person: names = person["names"] context['people'][unique_name]['names'] = names if "emails" in person: emails = person["emails"] context["people"][unique_name]['emails'] = emails if "phones" in person: phones = person["phones"] context["people"][unique_name]['phones'] = phones if "gender" in person: gender = person["gender"] context["people"][unique_name]['gender'] = gender if "dob" in person: dob = person["dob"] context["people"][unique_name]['dob'] = dob if "addresses" in person: addresses = person["addresses"] context["people"][unique_name]['addresses'] = addresses if "jobs" in person: jobs = person["jobs"] context["people"][unique_name]['jobs'] = jobs if "educations" in person: educations = person["educations"] context["people"][unique_name][ 'educations'] = educations if "images" in person: images = person["images"] context["people"][unique_name]['images'] = images if "urls" in person: urls = person["urls"] context["people"][unique_name]['urls'] = urls context["people"][unique_name][ 'personCounter'] = totalPeople #pprint.pprint(context["people"]) # print "printing data in context: " # for item in context['people']: # pprint.pprint(item) # for item2 in context['people'][item]: # pprint.pprint(item2) context["totalPeople"] = totalPeople peopleCounter = range(1, totalPeople) context["peopleCounter"] = peopleCounter return render(request, 'response_multi.html', context) # only one person found else: if "names" in json_response["person"]: names = json_response["person"]["names"] context['names'] = names if "emails" in json_response["person"]: emails = json_response["person"]["emails"] context['emails'] = emails if "phones" in json_response["person"]: phones = json_response["person"]["phones"] context['phones'] = phones if "gender" in json_response["person"]: gender = json_response["person"]["gender"] context['gender'] = gender if "dob" in json_response["person"]: dob = json_response["person"]["dob"] context['dob'] = dob if "addresses" in json_response["person"]: addresses = json_response["person"]["addresses"] context['addresses'] = addresses if "jobs" in json_response["person"]: jobs = json_response["person"]["jobs"] context['jobs'] = jobs if "educations" in json_response["person"]: educations = json_response["person"]["educations"] context['educations'] = educations if "images" in json_response["person"]: images = json_response["person"]["images"] context['images'] = images if "urls" in json_response["person"]: urls = json_response["person"]["urls"] context['urls'] = urls #context = {'names': names, 'emails': emails, 'phones': phones, 'gender': gender, 'dob': dob, 'addresses': addresses, 'jobs': jobs, 'educations': educations, 'images': images, 'urls': urls } return render(request, 'response.html', context) # if a GET (or any other method) we'll create a blank form else: form = PIPLSearch() return render(request, 'home.html', {'form': form}) context = {'latest_testresult_list': latest_testresult_list} return render(request, 'home.html', context)
def enhance_segment_user(user): resp = SearchAPIRequest(email=user.email, first_name=user.first_name, last_name=user.last_name, show_sources='matching').send() if resp.warnings: logger.warning("Got {} warnings for Pipl enhancement".format( len(resp.warnings))) for warning in resp.warnings: logger.warning(warning) if resp.person: traits = {} if person.dob: traits['age'] = person.dob.age if person.educations: traits['degree'] = person.educations[0]._display if person.languages: traits['language'] = person.languages[0]._display if person.gender: traits['gender'] = person.gender.display for p in person.phones: if p.type == 'work_phone': traits['phone'] = p.display_international if person.names and (not user.first_name or not user.last_name): name = person.names[0] traits['firstName'] = name.first traits['lastName'] = name.last if person.jobs: job = person.jobs[0] traits['Job Title'] = job.title traits['Organization'] = job.organization traits['Industry'] = job.industry if person.emails: query_md5 = resp.query.emails[0].address_md5 match_email = ( [e for e in person.emails if e.address_md5 == query_md5] or [None])[0] if match_email: traits[ 'Disposable Email'] = 'Yes' if match_email.disposable else 'No' traits[ 'Email Provider'] = 'Public' if match_email.email_provider else 'Work' domain_names = [ ('linkedin.com', 'LinkedIn'), ('facebook.com', 'Facebook'), ('plus.google.com', 'G+'), ('twitter.com', 'Twitter'), ('pinterest.com', 'Pinterest'), ('reddit.com', 'Reddit'), ] sources_by_domain = resp.group_sources_by_domain() for domain, name in domain_names: sources = sources_by_domain.get(domain, []) for src in sources: if src.usernames: traits['{} Username'.format( name)] = src.usernames[0].content if src.user_ids: traits['{} User ID'.format( name)] = src.user_ids[0].content.split('@')[0] break for src in sources: if 'avatar' not in traits and src.images: traits['avatar'] = src.images[0].url if 'avatar' not in traits and person.images: traits['avatar'] = person.images[0].url analytics.identify(user.email, traits)
def get_narrow_search_request(self): return SearchAPIRequest(email="*****@*****.**")
def get_broad_search_request(self): return SearchAPIRequest(first_name="brian", last_name="perks")
def index(request): if request.method == "POST": email_form = EmailForm(request.POST) email = email_form.data["user_email"] name = email_form.data["user_name"] # print(email) # email_func(email) #SH # IP Data API requests1 = requests.get( 'http://api.ipapi.com/api/check?access_key=3ce7a3e12763ba9551d020fa5a4b1117&output=json' ) response_dict = json.loads(requests1.text) # print(response_dict) # Reverse GeoCoding # key = "AIzaSyD7q2PVhT2SDl9jJCq8qiciuusZ_Z09AwQ" # requests3 = requests.get('https://maps.googleapis.com/maps/api/geocode/json?latlng={},{}&result_type=street_address&key={}'.format(response_dict["latitude"], response_dict["longitude"], key)) # response_dict1 = json.loads(requests3.text) # print(response_dict1['results']) # People Data API if len(email)==0 and len(name)==0 \ or len(email)!=0 and len(name)!=0: # messages.info(request, 'Please enter name OR email. Name must include the middle name as well when applicable.') messages.error(request, 'You must enter either name or email (not both)!') return HttpResponse( render(request, "securityApp/index.html", {"email_form": email_form})) if len(email)==0 and len(name)!=0 \ and len(name.split(' ')) >= 2: # api check by name request2 = SearchAPIRequest(raw_name=name, api_key='w55kotsni33vhkymn3ey8hxh' ) # raw_name or email GET APIs FROM ME else: # messages.info(request, 'Please enter name OR email. Name must include the middle name as well when applicable.') request2 = SearchAPIRequest(email=email, api_key='w55kotsni33vhkymn3ey8hxh' ) # raw_name or email GET APIs FROM ME response2 = request2.send() response2_dict = response2.to_dict() currentPerson = response2.person ip = response_dict["ip"] # VPN Detection API response = requests.get( 'https://api.ip2proxy.com/?ip={}&key=WU5VWACYRB&package=PX1'. format(ip)) response_dict2 = json.loads(response.text) #if response2 is None: print("Response: ", response2.name.__class__.__name__) print("Response Type: ", type(response2)) if response2.name.__class__.__name__ == "NoneType": messages.warning(request, "Email is not found.") return redirect(to="/securityApp") output = social_media(response2_dict) if email_form.is_valid(): return HttpResponse( render( request, "securityApp/results.html", { "email_form": email_form, "ipAddress": "" + response_dict["ip"], "ipType": response_dict["type"], "ipProxy": "" + response_dict2['isProxy'], "continentCode": response_dict["continent_code"], "continentName": response_dict["continent_name"], "countryCode": response_dict["country_code"], "countryName": response_dict["country_name"], "regionCode": response_dict["region_code"], "regionName": response_dict["region_name"], "ipCity": "" + response_dict["city"], "ipZip": response_dict["zip"], "ipLatitude": response_dict["latitude"], "ipLongitude": response_dict["longitude"], "currentPerson": response2.person, "names": response2.name.display, "usernames": "" + response2.username.display if hasattr(response2, 'username') and hasattr(response2.username, 'display') else '', "emails": "" + response2.email.display if hasattr(response2, 'email') and hasattr(response2.email, 'display') else '', "addresses": "" + response2.address.display if hasattr(response2, 'address') and hasattr(response2.address, 'display') else '', "phones": "" + response2.phone.display if hasattr(response2, 'phone') and hasattr(response2.phone, 'display') else '', "educations": "" + response2.education.display if hasattr(response2, 'education') and hasattr(response2.education, 'display') else '', "jobs": "" + response2.job.display if hasattr(response2, 'job') and hasattr(response2.job, 'display') else '', "privacyRating": privacyRatingCalculator(currentPerson), # # "currentPerson": response2.person, # "names": "John Aaron Doe", # "\n".join(map(str, currentPerson.names)), # "usernames": "jdoe70", # "\n".join(map(str, currentPerson.usernames)), # "emails": "*****@*****.**", # "\n".join(map(str, currentPerson.emails)), # "addresses": "4301 College Road, Houston, Texas", # "\n".join(map(str, currentPerson.addresses)), # "phones": "(976)-584-9090", # "\n".join(map(str, currentPerson.phones)), # "educations": "Texas A&M University", # "\n".join(map(str, currentPerson.educations)), # "jobs": "Process Operator at Dow Chemical", # "\n".join(map(str, currentPerson.jobs)), # "relationships": "Jane Ashley Doe", # "\n".join(map(str, currentPerson.relationships)), # "ethnicities": "Caucasian", # "\n".join(map(str, currentPerson.ethnicities)), # "gender": "Male", # "\n".join(str(currentPerson.gender)) # "privacyRating": privacyRatingCalculator(), "tweet_1": output['tweet_1'], "tweet_2": output['tweet_2'], "tweet_3": output['tweet_3'], "tw_name": output['tw_name'], "tw_url": output['tw_url'], "fb_count": output['fb_count'], "speechGen": speechGen(currentPerson, response2) # "fb_1": output['fb_1'], # "fb_2": output['fb_2'], # "fb_3": output['fb_3'] })) else: email_form = EmailForm() # messages.info(request, 'Please enter name OR email. Name must include the middle name as well when applicable.') # return HttpResponse("...") return HttpResponse( render(request, "securityApp/index.html", {"email_form": email_form}))
def api_pipl(defendant_name, business_tier=False): # submit api call to pipl using defendant name, city columbus, county muscogee, state georgia # code snippets # https://docs.pipl.com/docs/code-snippets # python library # https://docs.pipl.com/docs/code-libraries#section-python # get first match back, which is the most likely candidate, ignore multiple matches for now # if a match from pipl, set match_true = true, populate return variables with data from ppl # if no match from pipl, set met_true = false, leave other return variables blank # adapted from sample code: from api_keys import pipl_social_api_key, pipl_biz_api_key, pipl_contact_api_key from piplapis.search import SearchAPIRequest from piplapis.search import SearchAPIResponse from piplapis.search import SearchAPIError from piplapis.data import Person, Name, Address import pipl_processing import datetime # create return object + set default state defendant = {"match_true": False} SearchAPIRequest.set_default_settings( api_key=pipl_contact_api_key, minimum_probability=0.8, use_https=True ) # use encrypted connection and ensure 80% probability matching # Split name supplied into values parsable by request api names = defendant_name.split(' ') defendant_last_name = names[0] defendant_middle_name = "" # ensures always initialized # handle cases 2, 3 or more total names if len(names) == 2: defendant_first_name = names[1] elif len(names) == 3: defendant_middle_name = names[2] defendant_first_name = names[1] else: # TODO: handle >3 names dap_log_pipl(LogLevel.ERROR, "invalid name format: %s" % defendant_name) return defendant fields = [ Name(first=defendant_first_name, middle=defendant_middle_name, last=defendant_last_name), Address(country=u'US', state=u'GA', city=u'Columbus' ) # all cases on this mainframe will be located here, ] # prepare request (use contact-tier key by default, business-tier if specificied) key = pipl_biz_api_key if business_tier else pipl_contact_api_key request = SearchAPIRequest(person=Person(fields=fields), api_key=key) # for debugging dap_log_pipl(LogLevel.DEBUG, str(request.__dict__)) # TODO: log api messages to pipl.log # assures that reference is assigned before later access response = None person = None # try fetching a request try: dap_log_pipl(LogLevel.DEBUG, "fetching request...") response = request.send() except SearchAPIError as e: message = "SearchAPIError: %i: %s" % (e.http_status_code, e.error) dap_log_pipl(LogLevel.CRITICAL, message) # direct match found! if response and response.person: dap_log_pipl(LogLevel.DEBUG, "direct match!") person = response.person # possible matches found, pick most likely candidate elif response and len(response.possible_persons) > 0: dap_log_pipl(LogLevel.DEBUG, "possible matches, searching...") local_list = list() for possible in response.possible_persons: local_addresses = pipl_processing.get_matching_addresses( addresses=possible.addresses, city="Columbus", state="GA") # Person is a local resident, add them to list of local_list if len(local_addresses) != 0: local_list.append(possible) # TODO: pick from list of possible persons, placeholder for further processing if len(local_list) != 0: dap_log_pipl(LogLevel.DEBUG, "match found!") person = local_list[0] # no match found or empty response else: if not response: message = "Empty response!" dap_log_pipl(LogLevel.ERROR, message) else: message = "No matching person found for %s." % defendant_name dap_log_pipl(LogLevel.WARN, message) if person: # TODO: catch index exceptions thrown in case of empty arrays? # a match was found! defendant["match_true"] = True # set default values before parsing person object defendant_house = None defendant_address = None defendant_apartment = None defendant_email = "" defendant_facebook = "" # parse addresses, see https://docs.pipl.com/reference#address # Get addresses from within Columbus, GA addresses = pipl_processing.get_matching_addresses( addresses=person.addresses, city="Columbus", state="GA") # for matching addresses within the state find latest (if > 1) last_seen = None for address in addresses: # This is the marked current address, break out of loop if address.current and address.current == True: defendant_address = address break # Skip if old, skip if work and record to compliance log, default type is home if address.type: if address.type == "work": # TODO: record a note to compliance.log dap_log_pipl( LogLevel.INFO, "Work address found for %s, skipping." % defendant_name) elif address.type == "old": continue # address has last_seen date, compare to set as latest if address.last_seen: if not last_seen or address.last_seen >= last_seen: last_seen = address.last_seen defendant_address = address # if no last_seen on any address supplied, pick first from array # and set last_seen to unix epoch (so any last_seen is bigger) else: if not defendant_address: last_seen = datetime.datetime.utcfromtimestamp(0) defendant_address = address last_seen = None for email in person.emails: # This is the current email, break out of loop if email.current and email.current == True: defendant_email = email.address break # Skip if work email and record to compliance log, default type # if omitted is personal if email.type and email.type == "work": dap_log_pipl( LogLevel.INFO, "Work email found for %s, skipping." % defendant_name) continue # email has last_seen date, compare to set as latest if email.last_seen: if not last_seen or email.last_seen >= last_seen: last_seen = address.last_seen defendant_email = email.address # if no last_seen on any email supplied, pick first from array # and set last_seen to unix epoch (so any last_seen is bigger) else: if not defendant_email: last_seen = datetime.datetime.utcfromtimestamp(0) defendant_email = email.address # parse facebook, see see https://docs.pipl.com/reference#user-id last_seen = None for id in person.user_ids: # empty id or not a facebook id, continue through loop if not id.content or not id.content.endswith("@facebook"): continue # email has last_seen date, compare to set as latest if id.last_seen: if not last_seen or id.last_seen >= last_seen: last_seen = id.last_seen defendant_facebook = id.content[0:-9] # remove '@facebook' # if no last_seen on any email supplied, pick first from array # and set last_seen to unix epoch (so any last_seen is bigger) else: if not defendant_facebook: last_seen = datetime.datetime.utcfromtimestamp(0) defendant_facebook = id.content[0:-9] # remove '@facebook' # handle usage of contact vs. business tier api keys if business_tier: if not defendant_email: dap_log_pipl( LogLevel.ERROR, "business-tier api requested, but no email returned!") # if running at business tier, only return dict with email supplied, as this # call of api_pipl() will have been made recursively from a contact-tier call # to api_pipl() defendant["email"] = defendant_email return defendant else: if defendant_email == "*****@*****.**": dap_log_pipl( LogLevel.DEBUG, "contact-tier email returned, re-running with business api keys" ) defendant_email = api_pipl(defendant_name, business_tier=True)["email"] elif defendant_email != "": dap_log_pipl( LogLevel.ERROR, "contact-tier returned non-null, valid (?) email: %s" % defendant_email) # set all parsed values if not defendant_address: defendant_address = Address() defendant[ "house"] = defendant_address.house if defendant_address.house else "" defendant[ "street"] = defendant_address.street if defendant_address.street else "" defendant[ "apartment"] = defendant_address.apartment if defendant_address.apartment else "" defendant[ "city"] = defendant_address.city if defendant_address.city else "" defendant[ "state"] = defendant_address.state if defendant_address.state else "" defendant[ "zip"] = defendant_address.zip_code if defendant_address.zip_code else "" defendant["email"] = defendant_email defendant["facebook"] = defendant_facebook dap_log_pipl(LogLevel.DEBUG, "%s: %s" % (defendant_name, str(defendant))) return defendant
def _pipl_search_function_function(self, event, *args, **kwargs): """Function: Function enriches your leads (name, email address, phone number, or social media username) with Pipl and gets their personal, professional, demographic, and contact information. The minimal requirement to run a search is to have at least one full name, email, phone, username, user_id, URL or a single valid US address (down to a house number).""" def get_config_option(option_name, optional=False): """Given option_name, checks if it is in appconfig. Raises ValueError if a mandatory option is missing""" option = self.options.get(option_name) if not option and optional is False: err = "'{0}' is mandatory and is not set in the app.config file. " \ "You must set this value to run this function".format(option_name) raise ValueError(err) else: return option def get_function_input(inputs, input_name, optional=False): """Given input_name, checks if it defined. Raises ValueError if a mandatory input is None""" input = inputs.get(input_name) if input is None and optional is False: err = "'{0}' is a mandatory function input".format(input_name) raise ValueError(err) else: return input try: # Get the function parameters: artifact_type = get_function_input(kwargs, "pipl_artifact_type") # text artifact_value = get_function_input(kwargs, "pipl_artifact_value") # text log = logging.getLogger(__name__) log.info("artifact_type: %s", artifact_type) log.info("artifact_value: %s", artifact_value) # Read configuration settings: pipl_api_key = get_config_option("pipl_api_key") max_matches = int( get_config_option("pipl_max_no_possible_per_matches")) pipl_minimum_match = get_config_option("pipl_minimum_match", True) minimum_match = float( pipl_minimum_match) if pipl_minimum_match else None pipl_minimum_probability = get_config_option( "pipl_minimum_probability", True) minimum_probability = float( pipl_minimum_probability) if pipl_minimum_probability else None pipl_infer_persons = get_config_option("pipl_infer_persons", True) infer_persons = parse_bool( pipl_infer_persons) if pipl_infer_persons else None email, raw_name, username = None, None, None if artifact_type in ("Email Sender", "Email Recipient"): # In Pipl Data this are full email addresses. Personal and Work emails. email = artifact_value elif artifact_type == "User Account": # In Pipl Data this are usernames in use by the person online. This includes screen names, # handles and nicknames from across the web, social media sites, forums and more. username = artifact_value else: # In Pipl Data this is current name as well as maiden name and nicknames. raw_name = artifact_value # Set the required request data request = SearchAPIRequest(email=email, raw_name=raw_name, username=username, api_key=pipl_api_key, minimum_match=minimum_match, minimum_probability=minimum_probability, infer_persons=infer_persons) # get response response = request.send( ) # returns SearchAPIResponse object not dict # Create payload dict payload = FunctionPayload() if response: # If success extract person data if response.http_status_code == 200: response_json = response.raw_json persons_count = response.persons_count if persons_count and response_json: response_dict = json.loads(response_json) person_list = [] # A response can return either a Person or possible_persons array pipl_person = response_dict.get("person") possible_persons = response_dict.get( "possible_persons") if pipl_person: person_list.append(pipl_person) payload.pipl_response = "definite match" yield StatusMessage( "The data sent/found to Pipl is enough to identify a single, matching person." ) elif possible_persons: # Include only this number of possible person matches in the results new_list = possible_persons[:max_matches] person_list.extend(new_list) payload.pipl_response = "possible person matches" yield StatusMessage( "The data sent/found to Pipl is not enough to identify a single person. " "A list of possible person matches was returned." ) else: payload.pipl_response = "no match" yield StatusMessage( "No data was found in Pipl. " "Try adjusting the search settings in app.config." ) # Save the response in payload payload.person_list = person_list # Pretty printing payload.raw_data = json.dumps(person_list, sort_keys=True, indent=4, separators=(',', ': ')) # No data returned else: payload.person_list = [] payload.pipl_response = "no match" yield StatusMessage( "No data was found in Pipl. " "Try adjusting the search settings in app.config.") # If not a 200 code else: payload.success = False raise ValueError( "Error with Pipl API. Status Code: {0}".format( response.error)) else: payload.success = False raise ValueError( "No response from Pipl. Check your connection/credentials." ) # Send payload back to Appliance results = payload.as_dict() log.info(json.dumps(results)) log.info("Complete") # Produce a FunctionResult with the results yield FunctionResult(results) except Exception as err: log.info(err) yield FunctionError()
def main(): SearchAPIRequest.set_default_settings(api_key=my_key, minimum_probability=None, show_sources=None, minimum_match=None, hide_sponsored=None, live_feeds=None, use_https=True) search_object(read_the_files())
def test_forward_compatibility(self): SearchAPIRequest.BASE_URL += "&show_unknown_fields=1" request = SearchAPIRequest(email="*****@*****.**") response = request.send() self.assertIsNotNone(response.person)
def get_narrow_md5_search_request(self): return SearchAPIRequest(person=Person( fields=[Email(address_md5="e34996fda036d60aa2a595ca86ed8fef")]))
# Use any combination of search parameters. # Each parameter may be used only once. # A search request has to contain at least one valid name, # email address, phone, username, user id, URL, or a full US address (including a house number). // # Python Code: # imports from piplapis.search import SearchAPIRequest, Person, Address, Name, Phone, Email, Job, DOB # run search (request/response) SearchAPIRequest.set_default_settings(api_key=u'Your API Key', minimum_probability=None, show_sources=None, minimum_match=None, hide_sponsored=None, live_feeds=None, use_https=True) fields = [ Phone(raw=19785550145), Email("*****@*****.**"), Name(first=u'Clark', last=u'Kent') ] request = SearchAPIRequest(person=Person(fields=fields)) response = request.send() # print portion of response if response.person: # Has data so single Full Person response currentPerson = response.person print("Number of Names:", len(currentPerson.names))
def test_recursive_request(self): response = self.get_broad_search_request().send() self.assertGreater(len(response.possible_persons), 0) second_response = SearchAPIRequest( search_pointer=response.possible_persons[0].search_pointer).send() self.assertIsNotNone(second_response.person)