QuickScheme

Add Programatic Schema to arbitrary data for data processing without data markup

Build Status Coverage Status PyPI version

QuickScheme - Quick Way To Define Data Schema and Mapping Data To Objects

| ⚠️WARNING : This is currently a Work in Progress and is not ready for general use yet | | :—: |

QuickScheme Release Notes

Quick Intro to QuickScheme

QuickScheme is a quick and easy to map arbitrary data in any python dict to an object without forcing markup of the data file.

This allows easy data definition in YAML or JSON files including references, defaults, etc

Features

Usage

Basic Example Walkthrough

| NOTE: This example exists in examples directory as “basic.py” | | :—: |

To get the most out of QuickScheme you need to define the objects your schema consists of.

for example if we want to process a yaml file like this:

  version: 1
  updates:
    # this is our update log to demonstrate lists 
    - 2019-08-14: initial version
    - 2019-08-15: added user3
    - 2019-08-15: added project2
  users:
    user1:
      first_name: User
      last_name: One
    user2:
      first_name: Another
      last_name: User
      email: another.user@mydomain.com
      desc: Another User
    user3:
      first_name: Another
      last_name: User
      email: another.user@mydomain.com
      desc: Another User

  groups:
    users:
      desc: Regular Users
    admins: Admins

   projects:
      project1:
        desc: My First Project
        users:
          - user1
        groups:
          - admins
      project2:
        desc: My Other Project
        groups:
          - users

So, what we have here is a version of the file, a list of users and groups and list of projects. A few interesting things:

So, to be easily this we define our objects that represent the entities:

Let us define Group first:

class Group(SchemeNode):
    FIELDS = [
        Field('groupname', identity=True),
        Field('desc', brief=True, default='No Description')
    ]

What is happening here:

This takes care of how we defined admin group and allows us to know the groupname if we are working with this object directly in python.

Next lets define User

class User(SchemeNode):
    FIELDS = [
        Field('username', identity=True),
        Filed('userid', ftype=int, required=True),
        Field('first_name', default="", required=True),
        Field('last_name', default="", required=True),
        Field('email', default="", required=False),
        Field('desc', default="No Description", required=False),
        Field('groups', ftype=ListOfReferences(Group, ".groups", False),
              default=[], required=False),
    ]

What is happening here:

Lastly We need a Project object:

class Project(SchemeNode):
    FIELDS = [
        Field('projectname', identity=True),
        Field('order', ftype=int, required=True),
        Field('users', ftype=ListOfReferences(User, ".users"),
              default="", required=True),
        Field('groups', ftype=ListOfReferences(Group, ".groups"),
              default=[], required=False),
    ]

This is similar to previous objects

Now to put it all together, we create a root Object that represents the document:

class Data(SchemeNode):
    FIELDS = [
        Field('version', ftype=str, default='1'),
        Field('updates', ftype=ListOfNodes(str)),
        Field('groups', ftype=KeyBasedList(Group)),
        Field('users', ftype=KeyBasedList(User)),
        Field('projects', ftype=KeyBasedList(Project))
    ]

    PRESERVE_ORDER = True
    ALLOW_UNDEFINED = True

Here we have the same thing describing the root document:

Usage Reference

Node Types

Currently implemented Node Types:

Fields

Definitions of key-based fields

TODOS:

Things that may be documented but not yet implemented or are in works:

(right now this is a very open list, many things are not yet done)