Developers Notes for Hangout API

Hangout API Architecture Overview

Hangout API has modular structure. Base Hangout class provides only few methods to control a call. All other functionality are dynamically added to base class by using named utilities from zope.component (part of ZCA implementation).

Hangout API package has a bunch of build-in extensions:

Writing Hangouts Extensions

You can easily extend Hangout functionality by registering zope.component utility (just make sure that this code executes on package initialization):

provideUtility(MyNewExtension, IModule, 'my_new_extension')

After you do it your new extension will be accessible from Hangout instance:

hangout = Hangouts()
hangout.my_new_extension.do_some_thing()

List of available interfaces you can find at hangout_api.interfaces:

"""
Interfaces for Hangout API
"""
# pylint not working well with zope and don't get the Interface conception
# pylint: disable=E0611,F0401,R0903,W0232

from zope.interface import Interface


class IModule(Interface):
    """
    Interface to register extensions for regular hangout call.
    Resisted class instance will be reachable as Hangouts class property under
    the name you registered it.
    """
    def __init__(self, base):
        pass


class IOnAirModule(Interface):
    """
    Interface to register extensions for hangout OnAir call.
    Resisted class instance will be reachable as Hangouts class property under
    the name you registered it.
    """
    def __init__(self, base):
        pass

For more examples look at hangout_api.setting and hangout_api.gadgets.

As you can see from interfaces your class on initialization step should take base argument, which is instance of hangout_api.utils.Utils class.

PlugIns development

The PlugIn’s actually are a case Hangouts Extensions, but here you need to handle the browser frames context. To make that easier there is gadget_context_handler:

from hangout_api.gadgets.utils import gadget_context_handler

class Cameraman(object):

    def __init__(self, base):
        self.base = base

    @gadget_context_handler("Cameraman")
    def mute_new_guests(self, value=None):
        self.base.browser.execute_script(
            'gapi.hangout.av.setLocalParticipantVideoMirrored(%s);' % value)

Now you can be sure that mute_new_guests function will be called only when self.base.browser would be set to right iframe.

For more examples take a look at hangout_api.gadgets.

Testing

Tests require to have 4 active google accounts, one with mush have OTP protection. You need to put credential of these accounts into hangout_api/tests/resources/credentials.yaml file. Alternatively you can use already created account, just mail my for $super_secret_password and run following code:

What are tested:

  • pep8 && pylint
  • doctest to make sure that documentation code examples are correct
  • integration tests to make sure that library works with Hangouts well (that is nose based tests inside hangout_api/tests directory)

To run tests:

$ bin/test