Ecosyste.ms: Awesome
An open API service indexing awesome lists of open source software.
https://github.com/capless/pfunk
A Python library to make writing applications with FaunaDB easier. Includes GraphQL and generic ABAC auth workflow integrations.
https://github.com/capless/pfunk
fauna faunadb orm
Last synced: 3 months ago
JSON representation
A Python library to make writing applications with FaunaDB easier. Includes GraphQL and generic ABAC auth workflow integrations.
- Host: GitHub
- URL: https://github.com/capless/pfunk
- Owner: capless
- License: apache-2.0
- Created: 2020-02-05T17:14:48.000Z (almost 5 years ago)
- Default Branch: master
- Last Pushed: 2023-05-04T07:10:32.000Z (over 1 year ago)
- Last Synced: 2024-08-01T19:31:30.227Z (6 months ago)
- Topics: fauna, faunadb, orm
- Language: Python
- Homepage: https://www.pfunk.io/docs/pfunk.html
- Size: 924 KB
- Stars: 6
- Watchers: 3
- Forks: 1
- Open Issues: 12
-
Metadata Files:
- Readme: README.md
- License: LICENSE
Awesome Lists containing this project
README
![Pfunk logo](https://qwigocom.b-cdn.net/opensource/images/pfunk.png?width=160 "Pfunk")
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](https://github.com/capless/valley) library.## Full Documentation
[Documentation](https://pfunk.carcamp.dev/docs/pfunk.html)
## Table of Contents
- [Getting Started](#Getting-Started)
- [Installation](#Installation)
- [Setup the Connection](#setup-the-connection)
- [Define your Collections](#define-your-collections-collectionspy)
- [Choose an Auth Workflow](#auth-workflows)
- [Publish](#publish)
- [Save Some Data](#save-some-data)
- [Query Your Data](#query-your-data)
- [Delete a Record](#delete-a-record)
### 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.
```python
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, GenericUserBasedRoleSTATUS = 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 WorkflowsIn 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
```python
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.
```python
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
```python
# User instance from above (username: notthegoat)
user.add_permissions(group, ['create', 'read', 'write', 'delete'])
```
### Login```python
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.```python
# 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.```python
product = Product.get('the-key-for-the-previous-video', _token=token)
```Let's query for all videos using the server key.
```python
products = Products.all()
```Let's query for all videos that the logged in user has access to.
```python
products = Products.all(_token=token)
```### Delete a Record
Let's delete the record from above.
```python
product.delete()
```