基于Python的Webservice开发(二)-如何用Spyne开发Webservice


一、功能需求

本次案例是开发一个Item的新建的WebService。IN&OUT的类型JsonDocument。

通过传入相关的参数创建Item,且相关的参数可以被缺省。

二、Spyne的安装

pip install spyne

对于Python3

pip install spyne==2.13.4a1

三、实现代码

引入类

from spyne import Application,rpc,ServiceBase,Iterable,Integer,Unicode
#如果支持soap的协议需要用到Soap11
from spyne.protocol.soap import Soap11
#如果开发传入传出为Json需要用到JsonDocument
from spyne.protocol.json import JsonDocument
#可以创建一个wsgi服务器,做测试用
from spyne.server.wsgi import WsgiApplication
#将Spyne创建的app 发布为django
from django.views.decorators.csrf import csrf_exempt
#创建一个负责数据类型
from spyne.model.complex import ComplexModel
#引用其他的APP
from ItemAPI import APP_Item 

创建ItemData的相关属性

class ItemData(ComplexModel):
    __namespace__ = 'itemData'
    ItemCode=Unicode
    SearchCode=Unicode
    ItemName=Unicode
    Assortment=Unicode
    Brand=Unicode
    Material=Unicode
    ItemSource=Unicode
    Category=Unicode
    Series=Unicode
    Model=Unicode
    CostType=Unicode
    WareHouse=Unicode
    WareHouseLocation=Unicode
    Width=Unicode
    Length=Unicode
    Height=Unicode
    Volume=Unicode
    Size=Unicode
    GLAccountCost=Unicode
    GLAccountRevenue=Unicode
    GLAccountDistribution=Unicode
    SalesPrice=Unicode
    CostPrice=Unicode
    VatCode=Unicode
    IsHarbin=Unicode
    IsBatchItem=Unicode
    CountryCode=Unicode
创建ItemData相关属性

创建ItemAPI

#创建API
class ItemAPIService(ServiceBase):
    #传入参数ItemData,由之前定义的
    @rpc(ItemData, _returns=Iterable(Unicode))
    def item_api(ctx,itemData):
        fieldList=['ItemCode','SearchCode','ItemName','Assortment','Brand','Material','ItemSource','Category','Series','Model','CostType','WareHouse','WareHouseLocation','Width','Length','Height','Volume','Size','GLAccountCost','GLAccountRevenue','GLAccountDistribution','SalesPrice','CostPrice','VatCode','IsHarbin','IsBatchItem','CountryCode']
        dict_Data={}
        #itemData 会默认将未传值的根据顺序赋Null
        for field,value in zip(fieldList,itemData):
            if value is not None:
                dict_Data[field]=value
                #yield f"{field}={value}"
        #返回运行结果
        yield APP_Item(dict_Data)

#定义API的输入输出类型,如果需要支持Soap可以参考网页http://spyne.io
application = Application([ItemAPIService],
    tns='spyne.item.api',
    in_protocol=JsonDocument(validator='soft'),
    out_protocol=JsonDocument()
)
#定义DjangoApplication
item_app = csrf_exempt(DjangoApplication(application))
if __name__ == '__main__':
    # You can use any Wsgi server. Here, we chose
    # Python's built-in wsgi server but you're not
    # supposed to use it in production.
    from wsgiref.simple_server import make_server
    wsgi_app = WsgiApplication(application)
    server = make_server('0.0.0.0', 8000, wsgi_app)
    server.serve_forever()

四、对接口进行测试

import http.client,urllib.parse
import json
import requests

headers = {'Content-Type': 'application/json'}
requrl = f"http://127.0.0.1:8000/"
dict_Data={}
dict_Data["ItemCode"]="M09HLE220200030000"
dict_Data["ItemName"]="测试"
dict_Data["WareHouse"]="2001"
dict_Data["CountryCode"]="CN"
dict_Data["CostType"]="M-17XAC02-240"
dict_Data["Series"]="111"

#item_api是spyne的function名,itemData是传入参数名
postdata=json.dumps({"item_api": {"itemData":dict_Data}})
print(postdata)


req = requests.post(requrl,data=postdata)
print(json.loads(req.text))

四、Django配置

之前的spyne的app位于view.py中

from . import view
#item_app是view中定义的django应用名
urlpatterns = [
    url(r'^WebAPI/',view.item_app),]