Image de l'article

Générer des données aléatoires avec faker

Découvre comment générer des données aléatoires pour tester tes applications avec la bibliothèque Python faker.

Publié le 13 mai 2021 par ThibH

Il arrive très souvent quand on crée des scripts qu'on ait besoin de données pour tester les différentes fonctionnalités de notre application.

Si vous avez déjà suivi les formations de Docstring, vous avez par exemple déjà du m'entendre parler de Patrick. Ou Julien, ou Pierre, ou Paul... Des noms génériques qu'en tant que formateur on finit par utiliser à toutes les sauces.

Pour palier à ce problème et travailler avec des données plus variées et proches de la réalité, des développeurs ingénieux ont développé la bibliothèque Faker, qui permet de générer tous types de données aléatoires.

Préparez-vous à être surpris de la puissance de cette bibliothèque !

Installation et premiers pas

Pour installer Faker, rien de plus simple, on utilise pip :

pip install Faker

On peut ensuite très facilement commencer à générer des données aléatoire en créant une instance de la classe Faker :

from faker import Faker
fake = Faker()

fake.name()
# Keith Lewis

fake.address()
# USCGC Horton
# FPO AP 31959

fake.text()
# Visit watch collection able second still. Particular movement must phone expert next.
# Identify house cultural major. Exist standard new never. Base film itself little world.

Magique non ?

Et si vous en avez marre de l'anglais partout, vous pouvez préciser le pays à partir duquel vous souhaitez générer des données grâce au paramètre locale :

from faker import Faker
fake = Faker(locale="fr_FR")

print(fake.name())
# Victor Barre

print(fake.address())
# 930, boulevard de Barbier
# 56914 Saint Simone-les-Bains

print(fake.text())
# Sur science âge pareil premier sorte prévenir. Taille ajouter appartenir mariage sommeil rencontrer. Capable qui rue poser.
# Marche sauvage monde. Comprendre continuer pour posséder charge en quelque.

Vous êtes québécois et Saint Simone-les-Bains ne fait pas partie des villes de votre pays (oui j'ai dit pays 😱) ? Pas de soucis, on peut générer du M. Tremblay (oui je sais les clichés) avec fr_CA :

from faker import Faker
fake = Faker(locale="fr_CA")

for _ in range(10):
    print(fake.name())

# Louis Blouin
# Dominique Forget
# Emmanuelle Langlois-Lauzon
# Jean Pilon
# Audrey Gagné
# Sylvie Drolet
# Stéphanie Smith
# Louise Dufresne
# Robert-René Labbé
# Rémy Thériault
Vous trouverez la liste de toutes les valeurs supportées par le paramètre locale sur cette page.

Vous remarquerez également que les appels successifs à la méthode name nous retournent à chaque fois une valeur différente !

Une simple boucle for et on génère automatiquement dix noms différents d'habitants du Québec. Magique je vous dit ⚡️

Générer des données uniques

Généralement quand on a un jeu de données, on préfère éviter les valeurs en double.

Faker permet de générer des données uniques très facilement le mot unique devant l'élément que vous souhaitez générer.

Par exemple, si vous souhaitez générer 500 nombres aléatoires uniques :

import faker

fake = faker.Faker()

for _ in range(500):
    print(fake.unique.random_int())

Et si vous ne me croyez pas, on peut vérifier que la longueur de la liste est la même que la liste sous forme de set (les sets ne permettent pas d'avoir des valeurs en double) :

import faker

fake = faker.Faker()

numbers = [fake.unique.random_int() for _ in range(500)]
assert len(numbers) == len(set(numbers))  # Ne lèvera jamais de AssertionError

Si vous générer un nombre trop important de données, il se peut que Faker ne puisse pas vous garantir des données uniques. Si on essaie par exemple de générer 50,000 prénoms aléatoires, on va finir par tomber sur des doublons.

Faker vous avertira de la présence de doublons en levant l'exception UniquenessException :

from faker import Faker

fake = Faker()

for _ in range(50000):
    print(fake.unique.first_name())

# Au bout de 1,000 itérations, on obtient l'erreur
# faker.exceptions.UniquenessException: Got duplicated values after 1,000 iterations.

La base de données des prénoms ne contenant pas plus de 1,000 valeurs uniques, si vous essayez d'en générer 50,000, vous arriverez donc à la limite des valeurs uniques au bout de 1,000 itérations.

Quelques Providers intéressants

Faker dispose de nombreux « providers » qui vous permettent de générer des données aléatoires.

Vous pouvez retrouver la liste complète des providers et leurs attributs dans la documentation.

Vous serez vraiment impressionné par le nombre de données qui sont supportées par la bibliothèque.

Voici quelques exemples de Providers courant :

job pour générer des noms d'emplois :

from faker import Faker

fake = Faker(locale="fr_FR")

for _ in range(10):
    print(fake.job())

# cordiste
# technicien de maintenance en informatique
# halieute
# secrétaire d'édition
# géotechnicien
# secrétaire administratif
# chaudronnier
# inséminateur
# étalagiste
# chercheur en physique
Halieute 🧐 ? L'halieutique est la science de l'exploitation des ressources vivantes aquatiques 😮

file_path pour générer des chemins de fichier :

from faker import Faker

fake = Faker()

for _ in range(5):
    print(fake.file_path())

# /career/several.css
# /near/author.gif
# /lawyer/red.mp4
# /prevent/operation.flac
# /site/home.csv

Notez que chaque provider accepte un certain nombre de paramètres qui vous permettent d'obtenir des données plus précises. Pour les fichiers, on peut par exemple spécifier le nombre sous-dossiers et la catégorie (le type) des fichiers souhaités :

from faker import Faker

fake = Faker()

for _ in range(5):
    print(fake.file_path(depth=5, category='video'))

# /cell/both/small/style/reflect/strong.avi
# /many/buy/it/popular/maybe/drive.mp4
# /teach/really/finish/southern/however/image.mov
# /include/first/senior/argue/next/mother.avi
# /pick/color/every/within/along/outside.mp4

Pour connaître tous les paramètres disponibles, je vous renvoie là encore vers la documentation de la bibliothèque.

credit_card pour générer des numéros de carte de crédit avec notamment credit_card_expirecredit_card_number et credit_card_security_code :

from faker import Faker

fake = Faker()

for _ in range(5):
    print(fake.credit_card_number(), fake.credit_card_expire(), fake.credit_card_security_code())

# 3597992301554078 05/27 391
# 30558903049105 04/26 414
# 4309381212381 03/31 589
# 4796686812496068352 11/25 257
# 4681422435673721248 10/23 540

Malheureusement, ces cartes de crédits ne permettent pas d'effectuer des achats en ligne 😭 Bien essayé !

color avec notamment hex_color ou rgb_color qui permettent de générer des couleurs aléatoires :

from faker import Faker

fake = Faker()

for _ in range(5):
    print(fake.rgb_color())

# 205,49,136
# 32,160,130
# 255,178,40
# 41,123,122
# 100,48,43


from faker import Faker

fake = Faker()

for _ in range(5):
    print(fake.hex_color())

# #266358
# #1ce6a2
# #a35cd1
# #fa9f1b
# #aa0b21
Générer des données spécifiques

Parfois, on a besoin d'être un peu plus spécifique et de générer des données aléatoires qui suivent un certain format.

Si vous créez une application de gestion d'inventaire d'une librairie par exemple, vous aurez probablement besoin de générer des numéros ISBN spécifiques (numéros d'identification des livres).

Il existe bien un provider pour générer des données ISBN (magique cette bibliothèque je vous dit !) mais tous les cas de figures de tous les pays ne sont pas pris en compte.

Imaginez que vous deviez générer un numéro ISBN aléatoire sous cette forme :

'978-2-5351-3933-554-23'

La classe BaseProvider permet de générer des séquences aléatoires qui suivent un certain format.

La méthode numerify par exemple permet d'utiliser des caractères spécifiques par des nombres. Le caractère # sera ainsi remplacé par un nombre de 0 à 9. Le caractère % lui sera remplacé par un nombre de 1 à 9.

On peut ainsi générer un ISBN aléatoire de cette façon :

from faker import Faker

fake = Faker()

for _ in range(5):
    print(fake.numerify(text='%%%-%-%%%%-%%%%-%%%-%%'))

# 568-1-3152-1486-157-28
# 775-4-4936-7785-358-32
# 649-2-5754-9224-327-61
# 712-6-8111-1927-199-59
# 555-2-3311-4633-725-18

Besoin de générer des numéros de produits aléatoires ? Facile avec bothify :

from faker import Faker

fake = Faker()

for _ in range(5):
    print(fake.bothify(text='Product Number: ????-########'))

# Product Number: LEnd-92786420
# Product Number: XGFW-14616317
# Product Number: zWMP-16845523
# Product Number: SAxo-14205482
# Product Number: cwwt-23855798
Conclusion

Vous l'aurez compris, cette bibliothèque est vraiment très avancée et vous évitera d'abuser de Patrick, Pierre et Julie dans vos scripts d'exemples. On peut vraiment générer tous les types de données nécessaires à nos tests, en allant jusqu'à une précision extrême, selon les cas de figure.

Pour voir toutes les possibilités offertes par cette bibliothèque, n'hésitez pas à aller faire un tour dans la documentation.