Skip to main content

Microsoft 365 & Microsoft Graph Library for Python

Project description

office365-rest-python-client

Downloads PyPI PyPI pyversions Sponsor

Python client library for Microsoft 365 and Microsoft Graph APIs.

Covers SharePoint REST API v1, Microsoft Graph (Outlook, OneDrive, Teams, OneNote, Planner, and more), and supports all modern Azure AD authentication flows.

Python 3.8+ required.


Support

office365-rest-python-client is free and maintained in the open. Sponsorship funds security updates, new API coverage, documentation, and releases. See the roadmap for what's funded.


Table of Contents


Installation

pip install office365-rest-python-client

With uv:

uv pip install office365-rest-python-client

Latest from GitHub (includes unreleased changes):

pip install git+https://github.com/vgrem/office365-rest-python-client.git

Which client do I need?

ClientContext GraphClient
Target API SharePoint REST API v1 Microsoft Graph API
Use for SharePoint lists, files, folders, search, site admin, permissions Outlook, OneDrive, Teams, OneNote, Planner, Users, Groups
SharePoint via Graph? Partial - use ClientContext for full SharePoint fidelity
Docs SharePoint REST API Microsoft Graph

Authentication

All modern auth flows use Azure AD via the MSAL library. Legacy flows (ACS, SAML) are fully retired as of April/May 2026.

ACS retirement notice | SAML retirement MC1184649

Migrating from SAML? See examples/sharepoint/auth/modern/migrate_from_saml_to_cert.py

Two clients, different auth capabilities:

ClientContext GraphClient
Target SharePoint REST API v1 Microsoft Graph API
Resource {tenant}.sharepoint.com graph.microsoft.com

ClientContext — SharePoint auth

Flow Method User/App MFA Status Docs
Certificate (Azure AD) with_client_certificate(tenant, client_id, thumbprint, cert_path) App-only ✅ Recommended Docs
Username & password (MSAL ROPC) with_username_and_password(tenant, client_id, username, password) Delegated ✅ Supported Docs
Interactive (browser) with_interactive(tenant, client_id) Delegated ✅ Supported Docs
Device code with_device_flow(tenant, client_id) Delegated ✅ Supported Docs
NTLM (on-prem only) with_user_credentials(username, password) Delegated ✅ On-prem only Example
Client secret (Azure AD) with_client_secret(tenant, client_id, secret) App-only ❌ Not documented Microsoft's own migration guidance confirms: replace legacy ACS auth with OAuth2 client credentials flow using certificates, not client secrets, for SharePoint access.
SAML user auth with_user_credentials(username, password) Delegated 🚫 Retired May 2026 Migration guide
ACS app-only with_credentials(ClientCredential(...)) App-only 🚫 Retired Apr 2026 Notice

GraphClient — Microsoft Graph auth

Flow Method User/App MFA Status Docs
Client secret with_client_secret(client_id, secret) App-only ✅ Recommended Docs
Certificate with_client_certificate(client_id, thumbprint, key) App-only ✅ Recommended Docs
Interactive with_token_interactive(client_id) Delegated ✅ Supported Docs
Username & password with_username_and_password(client_id, username, password) Delegated ✅ Supported Docs
Custom token GraphClient(acquire_token_func) Both ✅ Supported

Azure Environments

For national and sovereign clouds, pass the environment parameter:

from office365.azure_env import AzureEnvironment
from office365.sharepoint.client_context import ClientContext

ctx = ClientContext("{site_url}", environment=AzureEnvironment.USGovernmentHigh)\
    .with_client_certificate(...)
Environment Constant
Global (default) AzureEnvironment.Global
US Government GCC AzureEnvironment.USGovernment
US Government GCC High AzureEnvironment.USGovernmentHigh
US Government DoD AzureEnvironment.USGovernmentDoD
China (21Vianet) AzureEnvironment.China
Germany (legacy) AzureEnvironment.Germany

SharePoint — ClientContext

Quick start

from office365.sharepoint.client_context import ClientContext

ctx = ClientContext("{site_url}").with_client_certificate(
    tenant="{tenant}", client_id="{client_id}",
    thumbprint="{thumbprint}", cert_path="./cert.pem"
)
web = ctx.web.get().execute_query()
print(f"Site title: {web.title}")

Lists & Items

# Get all items (handles 5000+ row threshold automatically)
items = ctx.web.lists.get_by_title("Orders").items.get_all().execute_query()
for item in items:
    print(item.properties["Title"])

# Create item
target_list = ctx.web.lists.get_by_title("Tasks")
item = target_list.add_item({"Title": "New task", "Status": "Active"}).execute_query()

# Bulk create — auto-batches in chunks of 100
for row in data:
    target_list.add_item({"Title": row["name"]})
ctx.execute_batch()

# Filter, select, expand
items = ctx.web.lists.get_by_title("Projects")\
    .items\
    .filter("Status eq 'Active'")\
    .select(["Title", "Author/Title"])\
    .expand(["Author"])\
    .get_all().execute_query()

All list examples

Files & Folders

# Upload file
with open("report.pdf", "rb") as f:
    folder = ctx.web.get_folder_by_server_relative_url("/sites/mysite/Shared Documents")
    file = folder.upload_file("report.pdf", f).execute_query()

# Download file
with open("report.pdf", "wb") as f:
    ctx.web.get_file_by_server_relative_path("/sites/mysite/Shared Documents/report.pdf")\
        .download(f).execute_query()

# Large file upload (chunked)
folder.files.create_upload_session(
    local_path, chunk_size=10*1024*1024,
    chunk_uploaded=lambda offset: print(f"{offset} bytes uploaded")
).execute_query()

# Download folder as zip
with open("archive.zip", "wb") as f:
    folder.download_folder(f).execute_query()

# Create nested folders
base = ctx.web.get_folder_by_server_relative_url("/sites/mysite/Shared Documents")
sub = base.add("Projects").execute_query()
sub.add("2025").execute_query()

All file examples | All folder examples

Search

from office365.sharepoint.search.request import SearchRequest
from office365.sharepoint.search.service import SearchService

search = SearchService(ctx)
request = SearchRequest("IsDocument:1", RowLimit=50, StartRow=0)
result = search.post_query(request).execute_query()

rows = result.value.PrimaryQueryResult.RelevantResults.Table.Rows
for row in rows:
    print(row)

All search examples

Permissions

from office365.sharepoint.roles.type import RoleType

# Break inheritance and grant access to a user
role_def = ctx.web.role_definitions.get_by_type(RoleType.Reader)
user = ctx.web.ensure_user("i:0#.f|membership|user@company.com")
item = ctx.web.lists.get_by_title("Confidential").items.get_by_id(1)
item.break_role_inheritance(copy_role_assignments=False)
item.add_role_assignment(user, role_def)
ctx.execute_query()

Permissions examples

Site Administration (Tenant)

from office365.sharepoint.tenant.administration.tenant import Tenant

tenant = Tenant(ctx)

# List all sites
sites = tenant.get_site_properties_from_sharepoint_by_filters().execute_query()
for site in sites:
    print(site.url)

# Create a site
tenant.create_site({"Url": "https://tenant.sharepoint.com/sites/newsite", "Title": "New Site"}).execute_query()

All tenant/admin examples


Microsoft Graph - GraphClient

Quick start

from office365.graph_client import GraphClient

client = GraphClient(tenant="{tenant}").with_client_secret(
    client_id="{client_id}", client_secret="{client_secret}"
)
me = client.me.get().execute_query()
print(f"Signed in as: {me.user_principal_name}")

Outlook - Mail & Calendar

# Send email
client.me.send_mail(
    subject="Hello",
    body="Message body",
    to_recipients=["user@company.com"]
).execute_query()

# List messages
messages = client.me.messages.top(10).get().execute_query()
for msg in messages:
    print(msg.subject)

# Create calendar event
from office365.outlook.calendar.events.event import Event
event = client.me.calendar.events.add(
    subject="Team standup",
    start="2025-06-01T09:00:00",
    end="2025-06-01T09:30:00"
).execute_query()

All Outlook examples

OneDrive

# List drives
drives = client.drives.get().execute_query()

# Upload file to OneDrive
with open("report.xlsx", "rb") as f:
    client.me.drive.root.upload("report.xlsx", f).execute_query()

# Download file
with open("report.xlsx", "wb") as local_file:
    client.me.drive.root.get_by_path("Documents/report.xlsx")\
        .download(local_file).execute_query()

All OneDrive examples

Teams

# List all teams
teams = client.groups.get().execute_query()

# Send channel message
client.teams["{team_id}"].channels["{channel_id}"]\
    .messages.add(body="Hello team!").execute_query()

# Create a team
new_team = client.groups["{group_id}"].add_team().execute_query()

All Teams examples

OneNote

# Create a page
with open("MyPage.html", "rb") as f:
    page = client.me.onenote.pages.add(presentation_file=f).execute_query()

All OneNote examples

Planner

# Create a task
task = client.planner.tasks.add(
    title="Review PR",
    planId="{plan_id}"
).execute_query()

All Planner examples

Users & Groups

# List users
users = client.users.top(100).get().execute_query()

# Create group
group = client.groups.add(
    display_name="Engineering",
    mail_nickname="engineering",
    mail_enabled=False,
    security_enabled=True
).execute_query()

All user examples


Dependencies

Installed automatically:

Package Purpose
requests HTTP transport
msal Azure AD authentication

Optional:

pip install office365-rest-python-client[pandas]   # to_dataframe() on collections

Contributing

PRs welcome. See issues for things to work on.

Links

Project details


Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distribution

office365_rest_python_client-3.0.0.tar.gz (949.8 kB view details)

Uploaded Source

Built Distribution

If you're not sure about the file name format, learn more about wheel file names.

office365_rest_python_client-3.0.0-py3-none-any.whl (2.9 MB view details)

Uploaded Python 3

File details

Details for the file office365_rest_python_client-3.0.0.tar.gz.

File metadata

File hashes

Hashes for office365_rest_python_client-3.0.0.tar.gz
Algorithm Hash digest
SHA256 3f95d29794ee0adc58e0b16f6574257c885c74af108e1789e4b3c286bc2ce5ac
MD5 f8910a4ac33b54a7c8d93854c063f21d
BLAKE2b-256 79636ccc58f2e20c770b9409ea5a4794aa8515e1158b23df2dd2bfe90b04aacd

See more details on using hashes here.

File details

Details for the file office365_rest_python_client-3.0.0-py3-none-any.whl.

File metadata

File hashes

Hashes for office365_rest_python_client-3.0.0-py3-none-any.whl
Algorithm Hash digest
SHA256 3432a9780febe0aa571543d21288d97ef9e0a0287aa0a5047523a65557e41932
MD5 95252cfb42007d2bb7377270dfd6d014
BLAKE2b-256 09703abd5a09c4213fc57c2b563b599ebaa05aa51a2f9b74e68c681a881f4e95

See more details on using hashes here.

Supported by

AWS Cloud computing and Security Sponsor Datadog Monitoring Depot Continuous Integration Fastly CDN Google Download Analytics Pingdom Monitoring Sentry Error logging StatusPage Status page