python之简析restful

     RESTful架构,目前是比较流行的一种互联网软件架构。REST,即Representational State Transfer的缩写。

说白点就是网站即软件,再白点就是一个服务软件支持http的四种方法:

     GET用来获取资源,POST用来新建资源、更新资源,PUT用来更新资源,DELETE用来删除资源。

     并对外提供一个或多个URI,每个URI对应一个资源;客户端通过URI配合上面的方法就可以和服务

段的软件交互。客户端主要是浏览器,使用restful框架的软件对http的支持也为了web应用带来方便。

     REST这个词,是Roy Thomas Fielding在他2000年的博士论文中提出的。他的贡献很多,

可以了解一下。本人工作的方向是SDN,也算是比较潮的东东,其中floodlight就用到了restful框架。

开发者为软件开发出一些功能,并提供URI api,用户就可以利用浏览器、curl等工具通过提供的URI

从软件中获得想要的信息或者设置软件的功能。

     对于发开者来说,就是提供URI和URI对应的资源,并将他们对应上,类似dicts={'/path?':resource}。

比如重写http GET方法:首先获得客户端请求的url,解析url然后判断其对应的URI,由于URI与应一个资源,

那么url就可以访问这个资源了。具体实现上资源也就是方法或者一个类,要看具体实现了。

     下面来个很简单的例子,因为对于真正功能强大的restful来说,这个例子有几点不足,但是作为简单的演示,

应该够了。

  

 1 #-*-coding:UTF-8-*-
 2 import socket,sys,urllib
 3 from BaseHTTPServer import *
 4 
 5 class Restful(BaseHTTPRequestHandler):  #所有rest的父类
 6     def __init__(self,request, client_address, server):
 7         BaseHTTPRequestHandler.__init__(self,request, client_address, server)
 8         self.dp=None
 9         self.router=None
10         
11     def basepath(self):
12         pass
13     def getresetlet(self):
14         pass
15     def send(self,src):
16         self.send_response(200)
17         self.send_header("Content-type", "text/html")
18         self.end_headers()
19         self.wfile.write(src)
20         self.wfile.close()
21     def done(self):
22         self.dp=self.basepath()
23         self.router=self.getrestlet()
24 class Test(Restful):            #测试1
25     def test(self):  #这就是一个资源
26         return "{\"date\":\"2013-11-19\"}"
27     def do_GET(self):  #重写get方法给了通过客户端请求的url找到对应的资源
28         self.done()
29         for key in self.router.keys():
30             tmp=self.dp+key
31             if tmp in self.path:
32                   self.send(self.router[key]()) #执行资源
33     def basepath(self): #这个简单的说就是和下面函数中的路径配合,即/wm/time
34         return "/wm"
35     def getrestlet(self):  #这儿就是URI与资源对应,这里只有test资源,可以注册多个
36         rr={}
37         rr['/time']=self.test 
38           return rr
39 class testjson(Restful):      #测试2
40     def testjson(self,vpc,vr):  #这里比测试1复杂些,因为参数的值需要从url中获得
41         src1="{\"vpc\":1,\"vrouter\":3,\"day\":[1,2,3]}"
42         src2="{\"vpc\":1,\"vrouter\":4,\"day\":[23,21,3]}"
43         src3="{\"vpc\":5,\"vrouter\":3,\"day\":[13,2,23]}"
44         tlist=[src1,src2,src3]
45         cmpvpc="\"vpc\":"+vpc
46         cmpvr="\"vrouter\":"+vr
47         for k in tlist:
48             if cmpvpc in k and cmpvr in k:
49                 return k
50     def firewall(self):
51         return "{\"filter\":[\"baid.com/\",\"c.cn/\"],\"acl\":{\"accept\":123,\"reject\":321}}"
52     def do_GET(self):  #重写GET,解析url,这里的self.path类似:/ins/json?vpc=1&vrouter=3
53         self.done()
54         print self.path
55         if 'vpc' in self.path and 'vrouter' in self.path:
56             query=None
57             if '?' in self.path:
58                 query =    urllib.splitquery(self.path)
59             key=query[0]+'?'
60             param=query[1].split('&') #解析获得属性信息,传递给资源函数
61             pdict={}
62             for p in param:
63                 tmp=p.split('=')
64                 pdict[tmp[0]]=tmp[1]  
65             for k in self.router.keys():
66                 if k in key:
67                     self.send(self.router[k](pdict['vpc'],pdict['vrouter'])) #执行资源
68         elif 'firewall' in self.path:
69             self.send(self.router['/firewall']())
70         else:
71             self.send("{}")
72     def basepath(self):
73         return "/ins"
74     def getrestlet(self):
75         rr={}
76         rr['/json?']=self.testjson #注册资源
77         rr['/firewall']=self.firewall
78         return rr
79         
80             
81 try:
82     server=HTTPServer(('',8084),testjson) #测试2
83     server.serve_forever()
84 except KeyboardInterrupt:
85     sys.exit(0)

 

      如果运行上面的程序,运行的是测试2,运行后此程序监听8084。

此时在浏览器地址栏输入http://127.0.0.1:8084/ins/json?vpc=1&vrouter=3

得到如下图,本人使用的chrome,安装插件后的效果。

        

输入:http://127.0.0.1:8084/ins/firewall

      

      这里仅仅作为演示,程序有有许多不足。对于好的框架,注册资源不应该和资源在同一个类中,

basepath()与getrestlet()不应该在实现的资源类里(也就是上面的测试里),也使router没起作用。

应该在另一个类里注册,这样可以通过不同的URI,两个测试都应该能够运行还有就是使用的python

自带的BaseHTTPServer模块,并不适合做restful。

     但是工作过程大体就是这样,后续有时间会写个python版的restful简易框架。

posted @ 2013-11-20 09:41  除e尘  阅读(7184)  评论(0编辑  收藏  举报