How to access a sharepoint site via the REST API in Python?

Learn how to access a sharepoint site via the rest api in python? with practical examples, diagrams, and best practices. Covers python, rest, authentication development techniques with visual expla...

Accessing SharePoint Sites with Python's REST API

Hero image for How to access a sharepoint site via the REST API in Python?

Learn how to programmatically interact with SharePoint (including SharePoint 2013) using Python and its REST API for authentication, data retrieval, and manipulation.

SharePoint, a powerful collaboration platform, often requires programmatic access for automation, integration, and custom applications. The SharePoint REST API provides a robust interface for interacting with sites, lists, documents, and users. This article will guide you through the process of authenticating and making requests to a SharePoint site using Python, covering common authentication methods and practical examples.

Understanding SharePoint REST API Authentication

Accessing SharePoint data via its REST API requires proper authentication. The method you choose depends on your SharePoint version and environment (on-premises vs. SharePoint Online). For SharePoint 2013, common methods include NTLM authentication for on-premises deployments or forms-based authentication. SharePoint Online typically uses OAuth 2.0 with Azure AD, but for simpler scripts, cookie-based authentication (often involving ADFS or a similar identity provider) can be used, especially when dealing with legacy setups or specific service accounts.

sequenceDiagram
    participant PythonClient as Python Script
    participant SharePoint as SharePoint Site
    participant IDP as Identity Provider (e.g., ADFS/Azure AD)

    PythonClient->>IDP: Initial Authentication Request (e.g., POST credentials)
    IDP-->>PythonClient: Authentication Cookies/Tokens
    PythonClient->>SharePoint: REST API Request (with Cookies/Tokens)
    SharePoint-->>PythonClient: Data/Response
    Note over PythonClient,SharePoint: Subsequent requests reuse cookies/tokens

Sequence diagram for SharePoint REST API authentication flow

Setting Up Your Python Environment

Before you can interact with SharePoint, you'll need to install the necessary Python libraries. The requests library is fundamental for making HTTP requests, and for NTLM authentication, requests_ntlm is essential. For more complex SharePoint Online scenarios, libraries like Office365-REST-Python-Client might be more suitable, but we'll focus on requests for direct REST API interaction.

pip install requests requests_ntlm

Install required Python libraries

Authenticating to SharePoint 2013 (On-Premises) with NTLM

For on-premises SharePoint 2013 instances, NTLM (NT LAN Manager) is a common authentication protocol. The requests_ntlm library integrates seamlessly with requests to handle the NTLM handshake. You'll need your domain, username, and password.

import requests
from requests_ntlm import HttpNtlmAuth

sharepoint_url = "https://your-sharepoint-2013-site.com"
username = "YOUR_DOMAIN\\your_username"
password = "your_password"

try:
    session = requests.Session()
    session.auth = HttpNtlmAuth(username, password)

    # Example: Get site title
    response = session.get(f"{sharepoint_url}/_api/web?$select=Title", headers={'Accept': 'application/json'})
    response.raise_for_status() # Raise an exception for HTTP errors

    site_info = response.json()
    print(f"SharePoint Site Title: {site_info['d']['Title']}")

except requests.exceptions.RequestException as e:
    print(f"An error occurred: {e}")
except KeyError:
    print("Could not parse site title from response.")

While OAuth is the modern standard for SharePoint Online, sometimes a simpler cookie-based approach is needed for scripts, especially if you're dealing with ADFS or a similar identity provider that issues authentication cookies. This often involves an initial POST request to an authentication endpoint to obtain the necessary cookies, which are then used in subsequent requests to SharePoint. This method can be fragile and is not recommended for production applications, but it's useful for quick scripting.

import requests
import json

# Replace with your SharePoint Online details
sharepoint_url = "https://yourtenant.sharepoint.com/sites/yoursite"
username = "your_email@yourtenant.onmicrosoft.com"
password = "your_password"

# This is a simplified example and might require adjustments
# based on your specific SharePoint Online / ADFS setup.
# Often, you'd need to POST to a login page to get cookies.
# A more robust solution would use Azure AD / OAuth.

def get_sharepoint_cookies(url, username, password):
    session = requests.Session()
    # This part is highly dependent on your IDP and login page structure.
    # A common pattern is to POST credentials to a login URL.
    # For simplicity, we'll simulate a direct login attempt if possible,
    # but real-world scenarios are more complex.
    # For SharePoint Online, consider using 'Office365-REST-Python-Client' for robust auth.
    print("Attempting to get SharePoint cookies (simplified)...")
    # This is a placeholder. Real SPO cookie auth is complex.
    # You might need to use a library like 'sharepoint-rest-python-client' or 'msal'
    # for proper modern authentication.
    # For this example, we'll assume a session can be established if direct access works.
    # In many cases, this direct approach will fail for SPO.
    return session

try:
    session = get_sharepoint_cookies(sharepoint_url, username, password)

    # Example: Get lists from the site
    # Note: For SPO, you often need to include 'X-RequestDigest' header for POST/PUT/DELETE
    # and sometimes for GET requests depending on the endpoint.
    # For GET, usually just 'Accept' is enough.
    response = session.get(f"{sharepoint_url}/_api/web/lists?$select=Title", 
                           headers={'Accept': 'application/json'})
    response.raise_for_status()

    lists_info = response.json()
    print("SharePoint Lists:")
    for list_item in lists_info['d']['results']:
        print(f"- {list_item['Title']}")

except requests.exceptions.RequestException as e:
    print(f"An error occurred: {e}")
except KeyError:
    print("Could not parse lists from response. Check API endpoint and permissions.")

Performing Common REST API Operations

Once authenticated, you can perform various operations using standard HTTP methods (GET, POST, PUT, DELETE). The SharePoint REST API endpoints typically start with _api/web for site-level operations or _api/web/lists/getbytitle('ListName') for list-specific operations.

import requests
import json
from requests_ntlm import HttpNtlmAuth # Or your SPO session setup

# --- Re-use your authenticated session from previous examples ---
# For NTLM:
sharepoint_url = "https://your-sharepoint-2013-site.com"
username = "YOUR_DOMAIN\\your_username"
password = "your_password"
session = requests.Session()
session.auth = HttpNtlmAuth(username, password)

# For SPO (if you managed to get a working session):
# session = get_sharepoint_cookies(sharepoint_url, username, password)

# 1. Get all lists on the site
try:
    response = session.get(f"{sharepoint_url}/_api/web/lists?$select=Title,Id", 
                           headers={'Accept': 'application/json'})
    response.raise_for_status()
    lists = response.json()['d']['results']
    print("\n--- All Lists ---")
    for lst in lists:
        print(f"Title: {lst['Title']}, ID: {lst['Id']}")
except requests.exceptions.RequestException as e:
    print(f"Error getting lists: {e}")

# 2. Get items from a specific list (e.g., 'Documents')
list_name = "Documents"
try:
    response = session.get(f"{sharepoint_url}/_api/web/lists/getbytitle('{list_name}')/items", 
                           headers={'Accept': 'application/json'})
    response.raise_for_status()
    items = response.json()['d']['results']
    print(f"\n--- Items in '{list_name}' ---")
    if items:
        for item in items:
            print(f"Item ID: {item['Id']}, Title: {item.get('Title', 'N/A')}, File Name: {item.get('FileLeafRef', 'N/A')}")
    else:
        print("No items found.")
except requests.exceptions.RequestException as e:
    print(f"Error getting items from '{list_name}': {e}")

# 3. Create a new list item (Example for a custom list, requires X-RequestDigest for POST)
# For SharePoint Online, you'd need to fetch the X-RequestDigest first:
# digest_response = session.post(f"{sharepoint_url}/_api/contextinfo", headers={'Accept': 'application/json'})
# digest_value = digest_response.json()['d']['GetContextWebInformation']['FormDigestValue']

# For NTLM, digest is often not strictly required for simple POSTs, but good practice.
# Let's assume we have a list named 'MyCustomList' with a 'Title' field.
custom_list_name = "MyCustomList"
new_item_data = {
    '__metadata': {'type': 'SP.Data.MyCustomListListItem'},
    'Title': 'New Item from Python'
}

# Note: The '__metadata' type needs to match your list's internal name. 
# You can find this by inspecting an existing item's metadata.
# For example, for a list named 'Tasks', it might be 'SP.Data.TasksListItem'.

try:
    headers = {
        'Accept': 'application/json',
        'Content-Type': 'application/json;odata=verbose'
        # 'X-RequestDigest': digest_value # Uncomment for SPO POST/PUT/DELETE
    }
    response = session.post(f"{sharepoint_url}/_api/web/lists/getbytitle('{custom_list_name}')/items", 
                            headers=headers, 
                            data=json.dumps(new_item_data))
    response.raise_for_status()
    created_item = response.json()
    print(f"\n--- Created New Item in '{custom_list_name}' ---")
    print(f"Item ID: {created_item['d']['Id']}, Title: {created_item['d']['Title']}")
except requests.exceptions.RequestException as e:
    print(f"Error creating item in '{custom_list_name}': {e}")
except KeyError:
    print("Could not parse created item details.")