# Path: ncdjango/geoprocessing/params.py
# class ParameterCollection(object):
#     """Manages a collection of parameter types and values"""
# 
#     def __init__(self, parameters):
#         """
#         :param parameters: A list of `Parameter` objects
#         """
# 
#         self.parameters = parameters
#         self.by_name = {p.name: p for p in self.parameters}
#         self.values = {}
# 
#     def __setitem__(self, key, value):
#         self.values[key] = self.by_name[key].clean(value)
# 
#     def __getitem__(self, item):
#         return self.values.get(item)
# 
#     @property
#     def is_complete(self):
#         """Do all required parameters have values?"""
# 
#         return all(p.name in self.values for p in self.parameters if p.required)
# 
#     def format_args(self):
#         """Returns dictionary containing values for all named parameters."""
# 
#         return self.values
# 
# class Parameter(metaclass=ParameterBase):
#     """
#     Base parameter (input, output, or uniform) class for a task or workflow. Extended to implement specific parameter
#     types.
#     """
# 
#     id = None  # A unique name for this parameter, used for serialization
# 
#     def __init__(self, name, required=True):
#         """
#         :param name: The parameter name. This will be used as a keyword argument to the task's `execute()` method.
#         :param required: When True, input validation will fail if no value is provided.
#         """
# 
#         self.name = name
#         self.required = required
# 
#     @classmethod
#     def by_id(cls, param_id):
#         return cls._parameters_by_id.get(param_id)
# 
#     def clean(self, value):
#         """Cleans and returns the given value, or raises a ParameterNotValidError exception"""
# 
#         return value
# 
#     def serialize_args(self):
#         """Returns (args, kwargs) to be used when deserializing this parameter."""
# 
#         return (self.name,), {'required': True}
# 
#     @staticmethod
#     def deserialize_args(args, kwargs):
#         """Returns deserialized forms of (args, kwargs) to be used when re-constructing this parameter."""
# 
#         return args, kwargs


import copy
import json
import logging
import time
from .params import ParameterCollection, Parameter

            node_inputs = {}
            for input_name, (source, value) in node.inputs.items():
                input_info = {'source': source}

                if source == 'input':
                    input_info['input'] = inputs.by_name[value].name
                else:
                    input_info['node'] = value

                node_inputs[input_name] = input_info

            d['workflow'].append({
                'id': node.id,
                'task': task_name,
                'inputs': node_inputs
            })

        return json.dumps(d, indent=indent)

    @classmethod
    def from_json(cls, text):
        """Return a new workflow, deserialized from a JSON string"""

        d = json.loads(text)

        meta = d.get('meta', {})
        workflow = cls(name=meta.get('name'), description=meta.get('description'))

        for workflow_input in d.get('inputs', []):

# Path: ncdjango/geoprocessing/params.py
# class ParameterCollection(object):
#     """Manages a collection of parameter types and values"""
# 
#     def __init__(self, parameters):
#         """
#         :param parameters: A list of `Parameter` objects
#         """
# 
#         self.parameters = parameters
#         self.by_name = {p.name: p for p in self.parameters}
#         self.values = {}
# 
#     def __setitem__(self, key, value):
#         self.values[key] = self.by_name[key].clean(value)
# 
#     def __getitem__(self, item):
#         return self.values.get(item)
# 
#     @property
#     def is_complete(self):
#         """Do all required parameters have values?"""
# 
#         return all(p.name in self.values for p in self.parameters if p.required)
# 
#     def format_args(self):
#         """Returns dictionary containing values for all named parameters."""
# 
#         return self.values
# 
# class Parameter(metaclass=ParameterBase):
#     """
#     Base parameter (input, output, or uniform) class for a task or workflow. Extended to implement specific parameter
#     types.
#     """
# 
#     id = None  # A unique name for this parameter, used for serialization
# 
#     def __init__(self, name, required=True):
#         """
#         :param name: The parameter name. This will be used as a keyword argument to the task's `execute()` method.
#         :param required: When True, input validation will fail if no value is provided.
#         """
# 
#         self.name = name
#         self.required = required
# 
#     @classmethod
#     def by_id(cls, param_id):
#         return cls._parameters_by_id.get(param_id)
# 
#     def clean(self, value):
#         """Cleans and returns the given value, or raises a ParameterNotValidError exception"""
# 
#         return value
# 
#     def serialize_args(self):
#         """Returns (args, kwargs) to be used when deserializing this parameter."""
# 
#         return (self.name,), {'required': True}
# 
#     @staticmethod
#     def deserialize_args(args, kwargs):
#         """Returns deserialized forms of (args, kwargs) to be used when re-constructing this parameter."""
# 
#         return args, kwargs


# Path: ncdjango/geoprocessing/workflow.py
import copy
import json
import logging
import time
from .params import ParameterCollection, Parameter


            node_inputs = {}
            for input_name, (source, value) in node.inputs.items():
                input_info = {'source': source}

                if source == 'input':
                    input_info['input'] = inputs.by_name[value].name
                else:
                    input_info['node'] = value

                node_inputs[input_name] = input_info

            d['workflow'].append({
                'id': node.id,
                'task': task_name,
                'inputs': node_inputs
            })

        return json.dumps(d, indent=indent)

    @classmethod
    def from_json(cls, text):
        """Return a new workflow, deserialized from a JSON string"""

        d = json.loads(text)

        meta = d.get('meta', {})
        workflow = cls(name=meta.get('name'), description=meta.get('description'))

        for workflow_input in d.get('inputs', []):

            parameter_cls = Parameter.by_id(workflow_input['type'])