Skip to main content

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.

Source Distribution

froshki-0.4.3.tar.gz (8.2 kB view details)

Uploaded Source

File details

Details for the file froshki-0.4.3.tar.gz.

File metadata

  • Download URL: froshki-0.4.3.tar.gz
  • Upload date:
  • Size: 8.2 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? No

File hashes

Hashes for froshki-0.4.3.tar.gz
Algorithm Hash digest
SHA256 be32dc5d3689940f34767192ed134f7edc0be3977c283537ec7c29dec1d6cbf9
MD5 7b2c39b32241473905b73384bee8a814
BLAKE2b-256 010e41ef67afe52114379654566f4911099ab2b3c1848f496cae97f55f4f462d

See more details on using hashes here.

Supported by

AWS Cloud computing and Security Sponsor Datadog Monitoring Depot Continuous Integration Fastly CDN Google Download Analytics Pingdom Monitoring Sentry Error logging StatusPage Status page