
J’ai construit mon premier pipeline ETL en tant que débutant complet. Voici comment.
de ma série de parcours en ingénierie des données. Dans la première partie, j’ai partagé ma feuille de route de 12 mois pour passer d’analyste de données à ingénieur de données. C’est ici que commence la construction proprement dite.
Lorsque j’ai publié mon premier article documentant mon parcours en ingénierie de données, quelque chose d’inattendu s’est produit. Les gens étaient en résonance avec cela. Des inconnus m’ont contacté pour me dire qu’ils étaient ravis de suivre. Cela faisait du bien.
Mais cela s’est aussi accompagné de pression.
Soudain, ce n’était plus seulement un objectif personnel que je pouvais abandonner tranquillement si les choses devenaient difficiles. Les gens regardaient. Les gens étaient dans le même bateau. Et cette responsabilité, honnêtement, fait partie de la raison pour laquelle vous lisez ceci en ce moment.
J’ai donc dû déménager. Et comme toute personne démarrant une nouvelle compétence, la première chose que j’ai faite a été de chercher des ressources. Il existe d’innombrables tutoriels sur Internet pour l’ingénierie des données. Vidéos YouTube, cours, guides écrits. Plus que vous ne pourrez jamais finir.
Mais je ne pouvais pas me résoudre à me contenter de théorie. J’avais besoin de construire quelque chose. Quelque chose de réel, avec de vraies données, qui a finalement fonctionné.
J’ai donc fermé les didacticiels et ouvert un bloc-notes Google Colab à la place. J’ai trouvé la documentation de l’API GitHub et j’ai décidé de créer mon premier pipeline ETL à partir de zéro. Pas de prise de main. Juste moi, du Python et un objectif.
Cet article est cette expérience documentée dans son intégralité. Le code, la confusion, les petites victoires et ce que j’ai réellement appris en le faisant.
Tout d’abord, qu’est-ce que l’ETL ?
Avant d’entrer dans ce que j’ai construit, permettez-moi d’expliquer rapidement ce que signifie réellement ETL, car j’ai dû le rechercher moi-même il n’y a pas si longtemps.
ETL signifie Extraire, Transformer, Charger. C’est l’un des concepts les plus fondamentaux de l’ingénierie des données.
- Extrait signifie aller quelque part pour obtenir des données. Une API, une base de données, un site internet, un fichier. Vous extrayez des informations brutes d’une source.
- Transformer signifie nettoyer et façonner ces données. Supprimer les mauvaises lignes, ajouter de nouvelles colonnes, les restructurer pour qu’elles soient réellement utiles.
- Charger signifie sauvegarder les données nettoyées quelque part. Une base de données, un entrepôt de données, un simple fichier CSV.
C’est ça. Ces trois étapes, effectuées dans l’ordre, constituent ce qu’est un pipeline de données. Tout le reste dans l’ingénierie des données, Airflow, Spark, Databricks, n’est que des moyens plus sophistiqués de faire ces trois mêmes choses à grande échelle.
Je suis au début de ma feuille de route, donc je suis resté simple. Python pur, pas encore d’outils d’orchestration. Mais la forme du problème est la même.
Ce que j’ai construit
J’ai extrait les données de l’API GitHub, en particulier les référentiels Python les plus appréciés créés au cours des 30 derniers jours. Je l’ai ensuite nettoyé, ajouté une nouvelle colonne et enregistré la sortie sous forme de fichier CSV.
Simple. Réel. Entièrement à moi.
Voici comment ça s’est passé.
Étape 1 : Extraire
La première chose que j’ai dû faire a été de comprendre comment parler à l’API GitHub. Une API est essentiellement une porte qu’une entreprise ou une plate-forme ouvre afin que les développeurs puissent lui demander des données par programme, sans avoir à copier et coller quoi que ce soit manuellement.
GitHub dispose d’une API publique gratuite. Aucun compte ou forfait payant n’est nécessaire pour les recherches de base.
Voici le code que j’ai écrit pour extraire les données :
import requests
url = "https://api.github.com/search/repositories"
params = {
"q": "language:python created:>2025-04-22",
"sort": "stars",
"order": "desc",
"per_page": 30
}
response = requests.get(url, params=params)
data = response.json()
print(response.status_code)
print(data.keys())
Je vais être honnête. Ce bloc m’a dérouté au début. Le requests la bibliothèque était nouvelle pour moi. Le params dictionnaire avec ça q la syntaxe semblait étrangère. Je n’ai pas immédiatement su quoi .json() ce que je faisais ou pourquoi j’en avais besoin.
Permettez-moi de le décomposer simplement.
requests.get()C’est ainsi que vous frappez à la porte de GitHub et demandez quelque chose. Leurlest l’adresse de ce que vous demandez. Leparamsle dictionnaire est la question spécifique que vous posez. Dans ce cas : « donnez-moi les dépôts Python, triés par étoiles, créés après le 22 avril, montrez-moi 30 résultats. ».json()convertit la réponse de GitHub à partir du texte brut en un dictionnaire Python avec lequel vous pouvez réellement travailler.
Quand je l’ai exécuté, j’ai eu ceci :
200
dict_keys(['total_count', 'incomplete_results', 'items'])
Le 200 signifie le succès. C’est la façon dont Internet dit « votre demande a fonctionné ». Si vous voyez 403 ou 404, quelque chose s’est mal passé.
Le dictionnaire comporte trois clés. total_count vous indique combien de dépôts correspondent à la recherche. incomplete_results vous indique si GitHub a dû écourter quelque chose. Et items C’est là que se trouvent les données réelles.
J’ai ensuite exécuté un deuxième bloc pour jeter un œil à l’intérieur :
print("Total matches on GitHub:", data['total_count'])
print("Repos returned:", len(data['items']))
first_repo = data['items'][0]
print("\nFirst repo name:", first_repo['name'])
print("Stars:", first_repo['stargazers_count'])
print("Language:", first_repo['language'])
print("URL:", first_repo['html_url'])
Sortir:
Total matches on GitHub: 9228201
Repos returned: 30
First repo name: skills
Stars: 139136
Language: Python
URL: https://github.com/anthropics/skills
Le premier résultat était un repo Anthropic avec 139 000 étoiles. Des données réelles. En direct. Tiré par le code que j’ai écrit.
Voilà, l’extrait est terminé.
Étape 2 : Transformer
Maintenant, j’avais 30 dépôts dans une liste Python, chacun étant un dictionnaire imbriqué avec des dizaines de champs. dont je n’avais pas besoin pour la plupart. L’étape de transformation est l’endroit où vous prenez ces données brutes et désordonnées et les transformez en quelque chose de propre et utile.
J’ai d’abord extrait uniquement les champs qui m’intéressaient et les ai chargés dans un dataframe Pandas :
import pandas as pd
repos = []
for repo in data['items']:
repos.append({
"name": repo['name'],
"owner": repo['owner']['login'],
"stars": repo['stargazers_count'],
"forks": repo['forks_count'],
"language": repo['language'],
"description": repo['description'],
"url": repo['html_url'],
"created_at": repo['created_at']
})
df = pd.DataFrame(repos)
df.head()
Voir cette trame de données apparaître était un véritable moment « wow ». Je suis passé d’un mur de JSON à un tableau propre et lisible avec des colonnes étiquetées en quelques lignes.
Ensuite j’ai fait trois transformations :
# Drop rows where description is missing
df_clean = df.dropna(subset=['description'])
# Add a viral flag for repos with over 50k stars
df_clean = df_clean.copy()
df_clean['viral'] = df_clean['stars'].apply(lambda x: 'Yes' if x > 50000 else 'No')
# Sort by stars descending
df_clean = df_clean.sort_values('stars', ascending=False).reset_index(drop=True)
print("Before cleaning:", len(df))
print("After cleaning:", len(df_clean))
Sortir:
Before cleaning: 30
After cleaning: 29
Un dépôt n’avait aucune description et a été abandonné. La colonne virale est apparue proprement. Les données étaient désormais triées et structurées.
C’est Transform terminé.
Étape 3 : Charger
La dernière étape. Prenez les données propres et enregistrez-les quelque part. J’ai gardé cela simple et je l’ai chargé dans un fichier CSV :
df_clean.to_csv('github_trending_repos.csv', index=False)
print("Pipeline complete. File saved.")
print(f"{len(df_clean)} repos loaded into github_trending_repos.csv")
Sortir:
Pipeline complete. File saved.
29 repos loaded into github_trending_repos.csv
J’ai téléchargé le fichier et je l’ai ouvert. Une feuille de calcul propre avec 29 lignes et 9 colonnes. De vraies données GitHub, façonnées et enregistrées par un pipeline que j’ai construit à partir de zéro.
C’est le chargement terminé.
À quoi cela ressemblait-il réellement
Avant cela, chaque fois que je voulais utiliser des données, je cherchais un ensemble de données publiques que quelqu’un avait déjà nettoyé et téléchargé. Kaggle, recherche d’ensembles de données Google, n’importe où. J’ai toujours été un consommateur de données préparées par quelqu’un d’autre.
Cela a changé quelque chose pour moi.
Au moment où j’ai réalisé que je pouvais simplement pointer Python vers une API qui m’intéressait et extraire moi-même des données en direct, les possibilités m’ont semblé complètement différentes. Je ne me limite pas aux ensembles de données qui existent déjà. Je peux construire le pipeline qui crée l’ensemble de données.
C’est un autre type de pouvoir. Et c’est l’une des choses qui m’ont attiré vers l’ingénierie des données en premier lieu.
Quelle est la prochaine étape
Ce pipeline est simple de par sa conception. J’en suis au début de ma feuille de route et je ne vais pas encore prétendre que j’utilise Airflow ou Spark. Mais le fondement est réel. Extraire, Transformer, Charger. Ça marche. Je l’ai construit. Je le comprends.
La prochaine étape consiste à le rendre plus robuste. Planifiez-le pour qu’il s’exécute quotidiennement. Stockez la sortie dans une base de données SQLite au lieu d’un CSV plat. Commencez à suivre l’évolution des mises en pension au fil du temps.
Et finalement, orchestrez le tout avec Airflow. Mais c’est un prochain article.
Pour l’instant, la chose la plus importante que je me suis prouvée est que construire vous apprend des choses que regarder ne vous apprendra jamais. J’ai passé des semaines au pays des tutoriels et j’ai à peine bougé. J’ai passé un après-midi à construire, et je comprends ETL mieux que n’importe quelle vidéo.
Arrêtez de regarder. Commencez à construire.
Il s’agit de la deuxième partie de ma série en cours sur l’ingénierie des données. Suivez-moi pendant que je documente chaque étape du voyage, y compris les parties qui ne se passent pas bien. N’hésitez pas à consulter ma version ETL plus approfondie sur ma chaîne YouTube ci-dessous.
Connectez-vous avec moi sur LinkedIn, YouTubeet Gazouillement.



