Pixeltable : base de données multimodale et orchestration dans un même fichier Python
The unified multimodal backend for AI data apps. Database, orchestration, and serving in one Python file.
En bref
- De quoi s’agit-il ?
- Pixeltable place les images, vidéos, audio et documents dans des tables, transforme les traitements en colonnes calculées et expose les routes HTTP depuis le même fichier. Voici ce que la documentation décrit, ce que cela remplace, et où l'outil ne convient pas.
- À qui s’adresse-t-il ?
- Adoptez Pixeltable si votre application manipule des images, vidéos, audio ou documents dans des tables et que vous voulez supprimer le code de copie entre stockage objet, base vectorielle et orchestrateur. Évitez-le si vous avez besoin d'un accès SQL direct depuis des outils externes ou si vous ne pouvez pas exécuter la CLI pxt dans votre chaîne de déploiement.
- Puis-je l’utiliser commercialement ?
- Oui. Apache-2.0 est une licence permissive : vous pouvez utiliser, modifier et vendre un logiciel qui en dépend, à condition de conserver les mentions de droit d’auteur et de licence.
- Est-il encore maintenu ?
- Oui. Les derniers commits datent d’il y a 1 jour.
- En quel langage est-il écrit ?
- Principalement Python, d’après les statistiques de langage de GitHub.
Ces réponses reposent sur les données GitHub du projet (dernière synchronisation le 15 septembre 2026) et sur notre analyse. Elles ne constituent pas un avis juridique.
ANALYSE OPEN SOURCE APPROFONDIE
Le problème : quatre systèmes à recoller pour une seule application
Une application qui traite des vidéos ou des PDF finit presque toujours par empiler les mêmes briques. Un stockage objet pour les fichiers, une base relationnelle pour les métadonnées, une base vectorielle pour les embeddings, un orchestrateur pour enchaîner les traitements, puis du code d'API qui recopie les données de l'un à l'autre. Chaque brique a son modèle de données, et la cohérence entre elles devient un travail à part entière.
Pixeltable prend le problème par l'autre bout. Le README annonce que le projet fournit « the database, orchestration, and serving layers » et que images, vidéo, audio et documents vivent dans des tables. Une transformation est une colonne calculée, un index est une déclaration, une route HTTP aussi. L'insertion d'une ligne déclenche tout ce qui en dépend. Le public visé est donc l'ingénieur qui construit une application de données multimodale ou un pipeline RAG et qui ne veut pas maintenir la glue entre quatre services.
Colonnes calculées et modèles de table : le mécanisme réel
Le fichier d'exemple du README montre deux mécanismes distincts. Une annotation, comme doc_id: pxt.Int ou title: pxt.String, désigne une valeur que vous insérez. Une affectation, comme title_upper = pxtf.string.upper(title), désigne une colonne calculée, recalculée à l'insertion et à la mise à jour. La documentation précise que le même fichier peut contenir des colonnes pxt.Image, pxt.Video, pxt.Audio ou pxt.Document, et qu'une colonne calculée au-dessus de l'une d'elles est une affectation de plus.
Les tables elles-mêmes sont déclarées comme classes héritant de TableModel, produites par pxt.model_base(). L'exemple définit Docs(TableModel, name='docs') avec les champs doc_id, title et body, puis deux colonnes calculées. Une fonction Python décorée par @pxt.udf, ici excerpt, peut être appelée par ces colonnes. Le point important est l'ordre : la déclaration décrit le graphe, et c'est l'insertion qui l'exécute. Le README résume cela par « Insert a row and everything below it runs ».
Cette architecture a une conséquence pratique. Le schéma n'est pas seulement une contrainte de stockage, c'est le programme de traitement. Modifier une colonne calculée revient à modifier le pipeline, ce qui rend la question du recalcul des valeurs existantes centrale. Le matériel fourni ne détaille pas ce comportement, et c'est un point à vérifier avant de s'engager sur un volume important.
Mise en route : les commandes pxt et leurs responsabilités
L'installation se fait par pip install 'pixeltable[serve]', puis pxt init. Le projet fournit un exemple d'application via pxt service example --out app.py. Pour créer le catalogue my_app et ses tables, la commande est pxt schema update app.py my_app. Le README insiste sur une séparation que l'on confond facilement : pxt schema update crée le catalogue et les tables mais ne démarre pas HTTP, tandis que pxt service update démarre HTTP mais ne crée pas de tables. Les deux commandes sont donc nécessaires, dans cet ordre.
Le port est attribué dynamiquement. Le README déconseille de le coder en dur et donne la méthode : URL=$(pxt service list --json | jq -r '.[0].endpoint'). L'appel de test est un POST sur $URL/docs avec un corps JSON contenant doc_id, title et body, et la réponse documentée est {"title_upper":"HELLO","summary":"Hello"}.
Pour un démarrage à partir d'un modèle, uvx pixeltable-new myapp copie une application depuis le starter kit ; la copie par défaut est une application de chat, et l'argument agent est passé à pxt schema update. L'option --video copie la recherche vidéo, avec videointel comme argument. Le README précise que l'insertion dans la table de connaissances ne demande pas de clé API, mais que la route /ask nécessite ANTHROPIC_API_KEY. Pour monter les routes sur une application FastAPI existante, app.include_router(...) est la voie indiquée.
Cloud, export SQL et la question du couplage
Pixeltable Cloud est annoncé en Limited Beta, avec une prise de contact par courriel. Le déploiement hébergé se pilote par URI. La séquence documentée est pxt db update pxt://org:mydb, puis pxt schema update app.py pxt://org:mydb, puis pxt service update app.py pxt://org:mydb. Chaque commande a un périmètre distinct : pxt db update crée ou met à jour la base hébergée mais n'insère pas de lignes, et pxt service run est local uniquement, sans possibilité de cibler le Cloud.
Deux éléments de configuration sont nommés : la variable PIXELTABLE_API_KEY, obtenue depuis le tableau de bord Cloud, et le fichier pixeltable.toml, où la base est désignée. Le matériel ne détaille pas le contenu attendu de ce fichier, ce qui laisse un flou sur la configuration exacte d'une cible distante.
Une porte de sortie existe pour les équipes qui ne veulent pas exposer HTTP. Le README indique de lancer pxt schema update, d'insérer depuis Python, puis d'utiliser export_sql. Autrement dit, les données peuvent être extraites vers une base relationnelle classique. C'est une soupape utile, mais elle transforme la table Pixeltable en source plutôt qu'en destination, et le graphe de colonnes calculées ne suit pas l'export.
La skill pour agents de codage et le piège de version
Le projet documente explicitement l'usage par des agents de codage. La commande npx skills add pixeltable/pixeltable-skill installe la skill, et get-started.md sert de playbook : installation du paquet, de la skill et de MCP. La skill 2.8.0 et suivantes écrivent un TableModel dans app.py.
Le README signale un symptôme précis : si votre agent produit du create_table dans le code applicatif, la skill installée est périmée et doit être réinstallée. Cette distinction mérite d'être lue attentivement, car elle sépare deux époques du projet. Les notebooks et les tests continuent d'utiliser pxt.create_table(), tandis qu'une application place les tables dans app.py et les crée avec pxt schema update. Un agent qui mélange les deux produit du code qui fonctionne en apparence mais qui ne suit pas le chemin de déploiement attendu.
C'est un coût de maintenance à intégrer. La surface d'API a évolué entre les deux styles, et le projet publie des versions rapprochées : v0.7.4 le 2 septembre 2026, v0.7.5 le 3 septembre, v0.7.6 le 9 septembre. Ce rythme, visible dans les releases fournies, suggère de figer une version plutôt que de suivre main en production.
Quand Pixeltable est le mauvais outil
Le choix d'enfermer le schéma, le pipeline et les routes dans un même fichier Python a un revers. Une équipe dont la base est lue par des outils externes, un client SQL, un outil de BI ou un service écrit dans un autre langage, devra passer par export_sql ou renoncer à ces accès. Le README ne décrit pas de protocole de connexion directe depuis un client tiers, et il serait imprudent de supposer qu'il en existe un.
Deuxième cas défavorable : une chaîne de déploiement qui ne peut pas exécuter la CLI pxt. Les étapes de création et de mise à jour passent par pxt schema update et pxt service update, avec des responsabilités séparées. Un environnement qui n'autorise que du code Python, sans binaire supplémentaire, devra trouver un contournement que la documentation fournie ne décrit pas.
Troisième cas : les traitements qui ne s'expriment pas comme une colonne calculée. Un pipeline dont les étapes dépendent d'un état externe, d'une validation humaine asynchrone ou d'une boucle de rétroaction ne se projette pas naturellement sur un graphe de colonnes recalculées à l'insertion. Le matériel ne montre pas de mécanisme pour interrompre ou reprendre un calcul de colonne, et c'est une limite à considérer sérieusement.
Ce qui distingue Pixeltable d'un orchestrateur classique
La comparaison la plus directe se fait avec un orchestrateur de workflows comme Airflow ou Dagster, éventuellement complété par une base vectorielle. Dans cette approche, le pipeline est un graphe de tâches planifiées, les données transitent par des artefacts ou des tables intermédiaires, et la cohérence entre le résultat d'une tâche et l'état de la base est à votre charge. Le déclenchement est temporel ou événementiel, jamais lié à une ligne.
Pixeltable inverse la relation. Le déclencheur est l'insertion d'une ligne, et la transformation est une propriété de la colonne, pas une tâche séparée. Le README présente cela comme la disparition de « object storage, a vector database, an orchestrator, and the endpoint code that copies between them ». La différence n'est pas cosmétique : dans un orchestrateur, ajouter un traitement signifie ajouter une tâche et gérer son ordonnancement ; ici, cela signifie ajouter une affectation dans la classe de table.
Le prix de cette intégration est la dépendance. Un pipeline Airflow peut être migré tâche par tâche vers un autre moteur. Un TableModel Pixeltable est lié à la sémantique de recalcul du projet, et le README ne décrit pas de format d'échange pour le graphe lui-même. export_sql exporte des données, pas la logique de colonne.
Licence, coût de mise à jour et points à vérifier
Le projet est publié sous Apache-2.0, ce qui autorise l'usage commercial et la modification. Cette licence ne couvre pas Pixeltable Cloud, qui est un service distinct en Limited Beta et dont les conditions ne figurent pas dans le matériel fourni. Un déploiement hybride, local pour le développement et Cloud pour la production, implique donc deux régimes à examiner séparément. Rien ici ne constitue un avis juridique.
Le coût de mise à jour se lit dans le rythme des publications et dans l'avertissement sur la skill. Trois versions en une semaine, et une rupture entre l'ancien create_table et le nouveau TableModel, indiquent qu'une montée de version peut demander de régénérer app.py plutôt que de simplement changer un numéro. La commande pxt schema update app.py my_app est le point où cette rupture se manifeste.
Avant adoption, trois vérifications concrètes s'imposent. D'abord, le comportement de recalcul d'une colonne calculée lorsque sa définition change, point que le README ne traite pas. Ensuite, le contenu attendu de pixeltable.toml pour une cible Cloud, nommé mais non détaillé. Enfin, la version de la skill installée, puisque toute version antérieure à 2.8.0 produit du create_table au lieu d'un TableModel.
Conclusion éditoriale
Adoptez Pixeltable si votre application manipule des images, vidéos, audio ou documents dans des tables et que vous voulez supprimer le code de copie entre stockage objet, base vectorielle et orchestrateur. Évitez-le si vous avez besoin d'un accès SQL direct depuis des outils externes ou si vous ne pouvez pas exécuter la CLI pxt dans votre chaîne de déploiement. Avant de vous engager, vérifiez trois points précis : le comportement de recalcul des colonnes calculées lors d'une modification de schéma, le contenu de pixeltable.toml et la variable PIXELTABLE_API_KEY pour une cible Cloud, et la version de la skill car une skill antérieure à 2.8.0 génère du create_table au lieu d'un TableModel.
Notes de la communauté