Web Services for Python

Christopher Blunck

Presentation Schedule

Introduction to web services

What are web services?

What new capabilities do they offer?

Web services under Python

How do I invoke a web service?

How do I provide a web service?

How do I define complex types?

Best practices (if we have time)

Questions and Comments

Introduction to Web Services

Web Services consists of three technologies:

Simple Object Access Protocol (SOAP)

A lightweight protocol for information exchange

Web Services Descriptor Language (WSDL)

An XML grammar used to describe SOAP endpoints

Universal Description, Discovery, and Integration (UDDI)

Categorizes WSDLs into a searchable hierarchy

Used to solve a variety of interested distributed computing problems

Web Service Capabilities

Exchange Patterns

Request/Response

Notification

Solicitation

Namespace aware

Low system reqts

Embedded devices?

An iPic web-server with a 256 byte

TCP/IP stack on an 8 pin processor.

Web Service Technologies

SOAP

XML over HTTP

Rules for encoding

Exchange Patterns

WSDL

XML document

UDDI

Accessible via SOAP

Web Services: Why Should You Care?

Microsoft, IBM, and Sun are pushing web services

There are a great number of developers exposing their software through web services

Being able to re-use their software from within your application makes you more productive

You shouldn't have to write:

float celsisus_to_fahrenheight(float)

float dollars_to_euros(float)

Web Services for Python

Technologies:

SOAP

WSDL

UDDI

SOAP

Works on client

Works on server

WSDL

Comprehension works

Web Service for Python: Vitals

Web Services for Python contains two projects:

SOAPpy

Zolera SOAP Infrastructure (ZSI)

Page: http://pywebsvcs.sf.net/

Mail: pywebsvcs-talk@lists.sf.net

This presentation covers ZSI

Calling Web Services

“It's like getting paid for somebody else's work.”

-- Anonymous

Calling a Web Service

If a WSDL exists for the operation

Use ServiceProxy to directly invoke the operation

Use wsdl2py to convert the operation to Python

If no WSDL exists

Use Binding to directly invoke the operation

If using complex types, you will have to define how the types should be marshalled on and off the wire

Invoking Services: ServiceProxy

>>> from ZSI import ServiceProxy

>>> WSDL='googleapi/GoogleSearch.wsdl'

>>> KEY='###########'

>>> google = ServiceProxy(WSDL, use_wsdl=True)

>>> resp = google.doSpellingSuggestion(key=KEY,

... phrase='brtney spears')

>>> print resp

Britney Spears

Bind to a Service using ServiceProxy

Pass the URL to the binding WSDL

Then invoke operations as you would regular methods

ServiceProxy Demo

Let's check and see if Google is up and running

It was down last night, and I'm not sure if this will actually work!

Calling Services: wsdl2py

Translate the WSDL into Python artifacts

Then use those artifacts to invoke the service

[chris@titan ~/]$ wsdl2py -f GoogleSearch.wsdl

[chris@titan ~/]$ python

Python 2.2.3 (#1, Oct 15 2003, 23:33:35)

>>> from GoogleSearch_services import *

>>> KEY='###########'

>>> locator = GoogleSearchServiceLocator()

>>> google = locator.getGoogleSearchPort()

>>> req = doSpellingSuggestionWrapper()

>>> req._key = KEY

>>> req._phrase = 'brtney spears'

>>> resp = google.doSpellingSuggestion(req)

>>> print resp._return

Britney Spears

Calling Services: Binding

Binding is very similar to ServiceProxy

Pass the URL to the SOAP endpoint to the constructor

More difficult to achieve dynamic binding

>>> from ZSI import Binding

>>> KEY='###########'

>>> URL='http://api.google.com/search/beta2'

>>> google = Binding(url=URL)

>>> resp = google.doSpellingSuggestion(key=KEY,

... phrase='brtney spears')

>>> print resp

Britney Spears

Providing Web Services

“Sharing what you've written with others, so that you may one day share in what they've written.”

-- Anonymous Coward

Providing Web Services

ZSI dispatches service requests to modules

Dispatching is possible from:

The web server in the standard Python distribution

Any CGI environment

mod_python

Implement your operation, and expose it through any of the aforementioned mechanisms

Usually a good idea to run wsdl2py to generate response TypeCode information

Providing Services: Dispatch

>>> from ZSI import dispatch

>>> from Example_services import *

>>> def echo(message):

... resp = echoResponseWrapper()

... resp._Message = message

... return resp

...

>>>

>>> dispatch.AsServer(port=8080)

Use wsdl2py to generate the response wrapper

This facilitates interoperability with different clients

Complex Types: TypeCodes

Previous examples used simple (primitive) types

doSpellingSuggestion(String, String)

String echo(String)

Complex types are marshalled using TypeCodes

TypeCodes are ZSI classes

They tell ZSI how to marshall objects

In the absence of a TypeCode definition:

ZSI marshalls objects as dictionaries and lists

Complex Types: TypeCodes

Don't use them

Use wsdl2py

They provide control

But are difficult to use

Only use if:

You have lots of existing classes you plan on exposing via services

TypeCode Example

ZSI looks for the typecode attribute in objects

If found, ZSI uses the TypeCode for marshalling

>>> from ZSI import TC

>>> class User:

... def __init__(self, name=None, age=25):

... self._name = name

... self._age = age

...

>>> User.typecode = TC.Struct(User,

... [TC.String('_name', oname='Name'),

... TC.Iinteger('_age', oname='Age')],

... 'types:User')

Server Best Practices

Use wsdl2py

Promotes interop

Wrap responses in TypeCode enabled classes

wsdl2py helps!

Publish your interface through a WSDL

Client Best Practices

Use wsdl2py

Promotes interop

Bind through WSDL

Use ServiceProxy

Use generated classes

Use dynamic binding where possible for fault tolerance

Questions and Comments

2004-03-25T21:13:16