注記
本記事は、以下の GitHub リポジトリにあるオリジナル記事を、筆者が日本語に翻訳・加筆したものです。
Copy-SharePoint-To-OneLake-LakehouseFiles(GitHub)
Intro
このリポジトリは、SharePoint フォルダー内の内容(サブフォルダーを含む)を OneLake(Lakehouse Files)へ再帰的にコピーする Python ベースのソリューションを提供します。認証には MSAL、SharePoint データへのアクセスには Microsoft Graph を使用します。実行中のノートブックは、対象サイトに対して別アプリへの 最小権限(Sites.Selected) 付与も行え、将来の自動化でも安全に同一サイトへアクセスできるようにします。
ソースコードはこちら:
sharepoint-to-onelake-recursive-copy.py
なぜ SharePoint Online から Fabric OneLake(Lakehouse Files)へコピーするのか?
分析は OneLake に集約されます。チームは日常的に PDF、画像、CSV、アドホックな書き出しを SharePoint に置きますが、ダッシュボードやノートブック、パイプラインは Fabric 上で動きます。SharePoint → OneLake(/Files)に取り込むことで次の利点があります。
- Fabric エンジン(Spark / SQL / セマンティックモデル)が読める場所にデータを一元化できます。OneLake は各 Fabric テナントに自動で含まれる「データの OneDrive」です。
- 手作業ではなくスケジュールで自動取り込みできます。
- Sites.Selected により最小権限を維持し、付与した特定サイトだけをアプリが見られるようにできます。
作るもの(全体像)
App A(ノートブック) ── MSAL トークン ──> Microsoft Graph
│
├─ siteId を解決 (/sites/{host}:/sites/{path})
├─ 対象サイトに App B への Sites.Selected(最小権限)付与を確認/実施
├─ 'Documents' ドライブを特定
├─ 対象フォルダーとサブフォルダーの子を再帰列挙
└─ 各ファイルをダウンロード(GET @microsoft.graph.downloadUrl)
──> Fabric Lakehouse へ書き込み /Files/<site>/<folder>/...(notebookutils/mssparkutils で base64)
前提条件
- ノートブックにアタッチされた Fabric Lakehouse(/Files 用)。
- Entra アプリを 2 つ用意:
- App A:ノートブックの呼び出し元(Graph トークン取得)。
- App B:SharePoint サイトに Sites.Selected で明示的に付与する最小権限アプリ。
Microsoft Entra ID アプリ登録のクイック準備
-
App A と App B を登録
Entra 管理センター → App registrations → New registration。Application (client) ID と Directory (tenant) ID を控えます。 -
App A のクライアント シークレット作成(または証明書)
App A → Certificates & secrets → New client secret。表示は一度きりなので値を控えます。 -
App A / App B の API アクセス許可
ノートブックの設定
Cell 1 — Parameters で次を設定:
# ── App A: このノートブックが Microsoft Graph を呼び出すためのアプリ(クライアント・クレデンシャル・フロー)
GRAPH_APP_CLIENT_ID = "<App A - Client ID>"
GRAPH_APP_CLIENT_SECRET = "<App A - Client Secret>"
GRAPH_TENANT_ID = "<Tenant (Directory) ID>"
# ── SharePoint テナント & サイト(URL から)
SP_TENANT_HOST = "MySharePoint.sharepoint.com"
SP_SITE_PATH = "MySites123" # /sites/ の後ろ
SP_TARGET_FOLDER_PATH = "01_MyFolders" # 'Documents' ライブラリ内。深い階層は "A/B/C" と表記
# ── App B: 対象サイトに GRANT する(Sites.Selected の付与先)2 つ目のアプリ
TARGET_APP_CLIENT_ID = "<App B - Client ID>"
TARGET_APP_DISPLAY = "MySite123-SharePoint-Access"
# ── App A にも(当面のコピー実行用に)付与したい場合は True(403 回避に有用)
GRANT_CALLER_APP_TOO = True
# ── Lakehouse Files の出力先
LAKEHOUSE_FILES_ROOT = "Files" # Fabric Lakehouse の "Files"(変更しない)
LAKEHOUSE_SITE_FOLDER = SP_SITE_PATH # サイトごとにサブフォルダーで整理
※ マッピング例(SharePoint からコピーする対象ファイル):
https://MySharePoint.sharepoint.com/sites/MySites123/Shared Documents/01_MyFolders/image1.png
→
SP_TENANT_HOST="MySharePoint.sharepoint.com",
SP_SITE_PATH="MySites123",
SP_TARGET_FOLDER_PATH="01_MyFolders"
仕組み(ステップごとの流れ)
-
MSAL をインストール
最初のセルでpip install msal。 -
Graph トークン取得(App A)
MSAL client credentials → acquire_token_for_client(scopes=["https://graph.microsoft.com/.default"]) -
サイト解決
GET /sites/{hostname}:/sites/{sitePath}で後続呼び出しで使うsiteIdを取得。 -
サイト アクセス付与(Sites.Selected)
- 既存のサイト権限一覧:
GET /sites/{siteId}/permissions。 - App B が無ければ作成:
POST /sites/{siteId}/permissions("roles": ["write"]と App B の client id を指定)。 - 必要なら App A にも付与して、ノートブックが即コピーできるようにします。
- Microsoft Learn
- 既存のサイト権限一覧:
-
“Documents” ドライブ特定
GET /sites/{siteId}/drives→documentLibraryで名前が “Documents”(ローカライズ環境では最初のライブラリ等)を選択。 -
対象フォルダー解決
GET /drives/{driveId}/root:/{SP_TARGET_FOLDER_PATH}でフォルダーの item id を取得。 -
再帰的にファイル列挙
深さ優先でGET /drives/{driveId}/items/{folderItemId}/childrenを辿り、ページングは@odata.nextLinkを追跡。サブフォルダーは再帰。 -
各ファイルのダウンロード
@microsoft.graph.downloadUrlを用いてバイト列を取得(短時間有効の事前認証 URL)。 -
Lakehouse /Files へ書き込み
- SharePoint の構造を次のようにミラーします:
Files/<site>/<SP_TARGET_FOLDER_PATH>/<subfolders...>/<filename> -
notebookutils.fs.mkdirs(...)でディレクトリ作成、 -
mssparkutils.fs.put(...)でテキストのみ対応のため Base64 文字列として書き込みます。 - Microsoft Learn
- Microsoft Learn
- SharePoint の構造を次のようにミラーします:
-
ログ
各ファイルについて、正確なマッピングを示すコメント行を出力します(例):
# COPY: SP 'Documents/01.folder/.../file' -> Lakehouse 'Files/<site>/01.folder/.../file'
実行手順
- Fabric でノートブックを開き、Lakehouse をアタッチ。
- Cell 1 — Parameters を自分の値に編集。
- 上から順にセルを実行。
- Lakehouse → Files で想定どおりのパス/ファイルが作成されているか確認。
自動実行のオプション
運用化(Operationalize):
- ノートブックを Fabric Data Pipeline に組み込み、スケジュール トリガーを設定、または
- ノートブックのスケジュール機能を使用(ワークスペースのガバナンス方針に従う)。
いずれの方法でも、SharePoint から OneLake への再現可能な Pull が構築できます。
セキュリティに関する注意点
- テナント全体の Sites.Read.All ではなく Sites.Selected を優先し、影響範囲を最小化しましょう。手順は 2 段階:(a)アプリに許可を追加、(b)特定サイトへのアクセスを割り当て(本ノートブックは (b) を実施)。
- クライアント シークレットは定期的にローテーションし、可能なら証明書認証を検討。
- シークレットは可能な限り Fabric ワークスペースの資格情報 / Key Vault に保存(ノートブック内のハードコーディングは避ける)。
参考情報
-
MSAL (Python) – acquire_token_for_client
https://learn.microsoft.com/en-us/entra/msal/python/getting-started/acquiring-tokens -
パスで SharePoint サイト取得 (/sites/{hostname}:/{relative-path})
https://learn.microsoft.com/en-us/graph/api/site-getbypath?view=graph-rest-1.0 -
フォルダーの子一覧 (/drives/{drive-id}/items/{item-id}/children)
https://learn.microsoft.com/en-us/graph/api/driveitem-list-children?view=graph-rest-1.0 -
DriveItem とダウンロード (/drives/{drive-id}/items/{item-id}, /content)
https://learn.microsoft.com/en-us/graph/api/driveitem-get?view=graph-rest-1.0 -
サイト権限の作成(POST /sites/{site-id}/permissions)
https://learn.microsoft.com/en-us/graph/api/site-list-permissions?view=graph-rest-1.0 -
Selected permissions(Sites.Selected)概要
https://learn.microsoft.com/en-us/sharepoint/dev/solution-guidance/security-apponly-azuread -
NotebookUtils / MSSparkUtils(ファイルシステム API)
https://learn.microsoft.com/en-us/fabric/data-engineering/notebook-utilities