A Quick Look At Rpclib Burak Arslan burak at arskom dot com dot tr - - PowerPoint PPT Presentation

a quick look at rpclib
SMART_READER_LITE
LIVE PREVIEW

A Quick Look At Rpclib Burak Arslan burak at arskom dot com dot tr - - PowerPoint PPT Presentation

A Quick Look At Rpclib Burak Arslan burak at arskom dot com dot tr March 10, 2012 1 What is Rpclib? Rpclib makes it convenient to expose your services using multiple protocols and/or transports. 2 What is Rpclib? It also forces you to


slide-1
SLIDE 1

A Quick Look At Rpclib

Burak Arslan

burak at arskom dot com dot tr

March 10, 2012

1

slide-2
SLIDE 2

What is Rpclib?

Rpclib makes it convenient to expose your services using multiple protocols and/or transports.

2

slide-3
SLIDE 3

What is Rpclib?

It also forces you to have a well-defined api.

3

slide-4
SLIDE 4

How?

4

slide-5
SLIDE 5

Here’s a simple function:

5

slide-6
SLIDE 6

Here’s a simple function:

from datetime import datetime def g e t u t c t i m e ( ) : r e t u r n datetime . utcnow ()

5

slide-7
SLIDE 7

Now, to make this function remotely callable;

6

slide-8
SLIDE 8

Now, to make this function remotely callable; 1) We wrap it in a ServiceBase subclass:

6

slide-9
SLIDE 9

def g e t u t c t i m e ( ) : r e t u r n datetime . utcnow ()

7

slide-10
SLIDE 10

from r p c l i b . model . p r i m i t i v e import DateTime from r p c l i b . decorator import srpc from r p c l i b . s e r v i c e import ServiceBase def g e t u t c t i m e ( ) : r e t u r n datetime . utcnow ()

7

slide-11
SLIDE 11

from r p c l i b . model . p r i m i t i v e import DateTime from r p c l i b . decorator import srpc from r p c l i b . s e r v i c e import ServiceBase c l a s s DateTimeService ( ServiceBase ) : def g e t u t c t i m e ( ) : r e t u r n datetime . utcnow ()

7

slide-12
SLIDE 12

from r p c l i b . model . p r i m i t i v e import DateTime from r p c l i b . decorator import srpc from r p c l i b . s e r v i c e import ServiceBase c l a s s DateTimeService ( ServiceBase ) : @srpc ( r e t u r n s=DateTime ) def g e t u t c t i m e ( ) : r e t u r n datetime . utcnow ()

7

slide-13
SLIDE 13

2) Now, we have to wrap the service definition in an Application definition.

8

slide-14
SLIDE 14

[ DateTimeService ] ,

9

slide-15
SLIDE 15

from r p c l i b . a p p l i c a t i o n import A p p l i c a t i o n from r p c l i b . p r o t o c o l . http import HttpRpc httprpc = A p p l i c a t i o n ( [ DateTimeService ] ,

9

slide-16
SLIDE 16

from r p c l i b . a p p l i c a t i o n import A p p l i c a t i o n from r p c l i b . p r o t o c o l . http import HttpRpc httprpc = A p p l i c a t i o n ( [ DateTimeService ] , tns=’rpclib.examples.multiprot’ ,

9

slide-17
SLIDE 17

from r p c l i b . a p p l i c a t i o n import A p p l i c a t i o n from r p c l i b . p r o t o c o l . http import HttpRpc httprpc = A p p l i c a t i o n ( [ DateTimeService ] , tns=’rpclib.examples.multiprot’ , i n p r o t o c o l=HttpRpc () ,

  • u t p r o t o c o l=HttpRpc ()

)

9

slide-18
SLIDE 18

3) Finally, we wrap the application in a transport.

10

slide-19
SLIDE 19

from r p c l i b . s e r v e r . wsgi import WsgiApplication a p p l i c a t i o n = WsgiApplication ( httprpc ) This is now a regular WSGI Application that we can pass to WSGI-compliant servers like CherryPy, mod wsgi, Twisted, etc.

11

slide-20
SLIDE 20

from r p c l i b . s e r v e r . wsgi import WsgiApplication a p p l i c a t i o n = WsgiApplication ( httprpc ) This is now a regular WSGI Application that we can pass to WSGI-compliant servers like CherryPy, mod wsgi, Twisted, etc. $ c u r l http :// l o c a l h o s t :9910/ g e t u t c t i m e 2012−03−09T17 :38:11.997784

11

slide-21
SLIDE 21

Now, what if we wanted to expose this function using another protocol?

12

slide-22
SLIDE 22

For example: SOAP

from r p c l i b . a p p l i c a t i o n import A p p l i c a t i o n from r p c l i b . p r o t o c o l . http import HttpRpc from r p c l i b . p r o t o c o l . soap import Soap11 soap = A p p l i c a t i o n ( [ DateTimeService ] , tns=’rpclib.examples.multiprot’ , i n p r o t o c o l=HttpRpc () ,

  • u t p r o t o c o l=Soap11 ()

)

13

slide-23
SLIDE 23

For example: SOAP

$ c u r l http :// l o c a l h o s t :9910/ g e t u t c t i m e \ | t i d y −xml −indent

<?xml v e r s i o n=’1.0 ’ encoding=’utf -8’?> <s e n v : E n v e l o p e xmlns:wsa="http: // schemas.xmlsoap.org/ws /2003/03/ addressing" x m l n s : t n s="rpclib.examples. multiple_protocols " x m l n s : p l i n k="http: // schemas.xmlsoap.org/ws /2003/05/ partner -link/" xmlns:xop="http: // www.w3.org /2004/08/ xop/include" xmlns:senc="http: // schemas.xmlsoap.org/soap/encoding/" xmlns:s12env="http: // www.w3.org /2003/05/ soap -envelope/" xmlns:s12enc="http: // www.w3.org /2003/05/ soap -encoding/" x m l n s : x s="http: // www.w3.org /2001/ XMLSchema" xmlns:wsdl="http: // schemas.xmlsoap.org/wsdl/" x m l n s : x s i="http: // www.w3.org /2001/ XMLSchema -instance" xmlns:senv="http: // schemas.xmlsoap.org/soap/envelope/" xmlns:soap="http: // schemas.xmlsoap.org/wsdl/soap/" > <senv:Body> <t n s : g e t u t c t i m e R e s p o n s e> <t n s : g e t u t c t i m e R e s u l t> 2012−03−06T17:43:30 .894466 </ t n s : g e t u t c t i m e R e s u l t> </ t n s : g e t u t c t i m e R e s p o n s e> </ senv:Body> </ s e n v : E n v e l o p e>

14

slide-24
SLIDE 24

Or, just XML:

from r p c l i b . a p p l i c a t i o n import A p p l i c a t i o n from r p c l i b . p r o t o c o l . http import HttpRpc from r p c l i b . p r o t o c o l . xml import XmlObject xml = A p p l i c a t i o n ( [ DateTimeService ] , tns=’rpclib.examples.multiprot’ , i n p r o t o c o l=HttpRpc () ,

  • u t p r o t o c o l=XmlObject ()

)

15

slide-25
SLIDE 25

Or, just XML:

$ c u r l http :// l o c a l h o s t :9910/ g e t u t c t i m e \ | t i d y −xml −indent

<?xml v e r s i o n=’1.0’ encoding=’utf-8’?> <ns0:get utc timeResponse xmlns:ns0="rpclib.examples.multiple_protocols"> <n s 0 : g e t u t c t i m e R e s u l t> 2012−03−06 T17:49:08 .922501 </ n s 0 : g e t u t c t i m e R e s u l t> </ ns0:get utc timeResponse>

16

slide-26
SLIDE 26

Or, HTML:

from r p c l i b . a p p l i c a t i o n import A p p l i c a t i o n from r p c l i b . p r o t o c o l . http import HttpRpc from r p c l i b . p r o t o c o l . xml import HtmlMicroFormat html = A p p l i c a t i o n ( [ DateTimeService ] , tns=’rpclib.examples.multiprot’ , i n p r o t o c o l=HttpRpc () ,

  • u t p r o t o c o l=HtmlMicroFormat ()

)

17

slide-27
SLIDE 27

Or, HTML:

$ c u r l http :// l o c a l h o s t :9910/ g e t u t c t i m e \ | t i d y −xml −indent <div c l a s s="get_utc_timeResponse"> <div c l a s s="get_utc_timeResult"> 2012−03−06T17 :52:50.234246 </ div> </ div>

18

slide-28
SLIDE 28

etc...

19

slide-29
SLIDE 29

Rpclib also makes it easy to implement custom protocols.

20

slide-30
SLIDE 30

Let’s implement an output protocol that renders the datetime value as an analog clock.

(without going into much detail )

21

slide-31
SLIDE 31

To do that, we need to implement the serialize and create out string functions in a ProtocolBase subclass.

22

slide-32
SLIDE 32

from r p c l i b . p r o t o c o l import ProtocolBase c l a s s SvgClock ( ProtocolBase ) : mime type = ’image/svg+xml’

23

slide-33
SLIDE 33

from r p c l i b . p r o t o c o l import ProtocolBase c l a s s SvgClock ( ProtocolBase ) : mime type = ’image/svg+xml’ def s e r i a l i z e ( s e l f , ctx , message ) : d = ctx . o u t o b j e c t [ 0 ] # the r e t u r n value

23

slide-34
SLIDE 34

from r p c l i b . p r o t o c o l import ProtocolBase c l a s s SvgClock ( ProtocolBase ) : mime type = ’image/svg+xml’ def s e r i a l i z e ( s e l f , ctx , message ) : d = ctx . o u t o b j e c t [ 0 ] # the r e t u r n value # ( some math and b o i l e r p l a t e suppressed )

23

slide-35
SLIDE 35

from r p c l i b . p r o t o c o l import ProtocolBase c l a s s SvgClock ( ProtocolBase ) : mime type = ’image/svg+xml’ def s e r i a l i z e ( s e l f , ctx , message ) : d = ctx . o u t o b j e c t [ 0 ] # the r e t u r n value # ( some math and b o i l e r p l a t e suppressed ) # clock i s a svg f i l e parsed as lxml Element ctx . out document = clock

23

slide-36
SLIDE 36

from r p c l i b . p r o t o c o l import ProtocolBase c l a s s SvgClock ( ProtocolBase ) : mime type = ’image/svg+xml’ def s e r i a l i z e ( s e l f , ctx , message ) : d = ctx . o u t o b j e c t [ 0 ] # the r e t u r n value # ( some math and b o i l e r p l a t e suppressed ) # clock i s a svg f i l e parsed as lxml Element ctx . out document = clock def c r e a t e o u t s t r i n g ( s e l f , ctx , c h a r s e t=None ) : ctx . o u t s t r i n g = [ e t r e e . t o s t r i n g ( ctx . out document ) ]

23

slide-37
SLIDE 37

The custom SVG protocol:

from r p c l i b . a p p l i c a t i o n import A p p l i c a t i o n svg = A p p l i c a t i o n ( [ DateTimeService ] , tns=’rpclib.examples.multiprot’ , i n p r o t o c o l=HttpRpc () ,

  • u t p r o t o c o l=SvgClock ()

)

24

slide-38
SLIDE 38

The custom SVG protocol:

$ c u r l http :// l o c a l h o s t :9910/ g e t u t c t i m e \ > utc time . svg

2012-03-09

25

slide-39
SLIDE 39

It’s also easy to implement declarative restrictions on your input data.

26

slide-40
SLIDE 40

So instead of doing this:

from datetime import datetime def get name of month ( month ) : ””” Takes an i n t e g e r between 1−12 and r e t u r n s the name of month as s t r i n g ””” value = i n t ( month ) i f not (1 <= value <= 12): r a i s e ValueError ( value ) r e t u r n datetime (2000 , month , 1 ) . s t r f t i m e ("%B")

27

slide-41
SLIDE 41

You can do this:

from datetime import datetime from r p c l i b . model . p r i m i t i v e import Integer , Unicode from r p c l i b . decorator import srpc from r p c l i b . s e r v i c e import ServiceBase c l a s s NameOfMonthService ( ServiceBase ) : @srpc ( Integer ( le =1,ge=12) , r e t u r n s=Unicode ) def get name of month ( month ) : r e t u r n datetime (2000 , month , 1 ) . s t r f t i m e ("%B")

28

slide-42
SLIDE 42

And if you enable validation;

from r p c l i b . a p p l i c a t i o n import A p p l i c a t i o n from r p c l i b . p r o t o c o l . http import HttpRpc r e s t = A p p l i c a t i o n ( [ NameOfMonthService ] , tns=’rpclib.examples.multiprot’ , i n p r o t o c o l=HttpRpc ( validator=’soft’ ) ,

  • u t p r o t o c o l=HttpRpc ()

)

29

slide-43
SLIDE 43

$ c u r l l o c a l h o s t :9912/ get name of month ?month=3 March

$ c u r l −D − l o c a l h o s t :9912/ get name of month ?month=13 HTTP/1.0 400 Bad Request Date : Sat , 10 Mar 2012 14:21:36 GMT Server : WSGIServer /0.1 Python / 2.7.2 Content−Length : 63 Content−Type : t e x t / p l a i n C l i e n t . V a l i d a t i o n E r r o r The s t r i n g ’13 ’ could not be v a l i d a t e d

30

slide-44
SLIDE 44

So, what’s missing?

Protocols: JSON! ProtoBuf! XmlRpc! Thrift! YAML! HTML! (The whole document) Transports: SMTP! Files! SPDY! WebSockets!

  • and many other things! see the ROADMAP.rst

in the source repo.

  • 31
slide-45
SLIDE 45

Additional Information:

github.com/arskom/rpclib

This example and the presentation are in: examples/multiple protocols examples/validation.py

32