Metadata-Version: 1.0
Name: TGInterface
Version: 0.2
Summary: Provides clients access to models and methods defined on a TurboGears server.
Home-page: http://code.google.com/p/tg-interface/
Author: Sam Wright
Author-email: UNKNOWN
License: MIT
Description: 
            With TurboGears Interface, the developer can write client code as if he 
            were writing it on the server with direct access to server-side models 
            and methods.
            
            It uses the most-excellent TGWebServices package to do the heavy lifting.
            Unfortunately, the latest egg doesn't seem to work so you'll need to 
            install TGWebServices with mercurial
            (``hg clone https://code.google.com/p/tgws.tgws-2/``) in the TurboGears 
            virtualenv (ie. server-side).
            
            Thanks to all who contributed to TGWebServices and TurboGears (and all
            packages contained therein).
        
            Here's an example:
            
            In the TurboGears model, decorate all tables that will be exposed with
            ``ExposeTable``.  In future, ``ExposeTable`` will take arguments such
            as ``"read_access"`` and ``"write_access"`` to secure the table.
            
            ::
            
                from TGInterface import ServerSide
        
                @ServerSide.ExposeTable()
                class Cheeses(DeclarativeBase):
                    id = Column(Integer, primary_key=True)
                    Shop_id = Column(Integer, ForeignKey('Shops.id'))
                    Shop = relation('Shops', uselist=False, backref='Cheeses')
                    Availability = Column(Boolean)
                
                @ServerSide.ExposeTable()
                class Shops(DeclarativeBase):
                    id = Column(Integer, primary_key=True)
        
            And in the TurboGears controllers if you want to add any methods to the
            client-side objects, decorate with ``AutoAPI``
            
            ::
            
                from TGInterface import ServerSide
        
                @ServerSide.AutoAPI(model.Cheeses)
                class Shops(ServerSide.Controller):
                    @ServerSide.Returns(int)
                    @ServerSide.self_as_model()
                    def getNumberOfAvailableCheeses(self):
                        available_cheeses = 0
                        for cheese in self.Cheeses:
                            if cheese.Available:
                                available_cheeses += 1
                        return available_cheeses
        
            Now add ``FinaliseAPI`` to the bottom of ``controllers/root.py``, passing
            it the ``RootController`` class
            
            ::
            
                from TGInterface import ServerSide
            
                class RootController(BaseController):
                    ...
                    
                ServerSide.FinaliseAPI(RootController)
            
            You can now download the API definitions from ``http://myhost:myport/api.py``,
            which will look like
            
            ::
            
                # Automatically generated TGInterface API file
                
                class Shops:
                    __exposed_methods__ = ['getNumberOfAvailableCheeses']
                    __exposed_attrs__ = ['Cheeses']
                    Cheeses = ['Cheeses']
        
                class Cheeses:
                    __exposed_methods__ = []
                    __exposed_attrs__ = ['Shop']
                    Shop = 'Shops'
                    Availability = bool
        
            Now on the client side, you can easily access these models and methods, eg
            
            ::
        
                from TGInterface import ClientSide
                import api  # Autogenerated file from server
        
                ClientSide.loadAPI(api)
        
                @ClientSide.AutoAPI(api.Shops)
                class Shops(object):
                    def _onCheesesChange_(self):
                        self.getNumberOfAvailableCheeses()
        
                    def _getNumberOfAvailableCheesesResponse_(self, number):
                        print 'Out of %d cheeses only %d are available.'                                         %(len(self.Cheeses), number)
        
                @ClientSide.AutoAPI(api.Cheeses)
                class Cheeses(object):
                    def _onAvailabilityChange_(self):
                        if self.Shop:
                            self.Shop.getNumberOfAvailableCheeses()
        
                camembert = Cheeses(Availability=True)
                my_shop = Shop(Cheeses=[camembert])
                cheddar = Cheeses(Shop=my_shop, Availability=False)
                
                # This first prints:
                # 'Out of 1 cheeses only 1 are available.'
                # Then soon after will print:
                # 'Out of 2 cheeses only 1 are available.'
                
            Note that you can access object attributes much like if you were using 
            SQLAlchemy's ORM
            
            ::
            
                print camambert.Shop
                # "Shop with id=1"
                
                print my_shop.Cheeses
                # ["Cheese with id=1", "Cheese with id=2"]
                
                print my_shop.Cheeses[0].Shop
                # "Shop with id=1"
                
                camembert.Availability = False
                # 'Out of 2 cheeses only 0 are available.'
                
            
            Features
            --------
            Server-side:
            
            * Works seamlessly with TurboGears
            * Gives access to models and methods that you decorate
            * API automatically created and offered for download
            * If you expose a model and don't create a controller, one is created for you
            * Methods defined in Controllers automatically import and export complex types defined in the API
            * (Optional) Methods can change 'self' to be the the 'self' object that initiated the call client-side
        
        
            Client-side:
            
            * Automatically provides access to methods and models defined in the API
            * Code looks identical to server-side code (using SQLAlchemy's ORM)
            * Automatically guesses database relationships to keep client-data up-to-date
            * All calls are made asynchronously and the module is multithread-safe
            * Allows the developer to easily define callback functions for data being updated or server-side methods finishing
        
            TODO
            ----
            
            Server-side:
            
            * No authentication built-in (should be easy enough to integrate TurboGear's authentication system)
            * Documentation with Sphinx
            
            Client-side TODO:
            
            * Make it easy to gracefully tell the user of network outage / server error (at the moment, the developer can make error handlers for specific things going wrong, but there's probably a better way)
            * Documentation with Sphinx
            
            
Platform: UNKNOWN
Classifier: Development Status :: 3 - Alpha
Classifier: Operating System :: OS Independent
Classifier: Programming Language :: Python
Classifier: Topic :: Software Development :: Libraries :: Python Modules
Classifier: Framework :: TurboGears
