Plume

https://img.shields.io/pypi/v/plume.svg https://img.shields.io/travis/JamesRamm/plume.svg Documentation Status Code Health Updates

A library to help you make Falcon web apps backed by MongoDB.

Features

  • Simple interface to MongoDB using marshmallow schemas. This allows a single document definition which also provides serialization and validation
  • Easy filtering/projection of documents per request
  • Useful extra fields for Schemas (Choice, Slug, MongoId, Password…)
  • Standard Resource classes for creating a full CRUD JSON API for REST collections and items.
  • Resource classes for generic file uploads. They can be configured to use different storage backends, and validate different content types

Example

The following example creates a basic JSON API for a representation of a user.

from datetime import datetime
from plume import create_app, schema, Collection, Item
from plume.connection import connect
from plume.fields import Slug
from marshmallow import fields, Schema

class UserSchema(schema.MongoSchema):
    name = fields.Str(required=True)
    email = fields.Email(required=True)
    created = fields.DateTime(
            missing=lambda: datetime.utcnow().isoformat(),
            default=lambda: datetime.utcnow().isoformat()
    )
    profile = fields.Nested("ProfileSchema")
    slug = Slug(populate_from='name')

class ProfileSchema(Schema):
    """Example of nesting a schema.
    In mongodb, this will be a nested document
    """
    biography = fields.Str()
    profile_image = fields.Url(load_from='profileImage', dump_to='profileImage')


def get_app(database_name='myapp')
    """Creates the falcon app.
    We pass the database name so we can use a different db for testing
    """
    # Connect to the database *before* making schema instance.
    # The ``connect`` function takes the same arguments as pymongo's
    # ``MongoClient``. Here we connect to localhost.
    connect(database_name)
    user = UserSchema()
    resources = (Collection(user, '/users'), Item(user, '/users/{email}'))
    return create_app(resources)

Name this file app.py and run it with gunicorn:

gunicorn 'app:get_app()'

Design

Plume intends to be a light and transparent library. It should compliment and enhance Falcon & MongoDB usage but not get in the way of custom development. To this end I have a small number of rules:

  • No magic. Like falcon itself, it should be easy to follow inputs to outputs. To this end we have a few soft rules such as:
    • Avoid mixins. Mixins introduce implicit dependencies and make it harder to reason about code.
    • Don’t mess with metaclasses and double underscore methods without good reason. There is often an easier, clearer way to achieve the same result.
  • No reinvention. We try to use well proven existing solutions before rolling our own. Hence the use of marshmallow for the ORM/serialization framework.
  • No hijacking. Plume is complimentary or an ‘add-on’ to Falcon. It does not replace direct usage of Falcon (what you might expect from a framework). It solves some common use cases and provides some useful tools. When you want to do something unsupported and go direct to falcon, it doesnt get in your way.