iPOPO Decorators

Component definition

Those decorators describe the component. They must decorate the factory class itself.

Factory definition

The factory definition decorator must be unique per class and must always be the last one executed, i.e. the top one in the source code.

class pelix.ipopo.decorators.ComponentFactory(name=None, excluded=None)

Manipulates the component class according to a FactoryContext object filled by other decorators.

This must be the last executed decorator, i.e. the one on top of others in the source code.

It accepts the following arguments:

Parameters:
  • name – the name of the component factory
  • excluded – the list of the IDs of the handlers which configuration must not be inherited from a parent component class

If no factory name is given, it will be generated as ClassNameFactory, e.g. a Foo class will have the factory name FooFactory.

The __init__() method of a component factory must not require any parameter.

@ComponentFactory()
class Foo(object):
    def __init__(self):
        pass

@ComponentFactory('my-factory')
class Bar(object):
   pass
Parameters:
  • name – Name of the component factory
  • excluded – List of IDs of handlers which configuration must not be inherited from the parent class
class pelix.ipopo.decorators.SingletonFactory(name=None, excluded=None)

This decorator is a specialization of the ComponentFactory: it accepts the same arguments and follows the same rule, but it allows only one instance of component from this factory at a time.

If the factory is instantiated while another already exist, a ValueError will be raised.

@SingletonFactory()
class Foo(object):
    def __init__(self):
        pass

@SingletonFactory('my-factory')
class Bar(object):
   pass
Parameters:
  • name – Name of the component factory
  • excluded – List of IDs of handlers which configuration must not be inherited from the parent class

Component properties

class pelix.ipopo.decorators.Property(field, name=None, value=None)

The @Property decorator defines a component property. A property can be used to configure the component at validation time and to expose the state of a component. Note that component properties are exposed in the properties of the services it provides.

This decorator accepts the following parameters:

Parameters:
  • field – The property field in the class (can’t be None nor empty)
  • name – The property name (if None, this will be the field name)
  • value – The property value (None by default)
Handler ID:

pelix.ipopo.constants.HANDLER_PROPERTY

If no initial value is given, the value stored in the field in the __init__() method will be used.

Warning

In Python 2, it is required that the component class inherits object for properties to work.

@ComponentFactory()
@Property('_answer', 'some.answer', 42)
class Foo(object):
    pass
Parameters:
  • field – The property field in the class (can’t be None nor empty)
  • name – The property name (if None, this will be the field name)
  • value – The property value (None by default)
Raises:
  • TypeError – Invalid argument type
  • ValueError – If the name or the name is None or empty
class pelix.ipopo.decorators.HiddenProperty(field, name=None, value=None)

The @HiddenProperty decorator defines a component property which won’t be visible in the properties of the services it provides. This kind of property is also not accessible using iPOPO reflection methods.

This decorator accepts the same parameters and follows the same rules as Property.

@ComponentFactory()
@HiddenProperty('_password', 'some.password', "secret")
class Foo(object):
    pass
Parameters:
  • field – The property field in the class (can’t be None nor empty)
  • name – The property name (if None, this will be the field name)
  • value – The property value (None by default)
Raises:
  • TypeError – Invalid argument type
  • ValueError – If the name or the name is None or empty

Special properties

Note that some properties have a special meaning for iPOPO and Pelix.

Name Type Description
instance.name str The name of the iPOPO component instance
service.id int The registration number of a service
service.ranking int The rank (priority) of the services provided by this component
@ComponentFactory()
@Property('_name', 'instance.name')    # Special property
@Property('_value', 'my.value')        # Some property
@Property('_answer', 'the.answer', 42) # Some property, with a default value
class Foo(object):
   def __init__(self):
       self._name = None    # This will overwritten by iPOPO
       self._value = 12     # 12 will be used if this property is not configured
       self._answer = None  # 42 will be used by default

Provided Services

class pelix.ipopo.decorators.Provides(specifications, controller=None, factory=False)

The @Provides decorator defines a service to be exposed by component instances. This service will be registered (visible) in the Pelix service registry while the component is valid and the service controller is set to True.

This decorator accepts the following parameters:

Parameters:
  • specifications – A list of provided specification(s), or the single provided specification (can’t be empty)
  • controller – The name of the service controller class field (optional)
Handler ID:

pelix.ipopo.constants.HANDLER_PROVIDES

All the properties of the component defined with the Property decorator will be visible in the service properties.

The controller is a Python property that must contain a boolean. By default, the controller is set to True, i.e. the service will be provided by the component when it is validated.

@ComponentFactory()
# 'answer.value' will be a property of the service
@Property('_answer', 'answer.value')
@Provides('hello.world')
class Foo(object):
    pass

@ComponentFactory()
# This service will provide multiple specifications
@Provides(['hello.world', 'hello.world.extended'], '_svc_flag')
class Bar(object):
    # self._svc_flag = False ; to forbid the service to be provided
    # self._svc_flag = True  ; to provide the service
    pass

Sets up a provided service. A service controller can be defined to enable or disable the service.

Parameters:
  • specifications – A list of provided interface(s) name(s) (can’t be empty)
  • controller – Name of the service controller class field (optional)
  • factory – If True, this service is a service factory
Raises:

ValueError – If the specifications are invalid

Requirements

class pelix.ipopo.decorators.Requires(field, specification, aggregate=False, optional=False, spec_filter=None, immediate_rebind=False)

The @Requires decorator defines the requirement of a service. It accepts the following parameters:

Parameters:
  • field – The field where to inject the requirement
  • specification – The specification of the service to inject
  • aggregate – If True, injects a list of services, else the first matching service
  • optional – If True, this injection is optional: the component can be valid without it
  • spec_filter – An LDAP query to filter injected services according to their properties
  • immediate_rebind – If True, the component won’t be invalidated then re-validated if a matching service is available when the injected dependency is unbound
Handler ID:

pelix.ipopo.constants.HANDLER_REQUIRES

The field and specification attributes are mandatory. By default, a requirement is neither aggregated nor optional (both are set to False and no specification filter is used.

Note

Since iPOPO 0.5.4, only one specification can be given.

@ComponentFactory()
@Requires('_hello', 'hello.world')
class Foo(object):
    pass

@ComponentFactory()
@Requires('_hello', 'hello.world', aggregate=True, optional=False,
          spec_filter='(language=fr)')
class Bar(object):
    pass
Parameters:
  • field – The injected field
  • specification – The injected service specification
  • aggregate – If True, injects a list
  • optional – If True, this injection is optional
  • spec_filter – An LDAP query to filter injected services upon their properties
  • immediate_rebind – If True, the component won’t be invalidated then re-validated if a matching service is available when the injected dependency is unbound
Raises:
  • TypeError – A parameter has an invalid type
  • ValueError – An error occurred while parsing the filter or an argument is incorrect
class pelix.ipopo.decorators.Temporal(field, specification, optional=False, spec_filter=None, timeout=10)

The @Temporal decorator defines a single immediate rebind requirement with a grace time when the injected service disappears.

This decorator acts like :class:Requires except it doesn’t support immediate_rebind (set to True) nor aggregate. It also adds the following argument:

Parameters:timeout – Temporal timeout, in seconds (must be greater than 0)
Handler ID:pelix.ipopo.constants.HANDLER_TEMPORAL

When the injected service disappears, the component won’t be invalidated before the given timeout. If a matching is found, it is injected in-place and the component instance continues its operations. If the service is used while no service is available, the call is put in hold and blocks until a new service is injected or until the timeout is reached. In the latter case, a TemporalException is raised.

@ComponentFactory()
@Temporal('_hello', 'hello.world', timeout=5)
class Bar(object):
    pass
Parameters:
  • field – The injected field
  • specification – The injected service specification
  • optional – If true, this injection is optional
  • spec_filter – An LDAP query to filter injected services upon their properties
  • timeout – Temporal timeout, in seconds (must be greater than 0)
Raises:
  • TypeError – A parameter has an invalid type
  • ValueError – An error occurred while parsing the filter or an argument is incorrect
class pelix.ipopo.decorators.RequiresBest(field, specification, optional=False, spec_filter=None, immediate_rebind=True)

The @RequiresBest decorator acts like Requires, but it always injects the service with the best rank (service.ranking property).

Unlike most of the other requirement decorators, @RequiresBest doesn’t support the injection of a list of services: only the best service can be injected.

Handler ID:pelix.ipopo.constants.HANDLER_REQUIRES_BEST
@ComponentFactory()
@RequiresBest('_hello', 'hello.world')
class Foo(object):
    pass

@ComponentFactory()
@RequiresBest('_hello', 'hello.world', optional=True,
              spec_filter='(language=fr)')
class Bar(object):
    pass
Parameters:
  • field – The injected field
  • specification – The injected service specification
  • optional – If true, this injection is optional
  • spec_filter – An LDAP query to filter injected services upon their properties
  • immediate_rebind – If True, the component won’t be invalidated then re-validated if a matching service is available when the injected dependency is unbound
Raises:
  • TypeError – A parameter has an invalid type
  • ValueError – An error occurred while parsing the filter or an argument is incorrect
class pelix.ipopo.decorators.RequiresMap(field, specification, key, allow_none=False, aggregate=False, optional=False, spec_filter=None)

The @RequiresMap decorator defines a requirement that must be injected in a dictionary.

In addition to the arguments of :class:Requires, this decorator also accepts or redefines the following ones:

Parameters:
  • key – The name of the service property to use as a dictionary key
  • allow_none – If True, also injects services with the property value set to None or missing
  • aggregate – If true, injects a list of services with the same property value, else injects only one service per value
Handler ID:

pelix.ipopo.constants.HANDLER_REQUIRES_MAP

@ComponentFactory()
@RequiresMap('_hello', 'hello.world', 'language')
class Bar(object):
    # self._hello['fr'].hello('le monde')
    pass
Parameters:
  • field – The injected field
  • specification – The injected service specification
  • key – Name of the service property to use as a dictionary key
  • allow_none – If True, inject services with a None property value
  • aggregate – If true, injects a list
  • optional – If true, this injection is optional
  • spec_filter – An LDAP query to filter injected services upon their properties
Raises:
  • TypeError – A parameter has an invalid type
  • ValueError – An error occurred while parsing the filter or an argument is incorrect
class pelix.ipopo.decorators.RequiresVarFilter(field, specification, aggregate=False, optional=False, spec_filter=None, immediate_rebind=False)

The @RequiresVarFilter decorator acts like Requires, but its LDAP filter dynamically adapts to the properties of this component.

Handler ID:pelix.ipopo.constants.HANDLER_REQUIRES_VARIABLE_FILTER
@ComponentFactory()
@Property('_lang', 'lang', 'fr')
@RequiresVarFilter('_hello', 'hello.world', optional=True,
                   spec_filter='(language={lang})')
class Bar(object):
    pass
Parameters:
  • field – The injected field
  • specification – The injected service specification
  • aggregate – If True, injects a list
  • optional – If True, this injection is optional
  • spec_filter – An LDAP query to filter injected services upon their properties
  • immediate_rebind – If True, the component won’t be invalidated then re-validated if a matching service is available when the injected dependency is unbound
Raises:
  • TypeError – A parameter has an invalid type
  • ValueError – An error occurred while parsing the filter or an argument is incorrect

Instance definition

class pelix.ipopo.decorators.Instantiate(name, properties=None)

This decorator tells iPOPO to instantiate a component instance from this factory as soon as its bundle is in ACTIVE state.

It accepts the following arguments:

Parameters:
  • name – The name of the component instance (mandatory)
  • properties – The initial properties of the instance

If no properties are given, the default value declared in @Property decorators will be used.

The properties are associated to the component instance but not added to it. This means that new (meta-) properties can be added to add information to the component (like the Remote Services export properties), but those won’t be accessible directly by the component. Those extra properties will be visible in component’s services properties and in the instance properties returned by the iPOPO get_instance_details() method, but no new field will be injected in the component instance.

@ComponentFactory()
@Property('_name', 'name', 'foo')
@Instantiate('component-1')
@Instantiate('component-2', {'name': 'bar'})
class Foo(object):
    pass
Parameters:
  • name – Instance name
  • properties – Instance properties

Life-cycle events

Those decorators store behavioral information on component methods. They must decorate methods in the component class.

Component state

pelix.ipopo.decorators.Validate(method)

The validation callback decorator is called when a component becomes valid, i.e. if all of its required dependencies has been injected.

The decorated method must accept the bundle’s BundleContext as argument:

@Validate
def validation_method(self, bundle_context):
    '''
    bundle_context: The component's bundle context
    '''
    # ...

If the validation callback raises an exception, the component goes into ERRONEOUS state.

If the component provides a service, the validation method is called before the provided service is registered to the framework.

Parameters:method – The validation method
Raises:TypeError – The decorated element is not a valid function
pelix.ipopo.decorators.Invalidate(method)

The invalidation callback decorator is called when a component becomes invalid, i.e. if one of its required dependencies disappeared.

The decorated method must accept the bundle’s BundleContext as argument:

@Invalidate
def invalidation_method(self, bundle_context):
    '''
    bundle_context: The component's bundle context
    '''
    # ...

Exceptions raised by an invalidation callback are ignored.

If the component provides a service, the invalidation method is called after the provided service has been unregistered to the framework.

Parameters:method – The decorated method
Raises:TypeError – The decorated element is not a function

Injections

pelix.ipopo.decorators.Bind(method)

The @Bind callback decorator is called when a component is bound to a dependency.

The decorated method must accept the injected service object and its ServiceReference as arguments:

@Bind
def bind_method(self, service, service_reference):
    '''
    service: The injected service instance.
    service_reference: The injected service ServiceReference
    '''
    # ...

If the service is a required one, the bind callback is called before the component is validated.

The service reference can be stored if it is released on unbind.

Exceptions raised by a bind callback are ignored.

Parameters:method – The decorated method
Raises:TypeError – The decorated element is not a valid function
class pelix.ipopo.decorators.BindField(field, if_valid=False)

The @BindField callback decorator is called when a component is bound to a dependency, injected in the given field.

This decorator accepts the following arguments:

Parameters:
  • field – The field associated to the binding
  • if_valid – If True, call the decorated method only when the component is valid

The decorated method must accept the field where the service has been injected, the service object and its ServiceReference as arguments:

@BindField('_hello')
def bind_method(self, field, service, service_reference):
    '''
    field: Field wherein the dependency is injected
    service: The injected service instance.
    service_reference: The injected service ServiceReference
    '''
    # ...

If the service is a required one, the bind callback is called before the component is validated. The bind field callback is called after the global bind method.

The service reference can be stored if it is released on unbind.

Exceptions raised by a bind callback are ignored.

Parameters:
  • field – Field associated to the binding
  • if_valid – Call the method only if the component is valid
pelix.ipopo.decorators.Update(method)

The @Update callback decorator is called when the properties of an injected service have been modified.

The decorated method must accept the injected service object and its ServiceReference and the previous properties as arguments:

@Update
def update_method(self, service, service_reference, old_properties):
    '''
    service: The injected service instance.
    service_reference: The injected service ServiceReference
    old_properties: The previous service properties
    '''
    # ...

Exceptions raised by an update callback are ignored.

Parameters:method – The decorated method
Raises:TypeError – The decorated element is not a valid function
class pelix.ipopo.decorators.UpdateField(field, if_valid=False)

The @UpdateField callback decorator is called when the properties of a service injected in the given field have been updated.

This decorator accepts the following arguments:

Parameters:
  • field – The field associated to the binding
  • if_valid – If True, call the decorated method only when the component is valid

The decorated method must accept the field where the service has been injected, the service object, its ServiceReference and its previous properties as arguments:

@UpdateField('_hello')
def update_method(self, service, service_reference, old_properties):
    '''
    field: Field wherein the dependency is injected
    service: The injected service instance.
    service_reference: The injected service ServiceReference
    old_properties: The previous service properties
    '''
    # ...

Exceptions raised by an update callback are ignored.

Parameters:
  • field – Field associated to the binding
  • if_valid – Call the method only if the component is valid
pelix.ipopo.decorators.Unbind(method)

The @Unbind callback decorator is called when a component dependency is unbound.

The decorated method must accept the injected service object and its ServiceReference as arguments:

@Unbind
def unbind_method(self, service, service_reference):
    '''
    service: The previously injected service instance.
    service_reference: Its ServiceReference
    '''
    # ...

If the service is a required one, the unbind callback is called after the component has been invalidated.

Exceptions raised by an unbind callback are ignored.

Parameters:method – The decorated method
Raises:TypeError – The decorated element is not a valid function
class pelix.ipopo.decorators.UnbindField(field, if_valid=False)

The @UnbindField callback decorator is called when an injected dependency is unbound.

This decorator accepts the following arguments:

Parameters:
  • field – The field associated to the binding
  • if_valid – If True, call the decorated method only when the component is valid

The decorated method must accept the field where the service has been injected, the service object, its ServiceReference and its previous properties as arguments:

@UnbindField('_hello')
def unbind_method(self, field, service, service_reference):
    '''
    field: Field wherein the dependency was injected
    service: The injected service instance.
    service_reference: The injected service ServiceReference
    '''
    # ...

If the service is a required one, the unbind callback is called after the component has been invalidated. The unbind field callback is called before the global unbind method.

Exceptions raised by an unbind callback are ignored.

Parameters:
  • field – Field associated to the binding
  • if_valid – Call the method only if the component is valid

Service state

pelix.ipopo.decorators.PostRegistration(method)

The service post-registration callback decorator is called after a service of the component has been registered to the framework.

The decorated method must accept the ServiceReference of the registered service as argument:

@PostRegistration
def callback_method(self, service_reference):
    '''
    service_reference: The ServiceReference of the provided service
    '''
    # ...
Parameters:method – The decorated method
Raises:TypeError – The decorated element is not a valid function
pelix.ipopo.decorators.PostUnregistration(method)

The service post-unregistration callback decorator is called after a service of the component has been unregistered from the framework.

The decorated method must accept the ServiceReference of the registered service as argument:

@PostUnregistration
def callback_method(self, service_reference):
    '''
    service_reference: The ServiceReference of the provided service
    '''
    # ...
Parameters:method – The decorated method
Raises:TypeError – The decorated element is not a valid function