private static boolean registerModule( Path pythonModuleRoot, String pythonModuleName, final String pythonClassName) { String pythonModuleRelPath = pythonModuleName.replace('.', '/'); Path pythonModuleFile = pythonModuleRoot.resolve(pythonModuleRelPath + ".py"); if (!Files.exists(pythonModuleFile)) { LOG.severe(String.format("Missing Python module '%s'", pythonModuleFile.toUri())); return false; } Path pythonInfoXmlFile = pythonModuleRoot.resolve(pythonModuleRelPath + "-info.xml"); if (!Files.exists(pythonInfoXmlFile)) { LOG.warning( String.format( "Missing operator metadata file '%s'. Using defaults.", pythonInfoXmlFile.toUri())); } DefaultOperatorDescriptor operatorDescriptor = createOperatorDescriptor(pythonInfoXmlFile, pythonModuleName); File pythonModuleRootFile = FileUtils.toFile(pythonModuleRoot); PyOperatorSpi operatorSpi = new PyOperatorSpi(operatorDescriptor) { @Override public Operator createOperator() throws OperatorException { PyOperator pyOperator = (PyOperator) super.createOperator(); pyOperator.setParameterDefaultValues(); pyOperator.setPythonModulePath(pythonModuleRootFile.getPath()); pyOperator.setPythonModuleName(pythonModuleName); pyOperator.setPythonClassName(pythonClassName); return pyOperator; } }; String operatorName = operatorDescriptor.getAlias() != null ? operatorDescriptor.getAlias() : operatorDescriptor.getName(); GPF.getDefaultInstance().getOperatorSpiRegistry().addOperatorSpi(operatorName, operatorSpi); LOG.info( String.format( "Python operator '%s' registered (Python module: '%s', class: '%s', root: '%s')", operatorName, pythonModuleName, pythonClassName, pythonModuleRootFile)); return true; }