← Back to team overview

launchpad-dev team mailing list archive

Re: Help please - launchpadlib collections

 

Hi Ian,

Thanks for finishing the integration of services into launchpadlib!

I'll try to help as best as I can.

On 12-04-10 08:27 PM, Ian Booth wrote:
> Hi
> 
> I'd like some input with an issue concerning collections in launchpadlib.
> 
> The background is that I want to have launchpadlib recognise a new top
> level collection called 'services'. Services are looked up by name. The
> collection is heterogeneous in that each named service provides
> different capabilities via different exported methods. All services
> extend an IService interface and this is how the collection is currently
> defined:
> 

[...]

> Because the services collection is heterogeneous, there needs to be some
> way which allows launchpadlib to know what each service instance in the
> collection provides. My initial solution was to define a new ServiceSet
> in launchpadlib (a solution already used for projects, bugs,
> distributions etc):
> 
> class ServiceSet(CollectionWithKeyBasedLookup):
>     """A custom subclass capable of service lookup by service name."""
> 
>     def _get_url_from_id(self, key):
>         """Transform a service name into the URL to a service."""
>         return str(
>             self._root._root_uri.ensureSlash()) +
>                 '+services/' + str(key)
> 
>     # All services are different so we need to ensure each service
>     # representation is retrieved when needed.
>     collection_of = None
> 
> This works well and correctly deals with the fact that each named
> service instance has different capabilities. However, concerns were
> raised that it adds to LOC count and could be done generically without
> the helper class.

Right, that's the current pattern in launchpadlib to export top-level
names that you can access with a key look-up.

One thing that I'm wondering though is if your ServiceSet is a real
collection. Can you iterate the services? Is there a use case for that?
In other word, is there any advantage to providing the collection API to it?

In a way, you might be better to export this as a ITopLevelEntry, and
still provide custom class that does the key-mapping in launchpadlib.

That doesn't help with the LOC though.
> 
> My understanding is that an alternative solution would require changes
> and/or enhancements to the WADL generation rules, and for additional
> information to be added to the WADL. At the moment, lazr.restful (which
> is used by launchpadlib) doesn't really know what constitutes a top
> level collection and uses heuristics to determine this.
> eg from ServiceRootResource
> 
>     # XXX sinzui 2008-09-29 bug=276079:
>     # Top-level collections need a marker interface
>     # so that so top-level utilities are explicit.
>     if (provided.isOrExtends(ICollection)
>          and ICollection.implementedBy(registration.factory)):

That's not really the issue. The heuristic works ok, and we do publish
the list of top-level collections in the WADL. What is missing from the
WADL is how to generate URLs to access entries within collection by
name. If you look at the +apidoc (
https://launchpad.net/+apidoc/1.0.html#branch) You'll see a URL:
https://api.launchpad.net/1.0/~<author.name>/<project.name>/<name>
field. That's hard-coded in the XSLT stylesheet instead of coming from
the WADL. If that information was in the WADL, it would allow
lazr.restfulclient to implement key lookup probably in a generic way.
There is no standard in WADL of how to represent that information. I
remember Leonard had some ideas of how it could be represented, but I
don't recall them.
> 
> This issue would need to be addressed along with the ability to define
> more specifically what's in each collection.
> 
> I would love to get input from the smart folks on this list as to what
> the best way forward is. I think Gary, Francis, (and Leonard) have
> worked on this specific stuff in the past. Do we want to attempt to
> tackle the higher level issues highlighted above? Apart from the bug
> concerning the definition of top level collections (276079), I couldn't
> find a bug specifically related to heterogeneous collections. The LOC
> count for an alternative solution would be (far?) greater than what my
> solution has, but may allow launchpadlib to in the future handle new
> heterogeneous collections without additional code changes. I am wary of
> diverting too much time away from the disclosure project for a nice to
> have but non-core disclosure item. I see the options as:
> 
> 1. Adopt my current solution which defines a ServiceSet in launchpadlib
> and allows the syntax lp.services['myservice']

I think that might be the best way forward - modulo my concerns with the
fact that you are not really exporting a collection.

> 2. Fix bug 681767 (not sure of the effort required) and use syntax
> lp.load('/+services/myservice')

That one looks shallow. It's worth fixing, but the API wouldn't be as
nice as the key lookup.


> 3. Address the WADL/lazr.restful issues to support syntax
> lp.services['myservice'] and make launchpadlib 'futureproof'
> 

Adding support for representing URLs in the WADL would be nice, but
would require some effort (and several branches across launchpad,
lazr.restful, lazr.restfulclient and launchpadlib). It would be a nice
addition, but probably a distraction at this point.

-- 
Francis J. Lacoste
francis.lacoste@xxxxxxxxxxxxx

Attachment: signature.asc
Description: OpenPGP digital signature


Follow ups

References