Construire une chaîne¶
Le chemin tient en cinq étapes, avant de déployer la chaîne. Prenez le temps de valider chacune avant d'attaquer la suivante : c'est fastidieux sur le moment, mais cela vous évite de chercher une erreur dans trois couches à la fois, sans savoir si le problème vient du script, de l'image ou du CWL.
Dans la documentation AntFlow
- Create your first workflow : le même parcours (script, image, CWL) sur un exemple complet
- CWL reference : ce qu'AntFlow accepte dans un package CWL
- Application packages : structure et métadonnées d'un package
1. Un script à interface propre¶
Commencez par un script qui tourne seul, hors de tout CWL. C'est votre seul terrain de débogage confortable : une fois la chaîne sur la plateforme, vous n'avez plus que des journaux.
Quatre exigences, qui découlent toutes de la façon dont le moteur appelle votre script :
- Entrées et sorties en arguments, jamais codées en dur - le CWL ne peut piloter que ce qui est paramétrable.
- Sorties écrites dans le répertoire courant, en chemins relatifs. Le moteur crée un répertoire de travail par étape et vient y récupérer les sorties ; un chemin absolu écrit en dehors, et le fichier est simplement perdu.
- Un code de retour non nul en cas d'échec (
sys.exit("message")). C'est le seul signal d'erreur que voit le moteur : un script qui échoue en silence avec un code 0 fait passer l'étape pour un succès, et le workflow continue sur des données absentes. - Aucune interaction ni affichage graphique : personne ne répondra à une invite, et il n'y a pas d'écran.
2. Conteneuriser¶
L'image embarque le code et ses dépendances. C'est un changement de point de vue utile : votre script n'est pas une donnée que le workflow transporte, il fait partie de l'outil, au même titre que les bibliothèques qu'il utilise.
FROM python:3.11-slim
RUN pip install --no-cache-dir rasterio boto3
WORKDIR /app
COPY mon_traitement.py /app/
ENV PATH="/app:${PATH}"
Trois précautions à la construction :
- Taguez une version, jamais
latest. Sans tag explicite, l'exécution n'est plus reproductible et la plateforme peut servir une image en cache qui n'est pas la vôtre. - Placez le code à un chemin absolu dans l'image (
/app/…), pour quebaseCommandne dépende pas du répertoire de travail du moment. - N'y mettez aucun identifiant : une image se partage et se télécharge.
Avant d'écrire la moindre ligne de CWL, vérifiez que le script tourne dans le conteneur :
docker run --rm -v "$PWD:/data" -w /data <image> python3 /app/mon_traitement.py entree.tif sortie.tif
Si ça échoue à ce stade, le CWL n'y est pour rien, et il est bien plus rapide de corriger ici que dans une chaîne complète.
3. Publier l'image¶
La marche à suivre est dans Utiliser la registry. Retenez seulement
que le nom de l'image doit reprendre le chemin du projet GitLab
(registry.gitlab.com/<groupe>/<projet>:<tag>) : la registry refuse tout autre nom.
Partage du projet
Le groupe urbiverde-if-pathfinder doit
être invité en Maintainer. Sans ce partage, l'image reste privée et la plateforme
échoue au pull - l'erreur apparaît à l'exécution, pas à la validation du CWL.
Aperçu du service
Une image référencée dans le README.md du projet sert d'aperçu dans la plateforme :
.
4. Écrire les CommandLineTool¶
Vient ensuite la description CWL proprement dite. Écrivez un tool par script : son rôle se limite à dire comment appeler le script - quels arguments, quelle image, quelles ressources, et quels fichiers récupérer ensuite.
cwlVersion: v1.2
class: CommandLineTool
label: Calcul d'indicateur # affiché dans AntFlow
baseCommand: [python3, /app/mon_traitement.py]
requirements:
DockerRequirement:
dockerPull: registry.gitlab.com/<groupe>/<projet>:0.1.2
ResourceRequirement:
ramMin: 1024
ramMax: 3026
coresMin: 1
coresMax: 2
inputs:
entree:
type: File
inputBinding:
position: 0
arguments:
- position: 1
valueFrom: sortie.tif
outputs:
produit:
type: File
outputBinding:
glob: sortie.tif
stdout: stdout.txt # journal capturé, précieux en cas d'échec
Avant de passer à la suite, relisez votre tool avec cette liste - chaque ligne correspond à une erreur courante :
- [ ]
DockerRequirementavec une image publiée et taguée - [ ]
baseCommanden chemin absolu dans l'image - [ ]
NetworkAccess: truesi l'étape sort du conteneur (S3, API) - [ ]
ResourceRequirementdès que l'étape charge des données en mémoire - [ ]
globcorrespondant réellement à ce que le script écrit - [ ]
labeletdocrenseignés - c'est ce que lit l'utilisateur d'AntFlow
5. Assembler le workflow¶
Le workflow est l'enveloppe qui relie vos tools. C'est aussi là que se joue l'essentiel de l'adaptation à la plateforme : il expose des entrées qu'AntFlow sait alimenter, puis les convertit en ce dont les tools ont réellement besoin.
cwlVersion: v1.2
class: Workflow
label: Calcul d'indicateur
requirements:
# hérité par toutes les étapes : sinon les conteneurs tournent en --net=none
NetworkAccess:
networkAccess: true
InlineJavascriptRequirement: {}
inputs:
entree_path:
type: string # string, pas File : contrainte AntFlow
label: Chemin S3 du fichier d'entrée
default: "s3://<votre-bucket>/donnees/entree.tif"
s3_config:
type: string
label: Configuration S3 au format JSON
outputs:
produit:
type: File
outputSource: traitement/produit
steps:
stage_in: # string -> Directory
run: stage_in.cwl
in:
entree_path: entree_path
s3_config: s3_config
out: [donnees]
traitement: # Directory -> produit
run: mon_traitement.cwl
in:
entree: stage_in/donnees
out: [produit]
Quatre règles d'assemblage à garder en tête :
- Déclarez les entrées en
string, jamais enFile- Contraintes de la plateforme explique pourquoi ce point est décisif. - Placez les requirements communs au niveau du workflow : ils sont hérités par les étapes, inutile de les répéter dans chaque tool.
- Renseignez
defaultquand une valeur est raisonnable : l'utilisateur a alors un formulaire pré-rempli et exécutable tel quel. labelsur chaque étape : c'est ce qui s'affiche dans le graphe AntFlow.
Valider¶
cwltool --validate mon_workflow.cwl # syntaxe et câblage
cwltool --outdir ./out mon_workflow.cwl job.json # exécution complète
Ne vous fiez pas à --validate seul : il vérifie la syntaxe et le câblage, mais ne détecte
ni une image absente, ni un glob qui ne correspond à aucun fichier. Seule l'exécution
complète le montre. Et tant qu'à faire, testez contre un MinIO local avant de viser le S3
de production.
Ce qu'un test local ne verra jamais¶
Reste une limite qu'il faut connaître : cwltool est plus permissif que la plateforme. Un workflow parfaitement vert sur votre poste peut échouer en production, et toujours sur les mêmes points :
| Point | Pourquoi ça passe en local |
|---|---|
| Fichiers intermédiaires | En local ils circulent librement entre étapes ; sur la plateforme, seule une sortie déclarée traverse. |
| Accès à l'image | Elle est en cache local, mais peut-être pas accessible à la plateforme. |
| Mémoire | En local, toute la RAM de la machine ; sur la plateforme, plafonné et tué en silence au-delà. |
| Secrets | cwltool:Secrets masque la valeur localement, mais c'est sur la plateforme qu'elle est alimentée depuis le compte. |
Aucun de ces quatre points ne se détecte en exécutant le workflow chez vous : ils se vérifient par relecture du CWL.