async def addFeedNodes(self, name, items): ''' Call a feed function and return what it returns (typically yields Node()s). Args: name (str): The name of the feed record type. items (list): A list of records of the given feed type. Returns: (object): The return value from the feed function. Typically Node() generator. ''' func = self.core.getFeedFunc(name) if func is None: raise s_exc.NoSuchName(name=name) logger.info( f'User ({self.user.name}) adding feed data ({name}): {len(items)}') genr = func(self, items) if not isinstance(genr, types.AsyncGeneratorType): if isinstance(genr, types.CoroutineType): genr.close() mesg = f'feed func returned a {type(genr)}, not an async generator.' raise s_exc.BadCtorType(mesg=mesg, name=name) async for node in genr: yield node
def load_ctor(name, opts): ''' Load the given ctor path as a synapse CoreModule for extending the Cortex implementation. Args: name (str): Python path to a class ctor to load. opts (dict): Dictionary of configuration options. Example: Load the foopkg.barmod.Baz ctor:: import synapse.lib.modules as s_modules s_modules.load_ctor('foopkg.barmod.Baz', {}) Notes: This can only be used to dynamically load a subclass of the CoreModule class. Users should be aware that the import process can perform arbitrary code execution by imported modules. Returns: The loaded class is returned. Raises: NoSuchCtor: If the imported module does not have the listed ctor BadCtorType: If the ctor is not a subclass of the CoreModule class. ''' # Deferred import to prevent a import-loop upon __init__.py # execution of the main library. import synapse.lib.module as s_module modpath, ctor = name.rsplit('.', 1) smod = ctors.get(name) if smod is None: smod = s_dyndeps.tryDynMod(modpath) cls = getattr(smod, ctor, None) if cls is None: raise s_exc.NoSuchCtor(name=name, mesg='Ctor not found.') if not issubclass(cls, s_module.CoreModule): raise s_exc.BadCtorType( name=name, mesg='Ctor is not a CoreModule implementation.') ctors[name] = smod ctorlist.append((name, smod, opts)) return ctor