SDK Python Frame.io — Guida al caricamento

Questa guida spiega come caricare i file in Frame.io usando l’SDK Python Frame.io (frameio). L’SDK gestisce caricamenti multi-parte basati su chunk verso S3 tramite URL pre-firmati, con worker paralleli, nuovi tentativi automatici e tracciamento facoltativo dello stato di avanzamento. Per i concetti generali dell’API di caricamento (URL di caricamento, intestazioni, suddivisione in chunk), consulta Come funzionano i caricamenti locali e remoti.


Prerequisiti

1

Autenticazione

Hai un client Frameio funzionante. Consulta la guida all’autenticazione per informazioni sulla configurazione.

2

Installa l'SDK

pip install frameio
3

Cartella di destinazione

Hai bisogno dell’account_id e del folder_id in cui deve essere caricato il file. Usa l’SDK per trovarli:

# List your accounts
accounts = client.accounts.index()
account_id = accounts.data[0].id
# List workspaces in the account
workspaces = client.workspaces.index(account_id=account_id)
workspace_id = workspaces.data[0].id
# List projects in the workspace
projects = client.projects.index(account_id=account_id, workspace_id=workspace_id)
project = projects.data[0]
# The project's root folder is the top-level upload target
folder_id = project.root_folder_id
# Or list subfolders to upload into a specific one
folders = client.folders.list(account_id=account_id, folder_id=folder_id)

Avvio rapido

import os
from frameio import Frameio
from frameio.files import FileCreateLocalUploadParamsData
from frameio.upload import FrameioUploader
client = Frameio(token="YOUR_TOKEN")
file_path = "/path/to/video.mp4"
file_size = os.path.getsize(file_path)
# 1. Create the file resource and get pre-signed upload URLs
response = client.files.create_local_upload(
account_id="YOUR_ACCOUNT_ID",
folder_id="YOUR_FOLDER_ID",
data=FileCreateLocalUploadParamsData(
name="video.mp4",
file_size=file_size,
),
)
# 2. Upload the file to S3
with open(file_path, "rb") as f:
FrameioUploader(response.data, f).upload()

Ecco fatto. L’SDK suddivide il file in chunk in base agli URL di caricamento restituiti dall’API, li carica in parallelo e gestisce automaticamente i nuovi tentativi.


Come funziona

Il caricamento locale è un processo in due fasi:

1

Crea una risorsa di file

Chiama client.files.create_local_upload() con il nome e la dimensione del file. L’API crea un file segnaposto e restituisce URL PUT S3 pre-firmati, uno per chunk. Il numero di URL (e perciò di chunk) dipende dalla dimensione del file.

2

Carica in S3

FrameioUploader legge gli URL di caricamento dalla risposta, suddivide il file in chunk corrispondenti e invia ciascun chunk al rispettivo URL in parallelo utilizzando un pool di thread. Ogni richiesta include le intestazioni obbligatorie x-amz-acl: private e Content-Type.

Il caricamento avviene direttamente dalla tua applicazione a S3, senza passare attraverso i server dell’API Frame.io. È lo stesso schema utilizzato da servizi come YouTube, Vimeo e Dropbox per il caricamento di file di grandi dimensioni.


Utilizzo di FrameioUploader

FrameioUploader è il modo consigliato per caricare file. Racchiude l’uploader basato su chunk a livello inferiore e gestisce tutti i dettagli: estrazione degli URL di caricamento dalla risposta dell’API, impostazione delle intestazioni richieste, suddivisione del file in chunk e caricamento in parallelo.

Tracciamento dello stato di avanzamento

Utilizza il callback on_progress per tenere traccia dello stato di avanzamento del caricamento:

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

Il callback viene richiamato una volta dopo il completamento di ogni chunk, con i byte cumulativi caricati finora e la dimensione totale del file.

Barra di avanzamento avanzata

Per un’esperienza avanzata del terminale, utilizza Rich:

from rich.progress import Progress, BarColumn, DownloadColumn, TransferSpeedColumn, TimeRemainingColumn
with Progress(
"[progress.description]{task.description}",
BarColumn(),
DownloadColumn(),
TransferSpeedColumn(),
TimeRemainingColumn(),
) as progress:
task = progress.add_task("Uploading...", total=file_size)
with open(file_path, "rb") as f:
FrameioUploader(
response.data, f,
on_progress=lambda done, total: progress.update(task, completed=done),
).upload()

Configurazione

FrameioUploader accetta diversi parametri opzionali:

ParametroPredefinitoDescrizione
max_workers5Numero di thread di caricamento simultanei
headers{"x-amz-acl": "private"}Intestazioni inviate con ogni richiesta PUT S3. Le intestazioni personalizzate vengono unite a quelle predefinite.
max_retries3Tentativi di ripetizione per chunk (backoff esponenziale: 1s, 2s, 4s …)
on_progressNoneCallback (bytes_uploaded, total_bytes) attivato dopo ogni chunk
with open(file_path, "rb") as f:
FrameioUploader(
response.data,
f,
max_workers=10, # more parallelism for high-bandwidth connections
max_retries=5, # more resilient on flaky networks
on_progress=on_progress,
).upload()

Esempio completo

Un esempio completo con autenticazione, caricamento e tracciamento dello stato di avanzamento:

import os
from frameio import Frameio
from frameio.auth import ServerToServerAuth
from frameio.files import FileCreateLocalUploadParamsData
from frameio.upload import FrameioUploader
# Authenticate
auth = ServerToServerAuth(
client_id="YOUR_CLIENT_ID",
client_secret="YOUR_CLIENT_SECRET",
)
client = Frameio(token=auth.get_token)
# Prepare the file
file_path = "/path/to/video.mp4"
file_name = os.path.basename(file_path)
file_size = os.path.getsize(file_path)
# Create the file resource
response = client.files.create_local_upload(
account_id="YOUR_ACCOUNT_ID",
folder_id="YOUR_FOLDER_ID",
data=FileCreateLocalUploadParamsData(
name=file_name,
file_size=file_size,
),
)
print(f"Uploading {file_name} ({file_size:,} bytes) in {len(response.data.upload_urls)} chunks...")
# Upload with progress
def on_progress(uploaded: int, total: int) -> None:
print(f"\r{uploaded / total:.0%}", end="", flush=True)
with open(file_path, "rb") as f:
FrameioUploader(response.data, f, on_progress=on_progress).upload()
print(f"\nDone! View at: {response.data.view_url}")

Se hai bisogno del controllo completo sul processo di caricamento (ad esempio per gestire manualmente i chunk, integrare una pipeline asincrona o personalizzare la logica di ripetizione), consulta Come funzionano i caricamenti locali e remoti per conoscere il flusso completo dell’API e vedere un esempio di script Python autonomo.


Caricamento remoto

Se il file è già accessibile tramite URL pubblico, usa il caricamento remoto. La suddivisone in chunk non è necessaria perché Frame.io recupera il file direttamente:

from frameio.files import FileCreateRemoteUploadParamsData
response = client.files.create_remote_upload(
account_id="YOUR_ACCOUNT_ID",
folder_id="YOUR_FOLDER_ID",
data=FileCreateRemoteUploadParamsData(
name="video.mp4",
source_url="https://example.com/video.mp4",
),
)
print(f"File created: {response.data.id}")

Il caricamento remoto ha attualmente un limite di dimensione del file di 50 GB. Per file più grandi di 50 GB, utilizza il caricamento locale.


Verifica dello stato di caricamento

Dopo il caricamento, puoi verificare che il file sia stato ricevuto:

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