This is exactly what I was looking for. Thanks for the explanation!
Tess
Christian Scholz wrote:
Hi!
Tess Chu schrieb:
I'm working on https://jira.secondlife.com/browse/SVC-2682, and
wanted to execute the exact urllib commands from the python command
line in order to repro it, but couldn't figure out from these changes
where all the network code went. Where is the actual library code
that's sending the request?
It's all in the network package:
http://svn.secondlife.com/trac/linden/browser/projects/2008/pyogp/pyogp.lib.base/trunk/pyogp/lib/base/network/stdlib_client.py
This gets called from caps.py:
http://svn.secondlife.com/trac/linden/browser/projects/2008/pyogp/pyogp.lib.base/trunk/pyogp/lib/base/caps.py
(line 63)
The serializer used is defined at the bottom of that file (it's
looking for an ISerialization adapter for a dict (payload) in line 53
(ISerialization(payload) and it will get the one defined in line 110
(grok.implements(ISerialization); grok.context(dict)).
The content-type it returns is defined in line 132 ff., serialize()
will simply call llsd.format_xml() for that dict.
But regarding the network layer I am now also confused what is in what
file so maybe we should rename those files to:
stdlib_client => rest_stdlib_client
mockup_client => rest_mockup_client
net => udp_client
mockup_net => udp_mockup_client
I also would suggest to move the mockups to the tests folder as IMHO
it makes sense to have them there as they are not really good for
something useful outside the test environment (my mockup client for
rest even uses the WSGI app defined in tests/ and thus imports it from
there).
But I might post this as separate proposal later again.
-- Christian
Tess
Christian Scholz wrote:
Hi!
Right now we use the networking layer like this:
client = getUtility(IRESTClient)
client.GET(url)
client.POST(url, data)
After a discussion with Locklainn if his UDPClient shouldn't rather
be a connection and store it's socket inside the instance instead of
passing it I was wondering if the same shouldn't be true for the
REST client.
So instead writing it like this:
resource = IRESTResource(url)
resource.GET()
resource.POST(data)
(headers are in both cases optional parameters to the call)
This would have the following benefits:
- it models more what REST is about (you call a method on a resource)
- it models how Capabilities in pyogp are used already (they also
have POST() and GET() methods and the capability basically is the
resource).
How the resource get's instantiated in the above example is by using
an adapter which adapts to a string (the url) for the IRESTResource
interface. A factory utility maybe would be a different way of doing
it:
factory = getUtility(IRESTResourceFactory)
resource = factory(url)
The first solution might be more flexible though if you want to
instantiate a resource from something different than a string as in
your client code you do not need to care. In the second case though
if the url is not a string but some sort of object with an interface
you would need to also change the getUtility call and use some
IRESTResourceFromAnotherObjectFactory.
But what do you think of the general idea? I think it would make
usage of resources and caps similar and you'd only need to learn
once how you do GET and POST and the cap would be more or less a
wrapper around the resource.
-- Christian
PS: Of course this means changing of code but it's pretty clear how
to do that and it might show if all our tests really notice such
changes. And we should try to refactor things where possible IMHO.
Merciless refactoring FTW! :-)
_______________________________________________
Click here to unsubscribe or manage your list subscription:
https://lists.secondlife.com/cgi-bin/mailman/listinfo/pyogp
_______________________________________________
Click here to unsubscribe or manage your list subscription:
https://lists.secondlife.com/cgi-bin/mailman/listinfo/pyogp
_______________________________________________
Click here to unsubscribe or manage your list subscription:
https://lists.secondlife.com/cgi-bin/mailman/listinfo/pyogp