Note that there are some explanatory texts on larger screens.

plurals
  1. PO
    primarykey
    data
    text
    <p>In order to do something like this you'll have to use a bit of python magic, however, it's absolutely possible to do with flask. The most straight-forward way to copy your example would be to subclass flask. This is one way to do it:</p> <pre><code>import inspect from flask import Flask def expose(f): """Decorator that flags a method to be exposed""" f._exposed_method = True return f class FlaskOfCherryPy(Flask): """Custom flask that allows cherrypy's expose decorator""" def quickstart(self, root_handler, *args, **kwargs): self._process_root_handler(root_handler) self.run(*args, **kwargs) def _process_root_handler(self, root_handler): # Prime the recursive processing root_url = [] self._process_a_handler(root_handler, root_url) def _process_a_handler(self, current_handler, url_stack): # This gives a list of all the members of current_handler members = inspect.getmembers(current_handler) for name, value in members: # You probably want to skip things that start with a _ or __ if name.startswith('_'): continue # Check if the method is decorated is_exposed_method = getattr(value, '_exposed_method', False) # If it's a callable with the _exposed_method attribute set # Then it's an exposed method if is_exposed_method and callable(value): self._add_exposed_url(url_stack, name, value) else: new_stack = url_stack[:] new_stack.append(name) self._process_a_handler(value, new_stack) def _add_exposed_url(self, url_stack, name, view_func): copied_stack = url_stack[:] if name != 'index': copied_stack.append(name) url = "/%s" % "/".join(copied_stack) if name == 'index': copied_stack.append(name) view_name = "_".join(copied_stack) self.add_url_rule(url, view_name, view_func) class Root(object): @expose def index(self): return 'my app' class Greeting(object): def __init__(self, name, greeting): self.name = name self.greeting = greeting @expose def index(self): return '%s %s!' %(self.greeting, self.name) @expose def again(self): return '%s again, %s!' %(self.greeting, self.name) if __name__ == '__main__': root = Root() root.hello = Greeting('Foo', 'Hello') root.bye = Greeting('Bar', 'Bye') app = FlaskOfCherryPy(__name__) app.quickstart(root) </code></pre> <p>Essentially the trick is grabbing all methods that are tagged with the <code>_exposed_method</code> attribute and passing them to the <code>Flask.add_url_rule</code> (<a href="http://flask.pocoo.org/docs/api/#flask.Flask.add_url_rule" rel="nofollow">see docs here</a>). The beauty of flask is that it's such a lightweight system that it isn't very scary to extend it. I highly suggest diving in yourself and giving it a shot, but I had fun solving your question so I have the script as <a href="https://gist.github.com/3412602" rel="nofollow">a gist here</a>. </p> <p>This particular code I've written isn't perfect and hasn't been heavily tested, but it definitely works for your particular use case. Also, it's not necessarily how you would want to run the app in production. You'd have to create some kind of application factory to do it. Again, I highly suggest looking into the internals of flask to make it do what you want. You may also want to look at class-based views or blueprints that flask offers. They're able to some things similarly to how you had them here. Granted, using them is very different and setting instance attributes is not something I know to be possible using vanilla blueprints. Again, you can always extend :-)</p>
    singulars
    1. This table or related slice is empty.
    1. This table or related slice is empty.
    plurals
    1. This table or related slice is empty.
    1. This table or related slice is empty.
    1. This table or related slice is empty.
    1. VO
      singulars
      1. This table or related slice is empty.
    2. VO
      singulars
      1. This table or related slice is empty.
    3. VO
      singulars
      1. This table or related slice is empty.
 

Querying!

 
Guidance

SQuiL has stopped working due to an internal error.

If you are curious you may find further information in the browser console, which is accessible through the devtools (F12).

Reload