← Back to team overview

lazr-users team mailing list archive

Re: Using lazr.restful with a zope3 app

 

On Jun 22, 2010, at 10:15 AM, Gustavo Rahal wrote:

> 2010/6/21 Gary Poster <gary.poster@xxxxxxxxxxxxx>
> 
> On Jun 21, 2010, at 2:42 PM, Gustavo Rahal wrote:
> 
> > The problem was really the __repr__ of z3c.form. I fixed it and things worked fine. Will contact z3c.form owner for a permanent fix
> 
> Great.
> 
> > Now zope.app.publication and z3c.form need fixes...
> >
> > So, one step closer but still not there. At least now it seems i'm really on lazr.restful space. I'm having problems with the following:
> >
> >    lazr/restful/_resource.py(1887)toDataForJSON()
> >    1886         for link_name, publication in publications.items():
> > -> 1887             data_for_json[link_name] = absoluteURL(publication,
> >    1888                                                    self.request)
> >
> > absoluteURL call fails with TypeError: There isn't enough context to get URL information
> > Here is what the various objects look like:
> >
> > ipdb> publications
> > Out[0]: {'systems_collection_link': <tp4.portal.restful.resources.SystemSet object at 0xaf14d6c>}
> > ipdb> publication
> > Out[0]: <tp4.portal.restful.resources.SystemSet object at 0xaf14d6c>
> > ipdb> self.request
> > Out[0]: <lazr.restful.simple.Request instance URL=http://localhost:8080/api/1.0>
> >
> > My RootResource is:
> >
> > class WebServiceRootResource(RootResource):
> >     """The root resource for a web service."""
> >
> >     def _build_top_level_objects(self):
> >         systemset = SystemSet()
> >         systemset.systems = [
> >             System(systemset, "foo", "bar"),
> >             System(systemset, "1", "2")
> >             ]
> >         collections = dict(systems=(ISystem, systemset))
> >         return collections, {}
> >
> > Configuration:
> >
> > class WebServiceConfiguration(BaseWebServiceConfiguration):
> >     code_revision = '1'
> >     active_versions = ['1.0',]
> >     use_https = False
> >     last_version_with_mutator_named_operations = None
> >     view_permission = 'zope.Public'
> >     service_root_uri_prefix = "api/"
> >     hostname = "localhost"
> >     port = "8080"
> >
> >
> > Thoughts?
> 
> It sounds like you need to define your own IAbsoluteURL implementation for the root object.
> 
> It might be sufficient to add this to your zcml:
> 
> <adapter factory="lazr.restful.simple.RootResourceAbsoluteURL" />
> 
> If you are curious what is going on here, see lazr/restful/docs/absoluteurl.txt
> 
> 
> This is already done
> 
> Look what happens in lazr/restful/_resource.py(1887)toDataForJSON() :
> 
> ipdb> self.request
> Out[0]: <lazr.restful.simple.Request instance URL=http://localhost:8080/api/1.0>
> ipdb> publication
> Out[0]: <tp4.portal.restful.resources.SystemSet object at 0xb0db04c>
> ipdb> getMultiAdapter((publication, self.request), IAbsoluteURL)
> Out[0]: <tp4.portal.restful.root.BelowRootAbsoluteURL object at 0xac00b6c>
> ipdb> self
> Out[0]: <tp4.portal.restful.root.WebServiceRootResource object at 0xe324b0c>
> ipdb> getMultiAdapter((self, self.request), IAbsoluteURL)
> Out[0]: <tp4.portal.restful.root.RootAbsoluteURL object at 0xb44d50c>
> 
> This works fine:
> ipdb> adapter_root = getMultiAdapter((self, self.request), IAbsoluteURL)
> ipdb> adapter_root()
> Out[0]: 'http://localhost:8080/api/1.0/'
> 
> But then:
> 
> ipdb> adapter = getMultiAdapter((publication, self.request), IAbsoluteURL)
> ipdb> adapter()
> *** TypeError: There isn't enough context to get URL information. This is probably due to a bug in setting up location information.

More guessing:

- Does SystemSet declare that it implements zope.location.interfaces.ILocation, either by a direct declaration or by ISystemSet inherting from ILocation?
- Does SystemSet actually implement ILocation?

See PairSet at the bottom of lazr/restful/example/wsgi/resources.py for an example.

Gary




Follow ups

References