Publish Python objects as RESTful resources over HTTP.
Project description
lazr.restful is a library for publishing Python objects through a RESTful web service. To tell lazr.restful which objects you want exposed and how, you annotate your existing Zope interfaces.
The WSGI example web service
The example web service in src/lazr/restful/example/wsgi/ is the best place to start understanding lazr.restful. It’s a very simple web service that uses a subset of lazr.restful’s features and can be run as a standalone WSGI application. An explanation of the code can be found in src/lazr/restful/example/wsgi/README.txt
The full example web service
To understand all of lazr.restful, you should look at the web service defined in src/lazr/restful/example/base/. It defines a simple application serving information about cookbooks and recipes. The interfaces (interfaces.py) are annotated with lazr.restful decorators that say which fields and methods to publish from IRecipe, ICookbook, and so on. The implementations of those interfaces are in root.py.
The machinery of lazr.restful takes the decorators in interfaces.py, and generates an interface that maps incoming HTTP requests to operations on the actual objects defined in root.py. You don’t have to do any HTTP server programming to get it to work (though at the moment you do have to know a fair amount about Zope).
You can test the example web service by running bin/test. The doctests in src/lazr/restful/example/base/tests use a fake httplib2 connection to simulate HTTP requests to the web service. You can watch the tests make GET, PUT, POST, PATCH, and DELETE requests to the web service. Start with root.txt.
Other code
Two other pieces of code might be of interest when you’re starting out.
declarations.py contains all the Python decorators. docs/webservice-declarations.txt shows how to use them.
docs/webservice.txt shows an example of a webservice that creates Entry and Collection classes directly rather than generating them with the declarations. If you want to use lazr.restful without using zope.schema, this is the test to look at.
NEWS for lazr.restful
0.13.3 (2010-09-29)
Named operations that take URLs as arguments will now accept URLs relative to the versioned service root. Previously they would only accept absolute URLs. PUT and PATCH requests will also accept relative URLs. This fixes bug 497602.
0.13.2 (2010-09-27)
Avoided an error when looking at a Location header that contains characters not valid in URIs. (An error will probably still happen, but having it happen in lazr.restful was confusing people.)
0.13.1 (2010-09-23)
Removed a Python 2.6-ism to restore compatibility with Python 2.5.
0.13.0 (2010-09-06)
Add the ability to annotate an exception so the client will be given the exception message as the HTTP body of the response.
0.12.1 (2010-09-02)
Make WADL generation more deterministic.
0.12.0 (2010-08-26)
Added the ability to take a read-write field and publish it as read-only through the web service.
0.11.2 (2010-08-23)
Optimized lazr.restful to send ‘total_size’ instead of ‘total_size_link’ when ‘total_size’ is easy to calculate, possibly saving the client from sending another HTTP request.
0.11.1 (2010-08-13)
Fixed a bug that prevented first_version_with_total_size_link from working properly in a multi-version environment.
0.11.0 (2010-08-10)
Added an optimization to total_size so that it is fetched via a link when possible. The new configuration option first_version_with_total_size_link specifies what version should be the first to expose the behavior. The default is for it to be enabled for all versions so set this option to preserve the earlier behavior for previously released web services.
0.10.0 (2010-08-05)
Added the ability to mark interface A as a contributor to interface B so that instead of publishing A separately we will add all of A’s fields and operations to the published version of B. Objects implementing B must be adaptable into A for this to work, but lazr.restful will take care of doing the actual adaptation before accessing fields/operations that are not directly provided by an object.
0.9.29 (2010-06-14)
Added invalidation code for the representation cache on events generated by lazr.restful itself. Made the cache more robust and fixed a bug where it would totally redact a forbidden representation rather than simply refuse to serve it. Made it possible for a cache to refuse to cache an object for any reason.
0.9.28 (2010-06-03)
Special note: This version adds a new configuration element, ‘enable_server_side_representation_cache’. This lets you turn the representation cache on and off at runtime without unregistering the cache utility.
Fixed some test failures.
0.9.27 (2010-06-01)
Added the ability to define a representation cache used to store the JSON representations of entry resources, rather than building them from scratch every time. Although the cache has hooks for invalidation, lazr.restful will never invalidate any part of the cache on its own. You need to hook lazr.restful’s invalidation code into your ORM or other data store.
0.9.26 (2010-05-18)
Special note: This version adds a new configuration element, ‘compensate_for_mod_compress_etag_modification’. If you are running lazr.restful behind an Apache server, setting this configuration element will make mod_compress work properly with lazr.restful. This is not a permanent solution: a better solution will be available when Apache bug 39727 is fixed.
Special note: This version removes the configuration element ‘set_hop_to_hop_headers’. You can still define this element in your configuration, but it will have no effect.
Removed code that handles compression through hop-to-hop headers. We’ve never encountered a real situation in which these headers were useful. Compression can and should be handled by intermediaries such as mod_compress. (Unfortunately, mod_compress has its own problems, which this release tries to work around.)
0.9.25 (2010-04-14)
Special note: This version introduces a new configuration element, ‘caching_policy’. This element starts out simple but may become more complex in future versions. See the IWebServiceConfiguration interface for more details.
Service root resources are now client-side cacheable for an amount of time that depends on the server configuration and the version of the web service requested. To get the full benefit, clients will need to upgrade to lazr.restfulclient 0.9.14.
When a PATCH or PUT request changes multiple fields at once, the changes are applied in a deterministic order designed to minimize possible conflicts.
0.9.24 (2010-03-17)
Entry resources will now accept conditional PATCH requests even if one of the resource’s read-only fields has changed behind the scenes recently.
0.9.23 (2010-03-11)
There are two new attributes of the web service configuration, “service_description” and “version_descriptions”. Both are optional, but they’re useful for giving your users an overview of your web service and of the differences between versions.
0.9.22 (2010-03-05)
Special note: this version will break backwards compatibility in your web service unless you take a special step. See “last_version_with_named_mutator_operations” below.
Refactored the code that tags request objects with version information, so that tagging would happen consistently.
By default, mutator methods are no longer separately published as named operations. To maintain backwards compatibility (or if you just want this feature back), put the name of the most recent version of your web service in the “last_version_with_mutator_named_operations” field of your IWebServiceConfiguration implementation.
0.9.21 (2010-02-23)
Fixed a family of bugs that were treating a request originated by a web browser as though it had been originated by a web service client.
0.9.20 (2010-02-16)
Fixed a bug that broke multi-versioned named operations that take the request user as a fixed argument.
0.9.19 (2010-02-15)
A few minor bugfixes to help with Launchpad integration.
0.9.18 (2010-02-11)
Special note: this version contains backwards-incompatible changes. You must change your configuration object to get your code to work in this version! See “active_versions” below.
Added a versioning system for web services. Clients can now request any number of distinct versions as well as a floating “trunk” which is always the most recent version. By using version-aware annotations, developers can publish the same data model differently over time. See the example web service in example/multiversion/ to see how the annotations work.
This release _replaces_ one of the fields in IWebServiceConfiguration. The string ‘service_version_uri’_prefix has become the list ‘active_versions’. The simplest way to deal with this is to just put your ‘service_version_uri_prefix’ into a list and call it ‘active_versions’. We recommend you also add a floating “development” version to the end of ‘active_versions’, calling it something like “devel” or “trunk”. This will give your users a permanent alias to “the most recent version of the web service”.
0.9.17 (2009-11-10)
Fixed a bug that raised an unhandled exception when a client tried to set a URL field to a non-string value.
0.9.16 (2009-10-28)
Fixed a bug rendering the XHTML representation of exproted objects when they contain non-ascii characters.
0.9.15 (2009-10-21)
Corrected a misspelling of the WADL media type.
0.9.14 (2009-10-20)
lazr.restful now runs without deprecation warnings on Python 2.6.
0.9.13 (2009-10-19)
Fixed WADL template: HostedFile DELETE method should have an id of HostedFile-delete, not HostedFile-put.
0.9.12 (2009-10-14)
Transparent compression using Transfer-Encoding is now optional and disabled by default for WSGI applications. (Real WSGI servers don’t allow applications to set hop-by-hop headers like Transfer-Encoding.)
This release introduces a new field to IWebServiceConfiguration: set_hop_by_hop_headers. If you are rolling your own IWebServiceConfiguration implementation, rather than subclassing from BaseWebServiceConfiguration or one of its subclasses, you’ll need to set a value for this. Basically: set it to False if your application is running in a WSGI server, and set it to True otherwise.
0.9.11 (2009-10-12)
Fixed a minor import problem.
0.9.10 (2009-10-07)
lazr.restful runs under Python 2.4 once again.
0.9.9 (2009-10-07)
The authentication-related WSGI middleware classes have been split into a separate project, lazr.authentication.
Fixed a bug that prevented some incoming strings from being loaded by simplejson.
0.9.8 (2009-10-06)
Added WSGI middleware classes for protecting resources with HTTP Basic Auth or OAuth.
0.9.7 (2009-09-24)
Fixed a bug that made it impossible to navigate to a field resource if the field was a link to another object.
0.9.6 (2009-09-16)
Simplified most web service configuration with grok directives.
0.9.5 (2009-08-26)
Added a function that generates a basic WSGI application, given a service root class, a publication class, and a response class.
Added an AbsoluteURL implementation for the simple ServiceRootResource.
Added an adapter from Django’s Manager class to IFiniteSequence, so that services that use Django can serve database objects as collections without special code.
Added an AbsoluteURL implementation for objects that provide more than one URL path for the generated URL.
For services that use Django, added an adapter from Django’s ObjectDoesNotExist to lazr.restful’s NotFoundView.
Fixed some testing infrastructure in lazr.restful.testing.webservice.
Fix some critical packaging problems.
0.9.4 (2009-08-17)
Fixed an import error in simple.py.
Removed a Python 2.6ism from example/wsgi/root.py.
0.9.3 (2009-08-17)
Added a lazr.restful.frameworks.django module to help with publishing Django model objects through lazr.restful web services.
TraverseWithGet implementations now pass the request object into get().
Create a simplified IServiceRootResource implementation for web services that don’t register their top-level collections as Zope utilities.
Make traversal work for entries whose canonical location is beneath another entry.
Raise a ValueError when numberic dates are passed to the DatetimeFieldMarshaller.
0.9.2 (2009-08-05)
Added a second example webservice that works as a standalone WSGI application.
Bug 400170; Stop hacking sys.path in setup.py.
Bug 387487; Allow a subordinate entry resource under a resource where there would normally be a field. Navigation to support subordinate IObjects is added to the publisher.
0.9.1 (2009-07-13)
Declare multipart/form-data as the incoming media type for named operations that include binary fields.
0.9 (2009-04-29)
Initial public release