Package: fake.py
Minimalistic, standalone alternative fake data generator with no dependencies.fake.pyis a standalone, portable library designed for generating various
random data types for testing.It offers a simplified, dependency-free alternative for creating random
texts, (person) names, URLs, dates, file names, IPs, primitive Python data
types (such asuuid,str,int,float,bool) and byte content
for multiple file formats includingPDF,DOCX,PNG,SVG,BMP,
andGIF.The package also supports file creation on the filesystem and includes
factories (dynamic fixtures) compatible withDjango,TortoiseORM,PydanticandSQLAlchemy.FeaturesGeneration of random texts, (person) names, emails, URLs, dates, IPs, and
primitive Python data types.Support for various file formats (PDF,DOCX,TXT,PNG,SVG,BMP,GIF) and file creation on the filesystem.Basic factories for integration withDjango,Pydantic,TortoiseORMandSQLAlchemy.PrerequisitesPython 3.8+Installationpippipinstallfake.pyDownload and copyfake.pyis the sole, self-contained module of the package. It includes
tests too. If it’s more convenient to you, you could simply download thefake.pymodule and include it in your repository.Since tests are included, it won’t have a negative impact on your test
coverage (you might need to apply tweaks to your coverage configuration).DocumentationDocumentation is available onRead the Docs.For various ready to use code examples see theRecipes.For tips on how to use the factories see theFactories.For customization tips see theCustomization.For tips onPDFcreation seeCreating PDF.For tips onDOCXcreation seeCreating DOCX.For tips on images creation seeCreating images.For guidelines on contributing check theContributor guidelines.For various implementation examples, see theExamples.UsageGenerate dataPerson namesfromfakeimportFAKERFAKER.first_name()FAKER.last_name()FAKER.name()FAKER.username()Random textsfromfakeimportFAKERFAKER.slug()FAKER.word()FAKER.sentence()FAKER.paragraph()FAKER.text()InternetfromfakeimportFAKERFAKER.email()FAKER.url()FAKER.ipv4()FilenamesfromfakeimportFAKERFAKER.filename()Primitive data typesfromfakeimportFAKERFAKER.pyint()FAKER.pybool()FAKER.pystr()FAKER.pyfloat()DatesfromfakeimportFAKERFAKER.date()FAKER.date_time()Generate filesAs bytesfromfakeimportFAKERFAKER.pdf()FAKER.docx()FAKER.png()FAKER.svg()FAKER.bmp()FAKER.gif()As files on the file systemfromfakeimportFAKERFAKER.pdf_file()FAKER.docx_file()FAKER.png_file()FAKER.svg_file()FAKER.bmp_file()FAKER.gif_file()FAKER.txt_file()FactoriesThis is how you could define factories forDjango’s built-inGroupandUsermodels.fromdjango.contrib.auth.modelsimportGroup,Userfromfakeimport(DjangoModelFactory,FACTORY,PostSave,PreSave,trait,)classGroupFactory(DjangoModelFactory):"""Group factory."""name=FACTORY.word()classMeta:model=Groupget_or_create=("name",)defset_password(user:User,password:str)->None:"""Helper function for setting password for the User."""user.set_password(password)defadd_to_group(user:User,name:str)->None:"""Helper function for adding the User to a Group."""group=GroupFactory(name=name)user.groups.add(group)classUserFactory(DjangoModelFactory):"""User factory."""username=FACTORY.username()first_name=FACTORY.first_name()last_name=FACTORY.last_name()email=FACTORY.email()date_joined=FACTORY.date_time()last_login=FACTORY.date_time()is_superuser=Falseis_staff=Falseis_active=FACTORY.pybool()password=PreSave(set_password,password="test1234")group=PostSave(add_to_group,name="Test group")classMeta:model=Userget_or_create=("username",)@traitdefis_admin_user(self,instance:User)->None:"""Trait."""instance.is_superuser=Trueinstance.is_staff=Trueinstance.is_active=TrueAnd this is how you could use it:# Create just one useruser=UserFactory()# Create 5 usersusers=UserFactory.create_batch(5)# Create a user using `is_admin_user` traituser=UserFactory(is_admin_user=True)# Create a user with custom passworduser=UserFactory(password=PreSave(set_password,password="another-password"),)# Add a user to another groupuser=UserFactory(group=PostSave(add_to_group,name="Another group"),)# Or even add user to multiple groups at onceuser=UserFactory(group_1=PostSave(add_to_group,name="Another group"),group_2=PostSave(add_to_group,name="Yet another group"),)CustomizeMake your own custom providers and utilize factories with them.importrandomimportstringfromfakeimportFaker,Factory,providerclassCustomFaker(Faker):@providerdefpostal_code(self)->str:number_part="".join(random.choices(string.digits,k=4))letter_part="".join(random.choices(string.ascii_uppercase,k=2))returnf"{number_part}{letter_part}"FAKER=CustomFaker()FACTORY=Factory(FAKER)Now you can use it as follows (make sure to import your custom instances
ofFAKERandFACTORY):FAKER.postal_code()fromfakeimportModelFactoryclassAddressFactory(ModelFactory):# ... other definitionspostal_code=FACTORY.postal_code()# ... other definitionsclassMeta:model=AddressTestsRun the tests with unittest:python-munittestfake.pyOr pytest:pytestDifferences with alternativesfake.pyisFaker+factory_boy+faker-filein one package,
radically simplified and reduced in features, but without any external
dependencies (not evenPillowordateutil).fake.pyis modeled after the famousFakerpackage. Its’ API is highly
compatible, although drastically reduced. It’s not multilingual and does not
support postal codes or that many RAW file formats. However, you could easily
include it in your production setup without worrying about yet another
dependency.On the other hand,fake.pyfactories look quite similar tofactory_boyfactories, although again - drastically simplified and reduced in
features.The file generation part offake.pyare modelled after thefaker-file.
You don’t get a large variety of file types supported and you don’t have that
much control over the content of the files generated, but you get
dependency-free valid files and if that’s all you need, you don’t need to look
further.However, at any point, if you discover that you “need more”, go forFaker,factory_boyandfaker-filecombination.LicenseMITSupportFor security issues contact me at the e-mail given in theAuthorsection.For overall issues, go toGitHub.AuthorArtur Barseghyan <artur.barseghyan@gmail.com>