zoukankan      html  css  js  c++  java
  • 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('
    ')
     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
    '+ 
    111             'Content-type: text/html
    
    '
    112         sendInfo=response+sendInfo+'
    '
    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

  • 相关阅读:
    豆瓣书籍数据采集
    动画精灵与碰撞检测
    图形
    模块
    对象
    函数
    列表与字典
    python 感悟
    SqlServer自动备份数据库(没有sql代理服务的情况下)
    关于AD获取成员隶属于哪些组InvokeGet("memberOf")的问题
  • 原文地址:https://www.cnblogs.com/wuchaofan/p/3440263.html
Copyright © 2011-2022 走看看