Guide de chargement du SDK Python Frame.io

Ce guide explique comment charger des fichiers sur Frame.io à l’aide du SDK Python Frame.io (frameio). Le SDK gère le chargement en plusieurs parties vers S3 via des URL pré-signées, avec des processus parallèles, des tentatives de reconnexion automatiques et un suivi facultatif de la progression. Pour en savoir plus sur les principes généraux de l’API en matière de chargement (URL de chargement, en-têtes, fractionnement), consultez Fonctionnement des chargements locaux et distants.


Conditions préalables

1

Authentification

Vous disposez d’un client Frameio fonctionnel. Pour plus d’informations sur la configuration, consultez le Guide d’authentification.

2

Installation du SDK

pip install frameio
3

Dossier cible

Vous avez besoin de l’account_id et du folder_id correspondant au dossier dans lequel le fichier doit être chargé. Utilisez le SDK pour les trouver :

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

Démarrage rapide

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

Et voilà. Le SDK partage le fichier en blocs en fonction des URL de chargement fournies par l’API, les charge en parallèle et gère automatiquement les tentatives de reprise.


Fonctionnement

Le chargement local se passe en deux étapes :

1

Créer une ressource de fichier

Appelez client.files.create_local_upload() avec le nom et la taille du fichier. L’API crée un espace réservé de fichier et renvoie des URL PUT S3 pré-signées, à raison d’une par bloc. Le nombre d’URL (et donc de blocs) dépend de la taille du fichier.

2

Charger vers S3

FrameioUploader lit les URL pour charger le fichier depuis la réponse, divise votre fichier en blocs correspondants, puis envoie chaque bloc à son URL via une requête PUT en parallèle à l’aide d’un pool de threads. Chaque requête comprend les en-têtes requis x-amz-acl: private et Content-Type.

Ce chargement passe directement de votre application vers S3, il ne passe pas par les serveurs de l’API Frame.io. C’est le même principe que celui utilisé par des services tels que YouTube, Vimeo et Dropbox pour charger des fichiers volumineux.


Utilisation de FrameioUploader

FrameioUploader est la méthode recommandée pour charger des fichiers. Cet outil encapsule le module pour charger des blocs de bas niveau et gère tous les détails : extraction des URL de chargement à partir de la réponse de l’API, définition des en-têtes requis, découpage du fichier en blocs et chargement en parallèle.

Suivi de la progression

Utilisez la fonction de rappel on_progress pour suivre la progression du chargement :

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

La fonction de rappel est appelée une fois après l’achèvement de chaque bloc, avec le nombre cumulé d’octets chargés jusqu’à présent et la taille totale du fichier.

Barre de progression enrichie

Pour une expérience optimale dans le terminal, utilisez 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()

Configuration

FrameioUploader accepte plusieurs paramètres facultatifs :

ParamètrePar défautDescription
max_workers5Nombre de threads de chargement simultanés
en-têtes{"x-amz-acl": "private"}En-têtes envoyés avec chaque requête PUT S3. Les en-têtes personnalisés sont fusionnés avec ceux par défaut.
max_retries3Nombre de tentatives par bloc (délai d’attente exponentiel : 1 s, 2 s, 4 s…)
on_progressAucunLa fonction de rappel (bytes_uploaded, total_bytes) est déclenchée après chaque bloc
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()

Exemple complet

Un exemple complet avec authentification, chargement et suivi de la progression :

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

Si vous avez besoin d’un contrôle total sur le processus de chargement, par exemple, pour gérer manuellement le fractionnement en blocs, intégrer un pipeline asynchrone ou personnaliser la logique de tentatives, consultez Fonctionnement des chargements locaux et distants concernant le flux API brut et un exemple de script Python autonome.


Chargement à distance

Si votre fichier est déjà accessible via une URL publique, utilisez plutôt le chargement à distance. Il n’est pas nécessaire de diviser le fichier en blocs, Frame.io récupère le fichier directement :

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 est actuellement possible de charger jusqu’à 50 Go via le chargement à distance. Pour les fichiers de plus de 50 Go, veuillez utiliser le chargement local.


Vérification de l’état du chargement

Une fois le fichier chargé, vous pouvez vérifier qu’il a bien été reçu :

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