import json import httplib2 from graphipy.graph.graph_base import BaseNode as Node, BaseEdge as Edge, BaseGraph as Graph from graphipy.graph.graph_pandas import PandasGraph class LinkedinPosition(Node): def __init__(self, position): """ This class is the position node class which inherits from the BaseNode class It describes the position a user has The position node has following attribute: Id Title (Label for Gephi) Company (Json) Company Id Company Industry Company Name Company Size Comment Type Is Current Job (Boolean) Location Start Month End Month Summary """ Node.__init__(self, str(position["id"]), position["title"], "Position") self.company = position["company"] self.company_id = position["company"]["id"] self.company_industry = position["company"]["industry"] self.company_name = position["company"]["name"] self.company_size = position["company"]["size"] self.company_type = position["company"]["type"] self.is_current = position["isCurrent"] self.location = position["location"]["name"] self.start_month = position["startDate"]["month"] self.start_year = position["startDate"]["year"] self.summary = position["summary"] class LinkedinProfile(Node): def __init__(self, profile): """ This class is the profile node class which inherits from the BaseNode class It describes the user profile The position node has following attribute: Id Formatted name (Label for Gephi) First name Last Name Head line Industry Location (Json) Location Name Location Country Code Number of Connections Number of Connections Capped (Boolean) Picture Url Summary May have: Maiden Name Phonetic First Name Phonetic Last Name Formatted Phonetic Name Speicialities """ Node.__init__(self, str(profile["id"]), profile["formattedName"], "Profile") self.first_name = profile["firstName"] self.last_name = profile["lastName"] self.headline = profile["headline"] self.industry = profile["industry"] self.location = profile["location"] self.location_name = profile["location"]["name"] self.location_country = profile["location"]["country"]["code"] self.num_connections = profile["numConnections"] self.num_connections_capped = profile["numConnectionsCapped"] self.picture_url = profile["pictureUrl"] self.summary = profile["summary"] if "maidenName" in profile: self.maiden_name = profile["maidenName"] if "phonetic-first-name" in profile: self.phonetic_first_name = profile["phoneticFirstName"] if "phonetic-last-name" in profile: self.phonetic_last_name = profile["phoneticLastName"] if "formatted-phonetic-name" in profile: self.formatted_phonetic_name = profile["formattedPhoneticName"] if "specialities" in profile: self.specialties = profile["specialities"] class Linkedin: """ Linkedin v1 API has limited functionality which only supports searching for the authorized person More functionalities can be achieved by using v2 which can be required by apply at: https://business.linkedin.com/marketing-solutions/marketing-partners/become-a-partner/marketing-developer-program """ def __init__(self,api, options="pandas"): self.access_token = api["access_token"] def get_self_info(self): """ This method queries for the user profile :return: profile json """ url = "https://api.linkedin.com/v1/people/~:(" \ "id," \ "first-name," \ "last-name," \ "maiden-name," \ "formatted-name," \ "phonetic-first-name," \ "phonetic-last-name," \ "formatted-phonetic-name," \ "picture-url," \ "headline," \ "location," \ "industry," \ "num-connections," \ "current-share," \ "num-connections-capped," \ "summary," \ "specialties," \ "positions" \ ")?format=json" http = httplib2.Http() headers = {"Host": "api.linkedin.com", "Connection": "Keep-Alive", "Authorization": self.access_token} response, content = http.request(url, method="GET", headers=headers) result = json.loads(content.decode()) return result def process_positions(self, graph, profile): """ This method processes the profile json and generates several position nodes and add to the graph :param graph: The graph we are passing in :param profile: The profile json :return: The graph """ positions = profile["positions"] num = positions["_total"] positions_array = positions["values"] for i in range(num): position = positions_array[i] position_node = LinkedinPosition(position) graph.create_node(position_node) graph.create_edge(Edge(str(profile["id"]),str(position["id"]), "hasPosition")) def fetch_self_node(self, graph): """ This method queries for the profile and generates the graph about the profile :param graph: The graph we are passing in :return: The graph """ profile = self.get_self_info() profile_node = LinkedinProfile(profile) graph.create_node(profile_node) graph = self.process_positions(graph, profile)