Giter Site home page Giter Site logo

capless / pfunk Goto Github PK

View Code? Open in Web Editor NEW
6.0 3.0 1.0 946 KB

A Python library to make writing applications with FaunaDB easier. Includes GraphQL and generic ABAC auth workflow integrations.

Home Page: https://www.pfunk.io/docs/pfunk.html

License: Apache License 2.0

Dockerfile 0.06% Python 99.79% Jinja 0.11% HTML 0.03%
faunadb fauna orm

pfunk's Introduction

Pfunk logo

A Python library to make writing applications with FaunaDB easier. Includes GraphQL and generic ABAC auth workflow integrations.

Key Features

  • DRY (Don't Repeat Yourself) code to help you create multiple collections, indexes, roles, and user-defined functions quickly. This helps you create more functionality with less code.
  • Mix and match authorization workflows (Group and user based)
  • Group level permissions
  • Create a GraphQL endpoint and a schema validating ORM with the same code.
  • Authentication collections, indexes, user-defined functions, and roles included.
  • Generic CRUD user-defined functions included
  • Create a REST API to integrate Fauna and Non-Fauna related tasks
  • Schema validation based on the Valley library.

Full Documentation

Documentation

Table of Contents

Getting Started

Installation

pip install pfunk

Setup the Connection

Using Environment Variables (Preferred Method)

If you can easily set environment variables just set the FAUNA_SECRET environment variable to your key.

Define your Collections (collections.py)

For an example project let's create a project management app.

from pfunk import (Collection, StringField, ReferenceField, DateField,
                   Project, Enum, EnumField, IntegerField, FloatField,
                  SlugField)
from pfunk.contrib.auth.collections import User, Group
from pfunk.contrib.auth.resources import GenericGroupBasedRole, GenericUserBasedRole



STATUS = Enum(name='ProductStatus', choices=['unstarted', 'started', 'completed', 'delivered'])


class AbstractGroupCollection(Collection):
    """
    Abstract Collection very similar to abstract models in Django. 
    The main difference is you don't have to add abstract=True in the Meta class.
    """
    # Here we are defining the roles that should be 
    # created for this collection (by proxy this role will be applied 
    # to its subclasses. We could however change the list of roles below.
    collection_roles = [GenericGroupBasedRole]
    title = StringField(required=True)
    group = ReferenceField(Group, required=True)
    
    def __unicode__(self):
        return self.title
    
    
class Product(AbstractGroupCollection):
    slug = SlugField(required=True)
    description = StringField()
    due_date = DateField(required=False)
    
    class Meta:
        """
        Add unique together index to ensure that the same slug is not used 
        for more than one product that belongs to a group. Similar to the
        Github's repo naming convention ex. https://github.com/capless/pfunk. 
        In that example 'capless' is the group slug and 'pfunk' is the 
        product's slug
        """
        unique_together = ('slug', 'group')
    
    
class Sprint(AbstractGroupCollection):
    product = ReferenceField(Product, required=True)
    start_date = DateField(required=True)
    end_date = DateField(required=True)
    
    
class Story(AbstractGroupCollection):
    description = StringField()
    points = IntegerField()
    product = ReferenceField(Product, required=True)
    sprint = ReferenceField(Sprint, required=False)
    status = EnumField(STATUS)
    

# Create a Project
project = Project()

# Add Collections to the Project
project.add_resources([User, Group, Product, Story, Sprint])

Auth Workflows

In the example above, the collection_roles list on the Collection classes attaches generic roles to the collection. Currently, you can choose a group based workflow, user based, or a mix of the two.

User Based Role

This role allows you to create, read, write, and delete documents that you haveyou are the owner of. The user field determines if you are the owner.

Group Based Role

This role allows you to create, read, write, and delete documents if both of the following conditions are true:

  1. You belong to the group that owns the document
  2. You have the create permission to perform the action (create, read, write, and delete)

Publish

project.publish()

Create Group and User

Both of the code samples below will create a new user, group, and users_groups (many-to-many relationship through collection) record.

from pfunk.contrib.auth.collections import Group, User
group = Group.create(name='base', slug='base')

# Example 2: You could also create a user with the following code
user = User.create(username='notthegoat', first_name='Lebron', last_name='James',
                   email='[email protected]', account_status='ACTIVE', groups=[group],
                   _credentials='hewillneverbethegoat')

Give User New Permissions

# User instance from above (username: notthegoat)
user.add_permissions(group, ['create', 'read', 'write', 'delete'])

Login

from pfunk.contrib.auth.collections import User

#The login classmethod returns the authenticated token if the credentials are correct.
token = User.login('goat23', 'cruelpass')

Save Some Data

Let's use the Video collection, and the authenticated token we created above to save some data.

# Use the token from above so the current users permissions are used.


product = Product.create(
    title='PFunk Project',
    slug='pfunk',
    description='Some example project for test Pfunk',
    group=group,
    _token=token #The token gained in the previous step. If you do not specify a token here it defaults to the key used in the FAUNA_SECRET env.
)

Query your Data

Let's get the video you just created.

product = Product.get('the-key-for-the-previous-video', _token=token)

Let's query for all videos using the server key.

products = Products.all()

Let's query for all videos that the logged in user has access to.

products = Products.all(_token=token)

Delete a Record

Let's delete the record from above.

product.delete()

pfunk's People

Contributors

bjinwright avatar brianjinwright avatar dependabot[bot] avatar zuiluj avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar

Forkers

jefford-qwigo

pfunk's Issues

Create CRUD/Admin API views

  • Create Create view
  • Create Update view
  • Create Delete view
  • Create Detail View
  • Create List View
  • Write unit tests

Add indexes to the GraphQL Jinja2 template

Problem

Currently, you have to add additional indexes to the GraphQL schema by using the extra_graphql_queries variable on the Project class.

Solution

Figure out how to add it to the GraphQL Jinja2 template

As a developer, I have a CLI

  • Add clicky to the project
  • Add init command
  • Init command should include a WSGI app
  • add-stage command that creates a new stage with new fauna key
  • local command that runs the wsgi app locally using Werkzeug's run_simple
  • deploy command that creats SAM template that deploys the API Gateway and Lambda

Add pre and post signals

  • add pre_create signal
  • add post_create signal
  • add pre_delete signal
  • add post_delete signal
  • add post_update signal
  • add pre_update signal

Create login view

  • Call the login method on the User class
  • Send HTTP-only cookie with encrypted JWT token
  • Send JSON response with encrypted JWT token
  • Write unit tests

Create Change Password view

  • Create change password method on User class
  • Create update password function
  • Create update password view
  • Update User role to include the function
  • Write unit tests

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    ๐Ÿ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. ๐Ÿ“Š๐Ÿ“ˆ๐ŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google โค๏ธ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.