メインコンテンツへスキップ
このチュートリアルでは、Python SDKを使用してBoxにコンテンツをアップロードする2つの方法 () を取り上げます。分割アップロードには、SDKの便利なメソッドを使う方法と、アップロードセッションを自分で管理する方法があります。各方法の仕組みと、と競合処理を組み合わせて新規ファイルをアップロードしたり、既存のファイルを更新したりする方法について説明します。
メソッド最適な用途最小サイズ最大サイズ
サイズの小さいファイル、シンプルなワークフロー下限なし50 MB
サイズの大きいファイル20 MB上限なし
このチュートリアルのコードサンプルでは、 を使用しています。

前提条件

  • Boxアプリケーションで [] スコープ (root_readwrite) が有効になっている
  • コンピュータにPython 3.8以降がインストールされている
  • Box Python SDKがインストールされている (pip install "boxsdk~=10")
  • が認証済みである

直接アップロード

ファイルをアップロードするには、upload_fileメソッドを呼び出します。直接アップロードAPIの詳細については、を参照してください。 最初にを実行します。同名のファイルがすでに存在する場合は、エラーレスポンスに競合ファイルのIDが含まれます。その名前のファイルのコンテンツを上書きしたくない場合は、名前を変更して新規ファイルとしてアップロードします。以下のサンプルでは、ファイルのコンテンツを上書きする必要があると想定し、そのIDを使用してをアップロードしています。
Python v10
import os

from box_sdk_gen import (
    BoxAPIError,
    PreflightFileUploadCheckParent,
    UploadFileAttributes,
    UploadFileAttributesParentField,
    UploadFileVersionAttributes,
)


def upload_file_or_file_version(client, file_path, folder_id):
    file_size = os.path.getsize(file_path)
    file_name = os.path.basename(file_path)

    with open(file_path, "rb") as file_stream:
        try:
            client.uploads.preflight_file_upload_check(
                name=file_name,
                size=file_size,
                parent=PreflightFileUploadCheckParent(id=folder_id),
            )
            files = client.uploads.upload_file(
                UploadFileAttributes(
                    name=file_name,
                    parent=UploadFileAttributesParentField(id=folder_id),
                ),
                file_stream,
            )
            return files.entries[0]
        except BoxAPIError as err:
            if err.response_info.code != "item_name_in_use":
                raise
            file_id = err.response_info.context_info["conflicts"]["id"]
            file_stream.seek(0)
            files = client.uploads.upload_file_version(
                file_id,
                UploadFileVersionAttributes(name=file_name),
                file_stream,
            )
            return files.entries[0]
フォルダでupload_fileを呼び出すと新規ファイルが作成されます。既存ファイルでupload_file_versionを呼び出すと新しいバージョンがアップロードされます。

分割アップロード

20 MB以上のファイルにはを使用します。各分割アップロードはを通じて行われます。アップロードセッションでは、セッションを作成して、し、することでファイルを確定します。これには、2つの方法があります。
  • 便利なメソッド: upload_big_fileを使用すると、3つのステップすべてが自動で行われます。
  • 手動のアップロードセッション: 詳細な制御が必要な場合は、セッションの作成、各パーツのアップロード、コミットを自分で行います。

便利なメソッド

upload_big_fileメソッドを使用すると、パーツ単位でファイルが自動的にアップロードされます。アップロード開始前に名前の競合を処理できるよう、最初に事前チェックを実行します。同名のファイルがすでに存在する場合は、upload_chunked_fileによって既存ファイル用のセッションが作成され、次のセクションで示すようにupload_file_via_sessionヘルパーによって新しいバージョンがアップロードされます。
Python v10
import os

from box_sdk_gen import BoxAPIError, PreflightFileUploadCheckParent


def upload_chunked_file(client, file_path, folder_id):
    file_size = os.path.getsize(file_path)
    file_name = os.path.basename(file_path)
    parent = PreflightFileUploadCheckParent(id=folder_id)

    try:
        client.uploads.preflight_file_upload_check(
            name=file_name,
            size=file_size,
            parent=parent,
        )
        with open(file_path, "rb") as file_stream:
            return client.chunked_uploads.upload_big_file(
                file_stream, file_name, file_size, folder_id
            )

    except BoxAPIError as err:
        if err.response_info.code != "item_name_in_use":
            raise

        file_id = err.response_info.context_info["conflicts"]["id"]
        upload_session = (
            client.chunked_uploads.create_file_upload_session_for_existing_file(
                file_id, file_size, file_name
            )
        )
        return upload_file_via_session(
            client, file_path, file_size, upload_session
        )

手動のアップロードセッション

アップロードを詳細に制御するには、自分でセッションを管理します。自分が渡したセッションについて、upload_file_via_sessionヘルパーによってすべてのパートがアップロードされ、セッションがコミットされます。
Python v10
import base64
import hashlib
from io import BytesIO

from box_sdk_gen import UploadPart


def upload_file_via_session(client, file_path, file_size, upload_session):
    file_sha1 = hashlib.sha1()
    parts: list[UploadPart] = []

    upload_part_url = upload_session.session_endpoints.upload_part
    commit_url = upload_session.session_endpoints.commit

    with open(file_path, "rb") as file_stream:
        part_size = upload_session.part_size
        for part_num in range(upload_session.total_parts):
            offset = part_num * part_size
            remaining = file_size - offset
            chunk_size = min(part_size, remaining)
            chunk = file_stream.read(chunk_size)

            part_sha1 = hashlib.sha1(chunk).digest()
            digest = f"sha={base64.b64encode(part_sha1).decode()}"
            content_range = (
                f"bytes {offset}-{offset + len(chunk) - 1}/{file_size}"
            )

            uploaded_part = client.chunked_uploads.upload_file_part_by_url(
                upload_part_url,
                BytesIO(chunk),
                digest,
                content_range,
            )
            parts.append(uploaded_part.part)
            file_sha1.update(chunk)

    content_sha1 = file_sha1.digest()
    digest = f"sha={base64.b64encode(content_sha1).decode()}"
    files = client.chunked_uploads.create_file_upload_session_commit_by_url(
        commit_url, parts, digest
    )
    return files.entries[0]
セッションの作成は、ヘルパーを呼び出す前に行います。最初に事前チェックを実行してから、create_file_upload_sessionを使用して新しいファイルを作成します。同名のファイルがすでに存在する場合、upload_file_manualcreate_file_upload_session_for_existing_fileにフォールバックして新しいバージョンをアップロードします。
Python v10
import os

from box_sdk_gen import BoxAPIError, PreflightFileUploadCheckParent


def upload_file_manual(client, file_path, folder_id):
    file_size = os.path.getsize(file_path)
    file_name = os.path.basename(file_path)
    parent = PreflightFileUploadCheckParent(id=folder_id)

    try:
        client.uploads.preflight_file_upload_check(
            name=file_name,
            size=file_size,
            parent=parent,
        )
        upload_session = client.chunked_uploads.create_file_upload_session(
            folder_id, file_size, file_name
        )
    except BoxAPIError as err:
        if err.response_info.code != "item_name_in_use":
            raise

        file_id = err.response_info.context_info["conflicts"]["id"]
        upload_session = (
            client.chunked_uploads.create_file_upload_session_for_existing_file(
                file_id, file_size, file_name
            )
        )

    return upload_file_via_session(
        client, file_path, file_size, upload_session
    )

リソース

最終更新日 2026年7月1日