> This page is for プラットフォーム, version V4 (default).
> For other versions, use one of these documentation indexes:
> - V4 (default): https://next.developer.frame.io/platform/v4/llms.txt
> - V4 Experimental: https://next.developer.frame.io/platform/v4-experimental/llms.txt
> - レガシー: https://next.developer.frame.io/platform/v2/llms.txt

> For clean Markdown of any page, append .md to the page URL.
> For a complete documentation index, see https://next.developer.frame.io/llms.txt.
> For AI client integration (Claude Code, Cursor, etc.), connect to the MCP server at https://next.developer.frame.io/_mcp/server.

# ローカルおよびリモートアップロードの仕組み

このガイドでは、Frame.io V4 API を使用してファイルをアップロードするための完全なフローを詳しく説明します。

## 前提条件

ファイルのアップロードを開始する前に、次の設定手順が完了していることを確認してください。

#### Frame.io V4 アカウント

[Adobe Admin Console](https://adminconsole.adobe.com/jp) を介して管理されている Frame.io V4 アカウントがあるか、アカウントユーザーの [Adobe 認証に切り替え](https://help.frame.io/ja/articles/11758018-connecting-to-adobe-authentication) 済みである

#### Adobe Developer Console の設定

[Adobe Developer Console](https://developer.adobe.com/console) にログインし、Frame.io API を新規または既存のプロジェクトに追加した

#### 認証資格情報

プロジェクトの [適切な認証資格情報](https://developer.adobe.com/frameio/guides/Authentication/) を生成済みである

#### アクセストークン

これらの認証情報を使用してアクセストークンを正常に生成した

## アップロードメソッドの選択

Frame.io API を使用してファイルをアップロードするには、次の 2 つの方法、`Create File (local upload)` および `Create File (remote upload)` があります。

#### ローカルアップロード

デスクトップからファイルをドラッグするのと同様に、メディアがアプリケーションにローカルでアクセスできる場合に使用します

#### リモートアップロード

別のサービスとの統合など、ネットワーク経由でメディアにアクセスする場合に使用します

このガイドでは、リモートアップロードを完了する簡単なケースから始めます。

## リモートアップロード

リモートアップロードを使用してファイルを作成するには、**Create File (remote upload)** エンドポイントを選択します。リクエスト本文には、ファイル名とそのソース URL が必要です。

### 要求の例

```json
{ 
    "data": {
        "name": "my_file.jpg",
        "source_url": "https://upload.wikimedia.org/wikipedia/commons/e/e1/White_Pixel_1x1.jpg"
    }
}
```

### レスポンスの例

要求が成功すると、次のようなレスポンスが返されます。

```json
{
    "data": {
        "id": "93e4079d-0a8a-4bf3-96cd-e6a03c465e5e",
        "name": "my_file.jpg",
        "status": "created",
        "type": "file",
        "file_size": 518,
        "updated_at": "2025-06-26T20:14:33.796116Z",
        "media_type": "image/jpeg",
        "parent_id": "2e426fe0-f965-4594-8b2b-b4dff1dc00ec",
        "project_id": "7e46e495-4444-4555-8649-bee4d391a997",
        "created_at": "2025-06-26T20:14:33.159489Z",
        "view_url": "https://next.frame.io/project/7e46e495-4444-4555-8649-bee4d391a997/view/93e4079d-0a8a-4bf3-96cd-e6a03c465e5e"
    },
    "links": {
        "status": "/v4/accounts/6f70f1bd-7e89-4a7e-b4d3-7e576585a181/files/93e4079d-0a8a-4bf3-96cd-e6a03c465e5e/status"
    }
}
```

## ローカルアップロード

ローカルアップロードを使用してファイルを作成するには、**Create File (local upload)** エンドポイントを選択します。リクエスト本文には、ファイル名とそのファイルサイズをバイト単位で指定する必要があります。

### 要求の例

```json
{ 
    "data": {
        "name": "my_file.jpg",
        "file_size": 50645990
    }
}
```

### レスポンスの例

要求が成功すると、コンテンツが含まれないプレースホルダーのファイルリソースが作成されます。ファイルサイズに応じて、応答本文には 1 つ以上の `upload_urls` が含まれます。この例では、このアップロードを複数のパートで管理する必要があります。

```json
{
    "data": {
        "id": "fa18ba7b-b3ee-4dd6-9b31-bd07e554241d",
        "name": "my_file.jpg",
        "status": "created",
        "type": "file",
        "file_size": 50645990,
        "updated_at": "2025-06-26T20:08:06.823170Z",
        "media_type": "image/jpeg",
        "parent_id": "2e426fe0-f965-4594-8b2b-b4dff1dc00ec",
        "project_id": "7e46e495-4444-4555-8649-bee4d391a997",
        "created_at": "2025-06-26T20:08:06.751313Z",
        "upload_urls": [
            {
                "size": 16881997,
                "url": "https://frameio-uploads-development.s3-accelerate.amazonaws.com/parts/fa18ba7b-b3ee-4dd6-9b31-bd07e554241d/part_1?..."
            },
            {
                "size": 16881997,
                "url": "https://frameio-uploads-development.s3-accelerate.amazonaws.com/parts/fa18ba7b-b3ee-4dd6-9b31-bd07e554241d/part_2?..."
            },
            {
                "size": 16881996,
                "url": "https://frameio-uploads-development.s3-accelerate.amazonaws.com/parts/fa18ba7b-b3ee-4dd6-9b31-bd07e554241d/part_3?..."
            }
        ],
        "view_url": "https://next.frame.io/project/7e46e495-4444-4555-8649-bee4d391a997/view/fa18ba7b-b3ee-4dd6-9b31-bd07e554241d"
    }
}
```

> **Warning**
>
> **重要なアップロード要件：**
>
> 後続のアップロード要求を送信する際には、次の重要な点に注意する必要があります。
>
> * HTTP 要求メソッドは `PUT` である必要があります
> * `x-amz-acl` ヘッダーを含め、「private」に設定する必要があります
> * `Content-Type` ヘッダーは、元の **Create File (local upload)** 要求で指定された `media_type` と一致する必要があります。これは、ファイルを個別の部分としてアップロードする場合でも該当します。上記の例では、`media_type` の値は `image/jpeg` です。したがって、`Content-Type` の値も `image/jpeg` である必要があります。

## マルチパートアップロード

特定のファイルが複数のアップロード URL になる場合、ソースファイルをチャンクに分割し、同じ数の後続する要求を発行するシェルスクリプトを作成すると便利です。

以下の Python スクリプトのサンプルでは、`upload_urls` パラメーターに複数のアップロード URL を渡しています。

### Python の実装例

**`Multi-part Upload Script`**

```python title="Multi-part Upload Script"
import requests
import math
from typing import List
from tqdm import tqdm  # For progress bar

def upload_file_in_chunks(file_path: str, upload_urls: list[str], content_type: str | None = None, chunk_size: int | None = None) -> bool:
    """
    Upload a file in chunks using presigned URLs.
    """
    try:
        # Auto-detect content type based on file extension
        if content_type is None:
            detected_content_type, _ = mimetypes.guess_type(file_path)
            content_type = detected_content_type # Default fallback

        print(f"Detected content type: {content_type}")

        # Get file size
        with open(file_path, 'rb') as f:
            f.seek(0, 2)  # Seek to end of file
            file_size = f.tell()

        # Calculate chunk size if not provided
        if chunk_size is None:
            chunk_size = math.ceil(file_size / len(upload_urls))

        print(f"File size: {file_size} bytes")
        print(f"Chunk size: {chunk_size} bytes")
        print(f"Number of chunks: {len(upload_urls)}")

        # Upload each chunk
        with open(file_path, 'rb') as f:
            with tqdm(total=len(upload_urls), desc="Uploading chunks") as pbar:
                for i, url in enumerate(upload_urls):
                    start_byte = i * chunk_size
                    end_byte = min(start_byte + chunk_size, file_size)

                    # Read chunk from file
                    f.seek(start_byte)
                    chunk = f.read(end_byte - start_byte)

                    print(f"Uploading chunk {i+1}: {len(chunk)} bytes")

                    # Upload chunk with minimal headers matching the signature
                    response = requests.put(
                        url,
                        data=chunk,
                        headers={
                            'content-type': content_type,  
                            'x-amz-acl': 'private'       
                        }
                    )

                    if response.status_code != 200:
                        print(f"Failed to upload chunk {i+1}. Status code: {response.status_code}")
                        print(f"Response text: {response.text}")
                        print(f"Response headers: {dict(response.headers)}")
                        return False
                    else:
                        print(f"Chunk {i+1} uploaded successfully!")

                    pbar.update(1)

        return True

    except Exception as e:
        print(f"Error during upload: {str(e)}")
        return False

# Example usage
if __name__ == "__main__":
    # Replace these with your actual values
    file_path = "/Users/MyComputer/local_upload/sample.jpg"  # Path to your file
    upload_urls = [
        "https://frameio-uploads-development.s3-accelerate.amazonaws.com/parts/fa18ba7b-b3ee-4dd6-9b31-bd07e554241d/part_1?...", 
        "https://frameio-uploads-development.s3-accelerate.amazonaws.com/parts/fa18ba7b-b3ee-4dd6-9b31-bd07e554241d/part_2?...", 
        "https://frameio-uploads-development.s3-accelerate.amazonaws.com/parts/fa18ba7b-b3ee-4dd6-9b31-bd07e554241d/part_3?..."
    ]
    content_type = "image/jpeg"

    print("Starting file upload...")
    success = upload_file_in_chunks(file_path, upload_urls, content_type)

    if success:
        print("File upload completed successfully!")
    else:
        print("File upload failed!")
```

## アップロードフローの要約

#### アップロードメソッドの選択

リモートアップロード（URL 経由でアクセス可能なファイル）またはローカルアップロード（システム上のファイル）のいずれかを選択します

#### ファイル要求の作成

必要なメタデータを使用して、ファイルリソースを作成するための最初の要求を作成します

#### アップロード URL の処理

ローカルアップロードの場合は、返された upload\_urls を処理します（単一または複数のパート）

#### ファイルのコンテンツのアップロード

適切なヘッダーを持つ PUT 要求を使用して、指定された URL にファイルのコンテンツをアップロードします

#### アップロードの検証

ファイルのステータスを確認して、アップロードと処理が正常に完了したことを確認します

> **Info**
>
> **次の手順**：ファイルのアップロード後、返されたファイル ID を使用して、コメントの追加、共有の作成、または Frame.io V4 API を使用したその他の操作を実行できます。