Python的Tornado框架的REST支持方案

来源:互联网 发布:中天制片软件 编辑:程序博客网 时间:2024/06/05 00:11
使用了Python的Tornado框架,想发布为REST规范的webservice.综合了网上的方法,基本上有三种:

1.     直接用tornado实现:

     tornado.web.RequestHandler.write() 可以输出json.

     但是对于header的操作需要自己封装。

     本着拿来主义的精神,还是想找现成的插件。

2.     有一个叫pyrestful的插件,可以试用一下。

     步骤如下:

     a.     pip install pyrestful

     b.     可以参考官方文档,我的代码片段如下:

     *入口代码:

          #!/usr/bin/python
#-*- coding: utf-8 -*-
__author__ = 'stone'
import tornado.ioloop
import pyrestful.rest
import os
os.environ['NLS_LANG'] = 'SIMPLIFIED CHINESE_CHINA.UTF8'
import logging
from common.Log import LogInit
from common.Cfg import config
from business.Customer import CustomerResource
LogInit("loggingREST.conf")
cfg = config(filename="config4REST.conf")
#a list to route different REST Service.
restservices = []
restservices.append(CustomerResource)
if __name__ == "__main__":
    loggerRoot = logging.getLogger('root')
    loggerRoot.debug("start run REST module.")
    try:
        app = pyrestful.rest.RestService(restservices)
        port = cfg.get('port','port')
        app.listen(port)
        tornado.ioloop.IOLoop.instance().start()
    except Exception,ex:
        pass
     

     *服务代码:
__author__ = 'stone'
#-*- coding: utf-8 -*-
import os
os.environ['NLS_LANG'] = 'SIMPLIFIED CHINESE_CHINA.UTF8'
import pyrestful.rest
from pyrestful import mediatypes
from pyrestful.rest import get, post, put, delete
import logging
import torndb


class Customer(object):
    def __init__(self,id_customer=0, name_customer=None, address_customer=None):
        self.id_customer = id_customer
        self.name_customer = name_customer
        self.address_customer = address_customer

    # Setters
    def setId_Customer(self,id_customer):
        self.id_customer = id_customer
    def setName_Customer(self,name_customer):
        self.name_customer = name_customer
    def setAddress_Customer(self,address_customer):
        self.address_customer = address_customer

    # Getters
    def getId_Customer(self):
        return self.id_customer
    def getName_Customer(self):
        return self.name_customer
    def getAddress_Customer(self):
        return self.address_customer

class CustomerDataBase(object):
    customerDB = dict()
    id_seq = 1
    def insert(self, name_customer, address_customer):
        sequence = self.id_seq
        customer = Customer(sequence, name_customer, address_customer)
        self.customerDB[sequence] = customer
        self.id_seq += 1
        return sequence

    def update(self,id_customer, name_customer, address_customer):
        if self.exists(id_customer):
            customer = self.customerDB[id_customer]
            customer.setName_Customer(name_customer)
            customer.setAddress_Customer(address_customer)
            self.customerDB[id_customer] = customer
            return True
        else:
            return False

    def delete(self,id_customer):
        if self.exists(id_customer):
            del self.customerDB[id_customer]
            return True
        else:
            return False

    def find(self,id_customer):
        if self.exists(id_customer):
            return self.customerDB[id_customer]
        else:
            return None

    def exists(self,id_customer):
        if id_customer in self.customerDB:
            return True
        else:
            return False

class CustomerResource(pyrestful.rest.RestHandler):
    """
    a class for Customer Resource.
    """
    def initialize(self):
        """
        special initial for tornado.web.RequestHandler.
        """
        loggerRoot = logging.getLogger('root')
        loggerRoot.debug("start CustomerResource module.")
        self.database = CustomerDataBase()

    #REST-GET
    @get(_path="/customer/{id_customer}",_types=[int],_produces=mediatypes.APPLICATION_JSON)
    def getTest(self,id_customer):
        try:
            if not self.database.exists(id_customer):
                self.gen_http_error(404,"Error 404 : do not exists the customer : %d"%id_customer)
                return

            customer = self.database.find(id_customer)

            response = dict()
            response['id_customer'] = customer.getId_Customer()
            response['name_customer'] = customer.getName_Customer()
            response['address_customer'] = customer.getAddress_Customer()
            return response
        except Exception,ex:
            pass

    #REST-POST
    @post(_path="/customer", _types=[str,str], _produces=mediatypes.APPLICATION_JSON)
    def createCustomer(self, name_customer, address_customer):
        try:
            id_customer = self.database.insert(name_customer, address_customer)
            return {"created_customer_id": id_customer}
        except Exception,ex:
            pass

    #REST-PUT
    @put(_path="/customer/{id_customer}", _types=[int,str,str], _produces=mediatypes.APPLICATION_JSON)
    def updateCustomer(self, id_customer, name_customer, address_customer):
        try:
            if not self.database.exists(id_customer):
                self.gen_http_error(404,"Error 404 : do not exists the customer : %d"%id_customer)
                return
            updated = self.database.update(id_customer,name_customer,address_customer)
            return {"updated_customer_id": id_customer, "success":updated}
        except Exception,ex:
            pass

    #REST-DELETE
    @delete(_path="/customer/{id_customer}", _types=[int], _produces=mediatypes.APPLICATION_JSON)
    def deleteCustomer(self,id_customer):
        try:
            if not self.database.exists(id_customer):
                self.gen_http_error(404,"Error 404 : do not exists the customer : %d"%id_customer)
                return
            deleted = self.database.delete(id_customer)
            return {"delete_customer_id": id_customer, "success":deleted}
        except Exception,ex:
            pass
     


     经过测试可用。

3.     但是,之前用的web.py框架时,有一个叫做mimerender的插件,封装比这个优雅,想用起来,这一折腾就花了3天,最终调通,使用方法如下:

     a.     pip install mimerender.

     b.     hacker mimerender的代码,添加tornado的支持,片段如下:

# tornado implementation
try:
    import tornado.web
    class TornadoMimeRender(MimeRenderBase):
        """
        a class for tornado mimerender.
        2014.11.13. stone spend a week to use it.
        we need set the handler from front app.
        """

        #a class hander for tornado
        localHandler = tornado.web.RequestHandler
        def setHandler(self,reqHandler):
            """
            set the handler for tornado.
            """
            self.localHandler = reqHandler

        def _get_request_parameter(self, key, default=None):
            #tornado.web.RequestHandler.get_argument()
            return self.localHandler.get_argument(key,default)

        def _get_accept_header(self, default=None):
            return self.localHandler.request.headers['ACCEPT']

        def _set_context_var(self, key, value):
            #tornado.web.RequestHandler.__setattr__(key,value)
            self.localHandler.__setattr__(key,value)

        def _clear_context_var(self, key):
            #tornado.web.RequestHandler.__delattr__(key)
            self.localHandler.__delattr__(key)

        def _make_response(self, content, content_type, status):
            #tornado.web.RequestHandler.set_status(status)
            # we only need first 3 int.
            self.localHandler.set_status(int(status[0:3]))
            #tornado.web.RequestHandler.set_header('Content-Type',content_type)
            self.localHandler.set_header('Content-Type',content_type)
            self.localHandler.write(content)

except ImportError:
    pass



     c.     使用的代码片段如下:
#!/usr/bin/python
#-*- coding: utf-8 -*-
__author__ = 'stone'
import tornado.ioloop
import tornado.web
import mimerender
import json
import os
os.environ['NLS_LANG'] = 'SIMPLIFIED CHINESE_CHINA.UTF8'
import logging
from common.Log import LogInit
from common.Cfg import config

LogInit("loggingREST.conf")

cfg = config(filename="config4REST.conf")

mimerender = mimerender.TornadoMimeRender()

render_xml = lambda message: '<message>this is xml:%s</message>'%message
render_json = lambda **args: json.dumps(args)
render_html = lambda message: '<html><body>this is html:%s</body></html>'%message
render_txt = lambda message: message

class Mimeservice(tornado.web.RequestHandler):
    """
    a mime render test service.
    """

    #use mimerender
    #step 1: set the handler.
    def initialize(self):
        """
        special init for tornado.web.RequestHandler class.
        set the handler for mime render.
        """
        mimerender.setHandler(self)

    #use mimerender
    #step 2: define mimerender format.
    @mimerender(
        default = 'json',
        html = render_html,
        xml = render_xml,
        json = render_json,
        txt = render_txt
    )
    #use mimerender
    #step 3: same with the all mimerender.
    def get(self):
        return {'message':'Hello'}

application = tornado.web.Application([
    (r"/mimeservice",Mimeservice),
    (r"/mime",Mimeservice)
])

if __name__ == "__main__":
    loggerRoot = logging.getLogger('root')
    loggerRoot.debug("start run REST module in mimerender.")
    try:
        port = cfg.get('port','port')
        application.listen(port)
        tornado.ioloop.IOLoop.instance().start()
    except Exception,ex:
        pass
     
     经测,可用,折腾死我了。
0 0
原创粉丝点击
热门问题 老师的惩罚 人脸识别 我在镇武司摸鱼那些年 重生之率土为王 我在大康的咸鱼生活 盘龙之生命进化 天生仙种 凡人之先天五行 春回大明朝 姑娘不必设防,我是瞎子 牛奶乳加钙咀嚼片吃多了怎么办 三生骗了我该怎么办 国珍产品新时代卡怎么办 三个月大的宝宝对眼怎么办 9月大婴儿眼睛对眼怎么办 30岁眼部有皱纹怎么办 才24岁眼部皱纹怎么办 被双开后以前的养老保险怎么办 尚赫辟谷期间来月经怎么办 保险公司给代理人奖金迟发怎么办 比亚迪f3烧机油怎么办 支付宝刷脸认证老失败怎么办 融e借没密码器怎么办 融e购不显示积分怎么办 王者荣耀区满了怎么办 苹果4s储存不够怎么办 乐视2费电超级快怎么办 支付宝手机订单号查不到怎么办 淘宝几个订单同一个快递单号怎么办 工商银行u盾丢了怎么办 银行不让开u盾怎么办 手机u盾识别不了怎么办 绿森商城不退款怎么办 电信手机号码过户积分清零怎么办 被电话诈骗骗了怎么办 诈骗电话骗了钱怎么办 被网友骗了一千块钱怎么办 被网友骗了1000块怎么办 微信红包被骗100怎么办 3m投资钱要不回来怎么办 手机照片超过3m怎么办 小说大于3m看不了怎么办 携程订单删除了怎么办 绿叶会员密码忘了怎么办 账号对名错了怎么办 lv双肩包肩带短了怎么办 微信充q币被骗了怎么办 qq隐私密码忘了怎么办 qq锁屏密码忘了怎么办 qq手势密码忘记了怎么办 qq红包的密码忘了怎么办