Thanks for getting this client library started, Florian! Here are some thoughts on your merge proposal. As we discussed on IRC, I now think the best place for this code is in src/mailmanclient. Don't worry about that though; I'll fix that up when I merge to trunk. I know for now it's difficult getting the test suite to run with that layout, so I'll take that on. I don't think it will be too difficult, but there will also be some other useful helpers to share. Omitting the non-controversial stuff. === added file 'src/mailman/rest/docs/restclient.txt' --- src/mailman/rest/docs/restclient.txt 1970-01-01 00:00:00 +0000 +++ src/mailman/rest/docs/restclient.txt 2010-06-25 16:50:42 +0000 > @@ -0,0 +1,89 @@ > +=================== > +Mailman REST Client > +=================== > + > +Domains > +======= > + > + # The test framework starts out with an example domain, so let's delete > + # that first. > + >>> from mailman.interfaces.domain import IDomainManager > + >>> from zope.component import getUtility > + >>> domain_manager = getUtility(IDomainManager) > + > + >>> domain_manager.remove('example.com') > + > + >>> transaction.commit() The test infrastructure currently sets up this sample domain. I wonder whether the REST client tests will more often want to start from a clean slate, or want this example domain. I think perhaps the former, so I should probably add a layer that is just like the ConfigLayer, but has an empty testSetUp(). (You don't have to worry about that for now. :) > +In order to add new lists first a new domain has to be added. > + > + >>> from mailmanclient.rest import MailmanRESTClient, MailmanRESTClientError > + >>> c = MailmanRESTClient('localhost:8001') > + >>> c.create_domain('example.com') > + True What do you think about having proxy objects for Domains, Lists, etc.? Launchpadlib works like this and it provides more of a natural, object oriented API to clients, rather than an XMLRPC style seen here. So for example, .create_domain() would return a Domain surrogate, and you'd call things like .get_lists() and .create_list() on that object. How much harder do you think it would be to do something like that, and do you think it would be worth it? > + > + > +Mailing lists > +============= > + > +You can get a lists of all lists by calling get_lists(). If no lists have been created yet, MailmanRESTClientError is raised. Please wrap narrative to 78 characters. > + > + >>> lists = c.get_lists() > + Traceback (most recent call last): > + ... > + MailmanRESTClientError: No mailing lists found I think it might be better to return an empty list instead of raising an exception here. Think about application code like so: # Display all the current lists. try: lists = c.get_lists() except MailmanRESTClientError: # Are we sure we got "No mailing lists found" or did some other # generic client error occur? lists = [] for mailing_list in lists: # ... The thing is, having no mailing lists isn't an error condition, so this should probably return an empty (Python) list rather than raise an exception. > + > +Lists can be created by calling create_list('