in modular_api/services/install_service.py [0:0]
def install_module(module_path):
"""
:param module_path: the path to the installing module
:return: none
"""
extract_dependencies_func_map = {
'setup.py': extract_module_requirements_setup_py,
'setup.cfg': extract_module_requirements_setup_cfg,
'pyproject.toml': extract_module_requirements_toml
}
setup_files = ["pyproject.toml", "setup.cfg", "setup.py"]
_LOG.info(f'Going to install module from path: {module_path}')
if not os.path.isdir(module_path):
incorrect_path_message = (
'Provided path is incorrect. It should be a directory.'
)
_LOG.error(incorrect_path_message)
sys.exit(incorrect_path_message)
with open(os.path.join(module_path, API_MODULE_FILE)) as file:
api_module_config = json.load(file)
_LOG.info('Checking module descriptor properties')
if not all(
[key in api_module_config.keys() for key in DESCRIPTOR_REQUIRED_KEYS]
):
descriptor_key_absence_message = \
f'Descriptor file must contains the following keys: ' \
f'{", ".join(DESCRIPTOR_REQUIRED_KEYS)}'
_LOG.error(descriptor_key_absence_message)
sys.exit(descriptor_key_absence_message)
# Check each setup file by priority
for setup_file in setup_files:
setup_file_path = os.path.join(module_path, setup_file)
if not os.path.isfile(setup_file_path):
continue # Skip if file doesn't exist
_LOG.info('Checking module requirements compatibility')
try:
_LOG.info(f"Reading dependencies from: {setup_file}")
extract_func = extract_dependencies_func_map[setup_file]
module_dependencies = extract_func(
module_path=setup_file_path
)
except KeyError:
_LOG.error(f'Unsupported setup file: {setup_file}')
sys.exit(f'Unsupported setup file: {setup_file}')
check_module_requirements_compatibility(
module_dependencies=module_dependencies,
module_name=api_module_config.get('module_name')
)
# Found valid setup file, break the loop
_LOG.info(f"Successfully loaded dependencies from {setup_file}")
break
else:
_LOG.error("No valid setup file found")
sys.exit("No valid setup file found")
_LOG.info('Checking module dependencies')
check_module_requirements(api_module_config)
modular_admin_path, _ = os.path.split(os.path.dirname(__file__))
destination_folder = os.path.join(modular_admin_path, MODULES_DIR,
api_module_config[MODULE_NAME_KEY])
module_name = api_module_config[MODULE_NAME_KEY]
path_to_module = os.path.join(MODULAR_ADMIN_ROOT_PATH, MODULES_DIR,
module_name)
if os.path.exists(path_to_module):
_LOG.warning(f'The \'{module_name}\' module will be reinstalled')
remove_tree(path_to_module)
copytree(
module_path, destination_folder,
ignore=ignore_patterns(
'*.tox', 'build', '*.egg-info', '*.git', 'tests',
'requirements-dev.txt', 'tox.ini', 'logs')
)
install_module_with_destination_folder(paths_to_module=destination_folder)
_LOG.info(f'Copy {api_module_config[MODULE_NAME_KEY]} module files '
f'to {destination_folder}')
mount_point = api_module_config[MOUNT_POINT_KEY]
valid_methods = generate_valid_commands(
destination_folder=destination_folder,
path_to_scan=os.path.join(modular_admin_path, MODULES_DIR,
api_module_config[MODULE_NAME_KEY],
*api_module_config[CLI_PATH_KEY].split('/')),
mount_point=mount_point,
is_private_mode_enabled=False,
path_to_setup_file_in_module=setup_file_path
)
web_service_cmd_base = os.path.join(modular_admin_path,
'web_service',
'commands_base.json')
_LOG.info(f'Updating commands meta file by path: {web_service_cmd_base}')
write_generated_meta_to_file(path_to_file=web_service_cmd_base,
mount_point=mount_point,
groups_meta=valid_methods)
message = f'{api_module_config[MODULE_NAME_KEY].capitalize()} ' \
f'successfully installed'
_LOG.info(message)
return CommandResponse(message=message)