simple and poor object data mapper library
Project description
Froshki is a simple and poor object data mapper library.
Looking quite similar to WTForms, rather intended to focus on data input/output abstraction, separating validation or conversion functions as APIs & extensions.
Instead of integrating with web forms etc., designed to achieve more flexible attribute sourcing.
Features
Define data schema as class definition.
Supply data inputs by keyword arguments, dict, or both.
Convert and validate data inputs with user defined methods or built-in integration with 3rd party libraries.
Access validated data as attributes / mapping.
Easy to hook your functions on validation.
Simple usage
Primitive demo:
>>> from froshki import Froshki, Attribute >>> >>> class ResourceId(Attribute): ... @classmethod ... def transform(klass, input_value): ... return int(input_value) ... @classmethod ... def validate(klass, input_value): ... if input_value in (1,5,7,9): ... return True, input_value ... else: ... return False, 'resource id not found' >>> >>> class Filetype(Attribute): ... @classmethod ... def transform(klass, input_value): ... return input_value.lower() ... @classmethod ... def validate(klass, input_value): ... if input_value in ('pdf', 'txt', 'mobi'): ... return True, input_value ... else: ... return False, 'filetype unavailable' >>> >>> class Download(Froshki): ... resource_id = ResourceId() ... filetype = Filetype() >>> >>> download = Download(resource_id='9', filetype='PDF') >>> download.validate() True >>> download.resource_id 9 >>> download.filetype 'pdf'
To use any functions of Froshki, extend froshki.Froshki to define data model schema. Attributes are represented by attaching froshki.Attribute subclasses onto the model.
You can add any data conversion (Attribute.transform) or validation (Attribute.validate) methods for attributes. Froshki.validate converts and validates all attributes as defined. But it’s a bit bothersome, and you can use a built-in extension supporting attribute definition.
Using trafaret extension
You need to pre-install trafaret to use the extension. Usage:
>>> from froshki import Froshki >>> import trafaret >>> from froshki.ext import trafaret_attr >>> >>> class SendInquiry(Froshki): ... user_name = trafaret_attr(trafaret.String())() ... user_contact = trafaret_attr(trafaret.Email())() ... message = trafaret_attr(trafaret.String(regex=r'\w{10,400}'))() >>> >>> send_inquiry = SendInquiry( ... user_name='yu mat', user_contact='drowse314@gmail.com', ... message='cannot post messages to my group' ... ) >>> send_inquiry.validate() True
If you prefer other validation libraries, you will find it so easy to extend froshki.Attribute.validate. Or some more libraries are built-in supported:
See froshki/ext/*_attr.py for documentation or details of extension wrinting.
Other features
Data as mappings
Some utility properties are available for accessing validated data:
(...) >>> send_inquiry.data {'user_name': 'yu mat', 'user_contact': 'drowse314@gmail.com', 'message': 'cannot post messages to my group'} >>> send_inquiry.errors # error messages are registered if validation failed {}
Further, you can initialize froshki.Froshki with mappings:
(...) >>> data = {'user_name': 'ymat', 'user_contact': 'drowse314.gmail.com', 'message': 'cannot post messages to my group'} >>> another_inquiry = SendInquiry(source=data) >>> another_inquiry.validate() False
Source attributes with alias names
You can use the names differring from the class attribute names for sourcing attributes:
>>> class ResourceAccess(Froshki): ... resource_id = Attribute() ... user_id = Attribute() ... resource_key = Attribute(key_alias='password') >>> access = ResourceAccess(resource_id='1276', user_id='ymat', password='VXFPF93') >>> access.resource_key 'VXFPF93'
Extra validation
You can add attribute dependent extra validator methods for attribute relations etc., using validation_hook decorator:
>>> from froshki import Froshki, Attribute, validation_hook >>> >>> class SendInquiry(Froshki): ... user_name = Attribute() ... user_contact = Attribute() ... user_contact_confirmation = Attribute() ... message = Attribute() ... @validation_hook ... def confirm_email(self): ... return self.user_contact == self.user_contact_confirmation >>> >>> send_inquiry = SendInquiry( ... user_name='yu mat', user_contact='drowse314@gmail.com', user_contact_confirmation='drose@gmail.com', ... message='cannot post messages to my group' ... ) >>> send_inquiry.validate() False
If you need error information with these extra validators, extend the decorator as following:
(...) >>> class SendInquiryExt(SendInquiry): ... @validation_hook.extend(error='inconsistent email inputs') ... def confirm_email(self): ... return self.user_contact == self.user_contact_confirmation >>> >>> send_inquiry = SendInquiry( ... user_name='yu mat', user_contact='drowse314@gmail.com', user_contact_confirmation='drose@gmail.com', ... message='cannot post messages to my group' ... ) >>> send_inquiry.validate() False >>> send_inquiry.errors {'confirm_email': 'inconsistent email inputs'}
Subclassing and attribute mixin
froshki.Froshki subclasses are usable as base classes:
(...) >>> class Resource(Froshki): ... resource_id = ResourceId() >>> >>> class Download(Resource): ... filetype = Filetype() >>> >>> download = Download(resource_id='9', filetype='pdf') >>> download.validate() True
Mixins are useful if you want to share some attribute definitions between schemas:
(...) >>> class UserMixin(object): ... user = Attribute() >>> >>> class DownloadAsUser(Download, UserMixin): ... pass >>> >>> download_as_someone = DownloadAsUser( ... resource_id='5', filetype='mobi', ... user='ymat', ... ) >>> download_as_someone.validate() True >>> download_as_someone.user 'ymat'
You can use any classes as attribute mixins by attaching froshki.Attribute instances, with the exception of froshki.Froshki subclass which causes MRO issue.
Other options
froshki.Froshki class has some useful options.
Froshki.default_values: provide attribute defaults as dict.
Froshki.ignore_unkown_keys: control if source argument accepts names that are not defined as attributes, or not (True/False).
Also some options for froshki.Attribute.
(As argument) Attribute(nullable=<bool>): allows None in validation (with any validation methods set).
Project details
Download files
Download the file for your platform. If you're not sure which to choose, learn more about installing packages.