Skip to content
This repository was archived by the owner on Jan 23, 2024. It is now read-only.
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
8 changes: 5 additions & 3 deletions example/app.py
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@
from flask.ext.mongorest.views import ResourceView
from flask.ext.mongorest.resources import Resource
from flask.ext.mongorest import operators as ops
from flask.ext.mongorest.methods import *
from flask.ext.mongorest.methods import Create, Update, Fetch, List, Delete, BulkUpdate
from flask.ext.mongorest.authentication import AuthenticationBase

from example import schemas, documents
Expand All @@ -27,8 +27,8 @@
},
)

db = MongoEngine(app)
api = MongoRest(app)
db = MongoEngine()
api = MongoRest()

class UserResource(Resource):
document = documents.User
Expand Down Expand Up @@ -304,6 +304,8 @@ class DictDocView(ResourceView):
resource = DictDocResource
methods = [Fetch, List, Create, Update]

db.init_app(app)
api.init_app(app)

if __name__ == "__main__":
port = int(os.environ.get('PORT', 8000))
Expand Down
65 changes: 57 additions & 8 deletions flask_mongorest/__init__.py
Original file line number Diff line number Diff line change
@@ -1,17 +1,61 @@
from flask import Blueprint
from flask_mongorest.methods import Create, BulkUpdate, List

class _DelayedApp(object):
"""
Stores URL rules for later merging with application URL map.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

unnecessary newline

"""

def __init__(self):
self.url_rules = []

def add_url_rule(self, *args, **kwargs):
self.url_rules.append((args, kwargs))


class MongoRest(object):
def __init__(self, app, **kwargs):
self.app = app
def __init__(self, app=None, template_folder='templates', **kwargs):
"""
Takes optional Flask application instance. If supplied, `init_app` will be
called to update application url map.

Copy link
Member

@wojcikstefan wojcikstefan Jul 9, 2016

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

unnecessary newline

"""

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

unnecessary newline

self.url_prefix = kwargs.pop('url_prefix', '')
app.register_blueprint(Blueprint(self.url_prefix, __name__, template_folder='templates'))
self.template_folder = template_folder
if app is not None:
self.init_app(app, **kwargs)
else:
self.app = _DelayedApp()

def init_app(self, app):
"""
Provides delayed application instance initialization to support
Flask application factory pattern. For further details on application
factories see:

http://flask.pocoo.org/docs/dev/patterns/appfactories/

and

http://mattupstate.com/python/2013/06/26/how-i-structure-my-flask-applications.html
"""

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

unnecessary newline

app.register_blueprint(
Blueprint(self.url_prefix, __name__, template_folder=self.template_folder))

if hasattr(self, 'app') and isinstance(self.app, _DelayedApp):
for args, kwargs in self.app.url_rules:
app.add_url_rule(*args, **kwargs)

self.app = app
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Would it be better to always set self.app in __init__ - either to _DelayedApp() or to a real Flask app object? We could then skip some of the ugly hasattr conditions.

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think that would be cleaner. I will see what works best.


def register(self, **kwargs):
def decorator(klass):

# Construct a url based on a 'name' kwarg with a fallback to a Mongo document's name
# Construct a url based on a 'name' kwarg with a fallback to a
# Mongo document's name
document_name = klass.resource.document.__name__.lower()
name = kwargs.pop('name', document_name)
url = kwargs.pop('url', '/%s/' % document_name)
Expand All @@ -24,11 +68,16 @@ def decorator(klass):
pk_type = kwargs.pop('pk_type', 'string')
view_func = klass.as_view(name)
if List in klass.methods:
self.app.add_url_rule(url, defaults={'pk': None}, view_func=view_func, methods=[List.method], **kwargs)
self.app.add_url_rule(
url, defaults={'pk': None}, view_func=view_func, methods=[List.method], **kwargs)
if Create in klass.methods or BulkUpdate in klass.methods:
self.app.add_url_rule(url, view_func=view_func, methods=[x.method for x in klass.methods if x in (Create, BulkUpdate)], **kwargs)
self.app.add_url_rule('%s<%s:%s>/' % (url, pk_type, 'pk'), view_func=view_func, methods=[x.method for x in klass.methods if x not in (List, BulkUpdate)], **kwargs)
methods = [x.method for x in klass.methods if x in (Create, BulkUpdate)]
self.app.add_url_rule(url, view_func=view_func, methods=methods, **kwargs)

methods = [x.method for x in klass.methods if x not in (List, BulkUpdate)]
self.app.add_url_rule(
'%s<%s:%s>/' % (url, pk_type, 'pk'), view_func=view_func, methods=methods, **kwargs)

return klass

return decorator