Base class for easy filtering of iterable of dictionaries.
Project description
AnyFilter is a simple base class for defining data filters. It provides the following functionality:
stores configurations in JSON
retains previous versions of configurations with user info and timestamp
isolates custom code
The intent is to create a subclass of the Filter class in any case where custom code has to be written. This keeps the custom code out of the primary workflow and codebase, and allows Filter subclasses to be inserted and toggled as needed, while storing configurations for the filters outside the codebase and the applications’s primary database for portability and ease of maintenance.
Motivation
The problem which led to this solution is the need to consume data from end users. Usually, and especially when the users are clients, this data can not be relied upon to meet the input specifications of your system.
This usually leads one of these sub-optimal solutions:
Have custom scripts to pre-process data per client
Adding a bunch of if statements, or other similar logic to the core product
Attempting to make transformation scripts generic enough to re-use, thus making them less useful for their primary purpose and harder to debug
Hard-coding data into transformation scripts
There is often a custom transformation per client or project, so these solutions do not scale well.
The goals of AnyFilter are:
Minimize the amount of custom code in the primary codebase
Store configurations outside the application’s database in a portable format
Allow updates of configuration data without deploying code (privileged users may even edit a configuration via some sort of GUI)
Benefits
create pluggable data filters
store configurations outside your application’s database
easily back up and restore configurations
easily duplicate configurations across servers
Planned features
Export and import configs
Convert configs to and from HTML forms for easy front-end functionality
Easily revert to a prior config
Comprehensive unit tests
Sample usage
#!/usr/bin/env python
"""
This is a simple example of the use of the Filter class. In this case, a
dictionary has some keys renamed. This is a trivial example; filters
can be as complex as required.
"""
from anyfilter import Filter
class NameFilter(Filter):
"""
A filter that changes the names of dictionary keys.
'data' should be an iterable of dictionaries
"""
def __call__(self, data):
"""
The contents of this function are the least-important part of
this demo. This is where you custom code will go, doing whatever
it is you need with whatever config format and content you need.
"""
for rec in data:
# The config for this filter is a dictionary where the
# key is the key name to replace, and the value is the new name.
# update values in "data" dict
for key, value in self.config.items():
if key in rec:
rec[value] = rec[key]
del rec[key]
return data
if __name__ == '__main__':
import os # for dealing with the environment variable manually
# set environment variable for demo purposes
original_envvar = os.environ.get('FILTER_CONFIG_DIR', '')
os.environ['FILTER_CONFIG_DIR'] = '/tmp'
# Instantiate subclass. The only argument is the uid of the subject
# of the filter. For example, if you need to store different rules
# per user of your site, you might use the user's primary key here.
# This allows storage of configs per filter *and* per user.
name_filter = NameFilter('foo')
# Set some filter items. This normally won't be a part of the flow.
# It's here for demo purposes. In normal usage, the config would
# already be set and probably rarely updated.
name_filter.config = {
'dog': 'canine',
'cat': 'feline',
'horse': 'equine',
}
name_filter.save_config(user='example')
data = [{
'cat': 'meow',
'dog': 'woof',
'horse': 'neigh',
'foo': 'bar',
}]
print data # original
print name_filter(data) # altered
# Put it back like we found it, just to be good citizens.
os.environ['FILTER_CONFIG_DIR'] = original_envvar
Sample output
[{'horse': 'neigh', 'foo': 'bar', 'dog': 'woof', 'cat': 'meow'}] [{'equine': 'neigh', 'feline': 'meow', 'canine': 'woof', 'foo': 'bar'}]
Project details
Download files
Download the file for your platform. If you're not sure which to choose, learn more about installing packages.
Source Distribution
File details
Details for the file AnyFilter-0.05.tar.gz
.
File metadata
- Download URL: AnyFilter-0.05.tar.gz
- Upload date:
- Size: 4.3 kB
- Tags: Source
- Uploaded using Trusted Publishing? No
File hashes
Algorithm | Hash digest | |
---|---|---|
SHA256 | 6cfab8f426c00c54b053d915553d9af5322811064e0a08a1c3503c99bca299e4 |
|
MD5 | 7600a89529e4567c3c20fc8c20a978ef |
|
BLAKE2b-256 | 26b11191e68cfa99532d3739f75f07987dcd232691920558514932eba7395d39 |