-
Notifications
You must be signed in to change notification settings - Fork 15
Expand file tree
/
Copy pathlinkedin_api.py
More file actions
160 lines (149 loc) · 5.96 KB
/
linkedin_api.py
File metadata and controls
160 lines (149 loc) · 5.96 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
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)