Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 0 additions & 4 deletions hydra_client/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,3 @@
from .connection import *
from .exception import *
from .output import *
from .templates import *
from .plugin import *

from hydra_base.exceptions import HydraPluginError
105 changes: 0 additions & 105 deletions hydra_client/click.py
Original file line number Diff line number Diff line change
@@ -1,9 +1,5 @@
""" This module contains helper functions and utilities for generating plugin.xml files from a click CLI.
"""
import click
from pathlib import Path
from xml.etree import ElementTree as ET
from xml.dom.minidom import parseString
import hydra_base
import os

Expand All @@ -28,69 +24,6 @@ def hydra_app_decorator(func):
return hydra_app_decorator


def make_plugins(group, shell, docker_image=None):
""" Generator of plugin XML data from the hydra_pywr CLI. """
for name, command in group.commands.items():

try:
hydra_app_category = command.hydra_app_category
except AttributeError:
hydra_app_category = False

if not hydra_app_category:
continue

# Create plugin data for each sub-command of the group.
data = make_plugin(command, hydra_app_category, shell, docker_image=docker_image)
# Convert the data to etree ElementTree
xml = plugin_to_xml(data)
yield name, xml


def make_plugin(command, category, shell, docker_image=None):
""" Make an individual plugin XML definition from a `click.Command`. """

name = command.hydra_app_name
if name is None:
name = command.short_help

if name is None:
name = command.name

plugin = {
'plugin_name': name,
'plugin_dir': '',
'plugin_description': command.help,
'plugin_category': category,
'plugin_location': '',
'plugin_nativelogextension': '.log',
'plugin_nativeoutputextension': '.out',
'smallicon': None,
'largeicon': None,
'plugin_epilog': command.epilog,
'mandatory_args': [],
'non_mandatory_args': [],
'switches': []
}

for category, arg in make_args(command):
plugin[category].append(arg)

if docker_image is None:
plugin.update({
'plugin_command': '{}'.format(command.name),
'plugin_shell': shell,
})
else:
plugin.update({
'plugin_command': '{} {}'.format(shell, command.name),
'plugin_shell': 'docker',
'plugin_docker_image': docker_image,
})

return plugin


def make_args(command):
""" Generate argument definitions for each parameter in command. """
for param in command.params:
Expand All @@ -115,41 +48,3 @@ def make_args(command):
arg['argtype'] = HYDRA_ARGTYPES[param.name]

yield category, arg


def plugin_to_xml(data):
""" Convert plugin definition to ElementTree. """
root = ET.Element('plugin_info')

for key, value in data.items():
e = ET.SubElement(root, key, )

if key in ('mandatory_args', 'non_mandatory_args', 'switches'):
for arg in value:
arg_element = ET.SubElement(e, 'arg')
for arg_key, arg_value in arg.items():
arg_sub_element = ET.SubElement(arg_element, arg_key)
arg_sub_element.text = arg_value
else:
e.text = value

return root


def write_plugins(plugins, app_name):
""" Write the generated plugins to XML files. """
base_plugin_dir = Path(hydra_base.config.get('plugin', 'default_directory'))
base_plugin_dir = base_plugin_dir.joinpath(app_name)

if not base_plugin_dir.exists():
base_plugin_dir.mkdir(parents=True, exist_ok=True)

for name, element in plugins:
plugin_path = os.path.join(base_plugin_dir, name)

if not os.path.exists(plugin_path):
os.mkdir(plugin_path)

with open(os.path.join(plugin_path, 'plugin.xml'), 'w') as fh:
reparsed = parseString(ET.tostring(element, 'utf-8'))
fh.write(reparsed.toprettyxml(indent="\t"))
4 changes: 2 additions & 2 deletions hydra_client/exception.py
Original file line number Diff line number Diff line change
Expand Up @@ -17,8 +17,8 @@

__all__ = ['RequestError']

from hydra_base.exceptions import HydraPluginError
from hydra_base.exceptions import HydraError


class RequestError(HydraPluginError):
class RequestError(HydraError):
pass
84 changes: 1 addition & 83 deletions hydra_client/output.py
Original file line number Diff line number Diff line change
Expand Up @@ -15,66 +15,16 @@
#
# -*- coding: utf-8 -*-

__all__ = ['create_xml_response', 'write_progress', 'write_output',
'validate_plugin_xml']
__all__ = ['write_progress', 'write_output']

import os
import logging
log = logging.getLogger(__name__)

from lxml import etree
from lxml.etree import XMLSyntaxError, ParseError

from hydra_base import config
from hydra_base.exceptions import HydraPluginError

import sys

def create_xml_response(plugin_name, network_id, scenario_ids,
errors=[], warnings=[], message=None, files=[]):
"""
Build the XML string required at the end of each plugin, describing
the errors, warnings, messages and outputed files, if any of these
are relevant.
"""

xml_string = """<plugin_result>
<message>%(message)s</message>
<plugin_name>%(plugin_name)s</plugin_name>
<network_id>%(network_id)s</network_id>
%(scenario_list)s
<errors>
%(error_list)s
</errors>
<warnings>
%(warning_list)s
</warnings>
<files>
%(file_list)s
</files>
</plugin_result>"""

scenario_string = "<scenario_id>%s</scenario_id>"
error_string = "<error>%s</error>"
warning_string = "<warning>%s</warning>"
file_string = "<file>%s</file>"

if scenario_ids is None:
scenario_ids = []

xml_string = xml_string % dict(
plugin_name = plugin_name,
network_id = network_id,
scenario_list = "\n".join([scenario_string % scen_id
for scen_id in scenario_ids]),
message = message if message is not None else "",
error_list = "\n".join([error_string%error for error in errors]),
warning_list = "\n".join([warning_string%warning for warning in warnings]),
file_list = "\n".join([file_string % f for f in files]),
)

return xml_string


def write_progress(x, y):
"""
Expand All @@ -94,35 +44,3 @@ def write_output(text):
msg = "!!Output %s" % (text,)
print(msg)
sys.stdout.flush()


def validate_plugin_xml(plugin_xml_file_path):
log.info('Validating plugin xml file (%s).' % plugin_xml_file_path)

try:
with open(plugin_xml_file_path) as f:
plugin_xml = f.read()
except:
raise HydraPluginError("Couldn't find plugin.xml.")

try:
plugin_xsd_path = os.path.expanduser(config.get('plugin',
'plugin_xsd_path'))
log.info("Plugin Input xsd: %s", plugin_xsd_path)
xmlschema_doc = etree.parse(plugin_xsd_path)
xmlschema = etree.XMLSchema(xmlschema_doc)
xml_tree = etree.fromstring(plugin_xml)
except XMLSyntaxError as e:
raise HydraPluginError("There is an error in your XML syntax: %s" % e)
except ParseError as e:
raise HydraPluginError("There is an error in your XML: %s" % e)
except Exception as e:
log.exception(e)
raise HydraPluginError("An unknown error occurred with the plugin xsd: %s"%e.message)

try:
xmlschema.assertValid(xml_tree)
except etree.DocumentInvalid as e:
raise HydraPluginError('Plugin validation failed: ' + e.message)

log.info("Plugin XML OK")
118 changes: 0 additions & 118 deletions hydra_client/plugin.py

This file was deleted.

Loading