The Discovery Module

This module implements discovery of packages which export various spec files.

You can use this API as follows, (examples assume use of the ‘test/discovery_workspaces/minimal’ workspace:

>>> from pprint import pprint
>>> from capabilities.discovery import package_index_from_package_path
>>> from capabilities.discovery import spec_file_index_from_package_index
>>> from capabilities.discovery import spec_index_from_spec_file_index
>>> workspaces = ['test/discovery_workspaces/minimal']
>>> package_index = package_index_from_package_path(workspaces)
>>> spec_file_index = spec_file_index_from_package_index(package_index)
>>> pprint(spec_file_index)
{'minimal_pkg': {
    'capability_interface': ['test/discovery_workspaces/minimal/minimal_pkg/interfaces/Minimal.yaml'],
    'capability_provider': [
        'test/discovery_workspaces/minimal/minimal_pkg/providers/minimal.yaml',
        'test/discovery_workspaces/minimal/minimal_pkg/providers/specific_minimal.yaml'],
    'package': <catkin_pkg.package.Package object at 0x10bb28df8>,
    'semantic_capability_interface': [
        'test/discovery_workspaces/minimal/minimal_pkg/interfaces/SpecificMinimal.yaml']}}

>>> spec_index, errors = spec_index_from_spec_file_index(spec_file_index)
>>> print(errors)
[]
>>> spec_index.names
[minimal_pkg/specific_minimal,
 minimal_pkg/Minimal,
 minimal_pkg/SpecificMinimal,
 minimal_pkg/minimal]
>>> pprint(spec_index.specs)
{minimal_pkg/minimal:
    <capabilities.specs.provider.CapabilityProvider object at 0x10391ce50>,
 minimal_pkg/specific_minimal:
    <capabilities.specs.provider.CapabilityProvider object at 0x10391cd10>,
 minimal_pkg/Minimal:
    <capabilities.specs.interface.CapabilityInterface object at 0x103952f90>,
 minimal_pkg/SpecificMinimal:
    <capabilities.specs.semantic_interface.SemanticCapabilityInterface object at 0x103952b50>}
>>> spec_index.interface_names
[minimal_pkg/Minimal]
>>> spec_index.interfaces
{minimal_pkg/Minimal: <capabilities.specs.interface.CapabilityInterface at 0x103952f90>}
>>> spec_index.interfaces['Minimal']
<capabilities.specs.interface.CapabilityInterface object at 0x10b7e3410>
>>> spec_index.semantic_interfaces
{'SpecificMinimal': <capabilities.specs.semantic_interface.SemanticCapabilityInterface object at 0x10b7bf3d0>}
>>> pprint(spec_index.providers)
{'minimal': <capabilities.specs.provider.CapabilityProvider object at 0x10b7bf750>,
 'specific_minimal': <capabilities.specs.provider.CapabilityProvider object at 0x10b7bfd10>}
exception capabilities.discovery.DuplicateNameException(name, colliding_package, spec_type)[source]

Raised when multiple specs with the same name are discovered

Variables:
  • spec_name (str) – name of the spec’s which collided
  • package (str) – package in which the colliding spec is defined
  • spec_type (str) – type of the colliding spec one of: capability_interface, semantic_capability_interface, capability_provider
exception capabilities.discovery.InterfaceNameNotFoundException(msg, spec_name, spec_type, spec_package)[source]

Raised when a referenced interface spec is not found

This can happen, for example, when a provider depends on an interface which is not defined anywhere.

Variables:
  • spec_name (str) – name of the spec’s which referenced the non existent interface
  • package (str) – package in which offending spec resides
  • spec_type (str) – type of the offending spec one of: capability_interface, semantic_capability_interface, capability_provider
class capabilities.discovery.SpecIndex[source]

Container for capability spec file locations and respective spec classes

add_interface(interface, file_path, package_name)[source]

Add a loaded CapabilityInterface object into the repository

Used by spec_index_from_spec_file_index() to build the SpecIndex.

Parameters:
  • interface (specs.interface.CapabilityInterface) – CapabilityInterface object which was loaded using a factory function
  • file_path (str) – path to the interface spec file that was loaded
  • package_name (str) – name of the package which contains the interface
Raises:

DuplicateNameException if there is a name collision

add_provider(provider, file_path, package_name)[source]

Add a loaded CapabilityProvider object into the repository

Used by spec_index_from_spec_file_index() to build the SpecIndex.

Parameters:
  • provider (specs.provider.CapabilityProvider) – CapabilityProvider object which was loaded using a factory function
  • file_path (str) – path to the provider spec file that was loaded
  • package_name (str) – name of the package which contains the provider
Raises:

DuplicateNameException if there is a name collision

Raises:

InterfaceNameNotFoundException if the interface which this capability provider implements is not found.

add_semantic_interface(semantic_interface, file_path, package_name)[source]

Add a loaded SemanticCapabilityInterface object into the repository

Used by spec_index_from_spec_file_index() to build the SpecIndex.

Parameters:
  • semantic_interface (specs.semantic_interface.SemanticCapabilityInterface) – SemanticCapabilityInterface object which was loaded using a factory function
  • file_path (str) – path to the semantic interface spec file that was loaded
  • package_name (str) – name of the package which contains the semantic interface
Raises:

DuplicateNameException if there is a name collision

Raises:

InterfaceNameNotFoundException if the interface which this semantic capability interface redefines is not found.

interface_names
Returns:list of capability interface names
Return type:list (str)
interface_paths
Returns:dict of capability interface spec paths, keyed by name
Return type:dict {str: str}
interfaces
Returns:dict of capability interfaces, keyed by name
Return type:dict {str: specs.interface.CapabilityInterface}
names
Returns:list of the names for all specs of all types
Return type:list (str)
provider_names
Returns:list of capability provider names
Return type:list (str)
provider_paths
Returns:dict of capability provider spec paths, keyed by name
Return type:dict {str: str}
providers
Returns:dict of capability providers, keyed by name
Return type:dict {str: specs.provider.CapabilityProvider}
remove_interface(interface_name)[source]

Removes a capability interface by name

Parameters:interface_name (str) – name of the interface to remove
Raises:KeyError if there is no interface by that name
remove_provider(provider_name)[source]

Removes a capability provider by name

Parameters:provider_name (str) – name of the interface to remove
Raises:KeyError if there is no interface by that name
remove_semantic_interface(semantic_interface_name)[source]

Removes a semantic capability interface by name

Parameters:semantic_interface_name (str) – name of the interface to remove
Raises:KeyError if there is no interface by that name
semantic_interface_names
Returns:list of semantic capability interface names
Return type:list (str)
semantic_interface_paths
Returns:dict of semantic capability interface spec paths, keyed by name
Return type:dict {str: str}
semantic_interfaces
Returns:dict of semantic capability interfaces, keyed by name
Return type:dict {str: specs.semantic_interface.SemanticCapabilityInterface}
specs

Possible spec types:

Returns:dict of specs, keyed by name
Return type:dict {str: spec}
capabilities.discovery.package_index_from_package_path(package_paths)[source]

Finds all packages on the given list of paths.

Iterates over the given list of paths in reverse order so that packages found in the paths at the beginning of the list get overlaid onto packages with the same name which were found in paths farther back in the list.

The resulting dictionary is keyed by the package name (so packages with duplicate names are overlaid) and the values are the catkin_pkg.package.Package class

Parameters:ros_package_path (list) – list of paths to search
Returns:dictionary of package objects keyed by name of the package
Return type:dict
capabilities.discovery.spec_file_index_from_package_index(package_index)[source]

Creates an index of spec files by package.

Takes a dict of package objects keyed by package name.

Returns a dict structured like this:

{
    '<package_name>': {
        'package': package_obj,
        'capability_interface': ['path to spec file', ...],
        'capability_provider': ['path to spec file', ...],
        'semantic_capability_interface': ['path to spec file', ...]
    },
    ...
}

This dict contains a dict for each package, keyed by package name. Those dicts contain the parsed package object, and a list of relative paths for spec files, separated by spec type.

Parameters:package_index (dict) – dict of catkin_pkg.package.Package‘s keyed by package name to be processed
Returns:spec file index strucutre
Return type:dict
capabilities.discovery.spec_index_from_spec_file_index(spec_file_index)[source]

Builds a SpecIndex from a spec file index

Goes through each spec paths foreach package of the given spec file index and parses them into objects. The objects are stored in a SpecIndex before being returned.

Duplicate Names are not allowed, even between different spec types and packages. Any duplicate names will be raised as a DuplicateNameException.

Any other errors encountered during spec file processing will be returned as a list along with the SpecIndex. Caught errors include:

Parameters:spec_file_index (dict) – spec_file_index, see spec_file_index_from_package_index()
Returns:SpecIndex (which contains all the loaded specs) and a list of any errors encountered while loading the spec files
Return type:SpecIndex, list (Exception‘s)
Raises:DuplicateNameException when two interfaces have the same name