Python Faker
last modified October 30, 2026 Python 3.15
In this article we show how to generate fake data in Python with the Faker package.
Faker
Faker is a Python library that generates fake data. Fake data is often used for testing or for filling databases with dummy data. Faker is inspired by PHP's Faker, Perl's Data::Faker, and Ruby's Faker.
The package is installed with pip.
$ pip install Faker
Faker generator
The faker.Faker class creates and initializes a faker
generator, which generates data through methods named after the type of
data, such as name or address.
Faker delegates the data generation to providers. The default locale is
en_US. Faker supports many other locales; they differ in level
of completion.
The data is random, so the output of the examples differs on each run. Seeding the generator, shown later, makes it reproducible.
Simple Faker
The following example is a simple demonstration of Faker.
from faker import Faker
faker = Faker()
print(f'name: {faker.name()}')
print(f'address: {faker.address()}')
print(f'text: {faker.text()}')
The example outputs a fake name, address, and text. The address and the text span several lines.
$ python simple.py name: Stephanie Mayer address: 7441 Jones Shoal West Jasmine, ND 93968 text: Into seek laugh important tough hold. Cost foreign central trouble general. Treatment key tough accept space top but. Least special tax PM. Science year fill decision factor.
Faking names
In the second example, we fake data related to user names.
from faker import Faker
faker = Faker()
print(f'Name: {faker.name()}')
print(f'First name: {faker.first_name()}')
print(f'Last name: {faker.last_name()}')
print('--------------------------')
print(f'Male name: {faker.name_male()}')
print(f'Female name: {faker.name_female()}')
print(f'Prefix: {faker.prefix()}, suffix: {faker.suffix()}')
The example creates fake full names, first names, and last names, names of males and females, and name prefixes and suffixes.
$ python names.py Name: Victoria Chen First name: Ariel Last name: Blackwell -------------------------- Male name: Matthew Camacho Female name: Melissa Velasquez Prefix: Mx., suffix: Jr.
Faking jobs
Jobs are generated with job.
from faker import Faker
faker = Faker()
for _ in range(6):
print(faker.job())
The example creates six fake jobs.
$ python jobs.py Surveyor, building control Estate manager/land agent Volunteer coordinator Exhibitions officer, museum/gallery Nurse, adult Lobbyist
Faking locale data
Faker supports localized data. The locale is passed to the constructor.
from faker import Faker
faker = Faker('cs_CZ')
for _ in range(3):
name = faker.name()
address = faker.address().replace('\n', ', ')
phone = faker.phone_number()
print(f'{name}; {address}; {phone}')
The example generates fake Czech names, addresses, and phone numbers. The
locale code is cs_CZ: the language code followed by the country
code. We replace the newline in the address with a comma to keep each
person on one line.
$ python localized.py Aleš Doležal CSc.; Opletalova 17, 242 17 Rtyně v Podkrkonoší; +420 605 417 169 Marie Ježková; K Lučinám 987, 304 61 Město Touškov; 00420 608 966 236 Vendula Králová; Chotětovská 474, 503 88 Chotěboř; +420 602 577 976
Multiple locales
The constructor also accepts a list of locales.
from faker import Faker
faker = Faker(['sk_SK', 'de_DE', 'ja_JP'])
for _ in range(4):
print(faker.name())
print('--------------------------')
for locale in faker.locales:
print(f'{locale}: {faker[locale].city()}')
Each call picks one of the locales at random. To use a specific locale, we
index the generator with the locale name. The locales attribute
lists the configured locales.
$ python multi_locale.py Martina Schmidtke-Thies Sibille Vollbrecht B.Sc. 小林 さゆり Jürgen Mielcarek-Bauer -------------------------- sk_SK: Padáň de_DE: Feuchtwangen ja_JP: 横浜市港南区
Faking currencies
The following example creates fake data for currencies.
from faker import Faker
faker = Faker()
print(f'currency: {faker.currency()}')
print(f'currency name: {faker.currency_name()}')
print(f'currency code: {faker.currency_code()}')
print(f'price tag: {faker.pricetag()}')
The currency method returns a tuple of the code and the name.
The pricetag method returns a formatted price.
$ python currencies.py
currency: ('AFN', 'Afghan afghani')
currency name: Namibian dollar
currency code: BDT
price tag: $35,255.57
Faking words and text
Faker can create dummy words, sentences, and paragraphs.
from faker import Faker
faker = Faker()
print(f'a word: {faker.word()}')
print(f'six words: {faker.words(6)}')
words = ['forest', 'blue', 'cloud', 'sky', 'wood', 'falcon']
print(f'customized unique words: {faker.words(3, words, True)}')
print(f'sentence: {faker.sentence(nb_words=5)}')
print(f'paragraph: {faker.paragraph(nb_sentences=2)}')
The example creates dummy words and text.
words = ['forest', 'blue', 'cloud', 'sky', 'wood', 'falcon']
print(f'customized unique words: {faker.words(3, words, True)}')
We can also pick words from our own list; the third argument requests unique words.
print(f'sentence: {faker.sentence(nb_words=5)}')
By default, the number of words in a sentence varies by up to 40 percent
around nb_words; with variable_nb_words=False,
the number is exact.
$ python words.py a word: run six words: ['still', 'lot', 'or', 'paper', 'marriage', 'own'] customized unique words: ['sky', 'sky', 'cloud'] sentence: Expect scientist half. paragraph: Whole far try decision along else. Should language minute way.
Faking profiles
Faker can create simple dummy profiles with simple_profile and
extended profiles with profile.
from pprint import pprint
from faker import Faker
faker = Faker()
profile1 = faker.simple_profile()
pprint(profile1)
print('--------------------------')
profile2 = faker.simple_profile(sex='M')
pprint(profile2)
print('--------------------------')
profile3 = faker.profile(fields=['name', 'job', 'company', 'blood_group',
'website'], sex='F')
pprint(profile3)
The example creates dummy profiles of females and males and prints them
with pprint. The fields parameter of
profile limits the profile to the selected fields.
$ python profiles.py
{'address': '31981 Tom Roads\nPort Kathleen, TX 84438',
'birthdate': datetime.date(1990, 5, 17),
'mail': 'scook@gmail.com',
'name': 'Deanna Byrd',
'sex': 'F',
'username': 'davidjohnson'}
--------------------------
{'address': 'Unit 0571 Box 5796\nDPO AA 72660',
'birthdate': datetime.date(1942, 5, 22),
'mail': 'mbond@yahoo.com',
'name': 'David Estrada',
'sex': 'M',
'username': 'nathanliu'}
--------------------------
{'blood_group': 'A-',
'company': 'Reyes and Sons',
'job': 'Chartered certified accountant',
'name': 'Cynthia Davis',
'website': ['http://orr-harrington.com/']}
Faking numbers
Faker can generate random digits, integers, floats, decimals, booleans, and elements of a collection.
from faker import Faker
faker = Faker()
print(f'Random int: {faker.random_int()}')
print(f'Random int: {faker.random_int(0, 100)}')
print(f'Random int with step: {faker.random_int(0, 100, step=10)}')
print(f'Random digit: {faker.random_digit()}')
print(f'Float: {faker.pyfloat(left_digits=2, right_digits=3, positive=True)}')
print(f'Decimal: {faker.pydecimal(left_digits=4, right_digits=2, positive=True)}')
print(f'Boolean: {faker.pybool()}')
print(f'Element: {faker.random_element(["red", "green", "blue"])}')
print(f'Elements: {faker.random_elements("abcdefgh", length=3, unique=True)}')
We can specify the bounds and the step in the random_int
method. The pyfloat and pydecimal methods take
the number of digits before and after the decimal point. The
random_elements method picks several elements; with
unique=True, without repetition.
$ python fake_numbers.py Random int: 1065 Random int: 2 Random int with step: 30 Random digit: 7 Float: 18.886 Decimal: 6560.95 Boolean: True Element: blue Elements: ['e', 'g', 'a']
Formatting templates
Faker can fill placeholders in a template string.
from faker import Faker
faker = Faker()
print(faker.numerify('order-####'))
print(faker.lexify('????-id'))
print(faker.bothify('##-??-##', letters='ABCDEF'))
print(faker.hexify('^^:^^:^^'))
print(faker.pystr_format('{{first_name}} ({{random_int}})'))
The numerify method replaces # with digits,
lexify replaces ? with letters, and
bothify does both; its letters parameter sets the
letters to choose from. The hexify method replaces
^ with hexadecimal digits. The pystr_format method
calls the methods named in double curly brackets.
$ python formats.py order-0801 ayBo-id 69-DA-04 c6:40:f0 Tina (5375)
Faking hashes and UUIDs
Faker can generate dummy hashes and UUIDs.
from faker import Faker
faker = Faker()
print(f'md5: {faker.md5()}')
print(f'sha1: {faker.sha1()}')
print(f'sha256: {faker.sha256()}')
print(f'uuid4: {faker.uuid4()}')
The example generates three fake hashes and one UUID value.
$ python hash_uuid.py md5: 16bbe790abb39d83f51b33a1aaddadd7 sha1: ce418346a9fe2518f8d360d754b8bed71c667bfd sha256: 52fa1d5b849db4f7ef010d81190bd9921e28d075669c6019d1d95110fe017b96 uuid4: 5321dcad-949c-4d80-b4a5-d1350d8e5729
Faking internet related data
Faker has several methods for faking internet related data.
from faker import Faker
faker = Faker()
print(f'Email: {faker.email()}')
print(f'Safe email: {faker.safe_email()}')
print(f'Free email: {faker.free_email()}')
print(f'Company email: {faker.company_email()}')
print('------------------------------------')
print(f'Host name: {faker.hostname()}')
print(f'Domain name: {faker.domain_name()}')
print(f'Domain word: {faker.domain_word()}')
print(f'TLD: {faker.tld()}')
print('------------------------------------')
print(f'IPv4: {faker.ipv4()}')
print(f'Private IPv4: {faker.ipv4_private()}')
print(f'IPv6: {faker.ipv6()}')
print(f'MAC address: {faker.mac_address()}')
print('------------------------------------')
print(f'URL: {faker.url()}')
print(f'Slug: {faker.slug()}')
print(f'User agent: {faker.user_agent()}')
The example shows various internet related data, including emails, domain
names, IP addresses, URLs, slugs, and user agents. The
safe_email method uses the reserved example.*
domains, so the generated addresses cannot belong to real people.
$ python internet.py Email: samuelbond@example.com Safe email: pcannon@example.com Free email: jonesstephanie@hotmail.com Company email: geraldkelly@gonzalez.com ------------------------------------ Host name: desktop-11.miller-lambert.com Domain name: rodriguez.com Domain word: benitez TLD: com ------------------------------------ IPv4: 157.150.110.47 Private IPv4: 192.168.2.123 IPv6: eca7:50f4:3901:91aa:3fa:1586:5bef:b8ed MAC address: f0:81:d2:5f:47:9d ------------------------------------ URL: https://www.case.com/ Slug: help-teacher-course User agent: Mozilla/5.0 (iPad; CPU iPad OS 17_4_1 like Mac OS X) AppleWebKit/533.2 (KHTML, like Gecko) CriOS/55.0.883.0 Mobile/81P534 Safari/533.2
Faking date and time
Faker has plenty of methods for faking date and time values.
from faker import Faker
faker = Faker()
print(f'Date of birth: {faker.date_of_birth(minimum_age=18, maximum_age=65)}')
print(f'Century: {faker.century()}')
print(f'Year: {faker.year()}')
print(f'Month: {faker.month()}')
print(f'Month name: {faker.month_name()}')
print(f'Day of week: {faker.day_of_week()}')
print(f'Day of month: {faker.day_of_month()}')
print(f'Time zone: {faker.timezone()}')
print(f'AM/PM: {faker.am_pm()}')
The example shows methods for the date of birth, date and time parts, time
zones, and AM/PM. The minimum_age and
maximum_age parameters bound the age of the person.
$ python date_time.py Date of birth: 1961-05-27 Century: XV Year: 2010 Month: 08 Month name: April Day of week: Friday Day of month: 12 Time zone: America/Guyana AM/PM: PM
Recent dates and time series
The next example generates values in the current century, decade, year, or month, and a time series.
from datetime import timedelta
from faker import Faker
faker = Faker()
print(f'Datetime this century: {faker.date_time_this_century()}')
print(f'Datetime this decade: {faker.date_time_this_decade()}')
print(f'Datetime this year: {faker.date_time_this_year()}')
print(f'Datetime this month: {faker.date_time_this_month()}')
print('-------------------------')
print(f'Date this century: {faker.date_this_century()}')
print(f'Date this decade: {faker.date_this_decade()}')
print(f'Date this year: {faker.date_this_year()}')
print(f'Date this month: {faker.date_this_month()}')
print('-------------------------')
series = faker.time_series(start_date='-12d', end_date='now',
precision=timedelta(days=2))
for timestamp, value in series:
print(timestamp, value)
The time_series method yields pairs of a timestamp and a random
value. The precision parameter sets the step between the
timestamps; relative dates such as -12d mean twelve days ago.
$ python date_time2.py Datetime this century: 2002-09-06 00:29:44.646039 Datetime this decade: 2021-12-18 06:54:31.362709 Datetime this year: 2026-04-13 23:32:39.677387 Datetime this month: 2026-10-09 04:39:50.258099 ------------------------- Date this century: 2010-10-17 Date this decade: 2023-11-04 Date this year: 2026-05-15 Date this month: 2026-10-10 ------------------------- 2026-10-18 20:53:44 80381.59040440954 2026-10-20 20:53:44 88973.72940411918 2026-10-22 20:53:44 110168.04424437074 2026-10-24 20:53:44 104294.88847840732 2026-10-26 20:53:44 101104.33042316716 2026-10-28 20:53:44 145529.7404315011
Date ranges
The third example shows methods for various datetime formats, for values in a chosen range, and for future or past values.
from faker import Faker
faker = Faker()
print(f'Unix time: {faker.unix_time()}')
print(f'Datetime: {faker.date_time()}')
print(f'iso8601: {faker.iso8601()}')
print(f'Date: {faker.date()}')
print(f'Time: {faker.time()}')
print('-------------------------')
print(f"Datetime between: {faker.date_time_between(start_date='-15y', end_date='now')}")
print(f"Date between: {faker.date_between(start_date='-30d', end_date='today')}")
print('-------------------------')
print(f'Future datetime: {faker.future_datetime()}')
print(f'Future date: {faker.future_date()}')
print(f'Past datetime: {faker.past_datetime()}')
print(f'Past date: {faker.past_date()}')
The date_time_between and date_between methods
generate values in a given range. The future and past methods generate
values within 30 days from now by default.
$ python date_time3.py Unix time: 1444940762.0257442 Datetime: 1991-02-10 19:30:34.072765 iso8601: 2011-08-31T04:00:44.342913 Date: 1997-03-08 Time: 23:09:58 ------------------------- Datetime between: 2017-05-05 19:30:59.724761 Date between: 2026-10-23 ------------------------- Future datetime: 2026-11-17 10:57:21.097191 Future date: 2026-11-12 Past datetime: 2026-10-28 21:39:56.542747 Past date: 2026-09-30
Seeding the generator
Tests need reproducible data. The Faker.seed class method seeds
the shared random generator, so the same sequence of calls produces the same
values.
from faker import Faker Faker.seed(4321) faker = Faker() print(faker.name(), faker.city(), faker.random_int(1, 100))
We run the program twice and get the same output. The values depend on the order of the calls and may change between Faker versions.
$ python seeding.py Jason Brown Lake Michael 87 $ python seeding.py Jason Brown Lake Michael 87
Unique values
The unique proxy ensures that a method does not return the same
value twice.
from faker import Faker
from faker.exceptions import UniquenessException
faker = Faker()
numbers = [faker.unique.random_int(1, 5) for _ in range(5)]
print(sorted(numbers))
try:
faker.unique.random_int(1, 5)
except UniquenessException as e:
print(f'error: {e}')
faker.unique.clear()
print(faker.unique.random_int(1, 5) in range(1, 6))
emails = {faker.unique.email() for _ in range(1000)}
print(len(emails))
We draw all five numbers between one and five. Another call cannot find a
new value and raises UniquenessException after a thousand
attempts. The clear method forgets the values seen so far. We
also generate a thousand unique emails, for instance for a table with a
unique column.
$ python unique_values.py [1, 2, 3, 4, 5] error: Got duplicated values after 1,000 iterations. True 1000
Custom providers
We can add our own providers to the generator.
from faker import Faker
from faker.providers import BaseProvider, DynamicProvider
class BookProvider(BaseProvider):
genres = ['fantasy', 'crime', 'history', 'science fiction', 'poetry']
def genre(self):
return self.random_element(self.genres)
def isbn_like(self):
return self.numerify('978-##-####-###-#')
language_provider = DynamicProvider(
provider_name='language',
elements=['Python', 'Go', 'Rust', 'C#', 'Java'],
)
faker = Faker()
faker.add_provider(BookProvider)
faker.add_provider(language_provider)
for _ in range(3):
print(f'{faker.catch_phrase()} | {faker.genre()} | {faker.isbn_like()}')
print(faker.language())
A provider is a subclass of BaseProvider; its public methods
become methods of the generator. The provider can use helpers such as
random_element and numerify. For a simple list of
values, a DynamicProvider is enough; its
provider_name becomes the method name.
$ python custom_provider.py Managed zero-defect forecast | fantasy | 978-38-0132-195-4 Down-sized uniform model | fantasy | 978-66-8149-710-7 Profound asymmetric synergy | fantasy | 978-79-7310-457-5 Go
Generating CSV data
Together with the csv module, we create a new CSV file with
fake data.
import csv
from faker import Faker
faker = Faker()
with open('users.csv', 'w', newline='') as f:
fieldnames = ['id', 'first_name', 'last_name', 'occupation']
writer = csv.DictWriter(f, fieldnames=fieldnames)
writer.writeheader()
for i in range(1, 101):
writer.writerow({'id': i, 'first_name': faker.first_name(),
'last_name': faker.last_name(),
'occupation': faker.job()})
The data contains an id, a first name, a last name, and a job title. The
data is written to the users.csv file.
fieldnames = ['id', 'first_name', 'last_name', 'occupation'] writer = csv.DictWriter(f, fieldnames=fieldnames)
We use the dictionary writer with the given field names.
writer.writeheader()
We write the header line.
for i in range(1, 101):
writer.writerow({'id': i, 'first_name': faker.first_name(),
'last_name': faker.last_name(),
'occupation': faker.job()})
We generate 100 users. Each user is written to the file with the
writerow method. Some job titles contain commas; the writer
quotes them.
$ python fake_csv.py $ head -5 users.csv id,first_name,last_name,occupation 1,Andrew,Mcgee,"Lecturer, further education" 2,Melissa,Durham,"Therapist, nutritional" 3,John,Green,Clinical research associate 4,April,Miller,Electronics engineer $ wc -l users.csv 101 users.csv
Generating XML data
In the following example, we generate XML data with Faker and a Jinja template. The XML file will contain users.
$ pip install jinja2
The XML generator
The program creates the users and renders them with the template.
from dataclasses import dataclass
from faker import Faker
from jinja2 import Environment, FileSystemLoader
@dataclass
class User:
first_name: str
last_name: str
occupation: str
faker = Faker()
users = [User(faker.first_name(), faker.last_name(), faker.job())
for _ in range(3)]
env = Environment(loader=FileSystemLoader('templates'), autoescape=True,
trim_blocks=True, lstrip_blocks=True,
keep_trailing_newline=True)
template = env.get_template('users.xml.j2')
output = template.render(users=users)
with open('users.xml', 'w', encoding='utf-8') as f:
f.write(output)
The program generates a list of three users, stored in a dataclass. The
list is passed to the Jinja template, which is located in the
templates directory. The generated content is written to the
users.xml file.
env = Environment(loader=FileSystemLoader('templates'), autoescape=True,
trim_blocks=True, lstrip_blocks=True,
keep_trailing_newline=True)
With autoescape=True, characters such as & in
the data are escaped, so the XML stays well-formed. The
trim_blocks and lstrip_blocks options remove the
whitespace left by the template tags.
<?xml version="1.0" encoding="UTF-8"?>
<users>
{% for user in users %}
<user id="{{ loop.index }}">
<firstname>{{ user.first_name }}</firstname>
<lastname>{{ user.last_name }}</lastname>
<occupation>{{ user.occupation }}</occupation>
</user>
{% endfor %}
</users>
In the template, we use the for directive to process the list
of users. The loop.index variable holds the iteration number,
starting from one.
$ python fake_xml.py
$ cat users.xml
<?xml version="1.0" encoding="UTF-8"?>
<users>
<user id="1">
<firstname>Theresa</firstname>
<lastname>Bridges</lastname>
<occupation>Development worker, international aid</occupation>
</user>
<user id="2">
<firstname>Nicholas</firstname>
<lastname>Barnes</lastname>
<occupation>Surveyor, building</occupation>
</user>
<user id="3">
<firstname>Joel</firstname>
<lastname>Hill</lastname>
<occupation>Clinical cytogeneticist</occupation>
</user>
</users>
Source
In this article we have used Python Faker to generate fake data.
Author
List all Python tutorials.