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:
|