Object representing an IOTile component that implements or extends CoreTools.
IOTile components are “projects” in the sense of traditional IDEs, “packages” in nodejs or “distributions” in python. They are single directories that contain related code and a metadata file that describes what the project is and how to use it.
Since IOTile components describe building blocks for IOT devies, they do not contain code in a single language but could describe a variety of different kinds of artifacts such as:
- firmware images
- python extensions for CoreTools
- build automation steps used in hardware manufacturing
- emulators for specific IOTile devices
The unifying concepts that extend to all of the above finds of components are that they product “artifacts” through a build process, the entire component has a single version and it can have dependencies on other components.
There is a single file inside the root of the component directory, module_settings.json that contains all of this metadata.
The IOTile object is constructed from a module_settings.json file and provides helper routines to parse and search its contents.
- folder (str): The path to a folder containing a module_settings.json
- file that will be loaded into this IOTile object.
The canonical list of all product types that contain python code.
This is used to know if this IOTile component will contain a support wheel, which happens if it produces any products of these types.
The canonical list of products that are stored as a list.
Most products are stored in module_settings.json in the products map where the key is the path to the product and the value is the type of product. Some products, those in this property, are stored where the key is the type of product and all of the specific products are stored in a single list under that key.
Declarations for products that require special path processing.
Parse a v1 module_settings.json file.
V1 is the older file format that requires a modules dictionary with a module_name and modules key that could in theory hold information on multiple modules in a single directory.
Load settings for a module.
Ensure that all product locations are strings.
Older components specify paths as lists of path components. Join those paths into a normal path string.
_process_product_path(self, product, declaration)¶
Search for products of a given type.
Search through the products declared by this IOTile component and return only those matching the given type. If the product is described by the path to a file, a complete normalized path will be returned. The path could be different depending on whether this IOTile component is in development or release mode.
The behavior of this function when filter_products has been called is slightly different based on whether product_type is in LIST_PRODUCTS or not. If product type is in LIST_PRODUCTS, then all matching products are returned if product_type itself was passed. So to get all tilebus_definitions you would call
By contrast, other products are filtered product-by-product. So there is no way to filter and get all libraries. Instead you pass the specific product names of the libraries that you want to
filter_productsand those specific libraries are returned. Passing the literal string
filter_productswill not return only the libraries, it will return nothing since no library is named
- product_type (str): The type of product that we wish to return.
list of str: The list of all products of the given type.
If no such products are found, an empty list will be returned. If filter_products() has been called and the filter does not include this product type, an empty list will be returned.
Return a list of directories containing any static libraries built by this IOTile.
When asked for a product, filter only those on this list.
The path to this component.
A mapping of all of the installed components on this system that can be used as build dependencies and where they are located. Also used to manage iotile plugins.
Return whether we have a cached list of all installed entry_points.
Lazily load the underlying key-value store backing this registry.
Lazily load iotile plugins only on demand.
This is a slow operation on computers with a slow FS and is rarely accessed information, so only compute it when it is actually asked for.
load_extensions(self, group, name_filter=None, comp_filter=None, class_filter=None, product_name=None, unique=False)¶
Dynamically load and return extension objects of a given type.
This is the centralized way for all parts of CoreTools to allow plugin behavior. Whenever a plugin is needed, this method should be called to load it. Examples of plugins are proxy modules, emulated tiles, iotile-build autobuilders, etc.
Each kind of plugin will typically be a subclass of a certain base class and can be provided one of three ways:
- It can be registered as an entry point in a pip installed package. The entry point group must map the group passed to load_extensions.
- It can be listed as a product of an IOTile component that is stored in this ComponentRegistry. The relevant python file inside the component will be imported dynamically as needed.
- It can be programmatically registered by calling
register_extension()on this class with a string name and an object. This is equivalent to exposing that same object as an entry point with the given name.
There is special behavior of this function if class_filter is passed and the object returned by one of the above three methods is a python module. The module will be search for object definitions that match the defined class.
The order of the returned objects list is only partially defined. Locally installed components are searched before pip installed packages with entry points. The order of results within each group is not specified.
- group (str): The extension type that you wish to enumerate. This
- will be used as the entry_point group for searching pip installed packages.
name_filter (str): Only return objects with the given name comp_filter (str): When searching through installed components(not entry_points), only search through components with the given name.
- class_filter (type or tuple of types): An object that will be passed to
- instanceof() to verify that all extension objects have the correct types. If not passed, no checking will be done.
- product_name (str): If this extension can be provided by a registered
- local component, the name of the product that should be loaded.
- unique (bool): If True (default is False), there must be exactly one object
- found inside this extension that matches all of the other criteria.
list of (str, object): A list of the found and loaded extension objects.
The string returned with each extension is the name of the entry_point or the base name of the file in the component or the value provided by the call to register_extension depending on how the extension was found.
If unique is True, then the list only contains a single entry and that entry will be directly returned.
register_extension(self, group, name, extension)¶
Register an extension.
group (str): The type of the extension name (str): A name for the extension extension (str or class): If this is a string, then it will beinterpreted as a path to import and load. Otherwise it will be treated as the extension object itself.
Clear all previously registered extensions.
Freeze the set of extensions into a single file.
Freezing extensions can speed up the extension loading process on machines with slow file systems since it requires only a single file to store all of the extensions.
Calling this method will save a file into the current virtual environment that stores a list of all currently found extensions that have been installed as entry_points. Future calls to load_extensions will only search the one single file containing frozen extensions rather than enumerating all installed distributions.
Remove a previously frozen list of extensions.
load_extension(self, path, name_filter=None, class_filter=None, unique=False, component=None)¶
Load a single python module extension.
This function is similar to using the imp module directly to load a module and potentially inspecting the objects it declares to filter them by class.
path (str): The path to the python file to load name_filter (str): If passed, the basename of the module must matchname or nothing is returned.
class_filter (type): If passed, only instance of this class are returned. unique (bool): If True (default is False), there must be exactly one objectfound inside this extension that matches all of the other criteria.
- component (IOTile): The component that this extension comes from if it is
- loaded from an installed component. This is used to properly import the extension as a submodule of the component’s support package.
list of (name, type): A list of the objects found at the extension path.
Remove all classes marked as not extensions.
This allows us to have a deeper hierarchy of classes than just one base class that is filtered by _filter_subclasses. Any class can define a class propery named:
__NO_EXTENSION__ = True
That class will never be returned as an extension. This is useful for masking out base classes for extensions that are declared in CoreTools and would be present in module imports but should not create a second entry point.
_filter_subclasses(self, obj, class_filter)¶
Set the global backing type used by the ComponentRegistry from this point forward
This function must be called before any operations that use the registry are initiated otherwise they will work from different registries that will likely contain different data
add_component(self, component, temporary=False)¶
Register a component with ComponentRegistry.
Component must be a buildable object with a module_settings.json file that describes its name and the domain that it is part of. By default, this component is saved in the permanent registry associated with this environment and will remain registered for future CoreTools invocations.
If you only want this component to be temporarily registered during this program’s session, you can pass temporary=True and the component will be stored in RAM only, not persisted to the underlying key-value store.
component (str): The path to a component that should be registered. temporary (bool): Optional flag to only temporarily register thecomponent for the duration of this program invocation.
List all of the plugins that have been registerd for the iotile program on this computer
find_component(self, key, domain='')¶
Remove component from registry
Clear all of the registered components
Clear all data from the registry
List all of the registered component names.
This list will include all of the permanently stored components as well as any temporary components that were added with a temporary=True flag in this session.
list of str: The list of component names.
Any of these names can be passed to get_component as is to get the corresponding IOTile object.
Iterate over all defined components yielding IOTile objects.
List all of the configuration variables
set_config(self, key, value)¶
Set a persistent config key to a value, stored in the registry
- key (string): The key name value (string): The key value
get_config(self, key, default=MISSING)¶
Get the value of a persistent config key from the registry
If no default is specified and the key is not found ArgumentError is raised.
- key (string): The key name to fetch default (string): an optional value to be returned if key cannot be found
- string: the key’s value
Remove a persistent config key from the registry
- key (string): The key name