Skip to main content

Simple. Streaming. Resilient. MFA-ready. Fetch files from SharePoint via Microsoft Graph.

Project description

🚀 spfetch

spfetch_lg

Simple. Streaming. Resilient. MFA-ready.
List and fetch files from SharePoint via Microsoft Graph with clean APIs and cloud-native downloads.


✨ What is spfetch?

spfetch is an asynchronous Python library built for data pipelines:

  • 📂 List SharePoint folders with structured metadata.
  • ⬇️ Stream large files directly to Local Disk, S3, GCS, or Azure without memory crashes.
  • 📊 Load small files directly into Pandas DataFrames.
  • 🔐 Authenticate via MFA (Device Code) or Silent (Client Secret) flows.
  • 🛡️ Auto-Recover from Microsoft API Throttling (HTTP 429) using Exponential Backoff.

🔐 1. Authentication

Before running any workflow, you must instantiate the client with your Microsoft Entra ID (Azure AD) credentials.

Option A: Interactive / Local (Device Code Flow)

Ideal for local scripts. Supports MFA.

from spfetch.auth import DeviceCodeAuth
from spfetch.client import SharePointClient

auth = DeviceCodeAuth(tenant_id="<YOUR_TENANT_ID>", client_id="<YOUR_CLIENT_ID>")
client = SharePointClient(auth=auth)

Option B: Automated / CI-CD (Client Secret Flow)

Ideal for Airflow, Databricks, or GitHub Actions.

from spfetch.auth import ClientSecretAuth
from spfetch.client import SharePointClient

auth = ClientSecretAuth(
    tenant_id="<YOUR_TENANT_ID>", 
    client_id="<YOUR_CLIENT_ID>", 
    client_secret="<YOUR_CLIENT_SECRET>"
)
client = SharePointClient(auth=auth)

📖 2. Exploration: Listing Folders

📦 Required Installation:

pip install spfetch
import asyncio

async def list_files():
    items = await client.ls(
        hostname="<tenant>.sharepoint.com",
        site_path="/sites/<YourSite>",
        folder_path="/Shared Documents/General"
    )
    for item in items:
        print(item["name"], item["size"], item["is_folder"])

asyncio.run(list_files())

🌊 3. Ingestion Workflows

💻 Workflow A: Download to Local Disk

📦 Required Installation:

pip install spfetch
from spfetch.destinations import LocalDestination
import asyncio

async def download_local():
    # 1. Setup local destination
    dest = LocalDestination()
    
    # 2. Stream to disk
    await client.download(
        hostname="<tenant>.sharepoint.com",
        site_path="/sites/<YourSite>",
        file_path="/Shared Documents/Data/file.csv",
        dest_path="./local_downloads/file.csv",  # Local file path
        destination=dest
    )

asyncio.run(download_local())

☁️ Workflow B: Download directly to Azure (ADLS / Blob)

📦 Required Installation:

pip install "spfetch[azure]"
from spfetch.destinations import AzureDestination
import asyncio

async def download_to_azure():
    # 1. Setup Azure credentials
    dest = AzureDestination(
        account_name="<YOUR_STORAGE_ACCOUNT_NAME>",
        account_key="<YOUR_STORAGE_ACCOUNT_KEY>"  # Or sas_token="<YOUR_SAS_TOKEN>"
    )
    
    # 2. Stream directly to Azure (abfs://)
    await client.download(
        hostname="<tenant>.sharepoint.com",
        site_path="/sites/<YourSite>",
        file_path="/Shared Documents/Data/file.parquet",
        dest_path="abfs://<container_name>/bronze/file.parquet",
        destination=dest
    )

asyncio.run(download_to_azure())

☁️ Workflow C: Download directly to Amazon S3

📦 Required Installation:

pip install "spfetch[s3]"
from spfetch.destinations import S3Destination
import asyncio

async def download_to_s3():
    # 1. Setup AWS credentials
    dest = S3Destination(
        key="<AWS_ACCESS_KEY_ID>",
        secret="<AWS_SECRET_ACCESS_KEY>"
    )
    
    # 2. Stream directly to S3 (s3://)
    await client.download(
        hostname="<tenant>.sharepoint.com",
        site_path="/sites/<YourSite>",
        file_path="/Shared Documents/Data/file.csv",
        dest_path="s3://<bucket_name>/raw/file.csv",
        destination=dest
    )

asyncio.run(download_to_s3())

☁️ Workflow D: Download directly to Google Cloud Storage (GCS)

📦 Required Installation:

pip install "spfetch[gcs]"
from spfetch.destinations import GCSDestination
import asyncio

async def download_to_gcs():
    # 1. Setup GCS credentials (can use default environment or token path)
    dest = GCSDestination(
        project="<my-gcp-project-id>",
        token="google_default"  # Or path to service_account.json
    )
    
    # 2. Stream directly to GCS (gs://)
    await client.download(
        hostname="<tenant>.sharepoint.com",
        site_path="/sites/<YourSite>",
        file_path="/Shared Documents/Data/file.csv",
        dest_path="gs://<bucket_name>/raw/file.csv",
        destination=dest
    )

asyncio.run(download_to_gcs())

📊 Workflow E: Read directly to Pandas DataFrame

📦 Required Installation:

pip install "spfetch[pandas]"

Ideal for smaller files (.csv, .xlsx). This method skips saving to disk and loads the file straight into memory.

import asyncio

async def read_to_memory():
    # client.read_df accepts all standard pandas kwargs (sheet_name, sep, skiprows, etc.)
    df = await client.read_df(
        hostname="<tenant>.sharepoint.com",
        site_path="/sites/<YourSite>",
        file_path="/Shared Documents/Reports/data.xlsx",
        sheet_name="Sheet1",
        skiprows=2,
        usecols="A:D"
    )
    print(df.head())

asyncio.run(read_to_memory())

🛡️ 4. Resilience (Handling HTTP 429)

Microsoft Graph API strictly throttles heavy requests. spfetch handles this out-of-the-box.

If a 429 Too Many Requests occurs, the client automatically:

  • Pauses execution.
  • Reads the Retry-After header.
  • Applies Exponential Backoff.
  • Retries seamlessly (up to 5 times for downloads).

Your pipeline won't crash; it will simply wait and recover gracefully.


🤝 Contributing

PRs are welcome! Check our CONTRIBUTING.md. Ensure all tests pass via make test.


📄 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 Distribution

spfetch-0.1.1.tar.gz (15.2 kB view details)

Uploaded Source

Built Distribution

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

spfetch-0.1.1-py3-none-any.whl (12.8 kB view details)

Uploaded Python 3

File details

Details for the file spfetch-0.1.1.tar.gz.

File metadata

  • Download URL: spfetch-0.1.1.tar.gz
  • Upload date:
  • Size: 15.2 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/6.2.0 CPython/3.13.12

File hashes

Hashes for spfetch-0.1.1.tar.gz
Algorithm Hash digest
SHA256 8e6232a2b6fd906fca48f3c5c7d601d26e9de7b316a2ebe08b45c0d7e693f4ae
MD5 878a86dc0663854ed00755819a3b326e
BLAKE2b-256 0943bd5ae8bb52738dc394ed8901b8a60d7cae824bebef19253f588e6092635d

See more details on using hashes here.

File details

Details for the file spfetch-0.1.1-py3-none-any.whl.

File metadata

  • Download URL: spfetch-0.1.1-py3-none-any.whl
  • Upload date:
  • Size: 12.8 kB
  • Tags: Python 3
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/6.2.0 CPython/3.13.12

File hashes

Hashes for spfetch-0.1.1-py3-none-any.whl
Algorithm Hash digest
SHA256 8181e8a652d482964a15a8f4933a25db2058e2616cc0673e12ee9e968e29d55f
MD5 7ab97130bce2c707541b4bd4d75e6f67
BLAKE2b-256 ed3d4efc2a1d353dc04e9fffc626d1b5f55f37e9f1a9b77c67cb517221df4d9a

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