Skip to main content

Python SDK for Microsoft Graph API — Mail and SharePoint made simple

Project description

apigraph

Python SDK for Microsoft Graph API — interact with Mail and SharePoint using a clean, simple interface.

Features

  • Mail: list folders & subfolders, fetch messages, read content, mark as read, move between folders, create folders.
  • SharePoint: list drives, browse items, download files, move items.
  • Context manager support (with statement handles connect/disconnect automatically).
  • Structured exceptions (HttpConnectionError, MailBoxException) for predictable error handling.
  • Certificate-based authentication via MSAL.

Requirements

  • Python ≥ 3.10
  • An Azure AD App Registration with:
    • Mail.Read, Mail.ReadWrite (and/or Sites.Read.All, Sites.ReadWrite.All for SharePoint) application permissions.
    • A certificate uploaded to the App Registration.

Installation

pip install apigraph

Or from source:

git clone https://github.com/YOUR_USERNAME/apigraph.git
cd apigraph
pip install -e .

Configuration

Set the following environment variables (copy .env.example as a starting point):

Variable Description
APIGRAPH_CLIENT_ID Azure App Registration client ID
APIGRAPH_TENANT_ID Azure tenant ID
APIGRAPH_CERT_PATH Path to the private key PEM file
APIGRAPH_CERT_THUMBPRINT Certificate thumbprint (hex, no colons)
cp .env.example .env
# edit .env with your values

Quick start

from apigraph import Graphapi

with Graphapi("user@company.com") as api:
    # List mail folders
    folders = api.fetch_mail_folders()
    for f in folders["value"]:
        print(f["displayName"], "—", f["id"])

    # Fetch unread emails
    mails = api.fetch_mails(filter_read_status="unread")
    for m in mails["value"]:
        print(m["subject"])

    # Get full content of an email
    content = api.get_mail_content(api.mailbox_email, mails["value"][0]["id"])

    # Mark as read
    api.mark_as_read(mails["value"][0]["id"])

    # Move email to a folder by name
    api.move_to_folder_by_name(mails["value"][0]["id"], "Archive")

SharePoint example

from apigraph import Graphapi

SITE_ID  = "your-site-id"
DRIVE_ID = "your-drive-id"

with Graphapi("user@company.com") as api:
    drives = api.list_sharepoint_drives(SITE_ID)
    folder_id = api.get_drive_folder_by_name(DRIVE_ID, "Reports")
    items = api.list_drive_items(DRIVE_ID, folder_id)
    for item in items:
        print(item["name"])
    content = api.download_drive_item(DRIVE_ID, items[0]["id"])

API reference

Method Description
fetch_mail_folders() List all mail folders
fetch_mail_subfolders(folder_id) List subfolders of a folder
fetch_all_folders_and_subfolders() Full folder tree with IDs
fetch_mails(filter_read_status) Fetch messages (None/"read"/"unread")
fetch_mails_from_folder(mailbox, folder_id) Messages by folder ID
fetch_mails_from_folder_by_name(folder_name) Messages by folder name
mark_as_read(mail_id) Mark a message as read
move_to_folder_by_name(email_id, folder_name) Move message by folder name
move_to_folder_by_id(email_id, folder_id) Move message by folder ID
create_folder(folder_name) Create a mail folder
create_subfolder(parent_id, name) Create a subfolder
get_mail_content(mailbox, email_id, filter_query) Retrieve message content
get_mail_content_from_folder(folder, field, value) Find message by arbitrary field
get_mail_by_subject(folder_name, subject_text) Find message by subject
fetch_paginated(url) Generic paginated Graph request
list_sharepoint_drives(site_id) List drives in a site
list_sharepoint_drive_items(site_id, drive_id) Root items of a drive
list_drive_items_by_path(site_id, drive_id, path) Items at a path
list_drive_items(drive_id, folder_id) Items in a folder (paginated)
download_drive_item(drive_id, item_id) Download file bytes
get_drive_folder_by_name(drive_id, folder_name) Folder ID by name
move_drive_item(drive_id, item_id, target_folder_id) Move a drive item

Error handling

from apigraph import Graphapi, HttpConnectionError, MailBoxException

try:
    with Graphapi("user@company.com") as api:
        api.mark_as_read("bad-id")
except MailBoxException as e:
    print("Config error:", e.message, e.details)
except HttpConnectionError as e:
    print("HTTP error:", e.message, e.status_code, e.details)

Development

pip install -e ".[dev]"
pytest tests/
ruff check src/

License

MIT

Project details


Download files

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

Source Distributions

No source distribution files available for this release.See tutorial on generating distribution archives.

Built Distribution

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

apigraph-0.1.0-py3-none-any.whl (39.0 kB view details)

Uploaded Python 3

File details

Details for the file apigraph-0.1.0-py3-none-any.whl.

File metadata

  • Download URL: apigraph-0.1.0-py3-none-any.whl
  • Upload date:
  • Size: 39.0 kB
  • Tags: Python 3
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/6.2.0 CPython/3.13.3

File hashes

Hashes for apigraph-0.1.0-py3-none-any.whl
Algorithm Hash digest
SHA256 039cf7e497be1538755b88f1dcdb6dcaa9aa1b6d3e4c89dd7ebf7fd759f02e1c
MD5 6c908af24ed42db4ba7cb991c512a1de
BLAKE2b-256 32a7cbd912bd172481d11f740830746962233848fc504ba21639af0ca680c9fc

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