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

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM