1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
|
= LAZR's field marshallers =
LAZR defines an interface for converting between the values that
come in on an HTTP request, and the object values appropriate for schema
fields. This is similar to Zope's widget interface, but much smaller.
To test the various marshallers we create a dummy request and
application root.
>>> from lp.services.webapp.adapter import set_request_started
>>> from lp.services.webapp.servers import (
... WebServicePublication,
... WebServiceTestRequest,
... )
>>> request = WebServiceTestRequest(method='GET')
>>> set_request_started()
>>> request.setPublication(WebServicePublication(None))
>>> login(ANONYMOUS, request)
>>> request.processInputs()
>>> from lp.systemhomes import WebServiceApplication
>>> root = WebServiceApplication()
>>> from lp.services.webapp.interfaces import IOpenLaunchBag
>>> getUtility(IOpenLaunchBag).add(root)
=== Choice of SQLObjectVocabularyBase ===
For vocabularies based on SQLObjectVocabularyBase, the values are
interpreted as URLs referencing objects on the web service. If the given
string is a URL corresponding to a vocabulary item, the marshaller
returns that item. Otherwise it raises a ValueError.
>>> from zope.component import getMultiAdapter
>>> from zope.schema import Choice
>>> from lazr.restful import EntryResource
>>> from lazr.restful.fields import ReferenceChoice
>>> from lazr.restful.interfaces import IFieldMarshaller
>>> from lp.registry.interfaces.person import IPerson
# Bind the field, to resolve the vocabulary name.
>>> field = ReferenceChoice(
... __name__='some_person', vocabulary='ValidPersonOrTeam',
... schema=IPerson)
>>> field = field.bind(None)
>>> marshaller = getMultiAdapter((field, request), IFieldMarshaller)
>>> verifyObject(IFieldMarshaller, marshaller)
True
>>> from lp.registry.interfaces.person import IPerson
>>> person = marshaller.marshall_from_request(
... "http://api.launchpad.dev/beta/~salgado")
>>> IPerson.providedBy(person)
True
>>> person.name
u'salgado'
>>> ubuntu_team = marshaller.marshall_from_json_data(
... "http://api.launchpad.dev/beta/~ubuntu-team")
>>> ubuntu_team.name
u'ubuntu-team'
>>> marshaller.marshall_from_request(
... "http://api.launchpad.dev/beta/~nosuchperson")
Traceback (most recent call last):
...
ValueError: No such object "http://api.launchpad.dev/beta/~nosuchperson".
>>> marshaller.marshall_from_json_data("salgado")
Traceback (most recent call last):
...
ValueError: "salgado" is not a valid URI.
Instead of unmarshall() returning the Person object (which
wouldn't look nice in a JSON representation), this marshaller returns
the URL to that object.
>>> person_resource = EntryResource(person, request)
>>> marshaller.unmarshall(person_resource, person)
u'http://.../~salgado'
This marshaller also appends '_link' to the representation name of
this field, so that clients can know this is a link to another
resource and not a random string.
>>> marshaller.representation_name
'some_person_link'
If you export a Choice that uses an SQLObjectVocabularyBase then you
get an error, as you should be using a ReferenceChoice instead to
ensure that the resulting wadl matches lazr.restful conventions.
>>> field = Choice(
... __name__='some_person', vocabulary='ValidPersonOrTeam')
>>> field = field.bind(None)
>>> getMultiAdapter((field, request), IFieldMarshaller)
... # doctest: +NORMALIZE_WHITESPACE
Traceback (most recent call last):
...
AssertionError: You exported some_person as an IChoice based on an
SQLObjectVocabularyBase, you should use
lazr.restful.fields.ReferenceChoice instead.
Cleanup.
>>> request.oopsid = None
>>> request.publication.endRequest(request, None)
|