로컬 및 원격 업로드 작동 방식

이 가이드에서는 Frame.io V4 API를 사용하여 파일을 업로드하는 전체 과정을 자세히 설명합니다. 로컬 및 원격 업로드 모두에 대한 원시 API 요청과 응답을 다룹니다.

SDK 전용 가이드가 필요하신가요? 청킹, 재시도, 진행률 추적 기능이 내장된 업로드 연동에 대해서는 Python SDK 업로드 가이드를 참조하세요.

사전 요구 사항

파일 업로드를 시작하기 전에 다음 설정 단계를 완료했는지 확인하세요.

1

Frame.io V4 계정

Adobe Admin Console을 통해 관리되는 Frame.io V4 계정이 있거나, 계정 사용자를 위해 Adobe 인증으로 전환했습니다.

2

Adobe Developer Console 설정

Adobe Developer Console에 로그인하여 신규 또는 기존 프로젝트에 Frame.io API를 추가했습니다.

3

인증 자격 증명

프로젝트에 적합한 인증 자격 증명을 생성했습니다.

4

액세스 토큰

해당 자격 증명을 사용하여 액세스 토큰을 성공적으로 생성했습니다.

업로드 방법 선택

Frame.io API를 사용하여 파일을 업로드하는 방법에는 파일 생성(로컬 업로드)파일 생성(원격 업로드) 두 가지가 있습니다.

로컬 업로드

바탕 화면에서 파일을 드래그하는 것과 같이 애플리케이션에서 미디어에 로컬로 액세스할 수 있는 경우에 사용합니다.

원격 업로드

다른 서비스와의 연동 등 네트워크를 통해 미디어에 액세스할 때 사용합니다.

이 가이드에서는 원격 업로드를 완료하는 더 간단한 사례부터 살펴보겠습니다.

원격 업로드

원격 업로드를 통해 파일을 생성하려면 파일 생성(원격 업로드) 엔드포인트를 선택합니다. 요청 본문에는 파일 이름과 소스 URL이 필요합니다.

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

요청 예시

1{
2 "data": {
3 "name": "my_file.jpg",
4 "source_url": "https://upload.wikimedia.org/wikipedia/commons/e/e1/White_Pixel_1x1.jpg"
5 }
6}

응답 예시

요청에 성공하면 다음과 같은 응답이 생성됩니다.

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

로컬 업로드

로컬 업로드를 통해 파일을 생성하려면 파일 생성(로컬 업로드) 엔드포인트를 선택합니다. 요청 본문에는 파일 이름과 바이트 단위로 지정된 파일 크기가 필요합니다.

요청 예시

1{
2 "data": {
3 "name": "my_file.jpg",
4 "file_size": 50645990
5 }
6}

응답 예시

요청에 성공하면 콘텐츠가 없는 자리 표시자 파일 리소스가 생성됩니다. 파일 크기에 따라 응답 본문에는 하나 이상의 upload_urls가 포함됩니다. 이 예시의 경우 해당 업로드를 여러 부분으로 나누어 관리해야 합니다.

1{
2 "data": {
3 "id": "fa18ba7b-b3ee-4dd6-9b31-bd07e554241d",
4 "name": "my_file.jpg",
5 "status": "created",
6 "type": "file",
7 "file_size": 50645990,
8 "updated_at": "2025-06-26T20:08:06.823170Z",
9 "media_type": "image/jpeg",
10 "parent_id": "2e426fe0-f965-4594-8b2b-b4dff1dc00ec",
11 "project_id": "7e46e495-4444-4555-8649-bee4d391a997",
12 "created_at": "2025-06-26T20:08:06.751313Z",
13 "upload_urls": [
14 {
15 "size": 16881997,
16 "url": "https://frameio-uploads-development.s3-accelerate.amazonaws.com/parts/fa18ba7b-b3ee-4dd6-9b31-bd07e554241d/part_1?..."
17 },
18 {
19 "size": 16881997,
20 "url": "https://frameio-uploads-development.s3-accelerate.amazonaws.com/parts/fa18ba7b-b3ee-4dd6-9b31-bd07e554241d/part_2?..."
21 },
22 {
23 "size": 16881996,
24 "url": "https://frameio-uploads-development.s3-accelerate.amazonaws.com/parts/fa18ba7b-b3ee-4dd6-9b31-bd07e554241d/part_3?..."
25 }
26 ],
27 "view_url": "https://next.frame.io/project/7e46e495-4444-4555-8649-bee4d391a997/view/fa18ba7b-b3ee-4dd6-9b31-bd07e554241d"
28 }
29}

중요 업로드 요구 사항.

후속 업로드 요청을 보낼 때 다음의 중요한 세부 사항을 유의해야 합니다.

  • HTTP 요청 메서드는 PUT이어야 합니다.
  • x-amz-acl 헤더가 포함되어야 하며 private으로 설정해야 합니다.
  • Content-Type 헤더는 원래의 파일 생성(로컬 업로드) 요청에 지정된 media_type과 일치해야 합니다. 이는 파일을 여러 부분으로 나누어 업로드할 때도 마찬가지입니다. 위 예시에서 media_type의 값은 image/jpeg입니다. 따라서 Content-Type의 값도 image/jpeg여야 합니다.

멀티파트 업로드

지정된 파일이 둘 이상의 업로드 URL을 반환하는 경우 소스 파일을 청크로 분할하고 각 청크에 대해 PUT 요청을 실행해야 합니다.

권장 사항:Python SDK 업로드 가이드에서는 청킹, 병렬 업로드, 재시도, 진행률 추적을 기본으로 처리하는 FrameioUploader를 사용한 멀티파트 업로드 방법을 다룹니다.

SDK가 없는 언어나 프로세스를 완전히 제어하기 위해 업로드를 수동으로 구현해야 하는 경우 아래 스크립트는 파일을 청크로 분할하고 사전 서명된 URL을 사용하여 각 청크를 업로드하는 방법을 보여 줍니다.

Python 구현 예제

멀티파트 업로드 스크립트
1import requests
2import math
3from typing import List
4from tqdm import tqdm # For progress bar
5
6def upload_file_in_chunks(file_path: str, upload_urls: list[str], content_type: str | None = None, chunk_size: int | None = None) -> bool:
7 """
8 Upload a file in chunks using presigned URLs.
9 """
10 try:
11 # Auto-detect content type based on file extension
12 if content_type is None:
13 detected_content_type, _ = mimetypes.guess_type(file_path)
14 content_type = detected_content_type # Default fallback
15
16 print(f"Detected content type: {content_type}")
17
18 # Get file size
19 with open(file_path, 'rb') as f:
20 f.seek(0, 2) # Seek to end of file
21 file_size = f.tell()
22
23 # Calculate chunk size if not provided
24 if chunk_size is None:
25 chunk_size = math.ceil(file_size / len(upload_urls))
26
27 print(f"File size: {file_size} bytes")
28 print(f"Chunk size: {chunk_size} bytes")
29 print(f"Number of chunks: {len(upload_urls)}")
30
31 # Upload each chunk
32 with open(file_path, 'rb') as f:
33 with tqdm(total=len(upload_urls), desc="Uploading chunks") as pbar:
34 for i, url in enumerate(upload_urls):
35 start_byte = i * chunk_size
36 end_byte = min(start_byte + chunk_size, file_size)
37
38 # Read chunk from file
39 f.seek(start_byte)
40 chunk = f.read(end_byte - start_byte)
41
42 print(f"Uploading chunk {i+1}: {len(chunk)} bytes")
43
44 # Upload chunk with minimal headers matching the signature
45 response = requests.put(
46 url,
47 data=chunk,
48 headers={
49 'content-type': content_type,
50 'x-amz-acl': 'private'
51 }
52 )
53
54 if response.status_code != 200:
55 print(f"Failed to upload chunk {i+1}. Status code: {response.status_code}")
56 print(f"Response text: {response.text}")
57 print(f"Response headers: {dict(response.headers)}")
58 return False
59 else:
60 print(f"Chunk {i+1} uploaded successfully!")
61
62 pbar.update(1)
63
64 return True
65
66 except Exception as e:
67 print(f"Error during upload: {str(e)}")
68 return False
69
70# Example usage
71if __name__ == "__main__":
72 # Replace these with your actual values
73 file_path = "/Users/MyComputer/local_upload/sample.jpg" # Path to your file
74 upload_urls = [
75 "https://frameio-uploads-development.s3-accelerate.amazonaws.com/parts/fa18ba7b-b3ee-4dd6-9b31-bd07e554241d/part_1?...",
76 "https://frameio-uploads-development.s3-accelerate.amazonaws.com/parts/fa18ba7b-b3ee-4dd6-9b31-bd07e554241d/part_2?...",
77 "https://frameio-uploads-development.s3-accelerate.amazonaws.com/parts/fa18ba7b-b3ee-4dd6-9b31-bd07e554241d/part_3?..."
78 ]
79 content_type = "image/jpeg"
80
81 print("Starting file upload...")
82 success = upload_file_in_chunks(file_path, upload_urls, content_type)
83
84 if success:
85 print("File upload completed successfully!")
86 else:
87 print("File upload failed!")

업로드 흐름 요약

1

업로드 방법 선택

원격 업로드(URL을 통해 액세스할 수 있는 파일) 또는 로컬 업로드(시스템에 있는 파일) 중에서 선택

2

파일 생성 요청

필요한 메타데이터로 파일 리소스를 생성하기 위한 초기 요청 수행

3

업로드 URL 처리

로컬 업로드의 경우 반환된 upload_urls(단일 또는 여러 파트)를 처리합니다.

4

파일 콘텐츠 업로드

적절한 헤더를 포함한 PUT 요청을 사용하여 제공된 URL에 파일 콘텐츠를 업로드합니다.

5

업로드 확인

파일 상태를 확인하여 업로드와 처리가 성공적으로 완료되었는지 확인합니다.

다음 단계: 파일이 업로드되면 반환된 파일 ID를 활용해 Frame.io V4 API로 코멘트를 추가하거나, 공유를 생성하거나, 기타 작업을 수행할 수 있습니다.