EN
Copied
Modules

Import

Objectif

Le module import introduit des données externes dans outsend en tant que source de pipeline. Il est interne au pipeline — voir /docs/fr/concepts/pipeline-orchestration — et produit une liste de POI normalisée que les nœuds d'enrichissement, de vérification ou de traitement en aval peuvent consommer. Contrairement à scrap, import ne consomme aucun quota d'extraction (coût EF nul).

Entrées

La configuration du nœud expose un seul discriminateur, source, avec trois modes mutuellement exclusifs.

Champ Type Requis Description
source "paste" | "url" | "from_job" oui Sélectionne lequel des trois canaux d'entrée ci-dessous s'applique. Vaut paste par défaut si omis.
text chaîne si source = paste Contenu CSV brut. Lu uniquement en mode paste.
url chaîne si source = url URL publique de tableur. Lue uniquement en mode url.
from_job_id chaîne si source = from_job UUID d'un job de scrap existant appartenant à l'appelant. Lu uniquement en mode from_job.

paste — CSV en ligne

La charge utile text est parsée comme CSV par la couche de résolution partagée (app/column_map.py). Le délimiteur est auto-détecté (virgule, point-virgule ou tabulation) ; UTF-8 est attendu, avec UTF-8 BOM et Latin-1 / cp1252 acceptés en repli. Les en-têtes ne sont pas obligatoires : les noms de colonnes sont reconnus de façon souple via des alias acceptés (un en-tête Website, url, e-mail ou raison sociale est mappé vers la bonne colonne canonique), et un fichier sans en-tête est auto-détecté — ses colonnes sont alors déduites de leur contenu. Dans tous les cas l'import émet une notice (bannière d'info sur la page du job, ⓘ au dashboard) indiquant ce qui a été auto-mappé, déduit ou ignoré, pour que le mapping ne soit jamais silencieux.

url — tableur public

La charge utile url pointe vers un tableur lisible publiquement (forme typique : https://docs.google.com/spreadsheets/d/.../edit#gid=0). La feuille doit être partagée en « toute personne ayant le lien peut consulter » — outsend ne s'authentifie pas auprès de fournisseurs tiers. Le contenu récupéré est parsé selon les mêmes règles CSV que paste.

from_job — réutilisation d'un scrap récent

La charge utile from_job_id référence un job scrap antérieur. La référence est validée côté serveur à la création du job :

Contrainte Règle
Existence L'ID du job doit correspondre à un job existant.
Propriété L'appelant doit être propriétaire du job source.
Type de job Doit être scrap. Les autres types ne peuvent pas être réimportés par ce canal.
Disponibilité Le CSV source doit encore être téléchargeable (is_download_available).
Fraîcheur Le job source doit avoir moins de 7 jours.

Lorsque la validation passe, l'import résultant hérite de toutes les colonnes produites par le scrap source.

Sorties

import produit une liste de POI normalisée, déclarée dans le registre du pipeline avec output: "pois" — la même forme que celle émise par scrap. Les nœuds en aval qui acceptent pois_any (reviews, emails, socials, dead-check, techstack, ads-intelligence, brand-assets) s'enchaînent directement. Les nœuds qui exigent pois_email (verify) ne s'enchaînent que si le CSV importé porte déjà une colonne email.

L'ensemble de colonnes est dynamique : il reflète ce que fournit la source. Le registre déclare needs: [] et produces: [] pour cette raison — le module est permissif en entrée et propage le schéma d'entrée en sortie.

Cycle de vie

Cycle de vie de job standard — voir /docs/fr/concepts/jobs-lifecycle. Le job est rattaché à son pipeline via pipeline_id et pipeline_node_id et s'exécute dès que le pipeline passe à running.

Pipeline

import est un nœud racine. Il n'accepte aucun arc amont. Tout nœud dont l'input est pois_any, any_pois ou pois_email (quand le CSV porte des emails) peut être câblé en aval.

Direction Types compatibles
Amont aucun — import est un ROOT_TYPE aux côtés de scrap
Aval reviews, emails, verify (avec colonne email), socials, dead_check, techstack, ads_intelligence, brand_assets, filter, sort

Registre : needs: [], produces: [].

Endpoints

Le module import n'est pas exposé comme endpoint de job autonome — il est interne au pipeline (voir /docs/fr/concepts/pipeline-orchestration) et créé uniquement comme racine de pipeline. Deux endpoints adjacents sont utiles lors de l'assemblage d'un import :

Méthode Chemin Rôle
POST /api/jobs/parse-list Valide l'entrée CSV avant soumission. Accepte soit un JSON {"text": "..."}, soit un envoi multipart/form-data avec un champ file. Renvoie {count, with_lien_google_maps, with_site_web, sample, items, delimiter}.
GET /api/jobs/{job_id}/items Renvoie les lignes CSV d'un job scrap terminé dans une structure adaptée à la réutilisation from_job.

La charge utile du nœud de pipeline suit cette forme :

{
  "type": "import",
  "config": {
    "source": "paste",
    "text": "nom,site_web\n...",
    "url": "",
    "from_job_id": ""
  }
}

Exactement un parmi text, url, from_job_id est lu, déterminé par source. Les champs inutilisés sont persistés sous forme de chaînes vides.

Limites

Limites globales — voir /docs/fr/concepts/limits. Spécifiques au module :

Limite Valeur
Fraîcheur from_job 7 jours. Le job source est rejeté au-delà.
Type source from_job scrap uniquement.
Formats pris en charge CSV avec délimiteur virgule, point-virgule ou tabulation. Encodages : UTF-8 (préféré), UTF-8 avec BOM, Latin-1 / cp1252 (repli). En-têtes facultatifs — un fichier sans en-tête est auto-détecté et ses colonnes déduites du contenu.

Erreurs

Condition Surface Forme du message
source hors de {paste, url, from_job} Création du pipeline Source d'import invalide : <value> (attendu: paste \| url \| from_job)
from_job sans from_job_id Création du pipeline Source 'from_job' : aucun job sélectionné
from_job_id inconnu Création du pipeline Job source introuvable : <id>
Source from_job non détenue par l'appelant Création du pipeline Job source non autorisé pour cet utilisateur
Source from_job n'étant pas un scrap Création du pipeline Seuls les scraps Gmaps peuvent être importés via 'from_job'
CSV source from_job indisponible Création du pipeline Le CSV du job source n'est pas (ou plus) disponible
Source from_job de plus de 7 jours Création du pipeline Le job source a plus de 7 jours — relancez un scrap ou collez le CSV.
Charge utile paste vide parse-list HTTP 400, Aucun texte fourni
Échec de parsing CSV parse-list HTTP 400, CSV invalide: <detail>
Zéro ligne parsée parse-list HTTP 400, Aucune ligne lue dans le CSV
Envoi multipart sans fichier parse-list HTTP 400, Aucun fichier fourni
URL injoignable ou réponse non CSV Exécution du pipeline Le job d'import passe à failed ; le message nomme la source injoignable.
Tableur privé (page de connexion renvoyée au lieu du CSV) Exécution du pipeline L'import échoue franchement avec une explication au lieu de réussir silencieusement — le contenu était du HTML (page de connexion), pas du CSV. Partagez la feuille en « toute personne ayant le lien peut consulter ».
Vide, en-tête seul, ou rien d'exploitable Exécution du pipeline / parse-list L'import échoue avec une explication (aucune ligne exploitable) plutôt que d'annoncer un faux succès.

Et après

Module Usage
filter Restreindre la liste importée par des prédicats de colonnes avant de payer l'enrichissement en aval.
sort Ordonner la liste importée — utile combiné à des limites de lignes dans les étapes ultérieures.