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 modern data pipelines:

  • ๐Ÿ“‚ List SharePoint folders with structured metadata
  • โฌ‡๏ธ Stream large files directly to Local Disk, S3, GCS, or Azure without memory crashes
  • โšก Smart Buffering โ€“ Control chunk and buffer sizes to optimize Cloud I/O (50+ MB/s)
  • ๐Ÿ“Š 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) with Exponential Backoff

๐Ÿš€ Performance Benchmark (v0.1.3)

Zero Intermediate Disk Architecture + Smart Buffering

Benchmark Results

  • Payload: 10.10 GB CSV (SharePoint โžก Azure Data Lake)
  • Time: 3m 11s (191.96s)
  • Average Speed: 53.87 MB/s
  • Config: chunk_size_mb=1 | buffer_size_mb=100

๐Ÿ” 1. Authentication

Instantiate the client using 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, 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. Telemetry & Dual Progress Bar

By default, spfetch does not override your logging configuration (uses NullHandler).

To enable structured logs and dual progress bars:

import asyncio
from spfetch.auth import ClientSecretAuth
from spfetch.client import SharePointClient
from spfetch.destinations import LocalDestination
from spfetch import enable_console_logs # <-- Add this line

enable_console_logs() # <-- Add this line

async def main():
    auth = ClientSecretAuth(
        tenant_id="YOUR_TENANT_ID",
        client_id="YOUR_CLIENT_ID",
        client_secret="YOUR_CLIENT_SECRET"
    )

    client = SharePointClient(auth=auth)
    destination = LocalDestination()

    await client.download(
        hostname="your_company.sharepoint.com",
        site_path="/sites/YourSite",
        file_path="/Folder/your_file.csv",
        dest_path="./data/your_file.csv",
        destination=destination
    )

if __name__ == "__main__":
    asyncio.run(main())

๐Ÿ–ฅ๏ธ Expected Terminal Output

๐Ÿš€ [INGESTรƒO STREAMING | STREAMING INGESTION] Started at: YYYY-MM-DD HH:MM:SS
๐Ÿ“ Destination: <DestinationClass> -> path/to/file.ext (Chunk: 1MB | Buffer: 16MB)
๐Ÿ“‚ Source: /path/in/sharepoint/file.ext (X.XX GB)

๐Ÿ“ฅ Reading | Leitura: 100%|โ–ˆโ–ˆโ–ˆโ–ˆโ–ˆโ–ˆโ–ˆโ–ˆโ–ˆโ–ˆโ–ˆโ–ˆโ–ˆโ–ˆโ–ˆ| X.XXG/X.XXG [MM:SS<00:00, XX.XMB/s]
๐Ÿ“ค Saving | Salvando: 100%|โ–ˆโ–ˆโ–ˆโ–ˆโ–ˆโ–ˆโ–ˆโ–ˆโ–ˆโ–ˆโ–ˆโ–ˆโ–ˆโ–ˆโ–ˆ| X.XXG/X.XXG [MM:SS<00:00, XX.XMB/s]

-------------------------------------------------------
โœ… INGESTION COMPLETED SUCCESSFULLY
โฑ Total Time: XXX.XXs
โšก Average Speed: XX.XX MB/s
๐Ÿ Finished at: YYYY-MM-DD HH:MM:SS
-------------------------------------------------------

๐Ÿ“– 3. Exploration โ€“ Listing Folders

๐Ÿ“ฆ 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())

๐ŸŒŠ 4. Ingestion Workflows


โ˜๏ธ A) Azure (ADLS / Blob)

๐Ÿ“ฆ Installation:

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

async def download_to_azure():
    destination = AzureDestination(
        account_name="<YOUR_STORAGE_ACCOUNT_NAME>",
        account_key="<YOUR_STORAGE_ACCOUNT_KEY>"
    )

    await client.download(
        hostname="<tenant>.sharepoint.com",
        site_path="/sites/<YourSite>",
        file_path="/Shared Documents/Data/file.parquet",
        dest_path="abfs://<container>/bronze/file.parquet",
        destination=destination,
        chunk_size_mb=1,
        buffer_size_mb=100
    )

asyncio.run(download_to_azure())

โ˜๏ธ B) Amazon S3

๐Ÿ“ฆ Installation:

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

async def download_to_s3():
    destination = S3Destination(
        key="<AWS_ACCESS_KEY_ID>",
        secret="<AWS_SECRET_ACCESS_KEY>"
    )

    await client.download(
        hostname="<tenant>.sharepoint.com",
        site_path="/sites/<YourSite>",
        file_path="/Shared Documents/Data/file.csv",
        dest_path="s3://<bucket>/raw/file.csv",
        destination=destination,
        chunk_size_mb=1,
        buffer_size_mb=16
    )

asyncio.run(download_to_s3())

โ˜๏ธ C) Google Cloud Storage (GCS)

๐Ÿ“ฆ Installation:

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

async def download_to_gcs():
    destination = GCSDestination(
        project="<my-gcp-project-id>",
        token="google_default"
    )

    await client.download(
        hostname="<tenant>.sharepoint.com",
        site_path="/sites/<YourSite>",
        file_path="/Shared Documents/Data/file.csv",
        dest_path="gs://<bucket>/raw/file.csv",
        destination=destination
    )

asyncio.run(download_to_gcs())

๐Ÿ’ป D) Local Disk

๐Ÿ“ฆ Installation:

pip install spfetch
from spfetch.destinations import LocalDestination
import asyncio

async def download_local():
    destination = LocalDestination()

    await client.download(
        hostname="<tenant>.sharepoint.com",
        site_path="/sites/<YourSite>",
        file_path="/Shared Documents/Data/file.csv",
        dest_path="./local_downloads/file.csv",
        destination=destination
    )

asyncio.run(download_local())

๐Ÿ“Š E) Read Directly to Pandas

๐Ÿ“ฆ Installation:

pip install "spfetch[pandas]"
import asyncio

async def read_to_memory():
    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())

๐Ÿ›ก๏ธ 5. Resilience โ€“ Handling HTTP 429

spfetch automatically handles Microsoft Graph throttling.

If HTTP 429 Too Many Requests occurs:

  1. Execution pauses
  2. Retry-After header is read
  3. Exponential Backoff is applied
  4. Retries up to 5 times

Your pipeline will wait and recover gracefully instead of crashing.


๐Ÿค Contributing

Pull Requests are welcome.

Before submitting:

make test

Ensure all tests pass.


๐Ÿ“„ License

MIT License

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.3.tar.gz (16.0 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.3-py3-none-any.whl (13.4 kB view details)

Uploaded Python 3

File details

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

File metadata

  • Download URL: spfetch-0.1.3.tar.gz
  • Upload date:
  • Size: 16.0 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.3.tar.gz
Algorithm Hash digest
SHA256 004c39f1372fb5bd2c46254a9da8539ed216dd9aa68ff1272ea929c06f039cd8
MD5 f5d995a711bb190c62c2028d080d2d58
BLAKE2b-256 ea4a7765de7f322c8442f6c967b47facbb4ca0b4d3bf11290dbb3f16caa22d13

See more details on using hashes here.

File details

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

File metadata

  • Download URL: spfetch-0.1.3-py3-none-any.whl
  • Upload date:
  • Size: 13.4 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.3-py3-none-any.whl
Algorithm Hash digest
SHA256 8711c71bb091e657d114ac53dd6a3eac5521e312f8d606e25d8cff521c8423e2
MD5 0cb637d256ebb0ee6d9a562b3395cd0f
BLAKE2b-256 b942f1885df1c0920a576951e4501a3fd4f3658900378d1ee54750f4bfe59bc8

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