Source code for poppy.pop.scripts.scripts
#!/usr/bin/env python
# -*- coding: utf-8 -*-
import logging.config
import importlib
import os
from poppy.core.conf import settings
from poppy.core.command import Command
from poppy.core.db.handlers import load_databases
from poppy.core.configuration import Configuration
from poppy.core.tools.exceptions import print_exception
from poppy.core.plugin import Plugin
from poppy.core.generic.manager import Manager
__all__ = ['main', 'setup', 'load_config', 'load_descriptor', 'set_config', 'set_descriptor', 'pipeline_init',
'import_module_from_path']
class LoggerNotFound(Exception):
"""
Exception for the logger that is not found.
"""
def set_plugins_loggers_config(plugins):
"""
Create a logger config with the correct name for each plugin in order to see what
happens in the program in different handlers (console, console in GUI,
activity file, etc).
"""
# get the path from where to read the configuration file for the platform
# set default path
config = settings.LOGGER_CONFIG
# loop over plugins for adding them to the logger and be fully
# integrated with the pipeline
for plugin in plugins:
# add them if they are not already a module of the pipeline
if not plugin.startswith("poppy."):
config["loggers"][plugin] = config["loggers"]["poppy"]
# set parameters to logging
def load_plugins(plugins):
"""
Read the file of plugins at the fixed place and then load plugins with the
specific work to do for the models loading, commands, etc.
"""
# get the logger
logger = logging.getLogger("poppy.loadPlugins")
# get the list of plugins
logger.debug('Load the plugin list from settings')
# try to import the module defined
for plugin in plugins:
# import the module
try:
module = importlib.import_module(plugin)
except Exception as e:
print_exception(
"Error occurred importing plugin {0}. Aborting.".format(
plugin,
)
)
continue
# create the plugin object
Plugin(plugin, module)
# now load all registered plugins
for plugin in Plugin.manager.instances:
try:
plugin.load()
except:
print_exception(
"Error for loading plugin {0}".format(plugin)
)
def import_module_from_path(module_name, filepath):
spec = importlib.util.spec_from_file_location(module_name, filepath)
module = importlib.util.module_from_spec(spec)
spec.loader.exec_module(module)
return module
[docs]def setup(options):
"""
Responsible of the setup before the generation of commands.
"""
if options.settings:
settings_module = import_module_from_path('settings_module', options.settings)
elif os.environ.get('PIPELINE_SETTINGS_FILE', None):
settings_module = import_module_from_path('settings_module', os.environ['PIPELINE_SETTINGS_FILE'])
else:
try:
import settings as settings_module
except ModuleNotFoundError:
# search for settings in the pipeline root dir
settings_module_path = os.path.join(settings.ROOT_DIRECTORY, 'settings.py')
if os.path.isfile(settings_module_path):
settings_module = import_module_from_path('settings_module', settings_module_path)
else:
raise Exception('No settings file found')
# update the default settings
settings.configure(settings_module)
if options.log_level:
# force the log-level of plugins
settings.LOGGER_CONFIG['loggers']['poppy']['level'] = options.log_level
# get the registered plugins
plugins = settings.PLUGINS
# set the loggers config for each non-poppy plugin
set_plugins_loggers_config(plugins)
# Load the logging configuration from the LOGGER_CONFIG dictionary
logging.config.dictConfig(settings.LOGGER_CONFIG)
# load plugins
load_plugins(plugins)
[docs]def load_config(config_path, schema_path):
"""
Load the data in the configuration file and set it in the class.
"""
# read the configuration file in the XML format
configuration = Configuration(
config_path,
schema_path,
name="pipeline",
)
configuration.read_validate()
# return the configuration
return configuration
[docs]def load_descriptor(path, schema_path):
"""
Load the data in the descriptor file and set it in the class.
"""
# read the configuration file in the XML format
configuration = Configuration(
path,
schema_path,
name="descriptor",
)
configuration.read_validate()
# return the configuration
return configuration
[docs]def set_config(args):
"""
Set the file name where are stored the configuration parameters.
"""
# check environment variable
config_path = os.getenv("PIPELINE_CONFIG_FILE", None)
# get the path of the configuration file from the command line
if not config_path:
config_path = args.config
# path for schema
config_schema_path = args.config_schema
# return paths
return config_path, config_schema_path
[docs]def set_descriptor(args):
"""
Set the file name where are stored the descriptors.
"""
# check environment variable
path = os.getenv("PIPELINE_DESCRIPTOR_FILE", None)
# get the path of the configuration file from the command line
if not path:
path = args.descriptor
# path for schema
schema_path = args.pipeline_descriptor_schema
# return paths
return path, schema_path
[docs]def pipeline_init(args):
"""
Used to init some things in the pipeline, without interacting with it
directly, allowing to reuse the commands defined for the pipeline from an
other environment where the databases, configuration, etc are already set.
"""
# select from where to read the configuration file path
config_path, schema_path = set_config(args)
# load the configuration file
args.configuration = load_config(config_path, schema_path)
# load databases defined in the configuration
load_databases(args.configuration["pipeline.databases"])
# select also from where to read the descriptor of the pipeline
descriptor_path, schema_path = set_descriptor(args)
# load the descriptor file
load_descriptor(descriptor_path, schema_path)
def clear_managers():
"""
Clear the content of each instance of poppy manager.
This operation is needed to avoid conflicts between different successive runs.
:return:
"""
for manager in Manager.manager_list:
manager.delete_all()
[docs]def main(argv=None):
"""
The main function, called when the pop program is running.
"""
# preprocess options like --settings and --config
# these options could affect the pipeline behavior
# so they must be processed early.
options, args = Command.manager.preprocess_args(argv)
# generate possible commands
Command.manager.generate(options)
# parse the arguments in the command line
Command.manager.launch(args)
# clear pipeline managers
clear_managers()
# connect to the signal of the command manager to set the logger before the
# generation of the commands, allowing to debug. At this place because needs to
# set also when calling directly the main function with the entry points of
# setuptools
Command.manager.generation_start.connect(setup)
# connect before the launch of the command to load databases defined in the
# configuration file, and read it also
Command.manager.run_start.connect(pipeline_init)
if __name__ == "__main__":
main()