Allow Extensions to extend the WebAPI

Review Request #1648 — Created June 8, 2010 and submitted

Information

Djblets
extensions

Reviewers

This diff relies on this review request:  http://reviews.reviewboard.org/r/1618/diff/6/
And also integrates http://reviews.reviewboard.org/r/1623/

We want extensions to be able to extend the API with their own resources.  So if I have an extension RBDefects, with a resource Defects, I could access that resource here:

ROOT/api/extensions/rbdefects.extension.RBDefectsExtension/defects/

Each resource is keyed to the extension they belong to, so requests to /api/extensions/[anything but rbdefects]/defects/ will return a 404.

Extensions define their own resources, and then supply them to the Extension through a class list called "resources".

This patch also includes code to create new tables for extension models.  Evolve has not been integrated, since I'm still working on refactoring it to work nicely.
Performed rudimentary tests with an extension with multiple resources.  Seemed to work out.
chipx86
  1. 
      
  2. djblets/extensions/base.py (Diff revision 1)
     
     
    Should wrap to < 80 chars.
  3. djblets/extensions/base.py (Diff revision 1)
     
     
    This would go before the djblets ones. Alphabetical order.
  4. djblets/extensions/base.py (Diff revision 1)
     
     
     
    Blank line between these.
  5. djblets/extensions/base.py (Diff revision 1)
     
     
    Can you make this a TODO in the comment?
  6. djblets/webapi/resources.py (Diff revision 1)
     
     
     
     
    This is more of a developer comment and less of a documentation comment. Doc blocks should always describe what the function does, which may be different than the reason the function exists. Maybe just make these normal comments.
  7. djblets/webapi/resources.py (Diff revision 1)
     
     
    No blank line here.
  8. djblets/webapi/resources.py (Diff revision 1)
     
     
     
    I'd prefer just doing a standard:
    
    for url_patterns in self.resource_url_patterns_queue:
        self.add_to_url_patterns(url_patterns)
    
    It's a little more standard and readable, whereas using a while loop and pop is less common. It's also potentially faster (in theory) due to fewer method calls and optimizations for iterators.
    
    We can then just reset the list after the loop.
  9. djblets/webapi/resources.py (Diff revision 1)
     
     
    I'm not really sure I love this class modifying the extension's state, especially using public variables. If an extension author tried to use this variable, checking first that Extension itself didn't define it, then we'd end up stomping over it.
    
    Maybe instead we should have a dict owned by this resource class that maps extensions to the pending patterns. That way it's fully contained.
  10. djblets/webapi/resources.py (Diff revision 1)
     
     
    Does this wrap to < 80 chars?
  11. djblets/webapi/resources.py (Diff revision 1)
     
     
    If this is for private use only, I'd prefix the name with a _. Same with any other private functions/variables for the URL building.
  12. djblets/webapi/resources.py (Diff revision 1)
     
     
    For signal handlers, I'd prefer names like "on_extension_initialized"
  13. djblets/webapi/resources.py (Diff revision 1)
     
     
    You can just have this as a parameter to the function:
    
    def notice_initialized_extension(self, sender, ext_class=None, **kwargs):
  14. 
      
mike_conley
chipx86
  1. 
      
  2. djblets/webapi/resources.py (Diff revision 2)
     
     
    Can do:
    
        if extension in self._resource_url_patterns_map:
    
    That'd actually be more forward-compatible with Python 3.
  3. djblets/webapi/resources.py (Diff revision 2)
     
     
     
    Same here.
  4. 
      
mike_conley
mike_conley
Review request changed
Change Summary:
Updated to merge nicely with latest extensions branch
chipx86
  1. Committed to extensions as 6097dc1.
  2.