GBilianis
GBilianis

Reputation: 15

Sharepoint Rest API access token runs out of time

I am trying to use REST API to update a specific column in sharepoint with data I get from a dataframe from an excel file, based on a matching column. The dataframe column size is about 25k rows. As far as I know, the access token lifetime is 1 hour. Since the update process takes longer than than, afterwards I get 401 error, for each row update I try. This is the request access token function:

def get_access_token(tenant_id, client_id, client_secret):    
    token_url = f'https://login.microsoftonline.com/{tenant_id}/oauth2/v2.0/token'
    token_data = {
        'grant_type': 'client_credentials',
        'client_id': client_id,
        'client_secret': client_secret,
        'scope': 'https://graph.microsoft.com/.default'
    }    
    try:
        token_response = requests.post(token_url, data=token_data)
        token_response.raise_for_status()
        token_json = token_response.json()
        access_token = token_json.get('access_token')        
        if not access_token:
            raise ValueError("Failed to retrieve access token.")
        return access_token, time.time()

and this is the update sharepoint column function:

    """
    Updates a single SharePoint list field based on a DataFrame column that matches a SharePoint field.
    
    Parameters:
    - df: The DataFrame containing data to update.
    - access_token: The OAuth token for accessing Microsoft Graph API.
    - site_id: The ID of the SharePoint site.
    - list_id: The ID of the SharePoint list.
    - match_column: The DataFrame column to match on.
    - update_column: The DataFrame column with the value to update in SharePoint.
    - sharepoint_match_field: The field name in SharePoint to match on.
    - sharepoint_update_field: The field name in SharePoint to be updated.
    """
    headers = {
        'Authorization': f'Bearer {access_token}',
        'Content-Type': 'application/json'
    }
    
    for _, row in df.iterrows():
        # Extract the match and update values
        match_value = row[match_column]  # Value in the DataFrame to match on
        update_value = row[update_column]  # Value in the DataFrame to update
        
        # Debug: Log match and update values
        print(f"Processing match_value: {match_value}, update_value: {update_value}")       
     
        
        # Ensure update_value is stripped of whitespace
        update_value = str(update_value).strip()
        print(update_value)
        # Step 1: Search for the SharePoint item based on the match column
        search_url = f"https://graph.microsoft.com/v1.0/sites/{site_id}/lists/{list_id}/items?$filter=fields/{sharepoint_match_field} eq '{match_value}'"
        print(f"Search URL: {search_url}")
        
        try:
            search_response = requests.get(search_url, headers=headers)
            search_response.raise_for_status()
        except requests.exceptions.RequestException as e:
            print(f"Error during search request: {e}")
            continue
        
        search_data = search_response.json()
        print(f"Search response: {search_data}")
        
        # Check if any item was found with the match value
        if 'value' in search_data and len(search_data['value']) > 0:
            # Step 2: Get the item ID from the search result
            item_id = search_data['value'][0]['id']
            print(f"Found item with ID: {item_id}")
            
            # Prepare the payload to update the single field
            payload = {sharepoint_update_field: update_value}
            print(f"Payload to update: {payload}")
            
            # Step 3: Update the item using the item ID
            update_url = f'https://graph.microsoft.com/v1.0/sites/{site_id}/lists/{list_id}/items/{item_id}/fields'
            try:
                update_response = requests.patch(update_url, headers=headers, json=payload)
                if update_response.status_code == 204:
                    print(f"Successfully updated item with {match_column}={match_value}")
                elif update_response.status_code == 401:  # Unauthorized error
                    print("Unauthorized. Attempting to get a new token.")
                    # Get a new token
                    new_token =get_access_token(tenant_id, client_id, client_secret)
                    headers['Authorization'] = f'Bearer {new_token}'  # Update the authorization header
            # Retry the update request
                    update_sharepoint_list_single_column(df, access_token, site_id, list_id, match_column, update_column, sharepoint_match_field, sharepoint_update_field)
                else:
                    print(f"Failed to update item with {match_column}={match_value}.")
                    print(f"Response: {update_response.json()}")
            except requests.exceptions.RequestException as e:
                print(f"Error during update request: {e}")
        else:
            print(f"No matching item found in SharePoint for {match_column}={match_value}")

Any solutions? As you can see, I try to get a new token if I get 401 error, but it doesn't work.

Upvotes: 0

Views: 22

Answers (0)

Related Questions