Frame.io Python SDK - Guia para fazer upload

Este guia explica como fazer upload de arquivos para o Frame.io usando o Frame.io Python SDKK (frameio). O SDK processa uploads fragmentados em blocos para o S3 por meio de URLs pré-assinadas, com workers paralelos, novas tentativas automáticas e rastreamento de progresso opcional. Para obter conceitos gerais da API de upload, como URLs para fazer upload, cabeçalhos e divisão em blocos, consulte Como funcionam os uploads locais e remotos.


Pré-requisitos

1

Autenticação

Você tem um cliente Frameio funcionando. Consulte o Guia de autenticação para configuração.

2

Instalar o SDK

$ pip install frameio
3

Pasta de destino

Você precisa do account_id e folder_id onde o arquivo deve receber upload. Use o SDK para encontrá-los:

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)

Início rápido

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()

É isso. O SDK divide o arquivo em blocos com base nas URLs para fazer upload retornadas pela API, faz upload deles em paralelo e processa novas tentativas automaticamente.


Como funciona

Fazer upload local é um processo em duas etapas:

1

Criar recurso de arquivo

Chame client.files.create_local_upload() com o nome e o tamanho do arquivo. A API cria um arquivo placeholder e retorna URLs S3 PUT pré-assinadas, uma por bloco. O número de URLs e, portanto, de blocos depende do tamanho do arquivo.

2

Fazer upload para o S3

FrameioUploader lê as URLs para fazer upload da resposta, divide o arquivo em blocos correspondentes e faz PUT de cada bloco na respectiva URL em paralelo usando um pool de threads. Cada solicitação inclui os cabeçalhos obrigatórios x-amz-acl: private e Content-Type.

O upload vai diretamente do seu aplicativo para o S3; ele não passa pelos servidores da API do Frame.io. Esse é o mesmo padrão usado por serviços como YouTube, Vimeo e Dropbox para fazer upload de arquivos grandes.


Uso do FrameioUploader

FrameioUploader é a forma recomendada de fazer upload de arquivos. Ele encapsula o uploader em blocos de nível inferior e processa todos os detalhes: extrair URLs para fazer upload da resposta da API, definir os cabeçalhos obrigatórios, dividir o arquivo em blocos e fazer upload em paralelo.

Rastreamento de progresso

Use o callback on_progress para rastrear o progresso do upload:

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!")

O callback é invocado uma vez após a conclusão de cada bloco, com os bytes cumulativos cujo upload foi feito até o momento e o tamanho total do arquivo.

Barra de progresso Rich

Para uma experiência refinada no terminal, use 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()

Configuração

FrameioUploader aceita vários parâmetros opcionais:

ParâmetroPadrãoDescrição
max_workers5Número de threads simultâneas para fazer upload
headers{"x-amz-acl": "private"}Cabeçalhos enviados com cada solicitação S3 PUT. Cabeçalhos personalizados são mesclados com os padrões.
max_retries3Tentativas de repetição por bloco (backoff exponencial: 1s, 2s, 4s, …)
on_progressNenhumCallback (bytes_uploaded, total_bytes) disparado após cada bloco
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()

Exemplo completo

Um exemplo completo com autenticação, upload e rastreamento de progresso:

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}")

Se precisar de controle total sobre o processo de fazer upload, por exemplo, para lidar manualmente com a divisão em blocos, integrar com um pipeline async ou personalizar a lógica de nova tentativa, consulte Como funcionam os uploads locais e remotos para ver o fluxo bruto da API e um exemplo de script Python independente.


Fazer upload remoto

Se o arquivo já estiver acessível por meio de uma URL pública, use o upload remoto. Não é necessário dividir em blocos. O Frame.io busca o arquivo diretamente:

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}")

No momento, o upload remoto tem um limite de tamanho de arquivo de 50 GB. Para arquivos maiores que 50 GB, use upload local.


Verificação do status do upload

Após fazer upload, você pode verificar se o arquivo foi recebido:

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}")