Frame.io Python SDK — 업로드 가이드

이 가이드는 Frame.io Python SDK(frameio)를 사용하여 Frame.io에 파일을 업로드하는 방법을 설명합니다. SDK는 병렬 작업자, 자동 재시도, 선택적 진행률 추적 기능과 함께 미리 서명된 URL을 통해 S3에 청크된 멀티파트 업로드를 처리합니다. 일반적인 업로드 API 개념(업로드 URL, 헤더, 청킹)에 대해서는 로컬 및 원격 업로드 작동 방식을 참조하세요.


필수 조건

1

인증

작동하는 Frameio 클라이언트가 있어야 합니다. 설정하려면 인증 안내서를 참조하세요.

2

SDK 설치

$ pip install frameio
3

대상 폴더

파일을 업로드할 위치의 account_idfolder_id가 필요합니다. SDK를 사용하여 찾으세요.

1 # List your accounts
2 accounts = client.accounts.index()
3 account_id = accounts.data[0].id
4
5 # List workspaces in the account
6 workspaces = client.workspaces.index(account_id=account_id)
7 workspace_id = workspaces.data[0].id
8
9 # List projects in the workspace
10 projects = client.projects.index(account_id=account_id, workspace_id=workspace_id)
11 project = projects.data[0]
12
13 # The project's root folder is the top-level upload target
14 folder_id = project.root_folder_id
15
16 # Or list subfolders to upload into a specific one
17 folders = client.folders.list(account_id=account_id, folder_id=folder_id)

빠른 시작

1import os
2from frameio import Frameio
3from frameio.files import FileCreateLocalUploadParamsData
4from frameio.upload import FrameioUploader
5
6client = Frameio(token="YOUR_TOKEN")
7
8file_path = "/path/to/video.mp4"
9file_size = os.path.getsize(file_path)
10
11# 1. Create the file resource and get pre-signed upload URLs
12response = client.files.create_local_upload(
13 account_id="YOUR_ACCOUNT_ID",
14 folder_id="YOUR_FOLDER_ID",
15 data=FileCreateLocalUploadParamsData(
16 name="video.mp4",
17 file_size=file_size,
18 ),
19)
20
21# 2. Upload the file to S3
22with open(file_path, "rb") as f:
23 FrameioUploader(response.data, f).upload()

이것이 전부입니다. SDK는 API가 반환한 업로드 URL을 기반으로 파일을 청크로 분할하고 이를 병렬로 업로드하며 재시도를 자동으로 처리합니다.


작동 방식

로컬 업로드는 2단계 프로세스입니다.

1

파일 리소스 생성

파일 이름 및 크기와 함께 client.files.create_local_upload()를 호출합니다. API는 자리 표시자 파일을 생성하고 미리 서명된 S3 PUT URL을 청크당 하나씩 반환합니다. URL(및 청크)의 수는 파일 크기에 따라 달라집니다.

2

S3에 업로드

FrameioUploader는 응답에서 업로드 URL을 읽고 파일을 일치하는 청크로 분할한 다음, 스레드 풀을 사용하여 각 청크를 해당 URL에 병렬로 PUT 요청합니다. 각 요청에는 필수인 x-amz-acl: privateContent-Type 헤더가 포함됩니다.

업로드는 애플리케이션에서 S3로 직접 전달되며, Frame.io API 서버를 거치지 않습니다. 이는 대용량 파일 업로드를 위해 YouTube, Vimeo, Dropbox와 같은 서비스에서 사용하는 것과 동일한 패턴입니다.


FrameioUploader 사용

FrameioUploader는 파일 업로드를 위해 권장되는 방법입니다. 이는 하위 수준의 청크 업로더를 래핑하며, API 응답에서 업로드 URL 추출, 필수 헤더 설정, 파일 청킹, 병렬 업로드 등 모든 세부 사항을 처리합니다.

진행률 추적

업로드 진행률을 추적하려면 on_progress 콜백을 사용하세요.

1def on_progress(bytes_uploaded: int, total_bytes: int) -> None:
2 pct = bytes_uploaded / total_bytes * 100
3 print(f"\r{pct:.1f}% ({bytes_uploaded:,} / {total_bytes:,} bytes)", end="", flush=True)
4
5with open(file_path, "rb") as f:
6 FrameioUploader(response.data, f, on_progress=on_progress).upload()
7
8print("\nUpload complete!")

이 콜백은 각 청크가 완료된 후 한 번씩 호출되며, 지금까지 업로드된 누적 바이트 수와 총 파일 크기가 전달됩니다.

Rich 진행률 표시줄

세련된 터미널 환경을 원한다면 Rich 라이브러리를 사용해 보세요.

1from rich.progress import Progress, BarColumn, DownloadColumn, TransferSpeedColumn, TimeRemainingColumn
2
3with Progress(
4 "[progress.description]{task.description}",
5 BarColumn(),
6 DownloadColumn(),
7 TransferSpeedColumn(),
8 TimeRemainingColumn(),
9) as progress:
10 task = progress.add_task("Uploading...", total=file_size)
11
12 with open(file_path, "rb") as f:
13 FrameioUploader(
14 response.data, f,
15 on_progress=lambda done, total: progress.update(task, completed=done),
16 ).upload()

구성

FrameioUploader는 몇 가지 선택적 매개변수를 허용합니다.

매개 변수Default설명
max_workers5동시 업로드 스레드 수
headers{"x-amz-acl": "private"}모든 S3 PUT 요청과 함께 전송되는 헤더입니다. 사용자 지정 헤더는 기본값과 병합됩니다.
max_retries3청크당 재시도 시도 횟수(지수 백오프: 1초, 2초, 4초, …)
on_progressNone각 청크 후 실행되는 콜백(bytes_uploaded, total_bytes)입니다.
1with open(file_path, "rb") as f:
2 FrameioUploader(
3 response.data,
4 f,
5 max_workers=10, # more parallelism for high-bandwidth connections
6 max_retries=5, # more resilient on flaky networks
7 on_progress=on_progress,
8 ).upload()

전체 예시

인증, 업로드, 진행률 추적이 포함된 전체 예시입니다.

1import os
2from frameio import Frameio
3from frameio.auth import ServerToServerAuth
4from frameio.files import FileCreateLocalUploadParamsData
5from frameio.upload import FrameioUploader
6
7# Authenticate
8auth = ServerToServerAuth(
9 client_id="YOUR_CLIENT_ID",
10 client_secret="YOUR_CLIENT_SECRET",
11)
12client = Frameio(token=auth.get_token)
13
14# Prepare the file
15file_path = "/path/to/video.mp4"
16file_name = os.path.basename(file_path)
17file_size = os.path.getsize(file_path)
18
19# Create the file resource
20response = client.files.create_local_upload(
21 account_id="YOUR_ACCOUNT_ID",
22 folder_id="YOUR_FOLDER_ID",
23 data=FileCreateLocalUploadParamsData(
24 name=file_name,
25 file_size=file_size,
26 ),
27)
28
29print(f"Uploading {file_name} ({file_size:,} bytes) in {len(response.data.upload_urls)} chunks...")
30
31# Upload with progress
32def on_progress(uploaded: int, total: int) -> None:
33 print(f"\r{uploaded / total:.0%}", end="", flush=True)
34
35with open(file_path, "rb") as f:
36 FrameioUploader(response.data, f, on_progress=on_progress).upload()
37
38print(f"\nDone! View at: {response.data.view_url}")

청킹을 수동으로 처리하거나, 비동기 파이프라인과 연동하거나, 재시도 로직을 사용자 지정하는 등 업로드 프로세스에 대한 완전한 제어가 필요한 경우 원시 API 흐름 및 독립형 Python 스크립트 예시에 대한 로컬 및 원격 업로드 작동 방식을 참조하세요.


원격 업로드

파일이 이미 퍼블릭 URL을 통해 액세스할 수 있는 상태라면 원격 업로드를 대신 사용하세요. 청킹이 필요하지 않습니다. Frame.io가 파일을 직접 가져옵니다.

1from frameio.files import FileCreateRemoteUploadParamsData
2
3response = client.files.create_remote_upload(
4 account_id="YOUR_ACCOUNT_ID",
5 folder_id="YOUR_FOLDER_ID",
6 data=FileCreateRemoteUploadParamsData(
7 name="video.mp4",
8 source_url="https://example.com/video.mp4",
9 ),
10)
11print(f"File created: {response.data.id}")

현재 원격 업로드의 파일 크기 제한은 50GB입니다. 50GB보다 큰 파일의 경우 로컬 업로드를 사용하세요.


업로드 상태 확인

업로드 후 파일이 수신되었는지 확인할 수 있습니다.

1status = client.files.show_file_upload_status(
2 account_id="YOUR_ACCOUNT_ID",
3 file_id=response.data.id,
4)
5print(f"Upload complete: {status.data.upload_complete}")