python之restful框架

     上篇“python之简析restful”描述了restful框架,但是代码部分的例子不能算是一个

框架,很混乱,也仅仅作为演示。

   今天介绍本人重新构思后的restful框架。如果你了解restful就应该知道,restful架构的软件

提供的api并不是确定的,比如: /wm/[a]?p&v=3,这里表示a可以选择不同的值,具体选择什么值

需要看提供的手册,“?”后的属性也不确定(v=3仅是举例,p也并不是必须加的)。作为开发者设计

这些url并要求使用者使用这样的规则得到想要的资源。对于真实的用户的请求就要根据设计的api

解析出所要的值做后续的处理并得到用户所要的资源。

  本人实现的getAttribute()函数就是为了获得“?”之前被中括号包表示部分的值,比如用户输入

/wm/12?p&v=23,对应的api是/wm/[a]?p&v=3通过a=getAttrbiute('a')我们就能得到a=12,通过

t=query('p')就能得到t是真,如果用户不加p就是假,同理,v=query(‘v’)得到23.

   还是通过代码说明吧(python-2.7.5):

  1 #-*-coding:UTF-8-*-
  2 import socket
  3 #import thread
  4 import select
  5 from urlparse import urlparse
  6 
  7 class Restful:
  8     def __init__(self,ip='127.0.0.1',port=12345):
  9         self.server=socket.socket(socket.AF_INET,socket.SOCK_STREAM)
 10         self.server.setsockopt(socket.SOL_SOCKET,socket.SO_REUSEADDR,1)
 11         self.server.bind((ip,port))
 12         self.server.listen(1)
 13         self.client=None
 14         self.uri=None
 15         self.path=None
 16         self.method=None
 17         self.body=None
 18         self.header=None
 19         self.resourceMethod=[]
 20         self.urlparser=None
 21         self.rest={}
 22     def router(self,uri,method='GET'):  #这里使用了一点技巧
 23         self.uri=uri
 24         self.resourceMethod.append(method)
 25         def _rout(func):
 26             self.rest[uri]=func
 27         return _rout
 28     def getClientInfo(self):
 29         self.client,_=self.server.accept()
 30         data=self.client.recv(4096)
 31        
 32         tmp=data.split('\r\n')
 33         firstLine=tmp[0]
 34         firstLine=firstLine.split()
 35         self.method=firstLine[0]
 36         self.path=firstLine[1]
 37         self.urlparser=urlparse(self.path)
 38         l=len(tmp)
 39         self.header=tmp[1:l-2]
 40         self.body=tmp[l-1]
 41        
 42         res=self.__getKey()
 43         if  res is None:
 44             print 'Url no match'
 45             self.client.close()
 46             return None
 47         print '-->',self.uri
 48         if 'GET'==self.__isMethod('GET'):
 49             self.do_GET()
 50         elif 'POST' ==self.__isMethod('POST'):
 51             self.do_POST()
 52         elif 'DELETE' == self.__isMethod('DELETE'):
 53             self.do_DELETE()
 54         elif 'PUT' == self.__isMethod('PUT'):
 55             self.do_PUT()
 56     def getAttribute(self,attr):   #上面介绍的getAttribute()函数在这儿
 57         attrs=self.urlparser.path.split('/')
 58         formatAttrs=self.uri.split('/')
 59         for i in range(len(attrs)):
 60             if attr in formatAttrs[i]:
 61                 return attrs[i]
 62         return ''
 63     def query(self,param):         #上面介绍的query()函数在这儿
 64         vals=self.urlparser.query.split('&')
 65         if 'POST' == self.__isMethod('POST'):
 66             postvals=self.body.split('&')
 67             vals+=postvals
 68         res=None
 69         for v in vals:
 70             if param in v:
 71                 if '=' in v:
 72                     res= v.split('=')[1]
 73                 else:
 74                     res= True
 75         if res:
 76             return res
 77         else:
 78             return None
 79     def __isMethod(self,m):
 80         if m==self.method and m in self.resourceMethod:
 81             return m
 82         else:
 83             return None
 84     def __getKey(self):
 85         for k in self.rest.keys():
 86             c=k.find('[')
 87             ktmp=k[:c]
 88             if ktmp in self.urlparser.path:
 89                 self.uri=k
 90                 break
 91         if self.uri:
 92             return True
 93         return None
 94     def do_GET(self):
 95         src=self.rest[self.uri]()
 96         self.blocking(src)
 97     def do_POST(self):
 98         src=self.rest[self.uri]()
 99         self.blocking(src)
100     def do_DELETE(self):
101         src=self.rest[self.uri]()
102         self.blocking(src)
103     def do_PUT(self):
104         src=self.rest[self.uri]()
105         self.blocking(src)
106     def run(self):
107         while True:
108             self.getClientInfo()
109     def blocking(self,sendInfo):
110         response='HTTP/1.1 200 OK\r\n'+ \
111             'Content-type: text/html\r\n\r\n'
112         sendInfo=response+sendInfo+'\r\n'
113         self.client.send(sendInfo)
114         self.client.close()
115 
116 #------------Test------------------ #这里是测试部分也是例子
117 rest=Restful()
118 @rest.router('/wm/[a]?')            #例子1,router()第二个参数默认是GET方法
119 def test():
120     a=rest.getAttribute('a')
121     v=rest.query('u')
122     if not v:
123         v=''
124     elif v is True:
125         v='\"true\"'
126     return '{\"test\":'+a+',\"value\":'+v+'}'
127 
128 @rest.router('/vpc/[b]')            #例子2
129 def test():
130     attrB=rest.getAttribute('b')
131     return '{\"vpc\":'+attrB+'}'
132 
133 @rest.router('/post','POST')        #例子3,这里router()第二个参数是POST
134 def testPost():
135     p=rest.query('p')
136     v=rest.query('v')
137     return '{\"q\":'+p+',\"v\":'+v+'}'
138 rest.run()

  通过116行一下的部分我们知道,对于使用restful框架仅仅先实例化Restful类,然后利用

装饰器提供api,例如:@rest.router('/wm/[a]?'),并实现GET(router函数第二个参数默认为

GET方法)访问的资源函数,想要获得用户实际的值就要通过上面介绍过的两个函数;最后利用实例

rest.run()运行。

   下面是例子1测试:http://127.0.0.1:12345/wm/1?u=12

    

  url中的1和12是不确定部分。

  下面是测试例子3的,但是是POST请求使用浏览器不方便,就使用curl。

curl -d "p=4&v=1" http://127.0.0.1:12345/post

  得到:

  {"q":4,"v":1}

测试结果没做过多的处理,仅仅是获得请求的值。

好了,使用就是这样,很简单。当然还有不足地方,后续更新。

https://github.com/915546302/restful

 

posted @ 2013-11-24 17:33  除e尘  阅读(10630)  评论(0编辑  收藏  举报