Faker is a test data generator we explored in the last post. Despite the large list of options to generate data, sometimes we need data in a format that Faker cannot offer. Should that happen, we can create our own data provider. Let us figure out how to do that.
Creating the custom provider
Our custom provider is a plain Python class that inherits from BaseProvider. The important part is that we use the self.random_element() method and do not access a different random generator. If we try that, we get random values, but the seed_instance() method will have no impact on our provider.
To create test data for a university, we could write a provider like this one:
fromfakerimportFakerfromfaker.providersimportBaseProviderclassUniversityProvider(BaseProvider):university_names=["Springfield University","Shelbyville Institute of Technology","Capitol City College","Metropolis University","Gotham City Academy"]faculty_names=["Faculty of Engineering","Faculty of Arts and Sciences","Faculty of Medicine","Faculty of Business Administration","Faculty of Law"]course_titles=["Introduction to Artificial Intelligence","Advanced Python Programming","Quantum Computing 101","History of Modern Art","Principles of Microeconomics"]building_names=["Newton Hall","Curie Science Center","Einstein Library","Turing Auditorium","Bohr Research Building"]defuniversity_name(self):returnself.random_element(self.university_names)deffaculty_name(self):returnself.random_element(self.faculty_names)defcourse_title(self):returnself.random_element(self.course_titles)defbuilding_name(self):returnself.random_element(self.building_names)
Register the provider
Before we can use our provider with Faker, we need to register it:
fake=Faker()fake.seed_instance(42)fake.add_provider(UniversityProvider)# Generate dataprint(fake.university_name())# Springfield Universityprint(fake.faculty_name())# Faculty of Medicineprint(fake.course_title())# Advanced Python Programmingprint(fake.building_name())# Einstein Library
If we run this code, we get a random set of university and faculty names, course titles and building names. That should help us already, but what if we want to influence the random generator a bit more?
Weighted data
Should we have a preference on how often certain values should be generated, we can make a slight modification and use a weighted approach. For that we put our data into an OrderedDict() and set a value for the weight. Be aware that the weight is only an indicator, but it is not guaranteed that we get values that exactly match what we specify.
To get grades where C and F are the most common and A is the least used, we could write this code and put it into our UniversityProvider class:
As we can see, F and C are usually the two most common grades, while A is the one with the least occurrences.
Conclusion
With a bit of our own code, we can create a custom provider that let us extend Faker. That way we can keep using Faker and all its amenities, even when we need a data format that does not ship with Faker.