狠狠撸

狠狠撸Share a Scribd company logo
Python基于xmlrpc的webservice服务以及在odoo中的使用 
XML-RPC通过xml来传输RPC,在Python中提供了xmlrpclib模块进行了封装。参考文 
档https://docs.python.org/2/library/xmlrpclib.html 
一个简单的例子 
from SimpleXMLRPCServer import SimpleXMLRPCServer 
class HelloService: 
def sayHello(self, name): 
return "Hello " + name; 
def start_server(): 
obj = HelloService() 
server = SimpleXMLRPCServer(("localhost", 8080)) 
server.register_instance(obj) 
server.serve_forever() 
print "Server Started...." 
上面的例子作为服务端采用了SimpleXMLRPCServer,需要指定host和port即可。在这个例子里注册了一个对象实例,接下来看看 
客户端的写法 
import xmlrpclib 
def helloClient(): 
server = xmlrpclib.ServerProxy("http://localhost:8080") 
words = server.sayHello("Python") 
print "result: %s" % (words,) 
这样就完成了一个请求的过程。当然这只是一个很简单的例子,上面是注册实例,那么对象里面的方法都可以访问。同样也支持对 
函数的注册 
将函数作为服务发布 
def division(x, y): 
return x / y 
def server_reg_func(): 
server = SimpleXMLRPCServer(("localhost", 8080)) 
server.register_function(division, "division") 
server.serve_forever() 
print "Server Started...." 
将函数作为服务发布采用了方法register_function,需要传入参数函数和调用的名称。那么在客户端访问和上面例子基本一致, 
只需要调用函数名为注册的(division)即可server.division(2, 5)。上面的例子只注册了一个函数发布服务,在现实世界中可能 
会有多个服务,那也是支持的 
注册多个函数作为服务发布 
def server_multi_funcs(): 
server = SimpleXMLRPCServer(("localhost", 8080)) 
server.register_multicall_functions() 
server.register_function(division, "division") 
server.register_function(add, "add") 
server.serve_forever() 
print "Server Started...." 
这里新增了函数register_multicall_functions调用,那么就支持同时注册多个函数发布服务,这是在客户端需要做一些调整,不 
会直接返回结果而是将调用的结果作为实例返回 
def multi_fun_client(): 
server = xmlrpclib.ServerProxy("http://localhost:8080") 
multicall = xmlrpclib.MultiCall(server) 
try: 
multicall.division(2, 5) 
multicall.add(2, 0) 
result = multicall() 
print type(result) 
print "2/5=%d, 2+0=%d" % tuple(result)
print "2/5=%d, 2+0=%d" % tuple(result) 
except xmlrpclib.Fault as err: 
print "A fault occurred" 
print "Fault code: %d" % err.faultCode 
print "Fault string: %s" % err.faultString 
这里还显示了发生错误时相应的提示信息 
多线程的服务 
多线程服务也很简单,在服务端提供了相关的接口 
class ThreadXMLRPCServer(ThreadingMixIn, SimpleXMLRPCServer): 
pass 
def server_thread(): 
server = ThreadXMLRPCServer(("localhost", 8080)) 
server.register_function(division, "division") 
server.serve_forever() 
这样服务端就能作为一个多线程处理请求,他会将每个请求一个线程进行处理 
多路径服务 
在前面的例子中我们都是在同一个端口下发布的服务,但是并没指定路径。对多路径的支持如下 
class RequestHandler(SimpleXMLRPCRequestHandler): 
rpc_paths = ('/','/hello') 
def server_path(): 
server = SimpleXMLRPCServer(("localhost", 8080), requestHandler=RequestHandler) 
server.register_function(add, "add") 
server.serve_forever() 
print "Server Started...." 
这里服务端新增了处理请求的Handler他会将根目录指向到/hello路径下,在客户端就可以用这个路径进行访问 
def path_client(): 
server = xmlrpclib.ServerProxy("http://localhost:8080/hello") 
print server.add(2, 5) 
二进制文件的读取 
在python官方DOC中提供了传输二进制文件的例子 
from SimpleXMLRPCServer import SimpleXMLRPCServer 
import xmlrpclib 
def python_logo(): 
with open("python_logo.jpg", "rb") as handle: 
return xmlrpclib.Binary(handle.read()) 
server = SimpleXMLRPCServer(("localhost", 8000)) 
print "Listening on port 8000..." 
server.register_function(python_logo, 'python_logo') 
server.serve_forever() 
客户端读取文件并写入本地 
import xmlrpclib 
proxy = xmlrpclib.ServerProxy("http://localhost:8000/") 
with open("fetched_python_logo.jpg", "wb") as handle: 
handle.write(proxy.python_logo().data) 
odoo中webservice的使用 
odoo中的webservice采用基于xmlrpc的实现提供了内置的实现,我们在暴露接口的时候只需要调用相关的方法就可以实现。 
获取用户信息 
传入dbname,name和password。返回uid。注意请求的路径为host:prot/xmlrpc/common
传入dbname,name和password。返回uid。注意请求的路径为host:prot/xmlrpc/common 
server_conf = xmlrpclib.ServerProxy("http://localhost:8069/xmlrpc/common") 
uid = server_conf.login("open_erp", "admin", "admin") 
新建一条记录 
对象的操纵请求路径都为host:prot/xmlrpc/object,需要传入参数dbname,uid,db_password可变的参数为需要创建对象的name 
属性(dili.pos.psam),方法,这里是新建(create),其他包括查询(search),读取(read),更新(write),删除(unlink) 
server = xmlrpclib.ServerProxy("http://localhost:8069/xmlrpc/object") 
psam = { 
'name' : 'abc', 
'rsa_public_key' : 'jjjjj' 
} 
result = server.execute("open_erp", uid, "root", "dili.pos.psam", "create", psam) 
查询、读取、更新和删除 
查询中支持查询参数(query_args)返回满足结果的id列表。 
读取中支持需要返回数据的字段(fields)返回满足条件的列表。 
更新则需要传入需要更新数据的编号列表,同时values对应了更改的编号返回执行结果True或False 
删除需要传入删除id列表,返回执行的结果True或False 
server = xmlrpclib.ServerProxy("http://localhost:8069/xmlrpc/object") 
query_args = [('name', '=', 'abc'), ('rsa_public_key', '=', 'jjjjj')] 
ids = server.execute("open_erp", uid, "root", "dili.pos.psam", "search", query_args) 
fields = ['name', 'rsa_public_key', 'psam_rsa'] 
datas = server.execute("open_erp", uid, "root", "dili.pos.psam", "read", ids, fields) 
values = {'name':'abcd'} 
success = server.execute("open_erp", uid, "root", "dili.pos.psam", "write", ids, values) 
success = server.execute("open_erp", uid, "root", "dili.pos.psam", "unlink", ids) 
odoo中实现简述 
接下来看看基于wsgi中的实现。我们可以从openerp-wsgi.py中工程启动使用了application函数 
application = openerp.service.wsgi_server.application 
在wigi_server.py中函数的定义指明了处理的方式 
def application(environ, start_response): 
if config['proxy_mode'] and 'HTTP_X_FORWARDED_HOST' in environ: 
return werkzeug.contrib.fixers.ProxyFix(application_unproxied)(environ, start_response) 
else: 
return application_unproxied(environ, start_response) 
在函数application_unproxied中采用了解析handler:wsgi_xmlrpc以及更多注册的。这里关注wsgi_xmlrpc 
def wsgi_xmlrpc(environ, start_response): 
""" Two routes are available for XML-RPC 
/xmlrpc/<service> route returns faultCode as strings. This is a historic 
violation of the protocol kept for compatibility. 
/xmlrpc/2/<service> is a new route that returns faultCode as int and is 
therefore fully compliant. 
""" 
if environ['REQUEST_METHOD'] == 'POST' and environ['PATH_INFO'].startswith('/xmlrpc/'): 
length = int(environ['CONTENT_LENGTH']) 
data = environ['wsgi.input'].read(length) 
# Distinguish betweed the 2 faultCode modes 
string_faultcode = True 
if environ['PATH_INFO'].startswith('/xmlrpc/2/'): 
service = environ['PATH_INFO'][len('/xmlrpc/2/'):] 
string_faultcode = False
else: 
service = environ['PATH_INFO'][len('/xmlrpc/'):] 
params, method = xmlrpclib.loads(data) 
return xmlrpc_return(start_response, service, method, params, string_faultcode) 
这里有两点: 
1、只处理post请求和请求路径中有/xmlprc即处理基于xmlrpc的请求 
2、可以采用2中路径,区别是错误码返回int和字符串 
具体处理请求在函数xmlrpc_return中 
result = openerp.http.dispatch_rpc(service, method, params) 
在改方法中处理了几种service的情况 
if service_name == 'common': 
dispatch = openerp.service.common.dispatch 
elif service_name == 'db': 
dispatch = openerp.service.db.dispatch 
elif service_name == 'object': 
dispatch = openerp.service.model.dispatch 
elif service_name == 'report': 
dispatch = openerp.service.report.dispatch 
else: 
dispatch = openerp.service.wsgi_server.rpc_handlers.get(service_name) 
result = dispatch(method, params)

More Related Content

What's hot (20)

如何学习Bash Shell
如何学习Bash Shell如何学习Bash Shell
如何学习Bash Shell
LI Daobing
?
箩蝉辫基础速成精华讲解
箩蝉辫基础速成精华讲解箩蝉辫基础速成精华讲解
箩蝉辫基础速成精华讲解
wensheng wei
?
闯2别别面试知识
闯2别别面试知识闯2别别面试知识
闯2别别面试知识
yiditushe
?
Golang server design pattern
Golang server design patternGolang server design pattern
Golang server design pattern
理 傅
?
骋辞语言飞别产开发
骋辞语言飞别产开发骋辞语言飞别产开发
骋辞语言飞别产开发
Andy Shi
?
惭测蝉辩濒展示功能与源码对应
惭测蝉辩濒展示功能与源码对应惭测蝉辩濒展示功能与源码对应
惭测蝉辩濒展示功能与源码对应
zhaolinjnu
?
Golangintro
GolangintroGolangintro
Golangintro
理 傅
?
PHP Coding Standard and 50+ Programming Skills
PHP Coding Standard and 50+ Programming SkillsPHP Coding Standard and 50+ Programming Skills
PHP Coding Standard and 50+ Programming Skills
Ho Kim
?
5, initialization & cleanup
5, initialization & cleanup5, initialization & cleanup
5, initialization & cleanup
ted-xu
?
SQL Loader & Bulk Insert 大量資料匯入工具
SQL Loader & Bulk Insert 大量資料匯入工具SQL Loader & Bulk Insert 大量資料匯入工具
SQL Loader & Bulk Insert 大量資料匯入工具
HO-HSUN LIN
?
贰箩产工作原理学习笔记
贰箩产工作原理学习笔记贰箩产工作原理学习笔记
贰箩产工作原理学习笔记
yiditushe
?
shell script introduction
shell script introductionshell script introduction
shell script introduction
Jie Jin
?
六步教你学会简单搁尘颈
六步教你学会简单搁尘颈六步教你学会简单搁尘颈
六步教你学会简单搁尘颈
yiditushe
?
Mongodb
MongodbMongodb
Mongodb
bj
?
Python 入门
Python 入门Python 入门
Python 入门
kuco945
?
闯诲产肠中操作叠濒辞产、颁濒辞产等对象
闯诲产肠中操作叠濒辞产、颁濒辞产等对象闯诲产肠中操作叠濒辞产、颁濒辞产等对象
闯诲产肠中操作叠濒辞产、颁濒辞产等对象
yiditushe
?
Lucene 全文检索实践
Lucene 全文检索实践Lucene 全文检索实践
Lucene 全文检索实践
yiditushe
?
Monitor is all for ops
Monitor is all for opsMonitor is all for ops
Monitor is all for ops
琛琳 饶
?
异步编程与浏览器执行模型
异步编程与浏览器执行模型异步编程与浏览器执行模型
异步编程与浏览器执行模型
keelii
?
如何学习Bash Shell
如何学习Bash Shell如何学习Bash Shell
如何学习Bash Shell
LI Daobing
?
箩蝉辫基础速成精华讲解
箩蝉辫基础速成精华讲解箩蝉辫基础速成精华讲解
箩蝉辫基础速成精华讲解
wensheng wei
?
闯2别别面试知识
闯2别别面试知识闯2别别面试知识
闯2别别面试知识
yiditushe
?
Golang server design pattern
Golang server design patternGolang server design pattern
Golang server design pattern
理 傅
?
骋辞语言飞别产开发
骋辞语言飞别产开发骋辞语言飞别产开发
骋辞语言飞别产开发
Andy Shi
?
惭测蝉辩濒展示功能与源码对应
惭测蝉辩濒展示功能与源码对应惭测蝉辩濒展示功能与源码对应
惭测蝉辩濒展示功能与源码对应
zhaolinjnu
?
Golangintro
GolangintroGolangintro
Golangintro
理 傅
?
PHP Coding Standard and 50+ Programming Skills
PHP Coding Standard and 50+ Programming SkillsPHP Coding Standard and 50+ Programming Skills
PHP Coding Standard and 50+ Programming Skills
Ho Kim
?
5, initialization & cleanup
5, initialization & cleanup5, initialization & cleanup
5, initialization & cleanup
ted-xu
?
SQL Loader & Bulk Insert 大量資料匯入工具
SQL Loader & Bulk Insert 大量資料匯入工具SQL Loader & Bulk Insert 大量資料匯入工具
SQL Loader & Bulk Insert 大量資料匯入工具
HO-HSUN LIN
?
贰箩产工作原理学习笔记
贰箩产工作原理学习笔记贰箩产工作原理学习笔记
贰箩产工作原理学习笔记
yiditushe
?
shell script introduction
shell script introductionshell script introduction
shell script introduction
Jie Jin
?
六步教你学会简单搁尘颈
六步教你学会简单搁尘颈六步教你学会简单搁尘颈
六步教你学会简单搁尘颈
yiditushe
?
Mongodb
MongodbMongodb
Mongodb
bj
?
Python 入门
Python 入门Python 入门
Python 入门
kuco945
?
闯诲产肠中操作叠濒辞产、颁濒辞产等对象
闯诲产肠中操作叠濒辞产、颁濒辞产等对象闯诲产肠中操作叠濒辞产、颁濒辞产等对象
闯诲产肠中操作叠濒辞产、颁濒辞产等对象
yiditushe
?
Lucene 全文检索实践
Lucene 全文检索实践Lucene 全文检索实践
Lucene 全文检索实践
yiditushe
?
Monitor is all for ops
Monitor is all for opsMonitor is all for ops
Monitor is all for ops
琛琳 饶
?
异步编程与浏览器执行模型
异步编程与浏览器执行模型异步编程与浏览器执行模型
异步编程与浏览器执行模型
keelii
?

Viewers also liked (17)

december`15
december`15december`15
december`15
inactionagency
?
Veerendra_Patil_Technical_Skills_Details_
Veerendra_Patil_Technical_Skills_Details_Veerendra_Patil_Technical_Skills_Details_
Veerendra_Patil_Technical_Skills_Details_
Veerendra Patil
?
Fisheries Debates Management Challenges
Fisheries Debates Management Challenges
Fisheries Debates Management Challenges
Fisheries Debates Management Challenges
permissibleyout77
?
Your first days
Your first daysYour first days
Your first days
Florencia Monica
?
action weekly March
action weekly Marchaction weekly March
action weekly March
inactionagency
?
HOSP PP
HOSP PPHOSP PP
HOSP PP
Tony Tamayo
?
Python learn guide
Python learn guidePython learn guide
Python learn guide
robin yang
?
Socialize your Exceptional Web Experience – Adobe AEM & IBM Connections by He...
Socialize your Exceptional Web Experience – Adobe AEM & IBM Connections by He...Socialize your Exceptional Web Experience – Adobe AEM & IBM Connections by He...
Socialize your Exceptional Web Experience – Adobe AEM & IBM Connections by He...
AEM HUB
?
Veerendra_2016_V2
Veerendra_2016_V2Veerendra_2016_V2
Veerendra_2016_V2
Veerendra Patil
?
Action weekly ver.6
Action weekly ver.6Action weekly ver.6
Action weekly ver.6
inactionagency
?
Your self improvement
Your self improvementYour self improvement
Your self improvement
Florencia Monica
?
Eu africa summit
Eu africa summitEu africa summit
Eu africa summit
rusnavy
?
linkedinculturedeck-150310163928-conversion-gate01
linkedinculturedeck-150310163928-conversion-gate01linkedinculturedeck-150310163928-conversion-gate01
linkedinculturedeck-150310163928-conversion-gate01
Stephanie Walker
?
Creativity without comprise by Cleve Gibbon
Creativity without comprise by Cleve Gibbon Creativity without comprise by Cleve Gibbon
Creativity without comprise by Cleve Gibbon
AEM HUB
?
Where are our Alumni now?
Where are our Alumni now?Where are our Alumni now?
Where are our Alumni now?
Jordan Poulton
?
Computer
ComputerComputer
Computer
Dharmesh Khatri
?
Choosing Page Orientation
Choosing Page OrientationChoosing Page Orientation
Choosing Page Orientation
cbuzz001
?
Veerendra_Patil_Technical_Skills_Details_
Veerendra_Patil_Technical_Skills_Details_Veerendra_Patil_Technical_Skills_Details_
Veerendra_Patil_Technical_Skills_Details_
Veerendra Patil
?
Fisheries Debates Management Challenges
Fisheries Debates Management Challenges
Fisheries Debates Management Challenges
Fisheries Debates Management Challenges
permissibleyout77
?
Python learn guide
Python learn guidePython learn guide
Python learn guide
robin yang
?
Socialize your Exceptional Web Experience – Adobe AEM & IBM Connections by He...
Socialize your Exceptional Web Experience – Adobe AEM & IBM Connections by He...Socialize your Exceptional Web Experience – Adobe AEM & IBM Connections by He...
Socialize your Exceptional Web Experience – Adobe AEM & IBM Connections by He...
AEM HUB
?
Eu africa summit
Eu africa summitEu africa summit
Eu africa summit
rusnavy
?
linkedinculturedeck-150310163928-conversion-gate01
linkedinculturedeck-150310163928-conversion-gate01linkedinculturedeck-150310163928-conversion-gate01
linkedinculturedeck-150310163928-conversion-gate01
Stephanie Walker
?
Creativity without comprise by Cleve Gibbon
Creativity without comprise by Cleve Gibbon Creativity without comprise by Cleve Gibbon
Creativity without comprise by Cleve Gibbon
AEM HUB
?
Where are our Alumni now?
Where are our Alumni now?Where are our Alumni now?
Where are our Alumni now?
Jordan Poulton
?
Choosing Page Orientation
Choosing Page OrientationChoosing Page Orientation
Choosing Page Orientation
cbuzz001
?

Similar to Python xmlrpc-odoo (20)

Flex 4.5 action data communication
Flex 4.5 action data communicationFlex 4.5 action data communication
Flex 4.5 action data communication
jexchan
?
用JAX-RS和Jersey完成RESTful Web Services
用JAX-RS和Jersey完成RESTful Web Services用JAX-RS和Jersey完成RESTful Web Services
用JAX-RS和Jersey完成RESTful Web Services
javatwo2011
?
惭测厂蚕尝源码分析.01.代码结构与基本流程
惭测厂蚕尝源码分析.01.代码结构与基本流程惭测厂蚕尝源码分析.01.代码结构与基本流程
惭测厂蚕尝源码分析.01.代码结构与基本流程
Lixun Peng
?
PHP & MySQL 教學
PHP & MySQL 教學PHP & MySQL 教學
PHP & MySQL 教學
Bo-Yi Wu
?
AWS Lambda Multi-Cloud Practices
AWS Lambda Multi-Cloud PracticesAWS Lambda Multi-Cloud Practices
AWS Lambda Multi-Cloud Practices
康志強 大人
?
走马观花— Haskell Web 开发
走马观花— Haskell Web 开发走马观花— Haskell Web 开发
走马观花— Haskell Web 开发
Gump Law
?
Android resource-management
Android resource-managementAndroid resource-management
Android resource-management
Lucas Xu
?
运维系统开发与Rails 3页面开发实践
运维系统开发与Rails 3页面开发实践运维系统开发与Rails 3页面开发实践
运维系统开发与Rails 3页面开发实践
Li JianYe
?
构建础肠迟颈辞苍厂肠谤颈辫迟游戏服务器,支持超过15000并发连接
构建础肠迟颈辞苍厂肠谤颈辫迟游戏服务器,支持超过15000并发连接 构建础肠迟颈辞苍厂肠谤颈辫迟游戏服务器,支持超过15000并发连接
构建础肠迟颈辞苍厂肠谤颈辫迟游戏服务器,支持超过15000并发连接
Renaun Erickson
?
厂迟谤耻肠迟蝉2介绍
厂迟谤耻肠迟蝉2介绍 厂迟谤耻肠迟蝉2介绍
厂迟谤耻肠迟蝉2介绍
catonchuang
?
高性能奥别产服务器狈驳颈苍虫及相关新技术的应用实践
高性能奥别产服务器狈驳颈苍虫及相关新技术的应用实践高性能奥别产服务器狈驳颈苍虫及相关新技术的应用实践
高性能奥别产服务器狈驳颈苍虫及相关新技术的应用实践
Frank Cai
?
高性能奥别产服务器狈驳颈苍虫及相关新技术的应用实践
高性能奥别产服务器狈驳颈苍虫及相关新技术的应用实践高性能奥别产服务器狈驳颈苍虫及相关新技术的应用实践
高性能奥别产服务器狈驳颈苍虫及相关新技术的应用实践
self study
?
高性能奥别产服务器狈驳颈苍虫及相关新技术的应用实践
高性能奥别产服务器狈驳颈苍虫及相关新技术的应用实践高性能奥别产服务器狈驳颈苍虫及相关新技术的应用实践
高性能奥别产服务器狈驳颈苍虫及相关新技术的应用实践
rewinx
?
闯2别别经典学习笔记
闯2别别经典学习笔记闯2别别经典学习笔记
闯2别别经典学习笔记
yiditushe
?
MongoDB for C# developer
MongoDB for C# developerMongoDB for C# developer
MongoDB for C# developer
dianming.song
?
Ecma script edition5-小试
Ecma script edition5-小试Ecma script edition5-小试
Ecma script edition5-小试
lydiafly
?
配置Oracle 10g 双向流复制
配置Oracle 10g 双向流复制配置Oracle 10g 双向流复制
配置Oracle 10g 双向流复制
maclean liu
?
Introduction to Parse JavaScript SDK
Introduction to Parse JavaScript SDKIntroduction to Parse JavaScript SDK
Introduction to Parse JavaScript SDK
維佋 唐
?
闯蝉辞苍知识分享
闯蝉辞苍知识分享闯蝉辞苍知识分享
闯蝉辞苍知识分享
Qianhan Chen
?
Asp.net mvc 培训
Asp.net mvc 培训Asp.net mvc 培训
Asp.net mvc 培训
lotusprince
?
Flex 4.5 action data communication
Flex 4.5 action data communicationFlex 4.5 action data communication
Flex 4.5 action data communication
jexchan
?
用JAX-RS和Jersey完成RESTful Web Services
用JAX-RS和Jersey完成RESTful Web Services用JAX-RS和Jersey完成RESTful Web Services
用JAX-RS和Jersey完成RESTful Web Services
javatwo2011
?
惭测厂蚕尝源码分析.01.代码结构与基本流程
惭测厂蚕尝源码分析.01.代码结构与基本流程惭测厂蚕尝源码分析.01.代码结构与基本流程
惭测厂蚕尝源码分析.01.代码结构与基本流程
Lixun Peng
?
PHP & MySQL 教學
PHP & MySQL 教學PHP & MySQL 教學
PHP & MySQL 教學
Bo-Yi Wu
?
AWS Lambda Multi-Cloud Practices
AWS Lambda Multi-Cloud PracticesAWS Lambda Multi-Cloud Practices
AWS Lambda Multi-Cloud Practices
康志強 大人
?
走马观花— Haskell Web 开发
走马观花— Haskell Web 开发走马观花— Haskell Web 开发
走马观花— Haskell Web 开发
Gump Law
?
Android resource-management
Android resource-managementAndroid resource-management
Android resource-management
Lucas Xu
?
运维系统开发与Rails 3页面开发实践
运维系统开发与Rails 3页面开发实践运维系统开发与Rails 3页面开发实践
运维系统开发与Rails 3页面开发实践
Li JianYe
?
构建础肠迟颈辞苍厂肠谤颈辫迟游戏服务器,支持超过15000并发连接
构建础肠迟颈辞苍厂肠谤颈辫迟游戏服务器,支持超过15000并发连接 构建础肠迟颈辞苍厂肠谤颈辫迟游戏服务器,支持超过15000并发连接
构建础肠迟颈辞苍厂肠谤颈辫迟游戏服务器,支持超过15000并发连接
Renaun Erickson
?
厂迟谤耻肠迟蝉2介绍
厂迟谤耻肠迟蝉2介绍 厂迟谤耻肠迟蝉2介绍
厂迟谤耻肠迟蝉2介绍
catonchuang
?
高性能奥别产服务器狈驳颈苍虫及相关新技术的应用实践
高性能奥别产服务器狈驳颈苍虫及相关新技术的应用实践高性能奥别产服务器狈驳颈苍虫及相关新技术的应用实践
高性能奥别产服务器狈驳颈苍虫及相关新技术的应用实践
Frank Cai
?
高性能奥别产服务器狈驳颈苍虫及相关新技术的应用实践
高性能奥别产服务器狈驳颈苍虫及相关新技术的应用实践高性能奥别产服务器狈驳颈苍虫及相关新技术的应用实践
高性能奥别产服务器狈驳颈苍虫及相关新技术的应用实践
self study
?
高性能奥别产服务器狈驳颈苍虫及相关新技术的应用实践
高性能奥别产服务器狈驳颈苍虫及相关新技术的应用实践高性能奥别产服务器狈驳颈苍虫及相关新技术的应用实践
高性能奥别产服务器狈驳颈苍虫及相关新技术的应用实践
rewinx
?
闯2别别经典学习笔记
闯2别别经典学习笔记闯2别别经典学习笔记
闯2别别经典学习笔记
yiditushe
?
MongoDB for C# developer
MongoDB for C# developerMongoDB for C# developer
MongoDB for C# developer
dianming.song
?
Ecma script edition5-小试
Ecma script edition5-小试Ecma script edition5-小试
Ecma script edition5-小试
lydiafly
?
配置Oracle 10g 双向流复制
配置Oracle 10g 双向流复制配置Oracle 10g 双向流复制
配置Oracle 10g 双向流复制
maclean liu
?
Introduction to Parse JavaScript SDK
Introduction to Parse JavaScript SDKIntroduction to Parse JavaScript SDK
Introduction to Parse JavaScript SDK
維佋 唐
?
闯蝉辞苍知识分享
闯蝉辞苍知识分享闯蝉辞苍知识分享
闯蝉辞苍知识分享
Qianhan Chen
?

Python xmlrpc-odoo

  • 1. Python基于xmlrpc的webservice服务以及在odoo中的使用 XML-RPC通过xml来传输RPC,在Python中提供了xmlrpclib模块进行了封装。参考文 档https://docs.python.org/2/library/xmlrpclib.html 一个简单的例子 from SimpleXMLRPCServer import SimpleXMLRPCServer class HelloService: def sayHello(self, name): return "Hello " + name; def start_server(): obj = HelloService() server = SimpleXMLRPCServer(("localhost", 8080)) server.register_instance(obj) server.serve_forever() print "Server Started...." 上面的例子作为服务端采用了SimpleXMLRPCServer,需要指定host和port即可。在这个例子里注册了一个对象实例,接下来看看 客户端的写法 import xmlrpclib def helloClient(): server = xmlrpclib.ServerProxy("http://localhost:8080") words = server.sayHello("Python") print "result: %s" % (words,) 这样就完成了一个请求的过程。当然这只是一个很简单的例子,上面是注册实例,那么对象里面的方法都可以访问。同样也支持对 函数的注册 将函数作为服务发布 def division(x, y): return x / y def server_reg_func(): server = SimpleXMLRPCServer(("localhost", 8080)) server.register_function(division, "division") server.serve_forever() print "Server Started...." 将函数作为服务发布采用了方法register_function,需要传入参数函数和调用的名称。那么在客户端访问和上面例子基本一致, 只需要调用函数名为注册的(division)即可server.division(2, 5)。上面的例子只注册了一个函数发布服务,在现实世界中可能 会有多个服务,那也是支持的 注册多个函数作为服务发布 def server_multi_funcs(): server = SimpleXMLRPCServer(("localhost", 8080)) server.register_multicall_functions() server.register_function(division, "division") server.register_function(add, "add") server.serve_forever() print "Server Started...." 这里新增了函数register_multicall_functions调用,那么就支持同时注册多个函数发布服务,这是在客户端需要做一些调整,不 会直接返回结果而是将调用的结果作为实例返回 def multi_fun_client(): server = xmlrpclib.ServerProxy("http://localhost:8080") multicall = xmlrpclib.MultiCall(server) try: multicall.division(2, 5) multicall.add(2, 0) result = multicall() print type(result) print "2/5=%d, 2+0=%d" % tuple(result)
  • 2. print "2/5=%d, 2+0=%d" % tuple(result) except xmlrpclib.Fault as err: print "A fault occurred" print "Fault code: %d" % err.faultCode print "Fault string: %s" % err.faultString 这里还显示了发生错误时相应的提示信息 多线程的服务 多线程服务也很简单,在服务端提供了相关的接口 class ThreadXMLRPCServer(ThreadingMixIn, SimpleXMLRPCServer): pass def server_thread(): server = ThreadXMLRPCServer(("localhost", 8080)) server.register_function(division, "division") server.serve_forever() 这样服务端就能作为一个多线程处理请求,他会将每个请求一个线程进行处理 多路径服务 在前面的例子中我们都是在同一个端口下发布的服务,但是并没指定路径。对多路径的支持如下 class RequestHandler(SimpleXMLRPCRequestHandler): rpc_paths = ('/','/hello') def server_path(): server = SimpleXMLRPCServer(("localhost", 8080), requestHandler=RequestHandler) server.register_function(add, "add") server.serve_forever() print "Server Started...." 这里服务端新增了处理请求的Handler他会将根目录指向到/hello路径下,在客户端就可以用这个路径进行访问 def path_client(): server = xmlrpclib.ServerProxy("http://localhost:8080/hello") print server.add(2, 5) 二进制文件的读取 在python官方DOC中提供了传输二进制文件的例子 from SimpleXMLRPCServer import SimpleXMLRPCServer import xmlrpclib def python_logo(): with open("python_logo.jpg", "rb") as handle: return xmlrpclib.Binary(handle.read()) server = SimpleXMLRPCServer(("localhost", 8000)) print "Listening on port 8000..." server.register_function(python_logo, 'python_logo') server.serve_forever() 客户端读取文件并写入本地 import xmlrpclib proxy = xmlrpclib.ServerProxy("http://localhost:8000/") with open("fetched_python_logo.jpg", "wb") as handle: handle.write(proxy.python_logo().data) odoo中webservice的使用 odoo中的webservice采用基于xmlrpc的实现提供了内置的实现,我们在暴露接口的时候只需要调用相关的方法就可以实现。 获取用户信息 传入dbname,name和password。返回uid。注意请求的路径为host:prot/xmlrpc/common
  • 3. 传入dbname,name和password。返回uid。注意请求的路径为host:prot/xmlrpc/common server_conf = xmlrpclib.ServerProxy("http://localhost:8069/xmlrpc/common") uid = server_conf.login("open_erp", "admin", "admin") 新建一条记录 对象的操纵请求路径都为host:prot/xmlrpc/object,需要传入参数dbname,uid,db_password可变的参数为需要创建对象的name 属性(dili.pos.psam),方法,这里是新建(create),其他包括查询(search),读取(read),更新(write),删除(unlink) server = xmlrpclib.ServerProxy("http://localhost:8069/xmlrpc/object") psam = { 'name' : 'abc', 'rsa_public_key' : 'jjjjj' } result = server.execute("open_erp", uid, "root", "dili.pos.psam", "create", psam) 查询、读取、更新和删除 查询中支持查询参数(query_args)返回满足结果的id列表。 读取中支持需要返回数据的字段(fields)返回满足条件的列表。 更新则需要传入需要更新数据的编号列表,同时values对应了更改的编号返回执行结果True或False 删除需要传入删除id列表,返回执行的结果True或False server = xmlrpclib.ServerProxy("http://localhost:8069/xmlrpc/object") query_args = [('name', '=', 'abc'), ('rsa_public_key', '=', 'jjjjj')] ids = server.execute("open_erp", uid, "root", "dili.pos.psam", "search", query_args) fields = ['name', 'rsa_public_key', 'psam_rsa'] datas = server.execute("open_erp", uid, "root", "dili.pos.psam", "read", ids, fields) values = {'name':'abcd'} success = server.execute("open_erp", uid, "root", "dili.pos.psam", "write", ids, values) success = server.execute("open_erp", uid, "root", "dili.pos.psam", "unlink", ids) odoo中实现简述 接下来看看基于wsgi中的实现。我们可以从openerp-wsgi.py中工程启动使用了application函数 application = openerp.service.wsgi_server.application 在wigi_server.py中函数的定义指明了处理的方式 def application(environ, start_response): if config['proxy_mode'] and 'HTTP_X_FORWARDED_HOST' in environ: return werkzeug.contrib.fixers.ProxyFix(application_unproxied)(environ, start_response) else: return application_unproxied(environ, start_response) 在函数application_unproxied中采用了解析handler:wsgi_xmlrpc以及更多注册的。这里关注wsgi_xmlrpc def wsgi_xmlrpc(environ, start_response): """ Two routes are available for XML-RPC /xmlrpc/<service> route returns faultCode as strings. This is a historic violation of the protocol kept for compatibility. /xmlrpc/2/<service> is a new route that returns faultCode as int and is therefore fully compliant. """ if environ['REQUEST_METHOD'] == 'POST' and environ['PATH_INFO'].startswith('/xmlrpc/'): length = int(environ['CONTENT_LENGTH']) data = environ['wsgi.input'].read(length) # Distinguish betweed the 2 faultCode modes string_faultcode = True if environ['PATH_INFO'].startswith('/xmlrpc/2/'): service = environ['PATH_INFO'][len('/xmlrpc/2/'):] string_faultcode = False
  • 4. else: service = environ['PATH_INFO'][len('/xmlrpc/'):] params, method = xmlrpclib.loads(data) return xmlrpc_return(start_response, service, method, params, string_faultcode) 这里有两点: 1、只处理post请求和请求路径中有/xmlprc即处理基于xmlrpc的请求 2、可以采用2中路径,区别是错误码返回int和字符串 具体处理请求在函数xmlrpc_return中 result = openerp.http.dispatch_rpc(service, method, params) 在改方法中处理了几种service的情况 if service_name == 'common': dispatch = openerp.service.common.dispatch elif service_name == 'db': dispatch = openerp.service.db.dispatch elif service_name == 'object': dispatch = openerp.service.model.dispatch elif service_name == 'report': dispatch = openerp.service.report.dispatch else: dispatch = openerp.service.wsgi_server.rpc_handlers.get(service_name) result = dispatch(method, params)