โ
Easy SharePoint file operations using Microsoft Graph API. ๐ค๐ผ
Download & Upload - Single files or entire folders
File Management - Create folders, move, copy, delete
Batch Operations - Process multiple files efficiently
Async Support - Full async/await API for parallel operations
Progress Callbacks - Track progress of transfers
CLI Tool - Command-line interface for quick operations
Retry & Resilience - Automatic retry with exponential backoff
Version History - List and download file versions
Sharing - Create share links with permissions
Calendar - Access Outlook/Exchange calendars and events via Microsoft Graph
pip install sharepointeasy
With progress bar support (rich):
pip install sharepointeasy[rich]
Set environment variables:
export MICROSOFT_CLIENT_ID=" your-client-id"
export MICROSOFT_CLIENT_SECRET=" your-client-secret"
export MICROSOFT_TENANT_ID=" your-tenant-id"
from sharepointeasy import SharePointClient
client = SharePointClient ()
client .download_file (
hostname = "contoso.sharepoint.com" ,
site_path = "sites/MySite" ,
file_path = "Documents/report.xlsx" ,
destination = "./report.xlsx" ,
)
client .upload_file (
hostname = "contoso.sharepoint.com" ,
site_path = "sites/MySite" ,
file_path = "Documents/new-report.xlsx" ,
source = "./local-report.xlsx" ,
)
After installation, use the sharepointeasy command:
# List sites
sharepointeasy list-sites
# List files
sharepointeasy -H contoso.sharepoint.com -S sites/MySite list Documents/
# Download file
sharepointeasy -H contoso.sharepoint.com -S sites/MySite download Documents/report.xlsx
# Upload file
sharepointeasy -H contoso.sharepoint.com -S sites/MySite upload ./report.xlsx -d Documents/
# Download entire folder
sharepointeasy -H contoso.sharepoint.com -S sites/MySite download-folder Documents/Reports
# Create folder
sharepointeasy -H contoso.sharepoint.com -S sites/MySite mkdir Documents/NewFolder -p
# Delete file
sharepointeasy -H contoso.sharepoint.com -S sites/MySite delete Documents/old-file.xlsx
# Create share link
sharepointeasy -H contoso.sharepoint.com -S sites/MySite share Documents/report.xlsx --type view
For parallel operations, use the async client:
import asyncio
from sharepointeasy import AsyncSharePointClient
async def main ():
async with AsyncSharePointClient () as client :
# Download multiple files in parallel
site = await client .get_site ("contoso.sharepoint.com" , "sites/MySite" )
drive = await client .get_drive (site ["id" ])
# Download entire folder (parallel)
await client .download_batch (
site ["id" ],
drive ["id" ],
"Documents/Reports" ,
"./local-reports" ,
max_concurrent = 10 ,
)
asyncio .run (main ())
SharePointClient (
client_id : str | None = None ,
client_secret : str | None = None ,
tenant_id : str | None = None ,
max_retries : int = 3 ,
retry_delay : float = 1.0 ,
)
Method
Description
list_sites()
List all available SharePoint sites
get_site(hostname, site_path)
Get a site by hostname and path
get_site_by_name(site_name)
Search for a site by name
Method
Description
list_drives(site_id)
List drives (document libraries) in a site
get_drive(site_id, drive_name)
Get a drive by name
Method
Description
list_files(site_id, drive_id, folder_path)
List files in a folder
list_files_recursive(site_id, drive_id, folder_path)
List all files recursively
search_file(site_id, drive_id, filename)
Search for a file by name
get_file_metadata(site_id, drive_id, file_path)
Get file metadata
Method
Description
download(site_id, drive_id, file_path, destination)
Download a file
download_batch(site_id, drive_id, folder_path, destination_dir)
Download folder recursively
download_file(hostname, site_path, file_path, destination)
Download file (simplified)
Method
Description
upload(site_id, drive_id, file_path, source)
Upload a file (auto chunked for large files)
upload_batch(site_id, drive_id, source_dir, destination_folder)
Upload folder recursively
upload_file(hostname, site_path, file_path, source)
Upload file (simplified)
Method
Description
create_folder(site_id, drive_id, folder_path)
Create a folder
create_folder_recursive(site_id, drive_id, folder_path)
Create folder with parents
delete(site_id, drive_id, file_path)
Delete a file or folder
move(site_id, drive_id, source_path, destination_folder)
Move a file or folder
copy(site_id, drive_id, source_path, destination_folder)
Copy a file or folder
Method
Description
list_versions(site_id, drive_id, file_path)
List file versions
download_version(site_id, drive_id, file_path, version_id, destination)
Download specific version
Method
Description
create_share_link(site_id, drive_id, file_path, link_type, scope)
Create share link
list_permissions(site_id, drive_id, file_path)
List file permissions
Method
Description
list_lists(site_id)
List all lists in a site
get_list(site_id, list_name)
Get a list by name or ID
get_list_columns(site_id, list_id)
Get list columns/fields
list_items(site_id, list_id, ...)
List items with filtering
list_all_items(site_id, list_id, ...)
List all items (auto-pagination)
get_item(site_id, list_id, item_id)
Get a specific item
create_item(site_id, list_id, fields)
Create a new item
update_item(site_id, list_id, item_id, fields)
Update an item
delete_item(site_id, list_id, item_id)
Delete an item
create_list(site_id, display_name, columns)
Create a new list
delete_list(site_id, list_id)
Delete a list
batch_create_items(site_id, list_id, items)
Create multiple items
batch_update_items(site_id, list_id, updates)
Update multiple items
batch_delete_items(site_id, list_id, item_ids)
Delete multiple items
Method
Description
search(query, entity_types, site_id, size)
Global search in SharePoint
search_files(query, file_extension, site_id, size)
Search files only
Method
Description
get_item_by_id(drive_id, item_id)
Get item metadata by ID
download_by_id(drive_id, item_id, destination)
Download file by ID
upload_by_id(drive_id, parent_id, filename, source)
Upload file to folder by ID
delete_by_id(drive_id, item_id)
Delete item by ID
Method
Description
list_user_calendars(user_id)
List calendars for a user
list_user_events(user_id, ...)
List events with filters (date range, subject, attendee)
list_all_user_events(user_id, ...)
List all events with auto-pagination
get_user_event(user_id, event_id)
Get a specific event by ID
search_meetings_with_attendee(user_id, attendee_email, ...)
Search meetings by attendee
Method
Description
list_teams()
List all teams
get_team(team_id)
Get team info
list_team_channels(team_id)
List team channels
get_team_drive(team_id)
Get team's drive
list_team_files(team_id, folder_path)
List files in team
list_channel_files(team_id, channel_id)
List files in channel
download_team_file(team_id, file_path, destination)
Download from team
upload_team_file(team_id, file_path, source)
Upload to team
Exception
Description
SharePointError
Base exception
AuthenticationError
Authentication failed
SiteNotFoundError
Site not found
DriveNotFoundError
Drive not found
FileNotFoundError
File not found
DownloadError
Download failed
UploadError
Upload failed
DeleteError
Delete failed
FolderCreateError
Folder creation failed
MoveError
Move/copy failed
ShareError
Share link creation failed
ListError
List operations failed
CalendarError
Calendar operations failed
EventNotFoundError
Event not found
from sharepointeasy import SharePointClient , create_progress_callback
client = SharePointClient ()
progress = create_progress_callback ("Downloading" )
client .download_file (
hostname = "contoso.sharepoint.com" ,
site_path = "sites/MySite" ,
file_path = "Documents/large-file.zip" ,
destination = "./large-file.zip" ,
progress_callback = progress ,
)
Rich progress bar (optional)
from sharepointeasy import SharePointClient , RICH_AVAILABLE
if RICH_AVAILABLE :
from sharepointeasy .utils import create_rich_progress , RichProgressCallback
client = SharePointClient ()
with create_rich_progress () as progress :
task = progress .add_task ("Downloading..." , total = 100 )
# Your download with callback...
To use this library, you need to register an app in Azure AD:
Go to Azure Portal โ Azure Active Directory โ App registrations
Click "New registration"
Name your app and click "Register"
Go to "Certificates & secrets" โ "New client secret"
Copy the secret value (this is your MICROSOFT_CLIENT_SECRET)
Go to "API permissions" โ "Add a permission" โ "Microsoft Graph"
Add these Application permissions :
Sites.Read.All - Read sites
Sites.ReadWrite.All - Read and write sites (for upload, delete, etc.)
Files.Read.All - Read files
Files.ReadWrite.All - Read and write files
Calendars.Read - Read calendars and events (for calendar features)
Click "Grant admin consent"
Your credentials:
MICROSOFT_CLIENT_ID = "Application (client) ID" on the app overview page
MICROSOFT_TENANT_ID = "Directory (tenant) ID" on the app overview page
MICROSOFT_CLIENT_SECRET = The secret value you copied
from sharepointeasy import SharePointClient
client = SharePointClient ()
sites = client .list_sites ()
for site in sites :
print (f"{ site ['displayName' ]} : { site ['webUrl' ]} " )
Download with error handling
from sharepointeasy import (
SharePointClient ,
FileNotFoundError ,
AuthenticationError ,
)
client = SharePointClient ()
try :
client .download_file (
hostname = "contoso.sharepoint.com" ,
site_path = "sites/MySite" ,
file_path = "Documents/report.xlsx" ,
destination = "./report.xlsx" ,
)
print ("Download completed!" )
except FileNotFoundError :
print ("File not found" )
except AuthenticationError :
print ("Authentication failed - check your credentials" )
Upload large file with progress
from sharepointeasy import SharePointClient , create_progress_callback
client = SharePointClient ()
# Files larger than 4MB are automatically uploaded in chunks
client .upload_file (
hostname = "contoso.sharepoint.com" ,
site_path = "sites/MySite" ,
file_path = "Backups/database.sql" ,
source = "./database.sql" ,
progress_callback = create_progress_callback ("Uploading" ),
)
from sharepointeasy import SharePointClient
client = SharePointClient ()
site = client .get_site ("contoso.sharepoint.com" , "sites/MySite" )
drive = client .get_drive (site ["id" ])
# Download all files from SharePoint folder
client .download_batch (
site ["id" ],
drive ["id" ],
"Documents/Project" ,
"./local-project" ,
)
# Upload all files to SharePoint
client .upload_batch (
site ["id" ],
drive ["id" ],
"./local-project" ,
"Documents/Project-Backup" ,
)
Working with SharePoint Lists
from sharepointeasy import SharePointClient
client = SharePointClient ()
site = client .get_site ("contoso.sharepoint.com" , "sites/MySite" )
lst = client .get_list (site ["id" ], "Tasks" )
# List items with filter
items = client .list_items (
site ["id" ],
lst ["id" ],
filter_query = "fields/Status eq 'Active'" ,
)
# Create a new item
client .create_item (site ["id" ], lst ["id" ], {
"Title" : "New Task" ,
"Status" : "Pending" ,
"Priority" : "High" ,
})
# Update an item
client .update_item (site ["id" ], lst ["id" ], "123" , {
"Status" : "Completed" ,
})
# Batch operations
client .batch_create_items (site ["id" ], lst ["id" ], [
{"Title" : "Task 1" , "Status" : "New" },
{"Title" : "Task 2" , "Status" : "New" },
{"Title" : "Task 3" , "Status" : "New" },
])
Calendar - List events and search meetings
from sharepointeasy import SharePointClient
client = SharePointClient ()
# List calendars
calendars = client .list_user_calendars ("[email protected] " )
# List events in a date range
events = client .list_user_events (
user_id = "[email protected] " ,
start_datetime = "2025-01-01T00:00:00" ,
end_datetime = "2025-12-31T23:59:59" ,
subject_contains = "weekly sync" ,
)
# Search meetings with a specific attendee
meetings = client .search_meetings_with_attendee (
user_id = "[email protected] " ,
attendee_email = "[email protected] " ,
start_datetime = "2025-01-01T00:00:00" ,
end_datetime = "2025-12-31T23:59:59" ,
)
for m in meetings :
print (f"{ m ['start' ]['dateTime' ][:10 ]} - { m ['subject' ]} " )
import asyncio
from sharepointeasy import AsyncSharePointClient
async def download_reports ():
async with AsyncSharePointClient () as client :
site = await client .get_site ("contoso.sharepoint.com" , "sites/MySite" )
drive = await client .get_drive (site ["id" ])
# Download 10 files in parallel
files = await client .download_batch (
site ["id" ],
drive ["id" ],
"Documents/Reports/2024" ,
"./reports" ,
max_concurrent = 10 ,
)
print (f"Downloaded { len (files )} files" )
asyncio .run (download_reports ())
MIT