开发者

AppEngine elegant way to handle similar requests

I'm making a server that can let clients upload and download data of different models. Is there some elegant way handle the requests?

More precisely, I don't want to do something like this,

app = webapp.WSGIApplication([
    ('/my_upload_and_download_url/ModelA/(.*)', MyRequestHandlerForA),
    ('/my_upload_and_download_url/ModelB/(.*)', MyRequestHandlerForB),
    ('/my_upload_and_download_url/ModelC/(.*)', MyRequestHandlerForC),
])
run_wsgi_app(app)

since what I do inside the handler would all be the same. For example,

class MyRequestHandlerForX(webapp.RequestHandler):
    def get(self, key=None):
        # return the instance with the designated key
    def post(self, key=None):
        # create/get the model instance
        # iterate through the property list of the instance and set the values

the only difference among the handlers is to create instance for different models. The urls are alike, and the handlers are almost the same.

I checked this post about redirect requests to other handlers, and I've also read some methods to开发者_StackOverflow create an instance by a class name; but I think neither of them is good.

Anyone has a good solution?

p.s. This is my first post here. If there is anything inappropriate please tell me, thanks.


How you do this depends largely on the details of your code in the request handler. You can do a fairly generic one like this:

class ModelHandler(webapp.RequestHandler):
  def get(self, kind, key):
    model = db.class_for_kind(kind)
    instance = model.get(key)
    # Do something with the instance - eg, print it out

  def post(self, kind, key):
    model = db.class_for_kind(kind)
    instance = model.create_from_request(self.request)

application = webapp.WSGIApplication([
    ('/foo/([^/]+)/([^/]+)', ModelHandler),
])

def main():
  run_wsgi_app(application)

if __name__ == '__main__':
  main()

This assumes you define a 'create_from_request' class method on each model class; you probably don't want to do it exactly this way, as it tightly couples model definitions with the forms used to input them; instead, you probably want to store a mapping of kind name or class to handler function, or do your forms and creation entirely automatically by reflecting on the properties of the class. Since you haven't specified what it is about doing this you're unsure about, it's hard to be more specific.

Also note the inclusion of a main() and other boilerplate above; while it will work the way you've pasted it, adding a main is substantially more efficient, as it allows the App Engine runtime to avoid having to evaluate your module on every request.


In your case I'd probably just have everything hit the same url path, and put the specifics in the GET parameters, like /my_upload_and_download_url?model=modelA.

You can also use webapp2 (http://webapp-improved.appspot.com/guide/app.html) which has a bunch of url routing support.


You could parse out the url path and do a look up, like this:

import urlparse

model_lookup = {'ModelA':ModelA,'ModelB':ModelB, 'ModelC':ModelC}

class MyRequestHandler(webapp.RequestHandler):
    def get(self):
        url = urlparse.urlparse(self.request.uri)
        path_model = url.path.replace('/my_upload_and_download_url/','')
        model = model_lookup[path_model]
        ...

Which allows you to use the same class for each path:

app = webapp.WSGIApplication([
    ('/my_upload_and_download_url/ModelA/(.*)', MyRequestHandler),
    ('/my_upload_and_download_url/ModelB/(.*)', MyRequestHandler),
    ('/my_upload_and_download_url/ModelC/(.*)', MyRequestHandler),
])
run_wsgi_app(app)
0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜