launchpad-reviewers team mailing list archive
-
launchpad-reviewers team
-
Mailing list archive
-
Message #07053
[Merge] lp:~wallyworld/launchpad/launchpadlib-services-974139 into lp:launchpad
Ian Booth has proposed merging lp:~wallyworld/launchpad/launchpadlib-services-974139 into lp:launchpad.
Requested reviews:
Launchpad code reviewers (launchpad-reviewers)
Related bugs:
Bug #974139 in launchpadlib : "Add "services" ServiceRoot to launchpadlib"
https://bugs.launchpad.net/launchpadlib/+bug/974139
For more details, see:
https://code.launchpad.net/~wallyworld/launchpad/launchpadlib-services-974139/+merge/101349
== Implementation ==
The changes in this branch allow launchpadlib to be used like so:
lp = Launchpad(...)
service = lp.services['myservice']
service.some_method()
Essentially, ServiceFactory is made a web service collection (requiring a collection_default_content to be defined). The default content method returns all registered services.
The changes mean that lp.services.webservice.services.ServicesLink needed to be removed.
This branch can be landed after lp:~wallyworld/launchpadlib/services-serviceroot
== Tests ==
The TestLaunchpadlib test case was changed to locate the service using the new syntax.
An additional test_registeredServices test was added for the new collection_default_content method.
== Lint ==
Checking for conflicts and issues in changed files.
Linting changed files:
versions.cfg
lib/lp/app/configure.zcml
lib/lp/app/services.py
lib/lp/app/interfaces/services.py
lib/lp/app/tests/test_services.py
lib/lp/registry/interfaces/webservice.py
lib/lp/registry/services/tests/test_sharingservice.py
--
https://code.launchpad.net/~wallyworld/launchpad/launchpadlib-services-974139/+merge/101349
Your team Launchpad code reviewers is requested to review the proposed merge of lp:~wallyworld/launchpad/launchpadlib-services-974139 into lp:launchpad.
=== modified file 'lib/lp/app/configure.zcml'
--- lib/lp/app/configure.zcml 2012-02-24 05:14:46 +0000
+++ lib/lp/app/configure.zcml 2012-04-10 10:20:44 +0000
@@ -74,13 +74,5 @@
<allow
interface="zope.publisher.interfaces.IPublishTraverse"/>
</securedutility>
- <securedutility
- class="lp.services.webservice.services.ServicesLink"
- provides="lp.services.webservice.services.IServicesLink">
- <allow
- interface="lazr.restful.interfaces.ITopLevelEntryLink"/>
- <allow
- interface="lp.services.webapp.interfaces.ICanonicalUrlData"/>
- </securedutility>
</configure>
=== modified file 'lib/lp/app/interfaces/services.py'
--- lib/lp/app/interfaces/services.py 2012-02-28 04:24:19 +0000
+++ lib/lp/app/interfaces/services.py 2012-04-10 10:20:44 +0000
@@ -12,8 +12,15 @@
]
from lazr.restful.declarations import (
+ collection_default_content,
+ export_as_webservice_collection,
export_as_webservice_entry,
+ export_read_operation,
exported,
+ operation_for_version,
+ operation_parameters,
+ operation_returns_collection_of,
+ operation_returns_entry,
)
from zope.interface import Interface
from zope.schema import TextLine
@@ -24,6 +31,9 @@
class IService(Interface):
"""Base interface for services."""
+ export_as_webservice_entry(
+ 'service', publish_web_link=False, as_of='beta')
+
name = exported(
TextLine(
title=_('Name'),
@@ -34,4 +44,18 @@
class IServiceFactory(Interface):
"""Interface representing a factory used to access named services."""
- export_as_webservice_entry(publish_web_link=False, as_of='beta')
+ export_as_webservice_collection(IService)
+
+ @collection_default_content()
+ @operation_returns_collection_of(IService)
+ @export_read_operation()
+ @operation_for_version("beta")
+ def registeredServices():
+ """Return all the registered services."""
+
+ @operation_parameters(name=TextLine(required=True))
+ @operation_returns_entry(IService)
+ @export_read_operation()
+ @operation_for_version("beta")
+ def getByName(name):
+ """Lookup a service by name."""
=== modified file 'lib/lp/app/services.py'
--- lib/lp/app/services.py 2012-02-23 10:13:48 +0000
+++ lib/lp/app/services.py 2012-04-10 10:20:44 +0000
@@ -8,7 +8,10 @@
'ServiceFactory',
]
-from zope.component import getUtility
+from zope.component import (
+ getAllUtilitiesRegisteredFor,
+ getUtility,
+ )
from zope.interface import implements
from lp.app.interfaces.services import (
@@ -19,9 +22,9 @@
class ServiceFactory(Navigation):
- """Creates a named service.
+ """Provides access to named services.
- Services are traversed via urls of the form /services/<name>
+ Services are traversed via urls of the form /+services/<name>
Implementation classes are registered as named zope utilities.
"""
@@ -31,7 +34,10 @@
super(ServiceFactory, self).__init__(None)
def traverse(self, name):
- return self.getService(name)
-
- def getService(self, service_name):
- return getUtility(IService, service_name)
+ return self.getByName(name)
+
+ def getByName(self, name):
+ return getUtility(IService, name)
+
+ def registeredServices(self):
+ return getAllUtilitiesRegisteredFor(IService)
=== modified file 'lib/lp/app/tests/test_services.py'
--- lib/lp/app/tests/test_services.py 2012-02-28 04:24:19 +0000
+++ lib/lp/app/tests/test_services.py 2012-04-10 10:20:44 +0000
@@ -43,5 +43,12 @@
self.registerUtility(fake_service, IService, "fake")
context, view, request = test_traverse(
'https://launchpad.dev/api/devel/+services/fake')
- self.assertEqual(getUtility(IServiceFactory), context)
- self.assertEqual(fake_service, view)
+ self.assertEqual(getUtility(IService, "fake"), context)
+
+ def test_registeredServices(self):
+ # Test the ServiceFactory registeredServices method.
+ login(ANONYMOUS)
+ service_factory = getUtility(IServiceFactory)
+ self.assertEqual(
+ [service_factory.getByName('sharing')],
+ service_factory.registeredServices())
=== modified file 'lib/lp/registry/interfaces/webservice.py'
--- lib/lp/registry/interfaces/webservice.py 2012-03-22 23:21:24 +0000
+++ lib/lp/registry/interfaces/webservice.py 2012-04-10 10:20:44 +0000
@@ -29,6 +29,7 @@
'IProductSet',
'IProjectGroup',
'IProjectGroupSet',
+ 'IService',
'IServiceFactory',
'ISharingService',
'ISSHKey',
@@ -43,7 +44,10 @@
# XXX: JonathanLange 2010-11-09 bug=673083: Legacy work-around for circular
# import bugs. Break this up into a per-package thing.
from lp import _schema_circular_imports
-from lp.app.interfaces.services import IServiceFactory
+from lp.app.interfaces.services import (
+ IService,
+ IServiceFactory,
+ )
from lp.registry.interfaces.commercialsubscription import (
ICommercialSubscription,
)
=== modified file 'lib/lp/registry/services/tests/test_sharingservice.py'
--- lib/lp/registry/services/tests/test_sharingservice.py 2012-04-06 17:28:25 +0000
+++ lib/lp/registry/services/tests/test_sharingservice.py 2012-04-10 10:20:44 +0000
@@ -758,10 +758,7 @@
def setUp(self):
super(TestLaunchpadlib, self).setUp()
self.launchpad = self.factory.makeLaunchpadService(person=self.owner)
- # XXX 2012-02-23 wallyworld bug 681767
- # Launchpadlib can't do relative url's
- self.service = self.launchpad.load(
- '%s/+services/sharing' % self.launchpad._root_uri)
+ self.service = self.launchpad.services['sharing']
flag = FeatureFixture(WRITE_FLAG)
flag.setUp()
self.addCleanup(flag.cleanUp)
=== removed file 'lib/lp/services/webservice/services.py'
--- lib/lp/services/webservice/services.py 2012-02-23 10:13:48 +0000
+++ lib/lp/services/webservice/services.py 1970-01-01 00:00:00 +0000
@@ -1,32 +0,0 @@
-# Copyright 2009-2011 Canonical Ltd. This software is licensed under the
-# GNU Affero General Public License version 3 (see the file LICENSE).
-
-"""A class for the top-level link to the services factory."""
-
-__metaclass__ = type
-__all__ = [
- 'IServicesLink',
- 'ServicesLink',
- ]
-
-from lazr.restful.interfaces import ITopLevelEntryLink
-from zope.interface import implements
-
-from lp.app.interfaces.services import IServiceFactory
-from lp.services.webapp.interfaces import ICanonicalUrlData
-
-
-class IServicesLink(ITopLevelEntryLink, ICanonicalUrlData):
- """A marker interface."""
-
-
-class ServicesLink:
- """The top-level link to the services factory."""
- implements(IServicesLink)
-
- link_name = 'services'
- entry_type = IServiceFactory
-
- inside = None
- path = 'services'
- rootsite = 'api'
=== modified file 'versions.cfg'
--- versions.cfg 2012-04-06 17:28:25 +0000
+++ versions.cfg 2012-04-10 10:20:44 +0000
@@ -35,7 +35,7 @@
Jinja2 = 2.2
keyring = 0.6.2
kombu = 2.1.1
-launchpadlib = 1.9.12
+launchpadlib = 1.9.13
lazr.amqp = 0.1
lazr.authentication = 0.1.1
lazr.batchnavigator = 1.2.10
Follow ups