Quantcast

Providing data to a function using a decorator

Previous Topic Next Topic
 
classic Classic list List threaded Threaded
5 messages Options
Reply | Threaded
Open this post in threaded view
|  
Report Content as Inappropriate

Providing data to a function using a decorator

Johan Hartzenberg
Many of my route handlers go through a sequence of similar steps, eg

def handler_x(self, **kwargs):
  #Check Authentication
  ...  
  #Validate Input
  ...
  #Check Authorization
  ....
  #Perform Database Query/Update
  ...
  #Format result into response
  return response

It would seem that this sequence lends itself to being put into decorators.  I have to some extent put these into functions already, but I still end up with a lot of code like


def handler_x(self, **kwargs):
  ...
  try:
    dbcursor = ....
  except ..

  Etc etc for every step of the handler

  The format of each of these "decorators" appears to be
  try to get some value (a user-name, a db connection, etc)
  Check whether it was sucesful
  Return a response if not
  Use the response in the next step

So basically imagine

@dict_to_json
@check_authentication (this sets username)
@check_valid_input
@get a database connection (this uses username, and sets a cursor)
@check authorization (this uses username and cursor)
def handler_x(self, **kwargs):
  use username and db_cursor here
  return a result

So the question is how do I get the results from one decorator to be accessible to the next.

My first thought would be to build on cherrypy.request ... set the results as properties on there, which can then be accessed by subsequent functions/decorators... But maybe there is another way that I am not aware of...



--
You received this message because you are subscribed to the Google Groups "cherrypy-users" group.
To unsubscribe from this group and stop receiving emails from it, send an email to [hidden email].
To post to this group, send email to [hidden email].
Visit this group at https://groups.google.com/group/cherrypy-users.
For more options, visit https://groups.google.com/d/optout.
Reply | Threaded
Open this post in threaded view
|  
Report Content as Inappropriate

Re: Providing data to a function using a decorator

Joseph S. Tate
Not decorators, Tools.

Tools do not need to be turned on and off to do unit testing, they happen outside the handler context. Unit testing becomes super simple: set up dummy request and response objects, and call the instantiated method with the proper arguments. Check the response.

Tools have a lot more flexibility than decorators. There are some six or seven registration points for tools. Pre-handler tools can register post handler tools in real time.

Tools can be configured in CONFIG, not in code.

Take a look at the built in tools, and the stuff posted on http://tools.cherrypy.org/wiki/TitleIndex for inspiration.

On Sat, Nov 5, 2016 at 4:23 PM Johan Hartzenberg <[hidden email]> wrote:
Many of my route handlers go through a sequence of similar steps, eg

def handler_x(self, **kwargs):
  #Check Authentication
  ...  
  #Validate Input
  ...
  #Check Authorization
  ....
  #Perform Database Query/Update
  ...
  #Format result into response
  return response

It would seem that this sequence lends itself to being put into decorators.  I have to some extent put these into functions already, but I still end up with a lot of code like


def handler_x(self, **kwargs):
  ...
  try:
    dbcursor = ....
  except ..

  Etc etc for every step of the handler

  The format of each of these "decorators" appears to be
  try to get some value (a user-name, a db connection, etc)
  Check whether it was sucesful
  Return a response if not
  Use the response in the next step

So basically imagine

@dict_to_json
@check_authentication (this sets username)
@check_valid_input
@get a database connection (this uses username, and sets a cursor)
@check authorization (this uses username and cursor)
def handler_x(self, **kwargs):
  use username and db_cursor here
  return a result

So the question is how do I get the results from one decorator to be accessible to the next.

My first thought would be to build on cherrypy.request ... set the results as properties on there, which can then be accessed by subsequent functions/decorators... But maybe there is another way that I am not aware of...



--
You received this message because you are subscribed to the Google Groups "cherrypy-users" group.
To unsubscribe from this group and stop receiving emails from it, send an email to [hidden email].
To post to this group, send email to [hidden email].
Visit this group at https://groups.google.com/group/cherrypy-users.
For more options, visit https://groups.google.com/d/optout.

--
You received this message because you are subscribed to the Google Groups "cherrypy-users" group.
To unsubscribe from this group and stop receiving emails from it, send an email to [hidden email].
To post to this group, send email to [hidden email].
Visit this group at https://groups.google.com/group/cherrypy-users.
For more options, visit https://groups.google.com/d/optout.
Reply | Threaded
Open this post in threaded view
|  
Report Content as Inappropriate

Re: Providing data to a function using a decorator

Johan Hartzenberg
Thank you.  This is already on my Todo list but I'm prioritising it now.

I ended up just storing the results from decorators in cherrypy.request.myvar for use by the wrapped function, but now I need the reverse:  I need access to something in the application class from inside a decorator (My DB connection pool in this case).  How do I pass "self" to the decorator?  I am almost afraid to ask as I suspect the answer will be LOOK AT TOOLS again!!  So I will do that today....

On Monday, November 7, 2016 at 8:02:19 AM UTC+2, Joseph Tate wrote:
Not decorators, Tools.

Tools do not need to be turned on and off to do unit testing, they happen outside the handler context. Unit testing becomes super simple: set up dummy request and response objects, and call the instantiated method with the proper arguments. Check the response.

Tools have a lot more flexibility than decorators. There are some six or seven registration points for tools. Pre-handler tools can register post handler tools in real time.

Tools can be configured in CONFIG, not in code.

Take a look at the built in tools, and the stuff posted on <a href="http://tools.cherrypy.org/wiki/TitleIndex" target="_blank" rel="nofollow" onmousedown="this.href=&#39;http://www.google.com/url?q\x3dhttp%3A%2F%2Ftools.cherrypy.org%2Fwiki%2FTitleIndex\x26sa\x3dD\x26sntz\x3d1\x26usg\x3dAFQjCNFBeB2C92t7J3olXLIvQCD_8dRukw&#39;;return true;" onclick="this.href=&#39;http://www.google.com/url?q\x3dhttp%3A%2F%2Ftools.cherrypy.org%2Fwiki%2FTitleIndex\x26sa\x3dD\x26sntz\x3d1\x26usg\x3dAFQjCNFBeB2C92t7J3olXLIvQCD_8dRukw&#39;;return true;">http://tools.cherrypy.org/wiki/TitleIndex for inspiration.

On Sat, Nov 5, 2016 at 4:23 PM Johan Hartzenberg <<a href="javascript:" target="_blank" gdf-obfuscated-mailto="ypllK8FwAQAJ" rel="nofollow" onmousedown="this.href=&#39;javascript:&#39;;return true;" onclick="this.href=&#39;javascript:&#39;;return true;">jo...@...> wrote:
Many of my route handlers go through a sequence of similar steps, eg

def handler_x(self, **kwargs):
  #Check Authentication
  ...  
  #Validate Input
  ...
  #Check Authorization
  ....
  #Perform Database Query/Update
  ...
  #Format result into response
  return response

It would seem that this sequence lends itself to being put into decorators.  I have to some extent put these into functions already, but I still end up with a lot of code like


def handler_x(self, **kwargs):
  ...
  try:
    dbcursor = ....
  except ..

  Etc etc for every step of the handler

  The format of each of these "decorators" appears to be
  try to get some value (a user-name, a db connection, etc)
  Check whether it was sucesful
  Return a response if not
  Use the response in the next step

So basically imagine

@dict_to_json
@check_authentication (this sets username)
@check_valid_input
@get a database connection (this uses username, and sets a cursor)
@check authorization (this uses username and cursor)
def handler_x(self, **kwargs):
  use username and db_cursor here
  return a result

So the question is how do I get the results from one decorator to be accessible to the next.

My first thought would be to build on cherrypy.request ... set the results as properties on there, which can then be accessed by subsequent functions/decorators... But maybe there is another way that I am not aware of...



--
You received this message because you are subscribed to the Google Groups "cherrypy-users" group.
To unsubscribe from this group and stop receiving emails from it, send an email to <a href="javascript:" target="_blank" gdf-obfuscated-mailto="ypllK8FwAQAJ" rel="nofollow" onmousedown="this.href=&#39;javascript:&#39;;return true;" onclick="this.href=&#39;javascript:&#39;;return true;">cherrypy-user...@googlegroups.com.
To post to this group, send email to <a href="javascript:" target="_blank" gdf-obfuscated-mailto="ypllK8FwAQAJ" rel="nofollow" onmousedown="this.href=&#39;javascript:&#39;;return true;" onclick="this.href=&#39;javascript:&#39;;return true;">cherryp...@googlegroups.com.
Visit this group at <a href="https://groups.google.com/group/cherrypy-users" target="_blank" rel="nofollow" onmousedown="this.href=&#39;https://groups.google.com/group/cherrypy-users&#39;;return true;" onclick="this.href=&#39;https://groups.google.com/group/cherrypy-users&#39;;return true;">https://groups.google.com/group/cherrypy-users.
For more options, visit <a href="https://groups.google.com/d/optout" target="_blank" rel="nofollow" onmousedown="this.href=&#39;https://groups.google.com/d/optout&#39;;return true;" onclick="this.href=&#39;https://groups.google.com/d/optout&#39;;return true;">https://groups.google.com/d/optout.

--
You received this message because you are subscribed to the Google Groups "cherrypy-users" group.
To unsubscribe from this group and stop receiving emails from it, send an email to [hidden email].
To post to this group, send email to [hidden email].
Visit this group at https://groups.google.com/group/cherrypy-users.
For more options, visit https://groups.google.com/d/optout.
Reply | Threaded
Open this post in threaded view
|  
Report Content as Inappropriate

Re: Providing data to a function using a decorator

Joseph S. Tate
Attach it to the response threadlocal object, but so much tight integration is going to bring you problems down the line.

Using a closure with a tool would be better. Set up a post handler in a pre handler that has the data you need. (not self, but perhaps self.var1)



On Mon, Nov 7, 2016 at 2:20 AM Johan Hartzenberg <[hidden email]> wrote:
Thank you.  This is already on my Todo list but I'm prioritising it now.

I ended up just storing the results from decorators in cherrypy.request.myvar for use by the wrapped function, but now I need the reverse:  I need access to something in the application class from inside a decorator (My DB connection pool in this case).  How do I pass "self" to the decorator?  I am almost afraid to ask as I suspect the answer will be LOOK AT TOOLS again!!  So I will do that today....

On Monday, November 7, 2016 at 8:02:19 AM UTC+2, Joseph Tate wrote:
Not decorators, Tools.

Tools do not need to be turned on and off to do unit testing, they happen outside the handler context. Unit testing becomes super simple: set up dummy request and response objects, and call the instantiated method with the proper arguments. Check the response.

Tools have a lot more flexibility than decorators. There are some six or seven registration points for tools. Pre-handler tools can register post handler tools in real time.

Tools can be configured in CONFIG, not in code.

Take a look at the built in tools, and the stuff posted on http://tools.cherrypy.org/wiki/TitleIndex for inspiration.

On Sat, Nov 5, 2016 at 4:23 PM Johan Hartzenberg <[hidden email]> wrote:
Many of my route handlers go through a sequence of similar steps, eg

def handler_x(self, **kwargs):
  #Check Authentication
  ...  
  #Validate Input
  ...
  #Check Authorization
  ....
  #Perform Database Query/Update
  ...
  #Format result into response
  return response

It would seem that this sequence lends itself to being put into decorators.  I have to some extent put these into functions already, but I still end up with a lot of code like


def handler_x(self, **kwargs):
  ...
  try:
    dbcursor = ....
  except ..

  Etc etc for every step of the handler

  The format of each of these "decorators" appears to be
  try to get some value (a user-name, a db connection, etc)
  Check whether it was sucesful
  Return a response if not
  Use the response in the next step

So basically imagine

@dict_to_json
@check_authentication (this sets username)
@check_valid_input
@get a database connection (this uses username, and sets a cursor)
@check authorization (this uses username and cursor)
def handler_x(self, **kwargs):
  use username and db_cursor here
  return a result

So the question is how do I get the results from one decorator to be accessible to the next.

My first thought would be to build on cherrypy.request ... set the results as properties on there, which can then be accessed by subsequent functions/decorators... But maybe there is another way that I am not aware of...



--
You received this message because you are subscribed to the Google Groups "cherrypy-users" group.
To unsubscribe from this group and stop receiving emails from it, send an email to [hidden email].
To post to this group, send email to [hidden email].

--
You received this message because you are subscribed to the Google Groups "cherrypy-users" group.
To unsubscribe from this group and stop receiving emails from it, send an email to [hidden email].
To post to this group, send email to [hidden email].
Visit this group at https://groups.google.com/group/cherrypy-users.
For more options, visit https://groups.google.com/d/optout.

--
You received this message because you are subscribed to the Google Groups "cherrypy-users" group.
To unsubscribe from this group and stop receiving emails from it, send an email to [hidden email].
To post to this group, send email to [hidden email].
Visit this group at https://groups.google.com/group/cherrypy-users.
For more options, visit https://groups.google.com/d/optout.
Reply | Threaded
Open this post in threaded view
|  
Report Content as Inappropriate

Re: Providing data to a function using a decorator

Johan Hartzenberg
Thank you, this is what I ended up doing.

The trick that I didn't get was how to specify "self" in a decorator that isn't part of the class definition.  The answer lies in either giving a formal parameter named self or else even use args[0] on the wrapper definition inside the decorator, since the calling function will implicitly add self in any case !!!!  Where I went wrong is in that it isn't necessary to change anything on the decorator definition - the arguments are handled transparently!


On Monday, November 7, 2016 at 7:27:50 PM UTC+2, Joseph Tate wrote:
Attach it to the response threadlocal object, but so much tight integration is going to bring you problems down the line.

Using a closure with a tool would be better. Set up a post handler in a pre handler that has the data you need. (not self, but perhaps self.var1)



On Mon, Nov 7, 2016 at 2:20 AM Johan Hartzenberg <<a href="javascript:" target="_blank" gdf-obfuscated-mailto="FzjssimWAQAJ" rel="nofollow" onmousedown="this.href=&#39;javascript:&#39;;return true;" onclick="this.href=&#39;javascript:&#39;;return true;">jo...@...> wrote:
Thank you.  This is already on my Todo list but I'm prioritising it now.

I ended up just storing the results from decorators in cherrypy.request.myvar for use by the wrapped function, but now I need the reverse:  I need access to something in the application class from inside a decorator (My DB connection pool in this case).  How do I pass "self" to the decorator?  I am almost afraid to ask as I suspect the answer will be LOOK AT TOOLS again!!  So I will do that today....

On Monday, November 7, 2016 at 8:02:19 AM UTC+2, Joseph Tate wrote:
Not decorators, Tools.

Tools do not need to be turned on and off to do unit testing, they happen outside the handler context. Unit testing becomes super simple: set up dummy request and response objects, and call the instantiated method with the proper arguments. Check the response.

Tools have a lot more flexibility than decorators. There are some six or seven registration points for tools. Pre-handler tools can register post handler tools in real time.

Tools can be configured in CONFIG, not in code.

Take a look at the built in tools, and the stuff posted on <a href="http://tools.cherrypy.org/wiki/TitleIndex" rel="nofollow" target="_blank" onmousedown="this.href=&#39;http://www.google.com/url?q\x3dhttp%3A%2F%2Ftools.cherrypy.org%2Fwiki%2FTitleIndex\x26sa\x3dD\x26sntz\x3d1\x26usg\x3dAFQjCNFBeB2C92t7J3olXLIvQCD_8dRukw&#39;;return true;" onclick="this.href=&#39;http://www.google.com/url?q\x3dhttp%3A%2F%2Ftools.cherrypy.org%2Fwiki%2FTitleIndex\x26sa\x3dD\x26sntz\x3d1\x26usg\x3dAFQjCNFBeB2C92t7J3olXLIvQCD_8dRukw&#39;;return true;">http://tools.cherrypy.org/wiki/TitleIndex for inspiration.

On Sat, Nov 5, 2016 at 4:23 PM Johan Hartzenberg <[hidden email]> wrote:
Many of my route handlers go through a sequence of similar steps, eg

def handler_x(self, **kwargs):
  #Check Authentication
  ...  
  #Validate Input
  ...
  #Check Authorization
  ....
  #Perform Database Query/Update
  ...
  #Format result into response
  return response

It would seem that this sequence lends itself to being put into decorators.  I have to some extent put these into functions already, but I still end up with a lot of code like


def handler_x(self, **kwargs):
  ...
  try:
    dbcursor = ....
  except ..

  Etc etc for every step of the handler

  The format of each of these "decorators" appears to be
  try to get some value (a user-name, a db connection, etc)
  Check whether it was sucesful
  Return a response if not
  Use the response in the next step

So basically imagine

@dict_to_json
@check_authentication (this sets username)
@check_valid_input
@get a database connection (this uses username, and sets a cursor)
@check authorization (this uses username and cursor)
def handler_x(self, **kwargs):
  use username and db_cursor here
  return a result

So the question is how do I get the results from one decorator to be accessible to the next.

My first thought would be to build on cherrypy.request ... set the results as properties on there, which can then be accessed by subsequent functions/decorators... But maybe there is another way that I am not aware of...



--
You received this message because you are subscribed to the Google Groups "cherrypy-users" group.
To unsubscribe from this group and stop receiving emails from it, send an email to cherrypy-user...@googlegroups.com.
To post to this group, send email to [hidden email].

Visit this group at <a href="https://groups.google.com/group/cherrypy-users" rel="nofollow" target="_blank" onmousedown="this.href=&#39;https://groups.google.com/group/cherrypy-users&#39;;return true;" onclick="this.href=&#39;https://groups.google.com/group/cherrypy-users&#39;;return true;">https://groups.google.com/group/cherrypy-users.
For more options, visit <a href="https://groups.google.com/d/optout" rel="nofollow" target="_blank" onmousedown="this.href=&#39;https://groups.google.com/d/optout&#39;;return true;" onclick="this.href=&#39;https://groups.google.com/d/optout&#39;;return true;">https://groups.google.com/d/optout.

--
You received this message because you are subscribed to the Google Groups "cherrypy-users" group.
To unsubscribe from this group and stop receiving emails from it, send an email to <a href="javascript:" target="_blank" gdf-obfuscated-mailto="FzjssimWAQAJ" rel="nofollow" onmousedown="this.href=&#39;javascript:&#39;;return true;" onclick="this.href=&#39;javascript:&#39;;return true;">cherrypy-user...@googlegroups.com.
To post to this group, send email to <a href="javascript:" target="_blank" gdf-obfuscated-mailto="FzjssimWAQAJ" rel="nofollow" onmousedown="this.href=&#39;javascript:&#39;;return true;" onclick="this.href=&#39;javascript:&#39;;return true;">cherryp...@googlegroups.com.
Visit this group at <a href="https://groups.google.com/group/cherrypy-users" target="_blank" rel="nofollow" onmousedown="this.href=&#39;https://groups.google.com/group/cherrypy-users&#39;;return true;" onclick="this.href=&#39;https://groups.google.com/group/cherrypy-users&#39;;return true;">https://groups.google.com/group/cherrypy-users.
For more options, visit <a href="https://groups.google.com/d/optout" target="_blank" rel="nofollow" onmousedown="this.href=&#39;https://groups.google.com/d/optout&#39;;return true;" onclick="this.href=&#39;https://groups.google.com/d/optout&#39;;return true;">https://groups.google.com/d/optout.

--
You received this message because you are subscribed to the Google Groups "cherrypy-users" group.
To unsubscribe from this group and stop receiving emails from it, send an email to [hidden email].
To post to this group, send email to [hidden email].
Visit this group at https://groups.google.com/group/cherrypy-users.
For more options, visit https://groups.google.com/d/optout.
Loading...