Synthèse automatique
Génère un script Python utilisant le SDK bauplan pour ingérer en toute sécurité des données depuis S3 selon le schéma Write-Audit-Publish, via une branche temporaire.
Points forts
- Applique une séparation claire Write/Audit/Publish sur une branche éphémère, jamais sur main
- Utilise les fusions atomiques multi-tables de merge_branch pour un chargement tout-ou-rien
- Expose des paramètres explicites pour le comportement en cas de succès (inspect/merge) et d'échec (keep/delete)
- Fournit un template de script complet avec assertions de sécurité (branche/table inexistante)
Limites
- Le SKILL.md fourni est tronqué : le template s'arrête au milieu de la phase Audit
- Spécifique à bauplan et au SDK Python ; ne couvre pas d'autres moteurs ou l'usage en CLI
- Suppose une source S3 et une inférence de schéma automatique, sans gestion détaillée des transformations ou schémas explicites
À utiliser lorsqu'il faut charger des fichiers parquet/csv/jsonl depuis S3 dans bauplan de manière sûre avec des contrôles qualité avant publication.
À éviter pour des écritures directes sur main, des sources non-S3, ou des workflows hors de l'écosystème bauplan.
Analyse de sécurité
PrudenceThe skill uses the bauplan SDK to interact with a remote data platform, including creating branches, importing data from S3, and optionally merging to main. These are legitimate operations but involve network access and potential modification of production data. The main concern is the unsanitized f-string SQL query, which is a minor injection risk. No destructive or exfiltrating instructions are present.
- •Template builds SQL query using f-string with user-provided table name and namespace, which could allow SQL injection if untrusted input is used.
- •The script can merge changes to the main branch and delete branches if the user selects those options, potentially modifying production data.
- •The skill declares Bash as an allowed tool but instructs to avoid CLI commands; no dangerous shell commands are present.
Exemples
Ingest s3://my-bucket/events/*.parquet into a table called events_raw in bauplan using the WAP pattern, keeping the branch for inspection on success.Use wap-ingestion to load s3://data-lake/orders/*.jsonl into namespace analytics as orders, and automatically merge to main on success.Write a WAP script that ingests sales and returns parquet files from S3 into bauplan, deleting the branch on failure but keeping it open on success.name: wap-ingestion description: "Ingest data from S3 into bauplan using the Write-Audit-Publish pattern for safe data loading. Use when loading new data from S3, performing safe data ingestion, or when the user mentions WAP, data ingestion, importing parquet/csv/jsonl files, or needs to safely load data with quality checks." allowed-tools:
- Read
- Write
- Glob
- Grep
- Bash
- WebFetch(domain:docs.bauplanlabs.com)
Write-Audit-Publish (WAP) Pattern
Implement WAP by writing a Python script using the bauplan SDK. Do NOT use CLI commands.
The three steps: Write (ingest to temp branch) → Audit (quality checks) → Publish (merge to main)
Branch safety: All operations happen on a temporary branch, NEVER on main. By default, branches are kept open for inspection after success or failure.
Atomic multi-table operations: merge_branch is atomic. You can create or modify multiple tables on a branch, and when you merge, either all changes apply to main or none do. This enables safe multi-table ingestion workflows.
Required User Input
Before writing the WAP script, you MUST ask the user for the following parameters:
- S3 path (required): The S3 URI pattern for the source data (e.g.,
s3://bucket/path/*.parquet) - Table name (required): The name for the target table
- On success behavior (optional):
inspect(default): Keep the branch open for user inspection before mergingmerge: Automatically merge to main and delete the branch
- On failure behavior (optional):
keep(default): Leave the branch open for inspection/debuggingdelete: Delete the failed branch
WAP Script Template
This is the complete template for WAP:
"""
WAP (Write-Audit-Publish) Template for bauplan data ingestion.
Usage:
python wap_template.py
Or import and call wap_ingest() with your parameters.
"""
import bauplan
from datetime import datetime
def wap_ingest(
table_name: str,
s3_path: str,
namespace: str = "bauplan",
on_success: str = "inspect", # "inspect" (default) or "merge"
on_failure: str = "keep", # "keep" (default) or "delete"
):
"""
Write-Audit-Publish flow for safe data ingestion.
Args:
table_name: Target table name
s3_path: S3 URI pattern (e.g., 's3://bucket/path/*.parquet')
namespace: Target namespace (default: 'bauplan')
on_success: "inspect" to keep branch for review, "merge" to auto-merge
on_failure: "keep" to preserve branch for debugging, "delete" to cleanup
Returns:
tuple: (branch_name, success)
"""
client = bauplan.Client()
# Generate unique branch name using username
info = client.info()
username = info.user.username
branch_name = f"{username}.wap_{table_name}_{int(datetime.now().timestamp())}"
success = False
try:
# === WRITE PHASE ===
# 1. Create temporary branch from main (must not exist)
assert not client.has_branch(branch_name), (
f"Branch '{branch_name}' already exists - this should be an ephemeral branch"
)
client.create_branch(branch_name, from_ref="main")
# 2. Verify table doesn't exist on branch before creating
assert not client.has_table(
table=table_name, ref=branch_name, namespace=namespace
), (
f"Table '{namespace}.{table_name}' already exists on branch - refusing to overwrite"
)
# 3. Create table (schema inferred from S3 files)
client.create_table(
table=table_name,
search_uri=s3_path,
namespace=namespace,
branch=branch_name,
)
# 4. Import data into table
client.import_data(
table=table_name,
search_uri=s3_path,
namespace=namespace,
branch=branch_name,
)
# === AUDIT PHASE ===
# 5. Run quality check: verify data was imported
fq_table = f"{namespace}.{table_name}"
result = client.query(
query=f"SELECT COUNT(*) as row_count FROM {fq_table}", ref=branch_name
)
row_count = result.column("row_count")[0].as_py()
assert row_count > 0, "No data was imported"
print(f"Imported {row_count} rows")
success = True
# === PUBLISH PHASE ===
if on_success == "merge":
# 6. Merge to main and cleanup
client.merge_branch(source_ref=branch_name, into_branch="main")
print(f"Successfully published {table_name} to main")
client.delete_branch(branch_name)
print(f"Cleaned up branch: {branch_name}")
else:
# Keep branch for inspection
print(
f"WAP completed successfully. Branch '{branch_name}' ready for inspection."
)
print(
f"To merge manually: client.merge_branch(source_ref='{branch_name}', into_branch='main')"
)
except Exception as e:
print(f"WAP failed: {e}")
if on_failure == "delete":
if client.has_branch(branch_name):
client.delete_branch(branch_name)
print(f"Cleaned up failed branch: {branch_name}")
else:
print(f"Branch '{branch_name}' preserved for inspection/debugging.")
raise
return branch_name, success
if __name__ == "__main__":
# Example: customize these parameters
branch, success = wap_ingest(
table_name="my_table",
s3_path="s3://my-bucket/data/*.parquet",
namespace="bauplan",
on_success="inspect",
on_failure="keep",
)
Minimal usage:
from wap_template import wap_ingest
branch, success = wap_ingest(
table_name="orders",
s3_path="s3://my-bucket/data/*.parquet",
namespace="bauplan",
on_success="inspect", # or "merge"
on_failure="keep" # or "delete"
)
Key SDK Methods
| Method | Description |
| ---------------------------------------------- | ----------------------------------------------------- |
| bauplan.Client() | Initialize the bauplan client |
| client.info() | Get client info; access username via .user.username |
| client.create_branch(name, from_ref="main") | Create a new branch from specified ref |
| client.has_branch(name) | Check if branch exists |
| client.delete_branch(name) | Delete a branch |
| client.create_table(table, search_uri, ...) | Create table with schema inferred from S3 |
| client.import_data(table, search_uri, ...) | Import data from S3 into table |
| client.query(query, ref) | Run SQL query, returns PyArrow Table |
| client.merge_branch(source_ref, into_branch) | Merge branch into target |
| client.has_table(table, ref, namespace) | Check if table exists on branch |
SDK Reference: For detailed method signatures, check https://docs.bauplanlabs.com/reference/bauplan
Workflow Checklist
Copy and track progress:
WAP Progress:
- [ ] Ask user for: S3 path, table name, on_success, on_failure
- [ ] Write script using wap_template.py
- [ ] Run script: python wap_script.py
- [ ] Verify output shows row count > 0
- [ ] If on_success="inspect": confirm branch ready for review
- [ ] If on_success="merge": confirm merge to main succeeded
Example Output
Successful run (on_success="inspect"):
$ python wap_script.py
Imported 15234 rows
WAP completed successfully. Branch 'alice.wap_orders_1704067200' ready for inspection.
To merge manually: client.merge_branch(source_ref='alice.wap_orders_1704067200', into_branch='main')
Successful run (on_success="merge"):
$ python wap_script.py
Imported 15234 rows
Successfully published orders to main
Cleaned up branch: alice.wap_orders_1704067200
Failed run (on_failure="keep"):
$ python wap_script.py
WAP failed: No data was imported
Branch 'alice.wap_orders_1704067200' preserved for inspection/debugging.
WAP on Existing Tables
To append data to an existing table, skip create_table and only call import_data:
# Table already exists on main - just import new data
client.import_data(
table=table_name,
search_uri=s3_path,
namespace=namespace,
branch=branch_name
)
This appends rows to the existing table schema. The audit and publish phases remain the same: the new rows are automatically sandboxed on the branch until merged.
CLI Merge After Inspection
When on_success="inspect" (default), the branch is left open for user review. If the user asks to merge after inspecting the data, use the CLI:
# 1. Checkout to main first (required before merging)
bauplan checkout main
# 2. Merge the WAP branch into main
bauplan branch merge <username>.wap_<table_name>_<timestamp>
# 3. Optionally delete the branch after successful merge
bauplan branch rm <username>.wap_<table_name>_<timestamp>
Note: You must be on
mainto runbauplan branch merge. The branch name is printed by the WAP script upon completion.
Du fichier au premier essai
Le téléchargement contient exactement le contenu affiché sur cette fiche. Cette copie peut différer de la dernière version du dépôt source.
Consulter la source et ses fichiers annexesCe téléchargement contient uniquement SKILL.md. Les scripts, références, modèles et dépendances éventuels ne sont pas inclus. Récupérez les fichiers nécessaires depuis la source en conservant leur arborescence avant de poursuivre.
1. Télécharger le fichier
Télécharger SKILL.mdDepuis la racine d’un projet de test, enregistrez le fichier sous .skill-downloads/wap-data-ingestion-with-bauplan-ms5lrgik/SKILL.md, ou utilisez la commande suivante. Ce dossier sert à examiner la skill avant son installation.
Commande pour macOS/Linux ou WSL : un shell POSIX et curl sont nécessaires. Sous Windows sans WSL, utilisez le bouton de téléchargement et créez le dossier manuellement.
mkdir -p '.skill-downloads/wap-data-ingestion-with-bauplan-ms5lrgik' && curl --fail --show-error --location 'https://skills-guides.com/api/skills/wap-data-ingestion-with-bauplan-ms5lrgik/download' --output '.skill-downloads/wap-data-ingestion-with-bauplan-ms5lrgik/SKILL.md.part' && mv '.skill-downloads/wap-data-ingestion-with-bauplan-ms5lrgik/SKILL.md.part' '.skill-downloads/wap-data-ingestion-with-bauplan-ms5lrgik/SKILL.md'2. Vérifier les prérequis
Lisez SKILL.md avant de l’utiliser. Si le fichier cite des scripts ou services externes, examinez-les et préparez les accès nécessaires dans votre environnement de test.
Aucune section de prérequis reconnue dans ce fichier. Cela ne signifie pas qu’il est autonome : les bibliothèques, outils et accès peuvent être cités ailleurs dans le contenu ou dans le dépôt source.
Les plateformes de la fiche sont des indications du catalogue. Les chemins ci-dessous suivent la documentation des outils ; ils ne prouvent pas que cette skill y a été exécutée. Aucune version minimale de ces outils n’est attestée pour cette fiche.
3. Charger la skill
Après vérification, copiez le dossier complet dans le projet avec l’une des commandes ci-dessous, puis ouvrez une nouvelle session de l’outil. La commande s’arrête si un dossier du même nom existe déjà : comparez les fichiers avant de le remplacer.
Claude Code
test -f '.skill-downloads/wap-data-ingestion-with-bauplan-ms5lrgik/SKILL.md' && test -s '.skill-downloads/wap-data-ingestion-with-bauplan-ms5lrgik/SKILL.md' && mkdir -p '.claude/skills' && test ! -e '.claude/skills/wap-ingestion' && cp -R '.skill-downloads/wap-data-ingestion-with-bauplan-ms5lrgik' '.claude/skills/wap-ingestion'Codex
test -f '.skill-downloads/wap-data-ingestion-with-bauplan-ms5lrgik/SKILL.md' && test -s '.skill-downloads/wap-data-ingestion-with-bauplan-ms5lrgik/SKILL.md' && mkdir -p '.agents/skills' && test ! -e '.agents/skills/wap-ingestion' && cp -R '.skill-downloads/wap-data-ingestion-with-bauplan-ms5lrgik' '.agents/skills/wap-ingestion'OpenSkills
OpenSkills doit déjà être installé. La procédure locale install/read est contrôlée avec OpenSkills 1.5.0, qui exige Node.js ≥ 20.6.0. Aucun slug du catalogue n’est résolu automatiquement.
Installation officielle d’OpenSkillsopenskills install './.skill-downloads/wap-data-ingestion-with-bauplan-ms5lrgik'openskills read 'wap-data-ingestion-with-bauplan-ms5lrgik'La lecture doit afficher le contenu du fichier installé et son dossier de base. Elle ne lance ni la skill ni ses dépendances.
Pour un agent qui lit AGENTS.md, synchronisez ensuite l’index. Cette commande modifie AGENTS.md : relisez le diff avant de l’utiliser.
openskills syncMode manuel ou autre outil : joignez SKILL.md à une conversation, ou ouvrez-le dans un agent capable de lire les fichiers. Ajoutez les ressources annexes nécessaires. Il n’existe pas de dossier universel reconnu par tous les outils.
4. Faire un premier essai
Utilisez une entrée courte et fictive : un endpoint d’API, un petit document ou un brief d’interface. Dans une nouvelle conversation, joignez le fichier ou donnez son chemin à l’agent, puis adaptez cette demande :
Lis .skill-downloads/wap-data-ingestion-with-bauplan-ms5lrgik/SKILL.md et applique ses instructions à cet exemple : [décrire une entrée de test]. Indique les fichiers, dépendances ou accès qui manquent. Produis le résultat demandé par la skill sans inventer de données ni exécuter de script non examiné.Résultat attendu : une sortie correspondant aux instructions de la skill, ou une liste précise des prérequis manquants. Une simple confirmation de lecture ne valide pas le premier usage. Si une ressource externe est indisponible, ce parcours reste à tester.
Créer des cartes interactives avec kepler.gl
Data & IA
Création de cartes interactives et export HTML autonome avec le package Python keplergl, à partir de données géospatiales (DataFrame, GeoJSON, CSV).
Optimisation de paramètres par agent
Data & IA
Guide d'optimisation de systèmes configurables avec objectif mesurable, via des essais bornés et une recommandation fondée sur des preuves.
Relance des visiteurs ICP
Data & IA
Identifiez les utilisateurs inscrits correspondant au profil client idéal mais qui n'ont pas activé, et rédigez des messages de relance personnalisés pour les réengager.