Spaces:
Running
Running
Update linkedin_follower_stats.py
Browse files- linkedin_follower_stats.py +24 -13
linkedin_follower_stats.py
CHANGED
@@ -4,7 +4,7 @@ import requests
|
|
4 |
import logging
|
5 |
from datetime import datetime, timezone, timedelta
|
6 |
from urllib.parse import quote, urlencode
|
7 |
-
|
8 |
|
9 |
# Assuming you have a sessions.py with create_session
|
10 |
# If sessions.py or create_session is not found, it will raise an ImportError,
|
@@ -15,7 +15,7 @@ logging.basicConfig(level=logging.INFO, format='%(asctime)s - %(levelname)s - %(
|
|
15 |
|
16 |
API_V2_BASE = 'https://api.linkedin.com/v2'
|
17 |
API_REST_BASE = "https://api.linkedin.com/rest"
|
18 |
-
LINKEDIN_API_VERSION = "202502"
|
19 |
|
20 |
# --- ID to Name Mapping Helper Functions ---
|
21 |
|
@@ -27,7 +27,9 @@ def _fetch_linkedin_names(session, url, params, result_key_path, name_key_path,
|
|
27 |
request_url_for_logging = url
|
28 |
response_obj = None
|
29 |
try:
|
30 |
-
logging.debug(f"_fetch_linkedin_names: About to prepare request. Session token: {session.token}, Session authorized: {session.authorized}")
|
|
|
|
|
31 |
req = requests.Request('GET', url, params=params)
|
32 |
prepared_req = session.prepare_request(req)
|
33 |
request_url_for_logging = prepared_req.url
|
@@ -133,7 +135,8 @@ def get_industries_map(session, industry_urns, version="DEFAULT"):
|
|
133 |
response_obj = None
|
134 |
logging.info(f"Fetching all industries (to filter {len(unique_ids)} IDs)")
|
135 |
try:
|
136 |
-
logging.debug(f"get_industries_map: About to prepare request. Session token: {session.token}, Session authorized: {session.authorized}")
|
|
|
137 |
req = requests.Request('GET', url, params=params)
|
138 |
prepared_req = session.prepare_request(req)
|
139 |
request_url_for_logging = prepared_req.url
|
@@ -243,7 +246,9 @@ def fetch_monthly_follower_gains(session, org_urn, api_rest_base_url):
|
|
243 |
response_obj = None
|
244 |
|
245 |
try:
|
246 |
-
logging.debug(f"fetch_monthly_follower_gains: About to prepare request. Session token: {session.token}, Session authorized: {session.authorized}")
|
|
|
|
|
247 |
if session.token and 'access_token' in session.token:
|
248 |
logging.debug(f"fetch_monthly_follower_gains: Access token (partial): {str(session.token['access_token'])[:20]}...")
|
249 |
else:
|
@@ -331,7 +336,9 @@ def fetch_follower_demographics(session, org_urn, functions_map, seniorities_map
|
|
331 |
response_obj = None
|
332 |
|
333 |
try:
|
334 |
-
logging.debug(f"fetch_follower_demographics: About to prepare request. Session token: {session.token}, Session authorized: {session.authorized}")
|
|
|
|
|
335 |
if session.token and 'access_token' in session.token:
|
336 |
logging.debug(f"fetch_follower_demographics: Access token (partial): {str(session.token['access_token'])[:20]}...")
|
337 |
else:
|
@@ -449,6 +456,7 @@ def fetch_follower_demographics(session, org_urn, functions_map, seniorities_map
|
|
449 |
|
450 |
def get_linkedin_follower_stats(comm_client_id, community_token, org_urn):
|
451 |
logging.info(f"--- Initiating get_linkedin_follower_stats for org: {org_urn} ---")
|
|
|
452 |
logging.debug(f"Received comm_client_id: {comm_client_id}")
|
453 |
logging.debug(f"Received community_token - Type: {type(community_token)}, IsSet: {bool(community_token)}")
|
454 |
if isinstance(community_token, str) and len(community_token) > 10:
|
@@ -480,8 +488,11 @@ def get_linkedin_follower_stats(comm_client_id, community_token, org_urn):
|
|
480 |
"LinkedIn-Version": LINKEDIN_API_VERSION,
|
481 |
"Accept-Language": "en_US"
|
482 |
})
|
483 |
-
logging.info(f"Session created and headers updated for org {org_urn}.")
|
484 |
-
logging.debug(f"get_linkedin_follower_stats: Session token after creation
|
|
|
|
|
|
|
485 |
if session.token and 'access_token' in session.token:
|
486 |
logging.debug(f"get_linkedin_follower_stats: Access token in session (partial): {str(session.token['access_token'])[:20]}...")
|
487 |
else:
|
@@ -492,20 +503,20 @@ def get_linkedin_follower_stats(comm_client_id, community_token, org_urn):
|
|
492 |
logging.error(f"Failed to create session or update headers for org {org_urn}: {e}", exc_info=True)
|
493 |
return []
|
494 |
|
495 |
-
logging.info(f"Starting follower stats retrieval for org: {org_urn}")
|
496 |
|
497 |
-
functions_map = get_functions_map(session)
|
498 |
-
seniorities_map = get_seniorities_map(session)
|
499 |
|
500 |
if not functions_map: logging.warning(f"Functions map is empty for org {org_urn}.")
|
501 |
if not seniorities_map: logging.warning(f"Seniorities map is empty for org {org_urn}.")
|
502 |
|
503 |
all_follower_data = []
|
504 |
|
505 |
-
monthly_gains = fetch_monthly_follower_gains(session, org_urn, API_REST_BASE)
|
506 |
all_follower_data.extend(monthly_gains)
|
507 |
|
508 |
-
demographics = fetch_follower_demographics(session, org_urn, functions_map, seniorities_map)
|
509 |
all_follower_data.extend(demographics)
|
510 |
|
511 |
if not all_follower_data:
|
|
|
4 |
import logging
|
5 |
from datetime import datetime, timezone, timedelta
|
6 |
from urllib.parse import quote, urlencode
|
7 |
+
import requests_oauthlib # For version logging
|
8 |
|
9 |
# Assuming you have a sessions.py with create_session
|
10 |
# If sessions.py or create_session is not found, it will raise an ImportError,
|
|
|
15 |
|
16 |
API_V2_BASE = 'https://api.linkedin.com/v2'
|
17 |
API_REST_BASE = "https://api.linkedin.com/rest"
|
18 |
+
LINKEDIN_API_VERSION = "202502"
|
19 |
|
20 |
# --- ID to Name Mapping Helper Functions ---
|
21 |
|
|
|
27 |
request_url_for_logging = url
|
28 |
response_obj = None
|
29 |
try:
|
30 |
+
logging.debug(f"_fetch_linkedin_names (id: {id(session)}): About to prepare request. Session token: {session.token}, Session authorized: {session.authorized}, Expires at: {session.token.get('expires_at') if session.token else 'N/A'}")
|
31 |
+
logging.debug(f"_fetch_linkedin_names (id: {id(session)}): Session auth object: type={type(session.auth)}, value={session.auth}")
|
32 |
+
|
33 |
req = requests.Request('GET', url, params=params)
|
34 |
prepared_req = session.prepare_request(req)
|
35 |
request_url_for_logging = prepared_req.url
|
|
|
135 |
response_obj = None
|
136 |
logging.info(f"Fetching all industries (to filter {len(unique_ids)} IDs)")
|
137 |
try:
|
138 |
+
logging.debug(f"get_industries_map (id: {id(session)}): About to prepare request. Session token: {session.token}, Session authorized: {session.authorized}, Expires at: {session.token.get('expires_at') if session.token else 'N/A'}")
|
139 |
+
logging.debug(f"get_industries_map (id: {id(session)}): Session auth object: type={type(session.auth)}, value={session.auth}")
|
140 |
req = requests.Request('GET', url, params=params)
|
141 |
prepared_req = session.prepare_request(req)
|
142 |
request_url_for_logging = prepared_req.url
|
|
|
246 |
response_obj = None
|
247 |
|
248 |
try:
|
249 |
+
logging.debug(f"fetch_monthly_follower_gains (id: {id(session)}): About to prepare request. Session token: {session.token}, Session authorized: {session.authorized}, Expires at: {session.token.get('expires_at') if session.token else 'N/A'}")
|
250 |
+
logging.debug(f"fetch_monthly_follower_gains (id: {id(session)}): Session auth object: type={type(session.auth)}, value={session.auth}")
|
251 |
+
logging.debug(f"fetch_monthly_follower_gains (id: {id(session)}): Auto-refresh URL: {session.auto_refresh_url}, Auto-refresh kwargs: {session.auto_refresh_kwargs}")
|
252 |
if session.token and 'access_token' in session.token:
|
253 |
logging.debug(f"fetch_monthly_follower_gains: Access token (partial): {str(session.token['access_token'])[:20]}...")
|
254 |
else:
|
|
|
336 |
response_obj = None
|
337 |
|
338 |
try:
|
339 |
+
logging.debug(f"fetch_follower_demographics (id: {id(session)}): About to prepare request. Session token: {session.token}, Session authorized: {session.authorized}, Expires at: {session.token.get('expires_at') if session.token else 'N/A'}")
|
340 |
+
logging.debug(f"fetch_follower_demographics (id: {id(session)}): Session auth object: type={type(session.auth)}, value={session.auth}")
|
341 |
+
logging.debug(f"fetch_follower_demographics (id: {id(session)}): Auto-refresh URL: {session.auto_refresh_url}, Auto-refresh kwargs: {session.auto_refresh_kwargs}")
|
342 |
if session.token and 'access_token' in session.token:
|
343 |
logging.debug(f"fetch_follower_demographics: Access token (partial): {str(session.token['access_token'])[:20]}...")
|
344 |
else:
|
|
|
456 |
|
457 |
def get_linkedin_follower_stats(comm_client_id, community_token, org_urn):
|
458 |
logging.info(f"--- Initiating get_linkedin_follower_stats for org: {org_urn} ---")
|
459 |
+
logging.info(f"requests-oauthlib version: {requests_oauthlib.__version__}") # Log version
|
460 |
logging.debug(f"Received comm_client_id: {comm_client_id}")
|
461 |
logging.debug(f"Received community_token - Type: {type(community_token)}, IsSet: {bool(community_token)}")
|
462 |
if isinstance(community_token, str) and len(community_token) > 10:
|
|
|
488 |
"LinkedIn-Version": LINKEDIN_API_VERSION,
|
489 |
"Accept-Language": "en_US"
|
490 |
})
|
491 |
+
logging.info(f"Session (id: {id(session)}) created and headers updated for org {org_urn}.")
|
492 |
+
logging.debug(f"get_linkedin_follower_stats (id: {id(session)}): Session token after creation: {session.token}, Session authorized: {session.authorized}, Expires at: {session.token.get('expires_at') if session.token else 'N/A'}")
|
493 |
+
logging.debug(f"get_linkedin_follower_stats (id: {id(session)}): Session auth object: type={type(session.auth)}, value={session.auth}")
|
494 |
+
logging.debug(f"get_linkedin_follower_stats (id: {id(session)}): Auto-refresh URL: {session.auto_refresh_url}, Auto-refresh kwargs: {session.auto_refresh_kwargs}")
|
495 |
+
|
496 |
if session.token and 'access_token' in session.token:
|
497 |
logging.debug(f"get_linkedin_follower_stats: Access token in session (partial): {str(session.token['access_token'])[:20]}...")
|
498 |
else:
|
|
|
503 |
logging.error(f"Failed to create session or update headers for org {org_urn}: {e}", exc_info=True)
|
504 |
return []
|
505 |
|
506 |
+
logging.info(f"Starting follower stats retrieval for org: {org_urn} using session (id: {id(session)})")
|
507 |
|
508 |
+
functions_map = get_functions_map(session) # Pass session
|
509 |
+
seniorities_map = get_seniorities_map(session) # Pass session
|
510 |
|
511 |
if not functions_map: logging.warning(f"Functions map is empty for org {org_urn}.")
|
512 |
if not seniorities_map: logging.warning(f"Seniorities map is empty for org {org_urn}.")
|
513 |
|
514 |
all_follower_data = []
|
515 |
|
516 |
+
monthly_gains = fetch_monthly_follower_gains(session, org_urn, API_REST_BASE) # Pass session
|
517 |
all_follower_data.extend(monthly_gains)
|
518 |
|
519 |
+
demographics = fetch_follower_demographics(session, org_urn, functions_map, seniorities_map) # Pass session
|
520 |
all_follower_data.extend(demographics)
|
521 |
|
522 |
if not all_follower_data:
|