Parfois, un projet qui semble simple sur le papier se transforme en véritable chasse aux bugs. Cette migration RoboTask vers Python pour la génération d'étiquettes d'expédition DPD en est l'exemple parfait : 4 versions successives ont été nécessaires pour résoudre un bug insidieux lié aux lecteurs Windows.
Voici le récit complet de cette migration, avec un focus particulier sur le problème du
double backslash qui m'a fait comprendre pourquoi pathlib et les lecteurs
Windows ne font pas toujours bon ménage.
Le Contexte : Automatiser DPD
Le Besoin Initial
Un client utilisait RoboTask (~200€/an) pour générer automatiquement des fichiers d'étiquettes DPD depuis sa base de données Cegid PMI. Le processus consistait à :
- 📊 Récupérer les expéditions du jour depuis SQL Server
- 🧮 Calculer le poids unitaire (poids total ÷ nombre de colis)
- 📝 Générer N étiquettes (une par colis, format DPD spécifique)
- 💾 Créer des fichiers texte sur un lecteur réseau (G:\)
Le format DPD est particulier : largeur fixe de 56 colonnes, encodage
ISO-8859-1, avec un en-tête $VERSION=110 et des données rigoureusement formatées.
Les Objectifs de Migration
Comme pour toute migration RoboTask vers Python, les objectifs étaient clairs :
- ✅ Économiser ~200€/an de licence
- ✅ Code versionnable (Git vs fichiers binaires)
- ✅ Logs détaillés pour le débogage
- ✅ Maintenabilité améliorée
- ✅ 100% de conformité fonctionnelle
Architecture Python : Simple et Modulaire
J'ai conçu une solution Python propre avec deux classes principales et plusieurs scripts utilitaires :
# Classes principales
DPDRecord # Validation et formatage des données
DPDGenerator # Orchestration et génération fichiers
# Scripts utilitaires
run_dpd_generation.bat # Wrapper Windows
install_dpd.bat # Installation 5 tâches planifiées
diagnostic.bat # Diagnostic automatique
test_installation.py # 7 tests de validation
Technologies utilisées :
Fonctionnalités Clés
- ✅ Configuration externalisée (fichier INI)
- ✅ Validation robuste des 56 colonnes
- ✅ Logs horodatés et détaillés
- ✅ Gestion multi-exécutions (pas de doublons)
- ✅ Support lecteurs Windows ET chemins UNC
- ✅ Tests automatisés (7 tests)
- ✅ Documentation exhaustive (100+ pages)
Les Défis Techniques : 4 Versions pour 1 Bug
Si j'avais su ce qui m'attendait avec le problème du double backslash, j'aurais peut-être
utilisé os.path dès le début. Mais voici le parcours complet...
Version 1.0 → 1.1 : Logs Manquants
🔴 Problème
Le script s'exécutait via le Planificateur Windows mais aucun log n'était créé. Impossible de savoir ce qui se passait.
Cause : Le logging était initialisé trop tard dans le code. Si une erreur survenait pendant le chargement de la configuration, aucun log n'était écrit.
✅ Solution v1.1
# Initialiser le logging DÈS LE DÉBUT
def __init__(self):
self._init_basic_logging() # ← AVANT tout
self.config = load_config()
# ... reste du code
Améliorations :
- Logs du wrapper batch (capture stdout/stderr)
- Script de diagnostic automatique
- Guide de dépannage (15+ pages)
Version 1.1 → 1.2 : Doublons d'Étiquettes
🔴 Problème
Les fichiers d'étiquettes étaient régénérés à chaque exécution, créant des doublons. Avec 5 tâches planifiées par jour pour les réessais, le problème s'amplifiait.
Cause : Le script vérifiait l'existence du fichier mais continuait quand même à traiter l'expédition et à ajouter des lignes.
✅ Solution v1.2
# Vérifier AVANT le traitement
for expedition in expeditions:
archive_file = output_dir / f"{expedition_id}.txt"
if archive_file.exists():
logging.info(f"DEJA TRAITEE - Skip {expedition_id}")
skipped_count += 1
continue # ← Skip complet
# Traitement uniquement si fichier inexistant
process_expedition(expedition)
Impact : Support multi-exécutions sans doublons + statistiques précises (compteur de skipped)
Versions 1.3 → 1.3.4 : Le Cauchemar du Double Backslash
Et là commence le vrai calvaire. Un bug qui m'a pris 4 itérations et plusieurs
heures de débogage pour comprendre que pathlib et les lecteurs Windows ont un problème
fondamental.
Itération 1 : Vérification d'Existence (v1.3.1)
🔴 Symptôme
[WinError 3] Le chemin d'accès spécifié est introuvable: 'G:\\'
Le script plantait avec un double backslash mystérieux.
Analyse : En testant Path("G:").exists(), Python ajoutait automatiquement
un backslash, créant "G:\\" qui est invalide pour Windows.
# Ce qui se passait
drive_path = Path("G:") # Semble OK
drive_path.exists() # Devient "G:\\" en interne
# → WinError 3
✅ Tentative de Solution v1.3.1
# Construire explicitement le chemin
drive_path = directory.drive + '\\' # "G:\"
if not Path(drive_path).exists():
raise FileNotFoundError(f"Lecteur {drive_path} inaccessible")
Mais ce n'était pas suffisant...
Itération 2 : Faux Positif (v1.3.3)
🔴 Nouveau Problème
Le script détectait G:\ comme inaccessible alors qu'il était accessible.
La vérification avec Path.exists() échouait dans certains contextes (compte SYSTEM,
tâches planifiées).
✅ Solution v1.3.3
Suppression de la vérification préalable. L'erreur sera détectée lors de l'utilisation réelle.
# Plus de vérification préalable
# L'erreur sera attrapée au moment de l'écriture
try:
file_path.write_text(content)
except Exception as e:
logging.error(f"Erreur écriture : {e}")
Itération 3 : Création de Dossiers (v1.3.4) - FINAL 🎯
🔴 Le Bug Persiste !
[WinError 3] Le chemin d'accès spécifié est introuvable: 'G:\\'
Même erreur, mais cette fois lors de la création des dossiers. Path.mkdir(parents=True)
essayait de créer la racine G:\ et échouait avec le double backslash.
Analyse Approfondie :
# Ce qui se passait avec pathlib
directory = Path("G:/DPD/Archive")
directory.mkdir(parents=True) # Essaie de créer toute la hiérarchie
# Étapes internes de pathlib :
# 1. Décompose : ['G:', 'DPD', 'Archive']
# 2. Essaie de créer G:
# 3. Path("G:") devient "G:\\" en interne
# 4. → WinError 3
✅ Solution Définitive v1.3.4
# Remplacer Path.mkdir par os.makedirs
import os
# Au lieu de
directory.mkdir(parents=True, exist_ok=True)
# Utiliser
os.makedirs(str(directory), exist_ok=True)
Pourquoi ça fonctionne :
- ✅
os.makedirs()utilise les API Windows natives - ✅ Pas de conversion Path qui introduit le double backslash
- ✅ Gère parfaitement les lecteurs Windows (G:, H:, etc.)
- ✅
exist_ok=Trueévite les erreurs si dossier existe
🎓 Leçon Apprise : pathlib vs os.path sur Windows
Sur Windows avec lecteurs mappés :
| Opération | ❌ pathlib (problèmes) | ✅ os.path (OK) |
|---|---|---|
| Vérifier existence | Path("G:").exists()→ Double backslash |
os.path.exists("G:")→ Fonctionne |
| Créer dossiers | Path.mkdir(parents=True)→ Double backslash |
os.makedirs()→ Fonctionne |
| Chemins internes | Conversion automatique problématique | Respecte le format Windows natif |
Recommandation : Sur Windows, avec des lecteurs mappés, privilégiez os.path et os.makedirs plutôt que pathlib.
Timeline des Versions
v1.0 - Migration Initiale
Migration fonctionnelle de base. Problème : pas de logs en cas d'erreur.
v1.1 - Logs Corrigés
Logging initialisé dès le début + wrapper batch avec logs.
v1.2 - Anti-Doublons
Skip complet des expéditions déjà traitées. Support multi-exécutions.
v1.3.1 - Premier Bug Backslash
Construction explicite des chemins lecteurs. Erreur persiste.
v1.3.3 - Suppression Vérification
Retrait de la vérification préalable. Bug se manifeste ailleurs.
v1.3.4 - Solution Définitive ✅
Remplacement de Path.mkdir par os.makedirs. Bug résolu !
Résultats : Mission Accomplie
Métriques Finales
Améliorations vs RoboTask
| Critère | RoboTask | Python |
|---|---|---|
| Coût | ~200€/an | 0€ (gratuit) |
| Logs | Basiques | Détaillés, horodatés, par jour |
| Doublons | Possible si multi-run | Impossible (skip automatique) |
| Versionning | Fichiers binaires | Git (8 versions trackées) |
| Maintenance | Interface graphique | Code lisible et documenté |
| Tests | Manuels | 7 tests automatisés |
| Diagnostic | Difficile | Script automatique |
| Documentation | Minimale | 100+ pages (9 guides) |
Documentation Produite
Un des points forts de cette migration : une documentation exhaustive pour ne plus jamais perdre de temps sur les mêmes problèmes.
- 📘 README.md - Documentation technique (40+ pages)
- 📗 GUIDE_RAPIDE.md - Installation en 10 minutes
- 📙 CHANGELOG.md - Historique des 8 versions
- 📕 BUG_DOUBLE_BACKSLASH.md - Analyse technique détaillée
- 📔 DEPANNAGE_LOGS.md - Guide de dépannage
- 📓 LECTEURS_MAPPES_TACHES_PLANIFIEES.md - Problème critique (20+ pages)
- 📑 CONFIGURATION_LECTEUR_RESEAU.md - Configuration réseau
- 📰 COMPORTEMENT_AVANT_APRES.md - Exemples visuels
- 📄 STRUCTURE_PROJET.md - Vue d'ensemble
Total : 9 documents techniques, 100+ pages
Besoin de Migrer une Automatisation RoboTask ?
Je développe des solutions Python pour remplacer RoboTask et autres outils propriétaires. Migration, debugging Windows, ou création from scratch — discutons de votre projet !
Parlons de votre automatisationLeçons Apprises
1. pathlib et Windows : Une Relation Compliquée
pathlib est excellent sur Linux et macOS, mais sur Windows avec des lecteurs mappés,
privilégiez os.path et os.makedirs. Le double backslash n'est pas un bug Python,
c'est une incompatibilité fondamentale entre la façon dont pathlib gère les chemins
et les attentes de l'API Windows.
2. Tester dans le Contexte Réel Dès le Début
J'aurais pu éviter 3 versions intermédiaires en testant avec un lecteur mappé dès le début.
Les tests unitaires sur C:\ ne révèlent pas les problèmes spécifiques aux lecteurs
réseau (G:, H:, etc.).
3. Logging : La Clé du Débogage
Sans logs détaillés, je serais encore en train de chercher pourquoi le script ne fonctionne pas. Investissez dans un système de logging robuste dès le début : logs horodatés, niveaux de gravité, rotation automatique.
4. Documentation = Investissement Rentable
Les 100+ pages de documentation semblent excessives, mais elles éviteront des heures de débogage futur. Chaque bug résolu et documenté devient une référence pour la suite.
5. Versionning Rigoureux
Utiliser Git avec un CHANGELOG.md détaillé a permis de tracker précisément
l'évolution du projet. Chaque version corrige un problème spécifique et peut être comparée.
Recommandations pour Projets Similaires
Avant de Commencer
- 🔍 Analyser le contexte d'exécution : Tâche planifiée ? Compte SYSTEM ? Lecteurs mappés ?
- 🧪 Tester avec les lecteurs réels dès le début
- 📝 Logging dès la première ligne de code
- 🛠️ Sur Windows avec lecteurs : Utiliser
os.pathetos.makedirs
Pendant le Développement
- 📊 Tests dans le contexte cible : PsExec pour simuler SYSTEM
- 📚 Documenter chaque bug avec analyse et solution
- 🔄 Versionning clair : v1.0, v1.1, v1.2 avec CHANGELOG
- 🧰 Scripts utilitaires : diagnostic, tests, installation
Après Déploiement
- 👀 Monitorer les premiers jours : Vérifier logs quotidiennement
- ✅ Double-run : Garder RoboTask en parallèle pendant 1 semaine
- 📈 Statistiques : Nombre d'étiquettes générées, skipped, erreurs
Conclusion
Cette migration RoboTask → Python fut plus complexe que prévu à cause du bug du double backslash, mais le résultat final est production-ready avec :
- ✅ 100% de conformité fonctionnelle
- ✅ 0€ de coût annuel (vs 200€/an)
- ✅ Logs détaillés pour débogage rapide
- ✅ Support multi-exécutions sans doublons
- ✅ Documentation exhaustive (100+ pages)
- ✅ Tests automatisés (7 tests)
La leçon principale ? Sur Windows, quand vous travaillez avec des lecteurs mappés,
os.path et os.makedirs sont vos amis. pathlib est excellent,
mais pas pour ce cas d'usage spécifique.
ROI : Immédiat (économie licence + maintenabilité)
Temps : 2 jours (incluant 4 itérations bug)
Statut : ✅ Production-ready avec zéro erreur depuis le déploiement