|
|
import gradio as gr |
|
|
import requests |
|
|
import os |
|
|
from urllib.parse import urlencode, parse_qs |
|
|
from http.server import BaseHTTPRequestHandler, HTTPServer |
|
|
import threading |
|
|
|
|
|
|
|
|
CLIENT_ID = "866hp4xfy5zmxz" |
|
|
CLIENT_SECRET = "WPL_AP1.p8sN30biu6BLlTn7.sudQlw==" |
|
|
REDIRECT_URI = "https://tkgauri.hf.space/callback" |
|
|
AUTH_URL = "https://www.linkedin.com/oauth/v2/authorization" |
|
|
TOKEN_URL = "https://www.linkedin.com/oauth/v2/accessToken" |
|
|
PROFILE_API = "https://api.linkedin.com/v2/me" |
|
|
EMAIL_API = "https://api.linkedin.com/v2/emailAddress?q=members&projection=(elements*(handle~))" |
|
|
|
|
|
access_token = "new_token" |
|
|
|
|
|
|
|
|
class OAuthCallbackHandler(BaseHTTPRequestHandler): |
|
|
def do_GET(self): |
|
|
global access_token |
|
|
query = parse_qs(self.path.split('?', 1)[-1]) |
|
|
code = query.get('code')[0] |
|
|
|
|
|
|
|
|
token_data = { |
|
|
'grant_type': 'authorization_code', |
|
|
'code': code, |
|
|
'redirect_uri': REDIRECT_URI, |
|
|
'client_id': CLIENT_ID, |
|
|
'client_secret': CLIENT_SECRET |
|
|
} |
|
|
|
|
|
response = requests.post(TOKEN_URL, data=token_data) |
|
|
token_json = response.json() |
|
|
access_token = token_json.get('access_token') |
|
|
|
|
|
self.send_response(200) |
|
|
self.end_headers() |
|
|
self.wfile.write(b'Authentication successful. Return to the app.') |
|
|
|
|
|
|
|
|
def start_oauth_server(): |
|
|
server = HTTPServer(('localhost', 8080), OAuthCallbackHandler) |
|
|
server.handle_request() |
|
|
|
|
|
def get_authorization_url(): |
|
|
params = { |
|
|
'response_type': 'code', |
|
|
'client_id': CLIENT_ID, |
|
|
'redirect_uri': REDIRECT_URI, |
|
|
'scope': 'r_liteprofile r_emailaddress' |
|
|
} |
|
|
return f"{AUTH_URL}?{urlencode(params)}" |
|
|
|
|
|
|
|
|
def summarize_profile(name, headline, email): |
|
|
text = f"{name} is a professional with expertise in: {headline}. Contact: {email}" |
|
|
response = requests.post( |
|
|
"https://api-inference.huggingface.co/models/facebook/bart-large-cnn", |
|
|
headers={"Authorization": f"Bearer {os.getenv('HF_API_KEY')}"}, |
|
|
json={"inputs": text} |
|
|
) |
|
|
return response.json()[0]["summary_text"] |
|
|
|
|
|
def linkedIn_summary_flow(): |
|
|
global access_token |
|
|
|
|
|
threading.Thread(target=start_oauth_server).start() |
|
|
return f"[Click here to authorize LinkedIn]({get_authorization_url()})" |
|
|
|
|
|
def fetch_and_summarize(_): |
|
|
headers = {"Authorization": f"Bearer {access_token}"} |
|
|
profile = requests.get(PROFILE_API, headers=headers).json() |
|
|
email_data = requests.get(EMAIL_API, headers=headers).json() |
|
|
|
|
|
name = profile.get("localizedFirstName", "") + " " + profile.get("localizedLastName", "") |
|
|
headline = profile.get("localizedHeadline", "") |
|
|
email = email_data['elements'][0]['handle~']['emailAddress'] |
|
|
|
|
|
summary = summarize_profile(name, headline, email) |
|
|
return f"**Name:** {name}\n**Headline:** {headline}\n**Email:** {email}\n\n**Summary:** {summary}" |
|
|
|
|
|
with gr.Blocks() as demo: |
|
|
gr.Markdown("# π LinkedIn Profile Summarizer") |
|
|
gr.Markdown("1. Click to authorize via LinkedIn\n2. Fetch & summarize your profile") |
|
|
|
|
|
btn_auth = gr.Button("π Connect to LinkedIn") |
|
|
btn_fetch = gr.Button("π Summarize My Profile") |
|
|
output = gr.Textbox(label="Summary", lines=10) |
|
|
|
|
|
btn_auth.click(linkedIn_summary_flow, outputs=output) |
|
|
btn_fetch.click(fetch_and_summarize, inputs=[], outputs=output) |
|
|
|
|
|
demo.launch() |
|
|
|