I'm having trouble saving MotorEngine instance using Tornado handler. Below are excerpts of code which I shortened for brevity.
if I replace motorengine imports with mongoengine the instance gets saved properly.
# model
from motorengine.document import Document
from motorengine.fields import *
class Test(Document):
nameTest = StringField(required=True)
numberTest = DecimalField(required=True)
boolTest = BooleanField(required=True)
# handler
class TestHandler(BaseHandler):
#tornado.gen.coroutine
def post(self, *args, **kwargs):
response = self._service.save_test()
print(response)
self.write('')
self.finish()
# save method
from models import Test
def save_test(self):
yield Test.objects.create(nameTest="foobar", boolTest=False, numberTest=123)
Are there any apparent errors in my code? Async programming is not my strong side.
:EDIT:
As per Ben's answer, this is the code that works
# handler
#tornado.gen.coroutine
def post(self, *args, **kwargs):
yield self._service.save_test()
# save method
#tornado.gen.coroutine
def save_test(self):
yield Test.objects.create(nameTest="foobar", boolTest=False, numberTest=123)
save_test (and any function which uses yield in this way) must have the #gen.coroutine decorator, and when you call it (or any other coroutine) in post() you must use yield save_test()
Related
I am kinda new to Django Rest Framework.
I have a views.py that looks something like this:
class MyAPIView(APIView):
""" My API """
def get(self, request, path):
""" Handles GET calls """
def post(self, request, path):
""" Handles POST calls """
And I have a util class in my package like so:
class MyUtilClass:
""" Helps out with stuff """
def some_method(self, path):
print('I will now do things to the path: ', path)
Now, I would like to inject an instance of some other class that does some task that it's supposed to into my view. Something like this:
class MyAPIView(APIView):
""" My API """
_some_util_instance = None # How to inject this?
def __init__(self, util_instance):
self._some_util_instance = util_instance # Is this the right way?
def get(self, request, path):
""" Handles GET calls """
self._some_util_instance.some_method(path) # This is why I want this object injected.
def post(self, request, path):
""" Handles POST calls """
What is the best way to inject such an instance into my views class?
I could not find much about this in the documentation. I am familiar with using DI and IoC Containers. However, I am not sure how Django Rest Framework handles all of that.
class MyAPIView(APIView):
""" My API """
_some_util_instance = MyUtilClass()
Or
class MyAPIView(APIView):
""" My API """
def __init__(self, *args, **kwargs):
self._some_util_instance = MyUtilClass()
super().__init__(self, *args, **kwargs)
Or
MyAPIView.as_view(
_some_util_instance=MyUtilClass()
)
class MyAPIView(APIView):
""" My API """
_some_util_instance = None
Or
don't use a class as a container for your utility functions, just define them as module-level functions. This is my preferred approach.
Or
Use static/class methods
class MyUtilClass:
""" Helps out with stuff """
#classmethod
def some_method(cls, path):
print('I will now do things to the path: ', path)
Then you can simply call MyUtilClass.some_method(path) in the view without creating an instance of MyUtilityClass
I would like to have a nose plugin that if enabled will just generate an HTML page with all the tests run which contain also the request/responses for each test.
This would be useful to generate some documentation FROM the tests.
Now I don't think it's too hard, but to do that I guess I have to intercept the self.client.get/post/whatever methods.
To do that however it looks like I have to replace the default TestCase class with something else, and I would like to not force any project that wants to use this tool to do have to do that.
This kind of works for example
import json
from mock import patch
from django.core.urlresolvers import reverse
from django.test import TestCase
from django.test.client import Client
class DebuggingClient(Client):
def __init__(self, *args, **kwargs):
super(DebuggingClient, self).__init__(*args, **kwargs)
def get(self, url, *args, **kwargs):
print("Calling endpoint {} with args {} and kwargs {}".format(url, args, kwargs))
response = super(DebuggingClient, self).get(url, *args, **kwargs)
print("Obtained response {}:{}".format(response.status_code, response.content))
return response
class TestSimpleApi(TestCase):
# TODO: how do I make this happen inside the plugin??
def _pre_setup(self):
super(TestSimpleApi, self)._pre_setup()
self.client = DebuggingClient()
def test_getting_numbers_returns_list_of_first_numbers(self):
url = reverse('gen_numbers')
response = self.client.get(url)
self.assertEqual(response.status_code, 200)
data = json.loads(response.content)
self.assertEqual(data, list(range(10)))
But I would like do do that just depending on a nose-plugin enabled.
Any idea how? I can't find a way to change the base class just from a nose-plugin (unless maybe doing some crazy monkey patching).
The project is here by the way even if far from working yet..
https://github.com/AndreaCrotti/django-docs-from-tests
I'm building a rate-limiting decorator in flask using redis stores that will recognize different limits on different endpoints. (I realize there are a number of rate-limiting decorators out there, but my use case is different enough that it made sense to roll my own.)
Basically the issue I'm having is ensuring that the keys I store in redis are class-specific. I'm using the blueprint pattern in flask, which basically works like this:
class SomeEndpoint(MethodView):
def get(self):
# Respond to get request
def post(self):
# Respond to post request
The issue here is that I want to be able to rate limit the post method of these classes without adding any additional naming conventions. In my mind the best way to do this would be something like this:
class SomeEndpoint(MethodView):
#RateLimit # Access SomeEndpoint class name
def post(self):
# Some response
but within the decorator, only the post function is in scope. How would I get back to the SomeEndpoint class given the post function? This is the basic layout of the decorator. That might be confusing, so here's a more concrete example of the decorator.
class RateLimit(object):
"""
The base decorator for app-specific rate-limiting.
"""
def __call__(self, f):
def endpoint(*args, **kwargs):
print class_backtrack(f) # Should print SomeEnpoint
return f(*args, **kwargs)
return endpoint
basically looking for what that class_backtrack function looks like. I've looked through the inspect module, but I haven't found anything that seems to accomplish this.
You can decorate the entire class instead of just the methods:
def wrap(Class, method):
def wrapper(self, *args, **kwargs):
print Class
return method(self, *args, **kwargs)
return method.__class__(wrapper, None, Class)
def rate_limit(*methods):
def decorator(Class):
for method_name in methods:
method = getattr(Class, method_name)
setattr(Class, method_name, wrap(Class, method))
return Class
return decorator
#rate_limit('post')
class SomeEndpoint(object):
def post(self):
pass
class Subclass(SomeEndpoint):
pass
a = Subclass()
a.post()
# prints <class 'SomeEndpoint'>
I'd like to do something like this:
class Basehandler(webapp.RequestHandler):
def __init__(self):
if checkforspecialcase: #check something that always needs to be handled
return SpecialCaseHandler.get()
class NormalHandler(Basehandler):
def get(self):
print 'hello world'
return
class SpecialCaseHandler(Basehandler):
def get(self):
print 'hello special world'
return
The idea is that no matter what handler is initially called, if a certain case is met, we basically switch to another handler.
I'm pretty new to python, so I'm not sure whether what I'm trying to do is possible. Or whether this is the best approach. What I'm really trying to do is make sure to show someone the complete-your-profile page if they've started the registration process but haven't completed it... no matter what request they're making. So the "checkforspecialcase" looks at their sessions and checks for incomplete info.
To keep things DRY, use the Template Method pattern
class BaseHandler(webapp.RequestHandler):
def DoGet(self, *args):
''' defined in derived classes, actual per-handler get() logic'''
pass
def get(self, *args):
# don't get caught in endless redirects!
if specialCase and not self.request.path.startswith('/special'):
self.redirect('/special')
else:
self.DoGet(*args)
class NormalHandler(BaseHandler):
def DoGet(self, *args):
# normal stuff
class SpecialHandler(BaseHandler):
def DoGet(self, *args):
# SPECIAL stuff
WSGIApplication routes incoming requests based on the URL. For example,
application = webapp.WSGIApplication(
[('/special-case', SpecialCaseHandler)])
When checkforspecialcase passes, you can use self.redirect('/special-case').
Your Basehandler could just implement a get() that checks for the special case and either redirects or calls self.view(), and each handler could implement view() (or whatever you'd like to call it) rather than get().
I'm not really into writing a class for each of my handlers, or using inheritance so conspicuously, so I'd recommend rolling decorators like these:
routes = []
def get (route):
def makeHandler (handle, *args, **kwargs):
class Handler (webapp.RequestHandler):
def get (self, *args, **kwargs):
shouldRedirectToCompleteProfile = # do your test
if shouldRedirectToCompleteProfile:
self.redirect('/special-case')
else:
handle(self, *args, **kwargs)
routes.append((route, Handler))
return Handler
return makeHandler
def post (route):
def makeHandler (handle, *args, **kwargs):
class Handler (webapp.RequestHandler):
def post (self, *args, **kwargs):
handle(self, *args, **kwargs)
routes.append((route, Handler))
return Handler
return makeHandler
#get('/')
def home (ctx):
# <...>
#get('/whatever/(.*)/(.*)')
def whatever (ctx, whatever0, whatever1):
# <...>
#post('/submit')
def submit (ctx):
# <...>
application = webapp.WSGIApplication(routes)
I am trying to define a base request handling class so that the webapp pages may inherit some basic methods and variable which otherwise would be required to be repeatedly be defined for each page of the application. A sort of similar functionality like django preprocessors. This is my base class from which other pages inherit:
class BasePage(webapp.RequestHandler):
def __init__(self):
self.user = users.get_current_user()
self.template_values = {
'user': self.user,
'environ': self, #I don't like the idea of passing the whole environ object to a template
##The below three functions cannot be executed during _init_ because of absence of self.request
#'openid_providers': self.openid_providers(),
#'logout_url': self.get_logout_url(),
#'request': self.get_request(),
}
##A sort of similar functionality like render_to_response in django
def render_template(self, template_name, values = None, *args, **kwargs):
#PATH is the directory containing the templates
if values:
for value in values: self.template_values[value] = values[value]
self.response.out.write(template.render(PATH+template_name, self.template_values, *args, **kwargs))
##Returns request as the name suggests
def logout_url(self):
return users.create_logout_url(self.request.url)
##Returns request as the name suggests
def request(self):
return request
##Returns openid login urls
def openid_providers(self):
#OPENID_POVIDERS is a list of dictionary
for p in OPENID_PROVIDERS:
p['login_url'] = users.create_login_url(self.request.get('next', '/') , p['name'], p['url'])
return OPENID_PROVIDERS
Everything is working fine except that I cannot pass some variables during initialization as self.request is not available. So for a workaround what I did is pass on whole self variable as a template variable.
Is there some other way to provide the template variables (request, logout_url etc) to the templates?
A much simpler solution than bgporter's is to do the common setup in the initialize method of webapp.RequestHandler. Here's an example from work, where we wanted to add a Django-like is_ajax method to the request object:
class BaseHandler(webapp.RequestHandler):
def initialize(self, request, response):
super(BaseHandler, self).initialize(request, response)
# Add a Django-like is_ajax() method to the request object
request.is_ajax = lambda: \
request.environ.get('HTTP_X_REQUESTED_WITH') == 'XMLHttpRequest'
This method is called to, uh, initialize each request handler with the current request and response objects, before the appropriate get or post (or whatever) methods are called.
I've solved that problem in my AppEngine code by using the Template Method Pattern
Basically, the base class looks like:
class MyBasePage(webapp.RequestHandler):
def __init__(self):
# common setup/init stuff here,
# omitted for this discussion
def Setup(self):
# request handling setup code needed in both GET/POST methods, like
# checking for user login, getting session cookies, etc.
# omitted for this discussion
def get(self, *args):
self.Setup()
# call the derived class' 'DoGet' method that actually has
# the logic inside it
self.DoGet(*args)
def post(self, *args):
self.Setup()
# call the derived class' 'DoPost' method
self.DoPost(*args)
def DoGet(self, *args):
''' derived classes override this method and
put all of their GET logic inside. Base class does nothing.'''
pass
def DoPost(self, *args):
''' derived classes override this method and
put all of their POST logic inside. Base class does nothing.'''
pass
...your derived classes then mostly just need to worry about the guts of those DoGet() and DoPost() methods.