123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152 |
- ****************
- Named operations
- ****************
- Entries and collections support named operations: one-off
- functionality that's been given a name and a set of parameters.
- >>> from lazr.restfulclient.tests.example import CookbookWebServiceClient
- >>> service = CookbookWebServiceClient()
- Arguments to named operations are automatically converted to JSON for
- transmission over the wire. Here's a named operation that takes a
- boolean argument.
- >>> [recipe for recipe in service.cookbooks.find_recipes(
- ... search="Chicken", vegetarian=True)]
- []
- Strings that happen to be numbers are handled properly. Here, if "1.234"
- were converted into a number at any point in the chain, the 'search'
- operation on the server wouldn't know how to handle it and the request
- would fail.
- >>> [people for people in service.cookbooks.find_recipes(search="1.234")]
- []
- Counts
- ------
- Named operations that return a collection return either a link that
- lazr.restfulclient can follow to get the size of the collection or
- (under some circumstances) the length itself. The len() function
- hides this indirection from the end-user.
- >>> results = service.cookbooks.find_recipes(search="Chicken")
- >>> print len(results)
- 0
- Special data types
- ------------------
- lazr.restfulclient uses some data types that don't directly correspond
- to JSON data types. These data types can be used in named
- operations. For instance, a named operation can take a date or
- datetime object as one of its arguments.
- >>> import datetime
- >>> date = datetime.datetime(1994, 1, 1)
- >>> cookbook = service.cookbooks.create(
- ... name="New cookbook", cuisine="General",
- ... copyright_date=date, price=1.23, last_printing=date)
- >>> print cookbook.name
- New cookbook
- A named operation can take an entry as one of its arguments.
- lazr.restfulclient lets you pass in the actual entry as the argument
- value.
- >>> dish = service.recipes[1].dish
- >>> cookbook = service.recipes[1].cookbook
- >>> print cookbook.find_recipe_for(dish=dish)
- http://cookbooks.dev/1.0/recipes/1
- A named operation can take binary data as one of its arguments.
- >>> cookbook.replace_cover(cover="\x00\xe2\xe3")
- >>> cookbook.cover.open().read()
- '\x00\xe2\xe3'
- A named operation that returns a null value corresponds to a Python
- value of None.
- >>> dish = service.recipes[4].dish
- >>> print cookbook.find_recipe_for(dish=dish)
- None
- A named operation may change the resource's location so we get a 301 response
- with the new URL.
- >>> from urllib import quote
- >>> from lazr.restful.testing.webservice import WebServiceCaller
- >>> webservice = WebServiceCaller(domain='cookbooks.dev')
- >>> url = quote("/cookbooks/New cookbook")
- >>> print webservice.named_post(url, 'make_more_interesting')
- HTTP/1.1 301 Moved Permanently
- ...
- Location: http://cookbooks.dev/devel/cookbooks/The%20New%20New%20cookbook
- ...
- JSON-encoding
- -------------
- lazr.restfulclient encodes most arguments (even string arguments) as
- JSON before sending them over the wire. This way, a named operation
- that takes a string argument can take a string that looks like a JSON
- object without causing confusion.
- >>> cookbooks = service.cookbooks.find_for_cuisine(cuisine="General")
- >>> len([cookbook for cookbook in cookbooks]) > 0
- True
- >>> cookbook = service.cookbooks.create(
- ... name="null", cuisine="General",
- ... copyright_date=date, price=1.23, last_printing=date)
- >>> cookbook.name
- u'null'
- >>> cookbook = service.cookbooks.create(
- ... name="4.56", cuisine="General",
- ... copyright_date=date, price=1.23, last_printing=date)
- >>> cookbook.name
- u'4.56'
- >>> cookbook = service.cookbooks.create(
- ... name='"foo"', cuisine="General",
- ... copyright_date=date, price=1.23, last_printing=date)
- >>> cookbook.name
- u'"foo"'
- A named operation that takes a non-string object (such as a float)
- will not accept a string that's the JSON representation of the
- object.
- >>> try:
- ... service.cookbooks.create(
- ... name="Yet another 1.23 cookbook", cuisine="General",
- ... copyright_date=date, last_printing=date, price="1.23")
- ... except Exception, e:
- ... print e.content
- price: got 'unicode', expected float, int: u'1.23'
- Named operations on collections don't fetch the collections
- -----------------------------------------------------------
- If you invoke a named operation on a collection, the only HTTP request
- made is the one for the named operation. You don't have to get a
- representation of the collection to invoke the operation.
- >>> import httplib2
- >>> httplib2.debuglevel = 1
- >>> service = CookbookWebServiceClient()
- send: ...
- ...
- >>> print service.cookbooks.find_recipes(
- ... search="Chicken", vegetarian=True)
- send: 'GET /1.0/cookbooks?...vegetarian=true...'
- ...
- Cleanup.
- >>> httplib2.debuglevel = None
|