MongoDB API framework
About
MongoDB API framework is a toolset for rapid API development.
Server-side example:
from typing import Dict
from datetime import datetime
from bson import ObjectId
from motor.motor_asyncio import AsyncIOMotorClient
from validate_it import Schema, StrField, ObjectIdField, DictField
from mongodb_api_framework.api import DocumentHook, RequestHook, HttpResource
from mongodb_api_framework.api.config import Get, Post, Put
class ArticleSchema(Schema):
_id = ObjectIdField()
title = StrField(required=True, min_length=4, max_length=160)
text = StrField(required=True, min_length=100, max_length=4000)
author = StrField(required=True)
is_published = BoolField(required=True)
created_at = DatetimeField(required=True)
# remove fields which user can't edit
UserArticleSchema = ArticleSchema().exclude('_id', 'author', 'is_published', 'created_at')
# allow filter only by title and text
class GetFilterSchema(Schema):
title = DictField()
text = DictField()
# allow filter by _id
class PutFilterSchema(Schema):
_id = ObjectIdField()
class AddAuthor(DocumentHook):
async def before_db_query(self, sandbox: Dict, document: Dict) -> Dict:
document['author'] = sandbox['session']['user']['email']
return document
class AddCreatedAt(DocumentHook):
async def before_db_query(self, sandbox: Dict, document: Dict) -> Dict:
document['created_at'] = datetime.now()
return document
class SessionFromCookies(RequestHook):
async def before_db_query(self, sandbox: Dict):
_id = sandbox['request'].cookies.get('session_id')
if _id:
_session = await sandbox['resource'].db.session.find_one(
{'_id': ObjectId(_id), 'is_archived': False}
)
if _session:
sandbox['session'] = _session
class ArticleResource(HttpResource):
collection_name = 'user_article'
get = Get(
output=ArticleSchema()
""" validate document prepared for user """
filter=GetFilterSchema()
""" restrict mongodb filter """
hooks=[
SessionFromCookies()
]
""" do something with request or document """
)
post = Post(
input=UserArticleSchema(),
""" validate user document """
db=ArticleSchema()
""" validate document before insert into collection """
hooks=[
SessionFromCookies(),
AddAuthor(),
AddCreatedAt()
]
""" do something with request or document """
)
put = Put(
input=UserArticleSchema(),
""" validate user document """
db=ArticleSchema()
""" validate document before update in db """
hooks=[
SessionFromCookies()
]
""" do something with request or document """
)
# init `motor`
client = AsyncIOMotorClient()
db = client.test_database
# create `aiohttp` app
app = Application()
# register resource
app.add_rest_route('/rest/v1/article', ArticleResource(db=db))
Python client-side example:
import requests
article = {
'title': 'Article example title',
'text': 'Article example text'
}
requests.post('/rest/v1/article', json=article)
Installation
With pip:
pip install mongodb-api-framework
Requirements
Tested with python3.6
, motor==1.2.1
and mongodb 3.4
, aiohttp==3.0.7
Contribution how-to
Run tests:
- clone repo:
git clone <your-fork>
- create and activate your virtualenv
pip install -r requirements.txt && pip install -r dev-requirements
./run_tests.sh