Instruction:
Explain what the following Python 3 code does
def assign_value(rs, data_type, val,
                 unit_id, name, metadata={}, data_hash=None, user_id=None, source=None):
    """
        Insert or update a piece of data in a scenario.
        If the dataset is being shared by other resource scenarios, a new dataset is inserted.
        If the dataset is ONLY being used by the resource scenario in question, the dataset
        is updated to avoid unnecessary duplication.
    """

    log.debug("Assigning value %s to rs %s in scenario %s",
              name, rs.resource_attr_id, rs.scenario_id)

    if rs.scenario.locked == 'Y':
        raise PermissionError("Cannot assign value. Scenario %s is locked"
                             %(rs.scenario_id))

    #Check if this RS is the only RS in the DB connected to this dataset.
    #If no results is found, the RS isn't in the DB yet, so the condition is false.
    update_dataset = False # Default behaviour is to create a new dataset.

    if rs.dataset is not None:

        #Has this dataset changed?
        if rs.dataset.hash == data_hash:
            log.debug("Dataset has not changed. Returning.")
            return

        connected_rs = db.DBSession.query(ResourceScenario).filter(ResourceScenario.dataset_id==rs.dataset.id).all()
        #If there's no RS found, then the incoming rs is new, so the dataset can be altered
        #without fear of affecting something else.
        if len(connected_rs) == 0:
        #If it's 1, the RS exists in the DB, but it's the only one using this dataset or
        #The RS isn't in the DB yet and the datset is being used by 1 other RS.
            update_dataset = True

        if len(connected_rs) == 1 :
            if connected_rs[0].scenario_id == rs.scenario_id and connected_rs[0].resource_attr_id==rs.resource_attr_id:
                update_dataset = True
        else:
            update_dataset=False

    if update_dataset is True:
        log.info("Updating dataset '%s'", name)
        dataset = data.update_dataset(rs.dataset.id, name, data_type, val, unit_id, metadata, flush=False, **dict(user_id=user_id))
        rs.dataset = dataset
        rs.dataset_id = dataset.id
        log.info("Set RS dataset id to %s"%dataset.id)
    else:
        log.info("Creating new dataset %s in scenario %s", name, rs.scenario_id)
        dataset = data.add_dataset(data_type,
                                val,
                                unit_id,
                                metadata=metadata,
                                name=name,
                                **dict(user_id=user_id))
        rs.dataset = dataset
        rs.source = source

    db.DBSession.flush()

Response: Assign a value to a resource in a scenario.


Instruction:
Can you generate the documentation for the following Python 3 function
def add_data_to_attribute(scenario_id, resource_attr_id, dataset,**kwargs):
    user_id = kwargs.get('user_id')

    _check_can_edit_scenario(scenario_id, user_id)

    scenario_i = _get_scenario(scenario_id, user_id)

    try:
        r_scen_i = db.DBSession.query(ResourceScenario).filter(
                                ResourceScenario.scenario_id==scenario_id,
                                ResourceScenario.resource_attr_id==resource_attr_id).one()
        log.info("Existing resource scenario found for %s in scenario %s", resource_attr_id, scenario_id)
    except NoResultFound:
        log.info("No existing resource scenarios found for %s in scenario %s. Adding a new one.", resource_attr_id, scenario_id)
        r_scen_i = ResourceScenario()
        r_scen_i.scenario_id      = scenario_id
        r_scen_i.resource_attr_id = resource_attr_id
        scenario_i.resourcescenarios.append(r_scen_i)

    data_type = dataset.type.lower()

    value = dataset.parse_value()

    dataset_metadata = dataset.get_metadata_as_dict(user_id=kwargs.get('user_id'),
                                                    source=kwargs.get('source'))
    if value is None:
        raise HydraError("Cannot set value to attribute. "
            "No value was sent with dataset %s", dataset.id)

    data_hash = dataset.get_hash(value, dataset_metadata)

    assign_value(r_scen_i, data_type, value, dataset.unit_id, dataset.name,
                          metadata=dataset_metadata, data_hash=data_hash, user_id=user_id)

    db.DBSession.flush()
    return r_scen_i

Response: Add data to a resource scenario in a network update the resource scenario


Instruction:
Can you implement a function in Python 3 that
gets all the datasets from the group with the specified name AttributeNames

Response:
def get_scenario_data(scenario_id,**kwargs):
    """
        Get all the datasets from the group with the specified name
        @returns a list of dictionaries
    """
    user_id = kwargs.get('user_id')

    scenario_data = db.DBSession.query(Dataset).filter(Dataset.id==ResourceScenario.dataset_id, ResourceScenario.scenario_id==scenario_id).options(joinedload_all('metadata')).distinct().all()

    for sd in scenario_data:
       if sd.hidden == 'Y':
           try:
                sd.check_read_permission(user_id)
           except:
               sd.value      = None
               sd.metadata = []

    db.DBSession.expunge_all()

    log.info("Retrieved %s datasets", len(scenario_data))
    return scenario_data


Instruction:
Write a Python 3 function for
getting all the resources and resource scenarios for a given attribute or set of attributes.

Response:
def get_attribute_data(attr_ids, node_ids, **kwargs):
    """
        For a given attribute or set of attributes, return  all the resources and
        resource scenarios in the network
    """
    node_attrs = db.DBSession.query(ResourceAttr).\
                                            options(joinedload_all('attr')).\
                                            filter(ResourceAttr.node_id.in_(node_ids),
                                            ResourceAttr.attr_id.in_(attr_ids)).all()

    ra_ids = []
    for ra in node_attrs:
        ra_ids.append(ra.id)

    resource_scenarios = db.DBSession.query(ResourceScenario).filter(ResourceScenario.resource_attr_id.in_(ra_ids)).options(joinedload('resourceattr')).options(joinedload_all('dataset.metadata')).order_by(ResourceScenario.scenario_id).all()

    for rs in resource_scenarios:
       if rs.dataset.hidden == 'Y':
           try:
                rs.dataset.check_read_permission(kwargs.get('user_id'))
           except:
               rs.dataset.value      = None
       db.DBSession.expunge(rs)

    return node_attrs, resource_scenarios


Instruction:
Create a Python 3 function to
get all the resource scenarios for a given ref_key in a given scenario.

Response:
def get_resource_data(ref_key, ref_id, scenario_id, type_id=None, expunge_session=True, **kwargs):
    """
        Get all the resource scenarios for a given resource
        in a given scenario. If type_id is specified, only
        return the resource scenarios for the attributes
        within the type.
    """

    user_id = kwargs.get('user_id')

    resource_data_qry = db.DBSession.query(ResourceScenario).filter(
        ResourceScenario.dataset_id   == Dataset.id,
        ResourceAttr.id == ResourceScenario.resource_attr_id,
        ResourceScenario.scenario_id == scenario_id,
        ResourceAttr.ref_key == ref_key,
        or_(
            ResourceAttr.network_id==ref_id,
            ResourceAttr.node_id==ref_id,
            ResourceAttr.link_id==ref_id,
            ResourceAttr.group_id==ref_id
        )).distinct().\
            options(joinedload('resourceattr')).\
            options(joinedload_all('dataset.metadata')).\
            order_by(ResourceAttr.attr_is_var)

    if type_id is not None:
        attr_ids = []
        rs = db.DBSession.query(TypeAttr).filter(TypeAttr.type_id==type_id).all()
        for r in rs:
            attr_ids.append(r.attr_id)

        resource_data_qry = resource_data_qry.filter(ResourceAttr.attr_id.in_(attr_ids))

    resource_data = resource_data_qry.all()

    for rs in resource_data:

        #TODO: Design a mechanism to read the value of the dataset if it's stored externally

        if rs.dataset.hidden == 'Y':
           try:
                rs.dataset.check_read_permission(user_id)
           except:
               rs.dataset.value      = None

    if expunge_session == True:
        db.DBSession.expunge_all()

    return resource_data


Instruction:
How would you explain what the following Python 3 function does
def get_attribute_datasets(attr_id, scenario_id, **kwargs):

    user_id = kwargs.get('user_id')

    scenario_i = _get_scenario(scenario_id, user_id)

    try:
        a = db.DBSession.query(Attr).filter(Attr.id == attr_id).one()
    except NoResultFound:
        raise HydraError("Attribute %s not found"%(attr_id,))

    rs_qry = db.DBSession.query(ResourceScenario).filter(
                ResourceAttr.attr_id==attr_id,
                ResourceScenario.scenario_id==scenario_i.id,
                ResourceScenario.resource_attr_id==ResourceAttr.id
            ).options(joinedload_all('dataset'))\
            .options(joinedload_all('resourceattr'))\
            .options(joinedload_all('resourceattr.node'))\
            .options(joinedload_all('resourceattr.link'))\
            .options(joinedload_all('resourceattr.resourcegroup'))\
            .options(joinedload_all('resourceattr.network'))

    resourcescenarios = rs_qry.all()

    json_rs = []
    #Load the metadata too
    for rs in resourcescenarios:
        rs.dataset.metadata
        tmp_rs = JSONObject(rs)
        tmp_rs.resourceattr=JSONObject(rs.resourceattr)
        if rs.resourceattr.node_id is not None:
            tmp_rs.resourceattr.node = JSONObject(rs.resourceattr.node)
        elif rs.resourceattr.link_id is not None:
            tmp_rs.resourceattr.link = JSONObject(rs.resourceattr.link)
        elif rs.resourceattr.group_id is not None:
            tmp_rs.resourceattr.resourcegroup = JSONObject(rs.resourceattr.resourcegroup)
        elif rs.resourceattr.network_id is not None:
            tmp_rs.resourceattr.network = JSONObject(rs.resourceattr.network)

        json_rs.append(tmp_rs)

    return json_rs

Response: Retrieve all the datasets in a scenario for a given attribute.


Instruction:
Explain what the following Python 3 code does
def get_resourcegroupitems(group_id, scenario_id, **kwargs):

    """
        Get all the items in a group, in a scenario. If group_id is None, return
        all items across all groups in the scenario.
    """

    rgi_qry = db.DBSession.query(ResourceGroupItem).\
                filter(ResourceGroupItem.scenario_id==scenario_id)

    if group_id is not None:
        rgi_qry = rgi_qry.filter(ResourceGroupItem.group_id==group_id)

    rgi = rgi_qry.all()

    return rgi

Response: Get all the items in a group in a scenario.


Instruction:
Implement a Python 3 function for
deleting specified items in a group in a scenario.

Response:
def delete_resourcegroupitems(scenario_id, item_ids, **kwargs):
    """
        Delete specified items in a group, in a scenario.
    """
    user_id = int(kwargs.get('user_id'))
    #check the scenario exists
    _get_scenario(scenario_id, user_id)
    for item_id in item_ids:
        rgi = db.DBSession.query(ResourceGroupItem).\
                filter(ResourceGroupItem.id==item_id).one()
        db.DBSession.delete(rgi)

    db.DBSession.flush()


Instruction:
Can you write a function in Python 3 where it
deletes all itemas in a group in a scenario.

Response:
def empty_group(group_id, scenario_id, **kwargs):
    """
        Delete all itemas in a group, in a scenario.
    """
    user_id = int(kwargs.get('user_id'))
    #check the scenario exists
    _get_scenario(scenario_id, user_id)

    rgi = db.DBSession.query(ResourceGroupItem).\
            filter(ResourceGroupItem.group_id==group_id).\
            filter(ResourceGroupItem.scenario_id==scenario_id).all()
    rgi.delete()


Instruction:
How would you explain what the following Python 3 function does
def add_resourcegroupitems(scenario_id, items, scenario=None, **kwargs):

    """
        Get all the items in a group, in a scenario.
    """
    user_id = int(kwargs.get('user_id'))

    if scenario is None:
        scenario = _get_scenario(scenario_id, user_id)

    _check_network_ownership(scenario.network_id, user_id)

    newitems = []
    for group_item in items:
        group_item_i = _add_resourcegroupitem(group_item, scenario.id)
        newitems.append(group_item_i)

    db.DBSession.flush()

    return newitems

Response: Add items to a group in a scenario.


Instruction:
Can you tell what is the following Python 3 function doing
def _add_resourcegroupitem(group_item, scenario_id):
    if group_item.id and group_item.id > 0:
        try:
            group_item_i = db.DBSession.query(ResourceGroupItem).filter(ResourceGroupItem.id == group_item.id).one()
        except NoResultFound:
            raise ResourceNotFoundError("ResourceGroupItem %s not found" % (group_item.id))

    else:
        group_item_i = ResourceGroupItem()
        group_item_i.group_id = group_item.group_id
        if scenario_id is not None:
            group_item_i.scenario_id = scenario_id

        db.DBSession.add(group_item_i)

    ref_key = group_item.ref_key
    group_item_i.ref_key = ref_key
    if ref_key == 'NODE':
        group_item_i.node_id =group_item.ref_id if group_item.ref_id else group_item.node_id
    elif ref_key == 'LINK':
        group_item_i.link_id =group_item.ref_id if group_item.ref_id else group_item.link_id
    elif ref_key == 'GROUP':
        group_item_i.subgroup_id = group_item.ref_id if group_item.ref_id else group_item.subgroup_id

    return group_item_i

Response: Add a resource group item to the database.


Instruction:
Write a Python 3 script to
update the value of a resource attribute mapping between two scenarios.

Response:
def update_value_from_mapping(source_resource_attr_id, target_resource_attr_id, source_scenario_id, target_scenario_id, **kwargs):
    """
        Using a resource attribute mapping, take the value from the source and apply
        it to the target. Both source and target scenarios must be specified (and therefor
        must exist).
    """
    user_id = int(kwargs.get('user_id'))

    rm = aliased(ResourceAttrMap, name='rm')
    #Check the mapping exists.
    mapping = db.DBSession.query(rm).filter(
        or_(
            and_(
                rm.resource_attr_id_a == source_resource_attr_id,
                rm.resource_attr_id_b == target_resource_attr_id
            ),
            and_(
                rm.resource_attr_id_a == target_resource_attr_id,
                rm.resource_attr_id_b == source_resource_attr_id
            )
        )
    ).first()

    if mapping is None:
        raise ResourceNotFoundError("Mapping between %s and %s not found"%
                                    (source_resource_attr_id,
                                     target_resource_attr_id))

    #check scenarios exist
    s1 = _get_scenario(source_scenario_id, user_id)
    s2 = _get_scenario(target_scenario_id, user_id)

    rs = aliased(ResourceScenario, name='rs')
    rs1 = db.DBSession.query(rs).filter(rs.resource_attr_id == source_resource_attr_id,
                                    rs.scenario_id == source_scenario_id).first()
    rs2 = db.DBSession.query(rs).filter(rs.resource_attr_id == target_resource_attr_id,
                                    rs.scenario_id == target_scenario_id).first()

    #3 possibilities worth considering:
    #1: Both RS exist, so update the target RS
    #2: Target RS does not exist, so create it with the dastaset from RS1
    #3: Source RS does not exist, so it must be removed from the target scenario if it exists
    return_value = None#Either return null or return a new or updated resource scenario
    if rs1 is not None:
        if rs2 is not None:
            log.info("Destination Resource Scenario exists. Updating dastaset ID")
            rs2.dataset_id = rs1.dataset_id
        else:
            log.info("Destination has no data, so making a new Resource Scenario")
            rs2 = ResourceScenario(resource_attr_id=target_resource_attr_id, scenario_id=target_scenario_id, dataset_id=rs1.dataset_id)
            db.DBSession.add(rs2)
        db.DBSession.flush()
        return_value = rs2
    else:
        log.info("Source Resource Scenario does not exist. Deleting destination Resource Scenario")
        if rs2 is not None:
            db.DBSession.delete(rs2)

    db.DBSession.flush()
    return return_value


Instruction:
Write a Python 3 function for
getting all available plugins and their details.

Response:
def get_plugins(**kwargs):
    """
        Get all available plugins
    """

    plugins = []
    plugin_paths = []

    #Look in directory or set of directories for
    #plugins

    base_plugin_dir = config.get('plugin', 'default_directory')
    plugin_xsd_path = config.get('plugin', 'plugin_xsd_path')

    base_plugin_dir_contents = os.listdir(base_plugin_dir)
    for directory in base_plugin_dir_contents:
        #ignore hidden files
        if directory[0] == '.' or directory == 'xml':
            continue

        #Is this a file or a directory? If it's a directory, it's a plugin.
        path = os.path.join(base_plugin_dir, directory)
        if os.path.isdir(path):
            plugin_paths.append(path)

    #For each plugin, get its details (an XML string)

    #Retrieve the xml schema for validating the XML to make sure
    #what is being provided  to the IU is correct.
    xmlschema_doc = etree.parse(plugin_xsd_path)

    xmlschema = etree.XMLSchema(xmlschema_doc)

    #Get the xml description file from the plugin directory. If there
    #is no xml file, the plugin in unusable.
    for plugin_dir in plugin_paths:
        full_plugin_path = os.path.join(plugin_dir, 'trunk')

        dir_contents = os.listdir(full_plugin_path)
        #look for a plugin.xml file in the plugin directory
        for file_name in dir_contents:
            file_path = os.path.join(full_plugin_path, file_name)
            if file_name == 'plugin.xml':

                f = open(file_path, 'r')

                #validate the xml using the xml schema for defining
                #plugin details
                try:
                    y = open(file_path, 'r')

                    xml_tree = etree.parse(y)

                    xmlschema.assertValid(xml_tree)

                    plugins.append(etree.tostring(xml_tree))
                except Exception as e:
                    log.critical("Schema %s did not validate! (error was %s)"%(file_name, e))

                break
        else:
            log.warning("No xml plugin details found for %s. Ignoring", plugin_dir)

    return plugins


Instruction:
Make a summary of the following Python 3 code
def run_plugin(plugin,**kwargs):

    args = [sys.executable]

    #Get plugin executable
    home = os.path.expanduser('~')
    path_to_plugin = os.path.join(home, 'svn/HYDRA/HydraPlugins', plugin.location)
    args.append(path_to_plugin)

    #Parse plugin arguments into a string
    plugin_params = " "
    for p in plugin.params:
        param = "--%s=%s "%(p.name, p.value)
        args.append("--%s"%p.name)
        args.append(p.value)
        plugin_params = plugin_params + param

    log_dir = config.get('plugin', 'result_file')
    log_file = os.path.join(home, log_dir, plugin.name)

    #this reads all the logs so far. We're not interested in them
    #Everything after this is new content to the file
    try:
        f = open(log_file, 'r')
        f.read()
    except:
        f = open(log_file, 'w')
        f.close()
        f = open(log_file, 'r')

    pid = subprocess.Popen(args).pid
    #run plugin
    #os.system("%s %s"%(path_to_plugin, plugin_params))

    log.info("Process started! PID: %s", pid)

    return str(pid)

Response: Run a plugin and return the pid


Instruction:
Explain what the following Python 3 code does
def load_config():
    global localfiles
    global localfile
    global repofile
    global repofiles
    global userfile
    global userfiles
    global sysfile
    global sysfiles
    global CONFIG
    logging.basicConfig(level='INFO')

    config = ConfigParser.ConfigParser(allow_no_value=True)

    modulepath = os.path.dirname(os.path.abspath(__file__))

    localfile = os.path.join(os.getcwd(), 'hydra.ini')
    localfiles = glob.glob(localfile)

    repofile = os.path.join(modulepath, 'hydra.ini')
    repofiles = glob.glob(repofile)

    if os.name == 'nt':
        import winpaths
        userfile = os.path.join(os.path.expanduser('~'),'AppData','Local','hydra.ini')
        userfiles = glob.glob(userfile)

        sysfile = os.path.join(winpaths.get_common_documents(), 'Hydra','hydra.ini')
        sysfiles = glob.glob(sysfile)
    else:
        userfile = os.path.join(os.path.expanduser('~'), '.hydra', 'hydra.ini')
        userfiles = glob.glob(userfile)

        sysfile = os.path.join('etc','hydra','hydra.ini')
        sysfiles = glob.glob(sysfile)

    for ini_file in repofiles:
        logging.debug("Repofile: %s"%ini_file)
        config.read(ini_file)
    for ini_file in sysfiles:
        logging.debug("Sysfile: %s"%ini_file)
        config.read(ini_file)
    for ini_file in userfiles:
        logging.debug("Userfile: %s"%ini_file)
        config.read(ini_file)
    for ini_file in localfiles:
        logging.info("Localfile: %s"%ini_file)
        config.read(ini_file)

    env_value = os.environ.get('HYDRA_CONFIG')
    if env_value is not None:
        if os.path.exists(env_value):
            config.read(ini_file)
        else:
            logging.warning('HYDRA_CONFIG set as %s but file does not exist', env_value)

    if os.name == 'nt':
        set_windows_env_variables(config)

    try:
        home_dir = config.get('DEFAULT', 'home_dir')
    except:
        home_dir = os.environ.get('HYDRA_HOME_DIR', '~')
    config.set('DEFAULT', 'home_dir', os.path.expanduser(home_dir))

    try:
        hydra_base = config.get('DEFAULT', 'hydra_base_dir')
    except:
        hydra_base = os.environ.get('HYDRA_BASE_DIR', modulepath)
    config.set('DEFAULT', 'hydra_base_dir', os.path.expanduser(hydra_base))

    read_values_from_environment(config, 'mysqld', 'server_name')

    CONFIG = config

    return config

Response: This function loads a config file in the order of the file names.


Instruction:
Can you generate the documentation for the following Python 3 function
def create_mysql_db(db_url):

    #Remove trailing whitespace and forwardslashes
    db_url = db_url.strip().strip('/')

    #Check this is a mysql URL
    if db_url.find('mysql') >= 0:

        #Get the DB name from config and check if it's in the URL
        db_name = config.get('mysqld', 'db_name', 'hydradb')
        if db_url.find(db_name) >= 0:
            no_db_url = db_url.rsplit("/", 1)[0]
        else:
            #Check that there is a hostname specified, as we'll be using the '@' symbol soon..
            if db_url.find('@') == -1:
                raise HydraError("No Hostname specified in DB url")

            #Check if there's a DB name specified that's different to the one in config.
            host_and_db_name = db_url.split('@')[1]
            if host_and_db_name.find('/') >= 0:
                no_db_url, db_name = db_url.rsplit("/", 1)
            else:
                no_db_url = db_url
                db_url = no_db_url + "/" + db_name

        db_url = "{}?charset=utf8&use_unicode=1".format(db_url)

        if config.get('mysqld', 'auto_create', 'Y') == 'Y':
            tmp_engine = create_engine(no_db_url)
            log.warning("Creating database {0} as it does not exist.".format(db_name))
            tmp_engine.execute("CREATE DATABASE IF NOT EXISTS {0}".format(db_name))

    return db_url

Response: Create a mysql database if it doesn t exist.


Instruction:
Here you have a function in Python 3, explain what it does
def add_project(project,**kwargs):
    user_id = kwargs.get('user_id')

    existing_proj = get_project_by_name(project.name,user_id=user_id)

    if len(existing_proj) > 0:
        raise HydraError("A Project with the name \"%s\" already exists"%(project.name,))

    #check_perm(user_id, 'add_project')
    proj_i = Project()
    proj_i.name = project.name
    proj_i.description = project.description
    proj_i.created_by = user_id

    attr_map = hdb.add_resource_attributes(proj_i, project.attributes)
    db.DBSession.flush() #Needed to get the resource attr's ID
    proj_data = _add_project_attribute_data(proj_i, attr_map, project.attribute_data)
    proj_i.attribute_data = proj_data

    proj_i.set_owner(user_id)

    db.DBSession.add(proj_i)
    db.DBSession.flush()

    return proj_i

Response: Add a new project returns a project object


Instruction:
How would you code a function in Python 3 to
update a project Returns a project

Response:
def update_project(project,**kwargs):
    """
        Update a project
        returns a project complexmodel
    """

    user_id = kwargs.get('user_id')
    #check_perm(user_id, 'update_project')
    proj_i = _get_project(project.id)

    proj_i.check_write_permission(user_id)

    proj_i.name        = project.name
    proj_i.description = project.description

    attr_map = hdb.add_resource_attributes(proj_i, project.attributes)
    proj_data = _add_project_attribute_data(proj_i, attr_map, project.attribute_data)
    proj_i.attribute_data = proj_data
    db.DBSession.flush()

    return proj_i


Instruction:
Can you generate the documentation for the following Python 3 function
def get_project(project_id, include_deleted_networks=False, **kwargs):
    user_id = kwargs.get('user_id')
    proj_i = _get_project(project_id)

    #lazy load owners
    proj_i.owners

    proj_i.check_read_permission(user_id)

    proj_j = JSONObject(proj_i)

    proj_j.networks = []
    for net_i in proj_i.networks:
        #lazy load owners
        net_i.owners
        net_i.scenarios

        if include_deleted_networks==False and net_i.status.lower() == 'x':
            continue

        can_read_network = net_i.check_read_permission(user_id, do_raise=False)
        if can_read_network is False:
            continue

        net_j = JSONObject(net_i)
        proj_j.networks.append(net_j)

    return proj_j

Response: get a project complexmodel


Instruction:
Given the following Python 3 function, write the documentation
def get_project_by_network_id(network_id,**kwargs):
    user_id = kwargs.get('user_id')

    projects_i = db.DBSession.query(Project).join(ProjectOwner).join(Network, Project.id==Network.project_id).filter(
                                                    Network.id==network_id,
                                                    ProjectOwner.user_id==user_id).order_by('name').all()

    ret_project = None
    for project_i in projects_i:
        try:
            project_i.check_read_permission(user_id)
            ret_project = project_i
        except:
            log.info("Can't return project %s. User %s does not have permission to read it.", project_i.id, user_id)
    return ret_project

Response: get a project by a network_id


Instruction:
Make a summary of the following Python 3 code
def get_project_by_name(project_name,**kwargs):
    user_id = kwargs.get('user_id')

    projects_i = db.DBSession.query(Project).join(ProjectOwner).filter(
                                                    Project.name==project_name,
                                                    ProjectOwner.user_id==user_id).order_by('name').all()

    ret_projects = []
    for project_i in projects_i:
        try:
            project_i.check_read_permission(user_id)
            ret_projects.append(project_i)
        except:
            log.info("Can't return project %s. User %s does not have permission to read it.", project_i.id, user_id)

    return ret_projects

Response: get a project by name


Instruction:
Can you create a Python 3 function that
converts SQLAlchemy object to a named tuple.

Response:
def to_named_tuple(obj, visited_children=None, back_relationships=None, levels=None, ignore=[], extras={}):
    """
        Altered from an example found on stackoverflow
        http://stackoverflow.com/questions/23554119/convert-sqlalchemy-orm-result-to-dict
    """

    if visited_children is None:
        visited_children = []

    if back_relationships is None:
        back_relationships = []

    serialized_data = {c.key: getattr(obj, c.key) for c in obj.__table__.columns}

    #Any other non-column data to include in the keyed tuple
    for k, v in extras.items():
        serialized_data[k] = v

    relationships = class_mapper(obj.__class__).relationships

    #Set the attributes to 'None' first, so the attributes are there, even if they don't
    #get filled in:
    for name, relation in relationships.items():
        if relation.uselist:
            serialized_data[name] = tuple([])
        else:
            serialized_data[name] = None

    visitable_relationships = [(name, rel) for name, rel in relationships.items() if name not in back_relationships]

    if levels is not None and levels > 0:
        for name, relation in visitable_relationships:

            levels = levels - 1

            if name in ignore:
                continue

            if relation.backref:
                back_relationships.append(relation.backref)

            relationship_children = getattr(obj, name)

            if relationship_children is not None:
                if relation.uselist:
                    children = []
                    for child in [c for c in relationship_children if c not in visited_children]:
                        visited_children.append(child)
                        children.append(to_named_tuple(child, visited_children, back_relationships, ignore=ignore, levels=levels))
                    serialized_data[name] = tuple(children)
                else:
                    serialized_data[name] = to_named_tuple(relationship_children, visited_children, back_relationships, ignore=ignore, levels=levels)

    vals = []
    cols = []
    for k, v in serialized_data.items():
        vals.append(k)
        cols.append(v)

    result = KeyedTuple(cols, vals)

    return result


Instruction:
Write a Python 3 script for
getting all the projects owned by the specified user.

Response:
def get_projects(uid, include_shared_projects=True, projects_ids_list_filter=None, **kwargs):
    """
        Get all the projects owned by the specified user.
        These include projects created by the user, but also ones shared with the user.
        For shared projects, only include networks in those projects which are accessible to the user.

        the include_shared_projects flag indicates whether to include projects which have been shared
        with the user, or to only return projects created directly by this user.
    """
    req_user_id = kwargs.get('user_id')

    ##Don't load the project's networks. Load them separately, as the networks
    #must be checked individually for ownership
    projects_qry = db.DBSession.query(Project)

    log.info("Getting projects for %s", uid)

    if include_shared_projects is True:
        projects_qry = projects_qry.join(ProjectOwner).filter(Project.status=='A',
                                                        or_(ProjectOwner.user_id==uid,
                                                           Project.created_by==uid))
    else:
        projects_qry = projects_qry.join(ProjectOwner).filter(Project.created_by==uid)

    if projects_ids_list_filter is not None:
        # Filtering the search of project id
        if isinstance(projects_ids_list_filter, str):
            # Trying to read a csv string
            projects_ids_list_filter = eval(projects_ids_list_filter)
            if type(projects_ids_list_filter) is int:
                projects_qry = projects_qry.filter(Project.id==projects_ids_list_filter)
            else:
                projects_qry = projects_qry.filter(Project.id.in_(projects_ids_list_filter))

    projects_qry = projects_qry.options(noload('networks')).order_by('id')

    projects_i = projects_qry.all()

    log.info("Project query done for user %s. %s projects found", uid, len(projects_i))

    user = db.DBSession.query(User).filter(User.id==req_user_id).one()
    isadmin = user.is_admin()

    #Load each
    projects_j = []
    for project_i in projects_i:
        #Ensure the requesting user is allowed to see the project
        project_i.check_read_permission(req_user_id)
        #lazy load owners
        project_i.owners

        network_qry = db.DBSession.query(Network)\
                                .filter(Network.project_id==project_i.id,\
                                        Network.status=='A')
        if not isadmin:
            network_qry.outerjoin(NetworkOwner)\
            .filter(or_(
                and_(NetworkOwner.user_id != None,
                     NetworkOwner.view == 'Y'),
                Network.created_by == uid
            ))

        networks_i = network_qry.all()

        networks_j = []
        for network_i in networks_i:
            network_i.owners
            net_j = JSONObject(network_i)
            if net_j.layout is not None:
                net_j.layout = JSONObject(net_j.layout)
            else:
                net_j.layout = JSONObject({})
            networks_j.append(net_j)

        project_j = JSONObject(project_i)
        project_j.networks = networks_j
        projects_j.append(project_j)

    log.info("Networks loaded projects for user %s", uid)

    return projects_j


Instruction:
Write a Python 3 function that can
set the status of a project to X

Response:
def set_project_status(project_id, status, **kwargs):
    """
        Set the status of a project to 'X'
    """
    user_id = kwargs.get('user_id')
    #check_perm(user_id, 'delete_project')
    project = _get_project(project_id)
    project.check_write_permission(user_id)
    project.status = status
    db.DBSession.flush()


Instruction:
Write a Python 3 function that can
set the status of a project to 'X'

Response:
def delete_project(project_id,**kwargs):
    """
        Set the status of a project to 'X'
    """
    user_id = kwargs.get('user_id')
    #check_perm(user_id, 'delete_project')
    project = _get_project(project_id)
    project.check_write_permission(user_id)
    db.DBSession.delete(project)
    db.DBSession.flush()

    return 'OK'


Instruction:
Implement a function in Python 3 to
get all networks in a project Returns an array of network objects.

Response:
def get_networks(project_id, include_data='N', **kwargs):
    """
        Get all networks in a project
        Returns an array of network objects.
    """
    log.info("Getting networks for project %s", project_id)
    user_id = kwargs.get('user_id')
    project = _get_project(project_id)
    project.check_read_permission(user_id)

    rs = db.DBSession.query(Network.id, Network.status).filter(Network.project_id==project_id).all()
    networks=[]
    for r in rs:
        if r.status != 'A':
            continue
        try:
            net = network.get_network(r.id, summary=True, include_data=include_data, **kwargs)
            log.info("Network %s retrieved", net.name)
            networks.append(net)
        except PermissionError:
            log.info("Not returning network %s as user %s does not have "
                         "permission to read it."%(r.id, user_id))

    return networks


Instruction:
Can you write a function in Python 3 where it
gets the project that a network is in

Response:
def get_network_project(network_id, **kwargs):
    """
        get the project that a network is in
    """

    net_proj = db.DBSession.query(Project).join(Network, and_(Project.id==Network.id, Network.id==network_id)).first()

    if net_proj is None:
        raise HydraError("Network %s not found"% network_id)

    return net_proj


Instruction:
Write a Python 3 script to
save a reference to the types used for this resource.

Response:
def add_resource_types(resource_i, types):
    """
    Save a reference to the types used for this resource.

    @returns a list of type_ids representing the type ids
    on the resource.

    """
    if types is None:
        return []

    existing_type_ids = []
    if resource_i.types:
        for t in resource_i.types:
            existing_type_ids.append(t.type_id)

    new_type_ids = []
    for templatetype in types:

        if templatetype.id in existing_type_ids:
            continue

        rt_i = ResourceType()
        rt_i.type_id     = templatetype.id
        rt_i.ref_key     = resource_i.ref_key
        if resource_i.ref_key == 'NODE':
            rt_i.node_id      = resource_i.id
        elif resource_i.ref_key == 'LINK':
            rt_i.link_id      = resource_i.id
        elif resource_i.ref_key == 'GROUP':
            rt_i.group_id     = resource_i.id
        resource_i.types.append(rt_i)
        new_type_ids.append(templatetype.id)

    return new_type_ids


Instruction:
Can you generate a brief explanation for the following Python 3 code
def create_default_users_and_perms():

    # perms = db.DBSession.query(Perm).all()
    # if len(perms) > 0:
    #     return

    default_perms = ( ("add_user",   "Add User"),
                    ("edit_user",  "Edit User"),
                    ("add_role",   "Add Role"),
                    ("edit_role",  "Edit Role"),
                    ("add_perm",   "Add Permission"),
                    ("edit_perm",  "Edit Permission"),

                    ("add_network",    "Add network"),
                    ("edit_network",   "Edit network"),
                    ("delete_network", "Delete network"),
                    ("share_network",  "Share network"),
                    ("edit_topology",  "Edit network topology"),

                    ("add_project",    "Add Project"),
                    ("edit_project",   "Edit Project"),
                    ("delete_project", "Delete Project"),
                    ("share_project",  "Share Project"),

                    ("edit_data", "Edit network data"),
                    ("view_data", "View network data"),

                    ("add_template", "Add Template"),
                    ("edit_template", "Edit Template"),

                    ("add_dimension", "Add Dimension"),
                    ("update_dimension", "Update Dimension"),
                    ("delete_dimension", "Delete Dimension"),

                    ("add_unit", "Add Unit"),
                    ("update_unit", "Update Unit"),
                    ("delete_unit", "Delete Unit")

                    )

    default_roles = (
                    ("admin",    "Administrator"),
                    ("dev",      "Developer"),
                    ("modeller", "Modeller / Analyst"),
                    ("manager",  "Manager"),
                    ("grad",     "Graduate"),
                    ("developer", "Developer"),
                    ("decision", "Decision Maker"),
                )

    roleperms = (
            # Admin permissions
            ('admin', "add_user"),
            ('admin', "edit_user"),
            ('admin', "add_role"),
            ('admin', "edit_role"),
            ('admin', "add_perm"),
            ('admin', "edit_perm"),
            ('admin', "add_network"),
            ('admin', "edit_network"),
            ('admin', "delete_network"),
            ('admin', "share_network"),
            ('admin', "add_project"),
            ('admin', "edit_project"),
            ('admin', "delete_project"),
            ('admin', "share_project"),
            ('admin', "edit_topology"),
            ('admin', "edit_data"),
            ('admin', "view_data"),
            ('admin', "add_template"),
            ('admin', "edit_template"),

            ('admin', "add_dimension"),
            ('admin', "update_dimension"),
            ('admin', "delete_dimension"),

            ('admin', "add_unit"),
            ('admin', "update_unit"),
            ('admin', "delete_unit"),

            # Developer permissions
            ("developer", "add_network"),
            ("developer", "edit_network"),
            ("developer", "delete_network"),
            ("developer", "share_network"),
            ("developer", "add_project"),
            ("developer", "edit_project"),
            ("developer", "delete_project"),
            ("developer", "share_project"),
            ("developer", "edit_topology"),
            ("developer", "edit_data"),
            ("developer", "view_data"),
            ("developer", "add_template"),
            ("developer", "edit_template"),

            ('developer', "add_dimension"),
            ('developer', "update_dimension"),
            ('developer', "delete_dimension"),

            ('developer', "add_unit"),
            ('developer', "update_unit"),
            ('developer', "delete_unit"),

            # modeller permissions
            ("modeller", "add_network"),
            ("modeller", "edit_network"),
            ("modeller", "delete_network"),
            ("modeller", "share_network"),
            ("modeller", "edit_topology"),
            ("modeller", "add_project"),
            ("modeller", "edit_project"),
            ("modeller", "delete_project"),
            ("modeller", "share_project"),
            ("modeller", "edit_data"),
            ("modeller", "view_data"),

            # Manager permissions
            ("manager", "edit_data"),
            ("manager", "view_data"),
    )

    # Map for code to ID
    id_maps_dict = {
        "perm": {},
        "role": {}
    }
    # Adding perms
    perm_dict = {}
    for code, name in default_perms:
        perm = Perm(code=code, name=name)
        perm_dict[code] = perm
        perms_by_name = db.DBSession.query(Perm).filter(Perm.code==code).all()
        if len(perms_by_name)==0:
            # Adding perm
            log.debug("# Adding PERM {}".format(code))
            db.DBSession.add(perm)
            db.DBSession.flush()

        perm_by_name = db.DBSession.query(Perm).filter(Perm.code==code).one()
        id_maps_dict["perm"][code] = perm_by_name.id

    # Adding roles
    role_dict = {}
    for code, name in default_roles:
        role = Role(code=code, name=name)
        role_dict[code] = role
        roles_by_name = db.DBSession.query(Role).filter(Role.code==code).all()
        if len(roles_by_name)==0:
            # Adding perm
            log.debug("# Adding ROLE {}".format(code))
            db.DBSession.add(role)
            db.DBSession.flush()

        role_by_name = db.DBSession.query(Role).filter(Role.code==code).one()
        id_maps_dict["role"][code] = role_by_name.id

    # Adding connections
    for role_code, perm_code in roleperms:
        #log.info("Link Role:{}({}) <---> Perm:{}({})".format(role_code, id_maps_dict["role"][role_code], perm_code, id_maps_dict["perm"][perm_code]))

        links_found = db.DBSession.query(RolePerm).filter(RolePerm.role_id==id_maps_dict["role"][role_code]).filter(RolePerm.perm_id==id_maps_dict["perm"][perm_code]).all()
        if len(links_found)==0:
            # Adding link
            log.debug("# Adding link")
            roleperm = RolePerm()
            # roleperm.role = role_dict[role_code]
            # roleperm.perm = perm_dict[perm_code]
            roleperm.role_id = id_maps_dict["role"][role_code]
            roleperm.perm_id = id_maps_dict["perm"][perm_code]
            db.DBSession.add(roleperm)
            db.DBSession.flush()

    db.DBSession.flush()

Response: Creates the default roles and perms for the current user and creates the default roles and perm.


Instruction:
Here you have a function in Python 3, explain what it does
def create_default_units_and_dimensions():
    default_units_file_location = os.path.realpath(\
        os.path.join(os.path.dirname(os.path.realpath(__file__)),
                     '../',
                     'static',
                     'default_units_and_dimensions.json'))

    d=None

    with open(default_units_file_location) as json_data:
        d = json.load(json_data)
        json_data.close()

    for json_dimension in d["dimension"]:
        new_dimension = None
        dimension_name = get_utf8_encoded_string(json_dimension["name"])

        db_dimensions_by_name = db.DBSession.query(Dimension).filter(Dimension.name==dimension_name).all()

        if len(db_dimensions_by_name) == 0:
            # Adding the dimension
            log.debug("Adding Dimension `{}`".format(dimension_name))
            new_dimension = Dimension()
            if "id" in json_dimension:
                # If ID is specified
                new_dimension.id = json_dimension["id"]

            new_dimension.name = dimension_name

            db.DBSession.add(new_dimension)
            db.DBSession.flush()

        # Get the dimension by name
        new_dimension = get_dimension_from_db_by_name(dimension_name)

        for json_unit in json_dimension["unit"]:
            db_units_by_name = db.DBSession.query(Unit).filter(Unit.abbreviation==get_utf8_encoded_string(json_unit['abbr'])).all()
            if len(db_units_by_name) == 0:
                # Adding the unit
                log.debug("Adding Unit %s in %s",json_unit['abbr'], json_dimension["name"])
                new_unit = Unit()
                if "id" in json_unit:
                    new_unit.id = json_unit["id"]
                new_unit.dimension_id   = new_dimension.id
                new_unit.name           = get_utf8_encoded_string(json_unit['name'])
                new_unit.abbreviation   = get_utf8_encoded_string(json_unit['abbr'])
                new_unit.lf             = get_utf8_encoded_string(json_unit['lf'])
                new_unit.cf             = get_utf8_encoded_string(json_unit['cf'])
                if "description" in json_unit:
                    # If Description is specified
                    new_unit.description = get_utf8_encoded_string(json_unit["description"])

                # Save on DB
                db.DBSession.add(new_unit)
                db.DBSession.flush()
            else:
                #log.critical("UNIT {}.{} EXISTANT".format(dimension_name,json_unit['abbr']))
                pass
    try:
        # Needed for test. on HWI it fails so we need to catch the exception and pass by
        db.DBSession.commit()
    except Exception as e:
        # Needed for HWI
        pass
    return

Response: Creates the default units and dimensions for the current language.


Instruction:
Given the following Python 3 function, write the documentation
def get_dimension_from_db_by_name(dimension_name):
    try:
        dimension = db.DBSession.query(Dimension).filter(Dimension.name==dimension_name).one()
        return JSONObject(dimension)
    except NoResultFound:
        raise ResourceNotFoundError("Dimension %s not found"%(dimension_name))

Response: Gets a dimension from the DB table.


Instruction:
Here you have a function in Python 3, explain what it does
def get_rules(scenario_id, **kwargs):
    rules = db.DBSession.query(Rule).filter(Rule.scenario_id==scenario_id, Rule.status=='A').all()

    return rules

Response: Get all the rules for a given scenario.


Instruction:
Here you have a function in Python 3, explain what it does
def get_attribute_by_id(attr_id, **kwargs):

    try:
        attr_i = db.DBSession.query(Attr).filter(Attr.id==attr_id).one()
        return attr_i
    except NoResultFound:
        return None

Response: Get a specific attribute by its ID.


Instruction:
Can you tell what is the following Python 3 function doing
def get_template_attributes(template_id, **kwargs):

    try:
        attrs_i = db.DBSession.query(Attr).filter(TemplateType.template_id==template_id).filter(TypeAttr.type_id==TemplateType.id).filter(Attr.id==TypeAttr.id).all()
        log.debug(attrs_i)
        return attrs_i
    except NoResultFound:
        return None

Response: Get a specific attribute by its ID.


Instruction:
Given the following Python 3 function, write the documentation
def get_attribute_by_name_and_dimension(name, dimension_id=None,**kwargs):
    try:
        attr_i = db.DBSession.query(Attr).filter(and_(Attr.name==name, Attr.dimension_id==dimension_id)).one()
        log.debug("Attribute retrieved")
        return attr_i
    except NoResultFound:
        return None

Response: Get a specific attribute by its name and dimension_id.


Instruction:
Create a Python 3 function for
adding a generic attribute to the resource attribute list and return a dictionary of the new attribute.

Response:
def add_attribute(attr,**kwargs):
    """
    Add a generic attribute, which can then be used in creating
    a resource attribute, and put into a type.

    .. code-block:: python

        (Attr){
            id = 1020
            name = "Test Attr"
            dimension_id = 123
        }

    """
    log.debug("Adding attribute: %s", attr.name)

    try:
        attr_i = db.DBSession.query(Attr).filter(Attr.name == attr.name,
                                                 Attr.dimension_id == attr.dimension_id).one()
        log.info("Attr already exists")
    except NoResultFound:
        attr_i = Attr(name = attr.name, dimension_id = attr.dimension_id)
        attr_i.description = attr.description
        db.DBSession.add(attr_i)
        db.DBSession.flush()
        log.info("New attr added")
    return JSONObject(attr_i)


Instruction:
Can you tell what is the following Python 3 function doing
def update_attribute(attr,**kwargs):

    log.debug("Updating attribute: %s", attr.name)
    attr_i = _get_attr(attr.id)
    attr_i.name = attr.name
    attr_i.dimension_id = attr.dimension_id
    attr_i.description = attr.description

    #Make sure an update hasn't caused an inconsistency.
    #check_sion(attr_i.id)

    db.DBSession.flush()
    return JSONObject(attr_i)

Response: Update an attribute in a resource attribute list.


Instruction:
Write a Python 3 function that can
add a list of generic attributes to the internal list of resource attributes and returns a list of resource attributes.

Response:
def add_attributes(attrs,**kwargs):
    """
    Add a list of generic attributes, which can then be used in creating
    a resource attribute, and put into a type.

    .. code-block:: python

        (Attr){
            id = 1020
            name = "Test Attr"
            dimen = "very big"
        }

    """

    #Check to see if any of the attributs being added are already there.
    #If they are there already, don't add a new one. If an attribute
    #with the same name is there already but with a different dimension,
    #add a new attribute.

    # All existing attributes
    all_attrs = db.DBSession.query(Attr).all()
    attr_dict = {}
    for attr in all_attrs:
        attr_dict[(attr.name.lower(), attr.dimension_id)] = JSONObject(attr)

    attrs_to_add = []
    existing_attrs = []
    for potential_new_attr in attrs:
        if potential_new_attr is not None:
            # If the attrinute is None we cannot manage it
            log.debug("Adding attribute: %s", potential_new_attr)

            if attr_dict.get((potential_new_attr.name.lower(), potential_new_attr.dimension_id)) is None:
                attrs_to_add.append(JSONObject(potential_new_attr))
            else:
                existing_attrs.append(attr_dict.get((potential_new_attr.name.lower(), potential_new_attr.dimension_id)))

    new_attrs = []
    for attr in attrs_to_add:
        attr_i = Attr()
        attr_i.name = attr.name
        attr_i.dimension_id = attr.dimension_id
        attr_i.description = attr.description
        db.DBSession.add(attr_i)
        new_attrs.append(attr_i)

    db.DBSession.flush()

    new_attrs = new_attrs + existing_attrs

    return [JSONObject(a) for a in new_attrs]


Instruction:
Can you write a function in Python 3 where it
gets all attributes in the hierarchy

Response:
def get_attributes(**kwargs):
    """
        Get all attributes
    """

    attrs = db.DBSession.query(Attr).order_by(Attr.name).all()

    return attrs


Instruction:
Write a Python 3 function that can
update a resource attribute.

Response:
def update_resource_attribute(resource_attr_id, is_var, **kwargs):
    """
        Deletes a resource attribute and all associated data.
    """
    user_id = kwargs.get('user_id')
    try:
        ra = db.DBSession.query(ResourceAttr).filter(ResourceAttr.id == resource_attr_id).one()
    except NoResultFound:
        raise ResourceNotFoundError("Resource Attribute %s not found"%(resource_attr_id))

    ra.check_write_permission(user_id)

    ra.is_var = is_var

    return 'OK'


Instruction:
Can you create a Python 3 function that
deletes a resource attribute and all associated data.

Response:
def delete_resource_attribute(resource_attr_id, **kwargs):
    """
        Deletes a resource attribute and all associated data.
    """
    user_id = kwargs.get('user_id')
    try:
        ra = db.DBSession.query(ResourceAttr).filter(ResourceAttr.id == resource_attr_id).one()
    except NoResultFound:
        raise ResourceNotFoundError("Resource Attribute %s not found"%(resource_attr_id))

    ra.check_write_permission(user_id)
    db.DBSession.delete(ra)
    db.DBSession.flush()
    return 'OK'


Instruction:
Can you generate a brief explanation for the following Python 3 code
def add_resource_attribute(resource_type, resource_id, attr_id, is_var, error_on_duplicate=True, **kwargs):

    attr = db.DBSession.query(Attr).filter(Attr.id==attr_id).first()

    if attr is None:
        raise ResourceNotFoundError("Attribute with ID %s does not exist."%attr_id)

    resource_i = _get_resource(resource_type, resource_id)

    resourceattr_qry = db.DBSession.query(ResourceAttr).filter(ResourceAttr.ref_key==resource_type)

    if resource_type == 'NETWORK':
        resourceattr_qry = resourceattr_qry.filter(ResourceAttr.network_id==resource_id)
    elif resource_type == 'NODE':
        resourceattr_qry = resourceattr_qry.filter(ResourceAttr.node_id==resource_id)
    elif resource_type == 'LINK':
        resourceattr_qry = resourceattr_qry.filter(ResourceAttr.link_id==resource_id)
    elif resource_type == 'GROUP':
        resourceattr_qry = resourceattr_qry.filter(ResourceAttr.group_id==resource_id)
    elif resource_type == 'PROJECT':
        resourceattr_qry = resourceattr_qry.filter(ResourceAttr.project_id==resource_id)
    else:
        raise HydraError('Resource type "{}" not recognised.'.format(resource_type))
    resource_attrs = resourceattr_qry.all()

    for ra in resource_attrs:
        if ra.attr_id == attr_id:
            if not error_on_duplicate:
                return ra

            raise HydraError("Duplicate attribute. %s %s already has attribute %s"
                             %(resource_type, resource_i.get_name(), attr.name))

    attr_is_var = 'Y' if is_var == 'Y' else 'N'

    new_ra = resource_i.add_attribute(attr_id, attr_is_var)
    db.DBSession.flush()

    return new_ra

Response: Add a resource attribute to a resource.


Instruction:
How would you explain what the following Python 3 function does
def add_resource_attrs_from_type(type_id, resource_type, resource_id,**kwargs):
    type_i = _get_templatetype(type_id)

    resource_i = _get_resource(resource_type, resource_id)

    resourceattr_qry = db.DBSession.query(ResourceAttr).filter(ResourceAttr.ref_key==resource_type)

    if resource_type == 'NETWORK':
        resourceattr_qry.filter(ResourceAttr.network_id==resource_id)
    elif resource_type == 'NODE':
        resourceattr_qry.filter(ResourceAttr.node_id==resource_id)
    elif resource_type == 'LINK':
        resourceattr_qry.filter(ResourceAttr.link_id==resource_id)
    elif resource_type == 'GROUP':
        resourceattr_qry.filter(ResourceAttr.group_id==resource_id)
    elif resource_type == 'PROJECT':
        resourceattr_qry.filter(ResourceAttr.project_id==resource_id)

    resource_attrs = resourceattr_qry.all()

    attrs = {}
    for res_attr in resource_attrs:
        attrs[res_attr.attr_id] = res_attr

    new_resource_attrs = []
    for item in type_i.typeattrs:
        if attrs.get(item.attr_id) is None:
            ra = resource_i.add_attribute(item.attr_id)
            new_resource_attrs.append(ra)

    db.DBSession.flush()

    return new_resource_attrs

Response: Adds all the attributes defined by a type to a node.


Instruction:
Write a Python 3 script to
get all the resource attributes for a given resource type within a given network.

Response:
def get_all_resource_attributes(ref_key, network_id, template_id=None, **kwargs):
    """
        Get all the resource attributes for a given resource type in the network.
        That includes all the resource attributes for a given type within the network.
        For example, if the ref_key is 'NODE', then it will return all the attirbutes
        of all nodes in the network. This function allows a front end to pre-load an entire
        network's resource attribute information to reduce on function calls.
        If type_id is specified, only
        return the resource attributes within the type.
    """

    user_id = kwargs.get('user_id')

    resource_attr_qry = db.DBSession.query(ResourceAttr).\
            outerjoin(Node, Node.id==ResourceAttr.node_id).\
            outerjoin(Link, Link.id==ResourceAttr.link_id).\
            outerjoin(ResourceGroup, ResourceGroup.id==ResourceAttr.group_id).filter(
        ResourceAttr.ref_key == ref_key,
        or_(
            and_(ResourceAttr.node_id != None,
                    ResourceAttr.node_id == Node.id,
                                        Node.network_id==network_id),

            and_(ResourceAttr.link_id != None,
                    ResourceAttr.link_id == Link.id,
                                        Link.network_id==network_id),

            and_(ResourceAttr.group_id != None,
                    ResourceAttr.group_id == ResourceGroup.id,
                                        ResourceGroup.network_id==network_id)
        ))

    if template_id is not None:
        attr_ids = []
        rs = db.DBSession.query(TypeAttr).join(TemplateType,
                                            TemplateType.id==TypeAttr.type_id).filter(
                                                TemplateType.template_id==template_id).all()
        for r in rs:
            attr_ids.append(r.attr_id)

        resource_attr_qry = resource_attr_qry.filter(ResourceAttr.attr_id.in_(attr_ids))

    resource_attrs = resource_attr_qry.all()

    return resource_attrs


Instruction:
Can you generate a brief explanation for the following Python 3 code
def get_resource_attributes(ref_key, ref_id, type_id=None, **kwargs):

    user_id = kwargs.get('user_id')

    resource_attr_qry = db.DBSession.query(ResourceAttr).filter(
        ResourceAttr.ref_key == ref_key,
        or_(
            ResourceAttr.network_id==ref_id,
            ResourceAttr.node_id==ref_id,
            ResourceAttr.link_id==ref_id,
            ResourceAttr.group_id==ref_id
        ))

    if type_id is not None:
        attr_ids = []
        rs = db.DBSession.query(TypeAttr).filter(TypeAttr.type_id==type_id).all()
        for r in rs:
            attr_ids.append(r.attr_id)

        resource_attr_qry = resource_attr_qry.filter(ResourceAttr.attr_id.in_(attr_ids))

    resource_attrs = resource_attr_qry.all()

    return resource_attrs

Response: Get all the resource attributes for a given resource.


Instruction:
How would you code a function in Python 3 to
check that the dimension of the resource attribute data is consistent with the definition of the attribute.

Response:
def check_attr_dimension(attr_id, **kwargs):
    """
        Check that the dimension of the resource attribute data is consistent
        with the definition of the attribute.
        If the attribute says 'volume', make sure every dataset connected
        with this attribute via a resource attribute also has a dimension
        of 'volume'.
    """
    attr_i = _get_attr(attr_id)

    datasets = db.DBSession.query(Dataset).filter(Dataset.id == ResourceScenario.dataset_id,
                        ResourceScenario.resource_attr_id == ResourceAttr.id,
                        ResourceAttr.attr_id == attr_id).all()
    bad_datasets = []
    for d in datasets:
        if  attr_i.dimension_id is None and d.unit is not None or \
            attr_i.dimension_id is not None and d.unit is None or \
            units.get_dimension_by_unit_id(d.unit_id) != attr_i.dimension_id:
                # If there is an inconsistency
                bad_datasets.append(d.id)

    if len(bad_datasets) > 0:
        raise HydraError("Datasets %s have a different dimension_id to attribute %s"%(bad_datasets, attr_id))

    return 'OK'


Instruction:
Here you have a function in Python 3, explain what it does
def get_resource_attribute(resource_attr_id, **kwargs):

    resource_attr_qry = db.DBSession.query(ResourceAttr).filter(
        ResourceAttr.id == resource_attr_id,
        )

    resource_attr = resource_attr_qry.first()

    if resource_attr is None:
        raise ResourceNotFoundError("Resource attribute %s does not exist", resource_attr_id)

    return resource_attr

Response: Get a specific resource attribute by ID.


Instruction:
Write a Python 3 script to
define one resource attribute from one network as being the same as the same as that from another network.

Response:
def set_attribute_mapping(resource_attr_a, resource_attr_b, **kwargs):
    """
        Define one resource attribute from one network as being the same as
        that from another network.
    """
    user_id = kwargs.get('user_id')
    ra_1 = get_resource_attribute(resource_attr_a)
    ra_2 = get_resource_attribute(resource_attr_b)

    mapping = ResourceAttrMap(resource_attr_id_a = resource_attr_a,
                             resource_attr_id_b  = resource_attr_b,
                             network_a_id     = ra_1.get_network().id,
                             network_b_id     = ra_2.get_network().id )

    db.DBSession.add(mapping)

    db.DBSession.flush()

    return mapping


Instruction:
How would you code a function in Python 3 to
delete the mapping between two resource attributes.

Response:
def delete_attribute_mapping(resource_attr_a, resource_attr_b, **kwargs):
    """
        Define one resource attribute from one network as being the same as
        that from another network.
    """
    user_id = kwargs.get('user_id')

    rm = aliased(ResourceAttrMap, name='rm')

    log.info("Trying to delete attribute map. %s -> %s", resource_attr_a, resource_attr_b)
    mapping = db.DBSession.query(rm).filter(
                             rm.resource_attr_id_a == resource_attr_a,
                             rm.resource_attr_id_b == resource_attr_b).first()

    if mapping is not None:
        log.info("Deleting attribute map. %s -> %s", resource_attr_a, resource_attr_b)
        db.DBSession.delete(mapping)
        db.DBSession.flush()

    return 'OK'


Instruction:
Can you generate a brief explanation for the following Python 3 code
def delete_mappings_in_network(network_id, network_2_id=None, **kwargs):
    qry = db.DBSession.query(ResourceAttrMap).filter(or_(ResourceAttrMap.network_a_id == network_id, ResourceAttrMap.network_b_id == network_id))

    if network_2_id is not None:
        qry = qry.filter(or_(ResourceAttrMap.network_a_id==network_2_id, ResourceAttrMap.network_b_id==network_2_id))

    mappings = qry.all()

    for m in mappings:
        db.DBSession.delete(m)
    db.DBSession.flush()

    return 'OK'

Response: Delete all the resource attribute mappings in a network.


Instruction:
Write a Python 3 function that can
get all the resource attribute mappings in a network.

Response:
def get_mappings_in_network(network_id, network_2_id=None, **kwargs):
    """
        Get all the resource attribute mappings in a network. If another network
        is specified, only return the mappings between the two networks.
    """
    qry = db.DBSession.query(ResourceAttrMap).filter(or_(ResourceAttrMap.network_a_id == network_id, ResourceAttrMap.network_b_id == network_id))

    if network_2_id is not None:
        qry = qry.filter(or_(ResourceAttrMap.network_a_id==network_2_id, ResourceAttrMap.network_b_id==network_2_id))

    return qry.all()


Instruction:
Can you implement a function in Python 3 that
gets all the resource attribute mappings between two nodes.

Response:
def get_node_mappings(node_id, node_2_id=None, **kwargs):
    """
        Get all the resource attribute mappings in a network. If another network
        is specified, only return the mappings between the two networks.
    """
    qry = db.DBSession.query(ResourceAttrMap).filter(
        or_(
            and_(
                ResourceAttrMap.resource_attr_id_a == ResourceAttr.id,
                ResourceAttr.node_id == node_id),
            and_(
                ResourceAttrMap.resource_attr_id_b == ResourceAttr.id,
                ResourceAttr.node_id == node_id)))

    if node_2_id is not None:
        aliased_ra = aliased(ResourceAttr, name="ra2")
        qry = qry.filter(or_(
            and_(
                ResourceAttrMap.resource_attr_id_a == aliased_ra.id,
                aliased_ra.node_id == node_2_id),
            and_(
                ResourceAttrMap.resource_attr_id_b == aliased_ra.id,
                aliased_ra.node_id == node_2_id)))

    return qry.all()


Instruction:
Can you implement a function in Python 3 that
gets all the resource attribute mappings in a network.

Response:
def get_link_mappings(link_id, link_2_id=None, **kwargs):
    """
        Get all the resource attribute mappings in a network. If another network
        is specified, only return the mappings between the two networks.
    """
    qry = db.DBSession.query(ResourceAttrMap).filter(
        or_(
            and_(
                ResourceAttrMap.resource_attr_id_a == ResourceAttr.id,
                ResourceAttr.link_id == link_id),
            and_(
                ResourceAttrMap.resource_attr_id_b == ResourceAttr.id,
                ResourceAttr.link_id == link_id)))

    if link_2_id is not None:
        aliased_ra = aliased(ResourceAttr, name="ra2")
        qry = qry.filter(or_(
            and_(
                ResourceAttrMap.resource_attr_id_a == aliased_ra.id,
                aliased_ra.link_id == link_2_id),
            and_(
                ResourceAttrMap.resource_attr_id_b == aliased_ra.id,
                aliased_ra.link_id == link_2_id)))

    return qry.all()


Instruction:
Here you have a function in Python 3, explain what it does
def get_network_mappings(network_id, network_2_id=None, **kwargs):
    qry = db.DBSession.query(ResourceAttrMap).filter(
        or_(
            and_(
                ResourceAttrMap.resource_attr_id_a == ResourceAttr.id,
                ResourceAttr.network_id == network_id),
            and_(
                ResourceAttrMap.resource_attr_id_b == ResourceAttr.id,
                ResourceAttr.network_id == network_id)))

    if network_2_id is not None:
        aliased_ra = aliased(ResourceAttr, name="ra2")
        qry = qry.filter(or_(
            and_(
                ResourceAttrMap.resource_attr_id_a == aliased_ra.id,
                aliased_ra.network_id == network_2_id),
            and_(
                ResourceAttrMap.resource_attr_id_b == aliased_ra.id,
                aliased_ra.network_id == network_2_id)))

    return qry.all()

Response: Get all the mappings between two networks.


Instruction:
How would you implement a function in Python 3 that
gets a specific attribute group

Response:
def get_attribute_group(group_id, **kwargs):
    """
        Get a specific attribute group
    """

    user_id=kwargs.get('user_id')

    try:
        group_i = db.DBSession.query(AttrGroup).filter(
                                            AttrGroup.id==group_id).one()
        group_i.project.check_read_permission(user_id)
    except NoResultFound:
        raise HydraError("Group %s not found" % (group_id,))

    return group_i


Instruction:
How would you explain what the following Python 3 function does
def add_attribute_group(attributegroup, **kwargs):
    log.info("attributegroup.project_id %s",attributegroup.project_id) # It is None while it should be valued
    user_id=kwargs.get('user_id')
    project_i = db.DBSession.query(Project).filter(Project.id==attributegroup.project_id).one()
    project_i.check_write_permission(user_id)
    try:

        group_i = db.DBSession.query(AttrGroup).filter(
                                            AttrGroup.name==attributegroup.name,
                                            AttrGroup.project_id==attributegroup.project_id).one()
        log.info("Group %s already exists in project %s", attributegroup.name, attributegroup.project_id)

    except NoResultFound:

        group_i = AttrGroup()
        group_i.project_id  = attributegroup.project_id
        group_i.name        = attributegroup.name
        group_i.description = attributegroup.description
        group_i.layout      = attributegroup.get_layout()
        group_i.exclusive   = attributegroup.exclusive

        db.DBSession.add(group_i)
        db.DBSession.flush()

        log.info("Attribute Group %s added to project %s", attributegroup.name, attributegroup.project_id)

    return group_i

Response: Adds an attribute group to the list of available attributes.


Instruction:
Implement a Python 3 function for
updating an attribute group.

Response:
def update_attribute_group(attributegroup, **kwargs):
    """
        Add a new attribute group.

        An attribute group is a container for attributes which need to be grouped
        in some logical way. For example, if the 'attr_is_var' flag isn't expressive
        enough to delineate different groupings.

        an attribute group looks like:
            {
                'project_id' : XXX,
                'name'       : 'my group name'
                'description : 'my group description' (optional)
                'layout'     : 'my group layout'      (optional)
                'exclusive'  : 'N' (or 'Y' )          (optional, default to 'N')
            }
    """
    user_id=kwargs.get('user_id')

    if attributegroup.id is None:
        raise HydraError("cannot update attribute group. no ID specified")

    try:

        group_i = db.DBSession.query(AttrGroup).filter(AttrGroup.id==attributegroup.id).one()
        group_i.project.check_write_permission(user_id)

        group_i.name        = attributegroup.name
        group_i.description = attributegroup.description
        group_i.layout      = attributegroup.layout
        group_i.exclusive   = attributegroup.exclusive

        db.DBSession.flush()

        log.info("Group %s in project %s updated", attributegroup.id, attributegroup.project_id)
    except NoResultFound:

        raise HydraError('No Attribute Group %s was found in project %s', attributegroup.id, attributegroup.project_id)

    return group_i


Instruction:
Make a summary of the following Python 3 code
def delete_attribute_group(group_id, **kwargs):
    user_id = kwargs['user_id']

    try:

        group_i = db.DBSession.query(AttrGroup).filter(AttrGroup.id==group_id).one()

        group_i.project.check_write_permission(user_id)

        db.DBSession.delete(group_i)
        db.DBSession.flush()

        log.info("Group %s in project %s deleted", group_i.id, group_i.project_id)
    except NoResultFound:

        raise HydraError('No Attribute Group %s was found', group_id)

    return 'OK'

Response: Delete an attribute group.


Instruction:
Implement a Python 3 function for
getting all the group items in a network

Response:
def get_network_attributegroup_items(network_id, **kwargs):
    """
        Get all the group items in a network
    """

    user_id=kwargs.get('user_id')

    net_i = _get_network(network_id)

    net_i.check_read_permission(user_id)

    group_items_i = db.DBSession.query(AttrGroupItem).filter(
                                    AttrGroupItem.network_id==network_id).all()

    return group_items_i


Instruction:
Implement a Python 3 function for
getting all the items in a specified group within a network

Response:
def get_group_attributegroup_items(network_id, group_id, **kwargs):
    """
        Get all the items in a specified group, within a network
    """
    user_id=kwargs.get('user_id')

    network_i = _get_network(network_id)

    network_i.check_read_permission(user_id)

    group_items_i = db.DBSession.query(AttrGroupItem).filter(
                                    AttrGroupItem.network_id==network_id,
                                    AttrGroupItem.group_id==group_id).all()

    return group_items_i


Instruction:
Can you generate a brief explanation for the following Python 3 code
def get_attribute_item_groups(network_id, attr_id, **kwargs):
    user_id=kwargs.get('user_id')

    network_i = _get_network(network_id)

    network_i.check_read_permission(user_id)

    group_items_i = db.DBSession.query(AttrGroupItem).filter(
                                        AttrGroupItem.network_id==network_id,
                                        AttrGroupItem.attr_id==attr_id).all()

    return group_items_i

Response: Get all the group items in a given attribute_id


Instruction:
Here you have a function in Python 3, explain what it does
def add_attribute_group_items(attributegroupitems, **kwargs):

    """
        Populate attribute groups with items.
        ** attributegroupitems : a list of items, of the form:
            ```{
                    'attr_id'    : X,
                    'group_id'   : Y,
                    'network_id' : Z,
               }```

        Note that this approach supports the possibility of populating groups
        within multiple networks at the same time.

        When adding a group item, the function checks whether it can be added,
        based on the 'exclusivity' setup of the groups -- if a group is specified
        as being 'exclusive', then any attributes within that group cannot appear
        in any other group (within a network).
    """

    user_id=kwargs.get('user_id')

    if not isinstance(attributegroupitems, list):
        raise HydraError("Cannpt add attribute group items. Attributegroupitems must be a list")

    new_agis_i = []

    group_lookup = {}

    #for each network, keep track of what attributes are contained in which groups it's in
    #structure: {NETWORK_ID : {ATTR_ID: [GROUP_ID]}
    agi_lookup = {}

    network_lookup = {}

    #'agi' = shorthand for 'attribute group item'
    for agi in attributegroupitems:

        network_i = network_lookup.get(agi.network_id)

        if network_i is None:
            network_i = _get_network(agi.network_id)
            network_lookup[agi.network_id] = network_i

        network_i.check_write_permission(user_id)

        #Get the group so we can check for exclusivity constraints
        group_i = group_lookup.get(agi.group_id)
        if group_i is None:
            group_lookup[agi.group_id] = _get_attr_group(agi.group_id)

        network_agis = agi_lookup

        #Create a map of all agis currently in the network
        if agi_lookup.get(agi.network_id) is None:
            agi_lookup[agi.network_id] = {}
            network_agis = _get_attributegroupitems(agi.network_id)
            log.info(network_agis)
            for net_agi in network_agis:

                if net_agi.group_id not in group_lookup:
                    group_lookup[net_agi.group_id] = _get_attr_group(net_agi.group_id)

                if agi_lookup.get(net_agi.network_id) is None:
                    agi_lookup[net_agi.network_id][net_agi.attr_id] = [net_agi.group_id]
                else:
                    if agi_lookup[net_agi.network_id].get(net_agi.attr_id) is None:
                        agi_lookup[net_agi.network_id][net_agi.attr_id] = [net_agi.group_id]
                    elif net_agi.group_id not in agi_lookup[net_agi.network_id][net_agi.attr_id]:
                        agi_lookup[net_agi.network_id][net_agi.attr_id].append(net_agi.group_id)
        #Does this agi exist anywhere else inside this network?
        #Go through all the groups that this attr is in and make sure it's not exclusive
        if agi_lookup[agi.network_id].get(agi.attr_id) is not None:
            for group_id in agi_lookup[agi.network_id][agi.attr_id]:
                group = group_lookup[group_id]
                #Another group has been found.
                if group.exclusive == 'Y':
                    #The other group is exclusive, so this attr can't be added
                    raise HydraError("Attribute %s is already in Group %s for network %s. This group is exclusive, so attr %s cannot exist in another group."%(agi.attr_id, group.id, agi.network_id, agi.attr_id))

            #Now check that if this group is exclusive, then the attr isn't in
            #any other groups
            if group_lookup[agi.group_id].exclusive == 'Y':
                if len(agi_lookup[agi.network_id][agi.attr_id]) > 0:
                    #The other group is exclusive, so this attr can't be added
                    raise HydraError("Cannot add attribute %s to group %s. This group is exclusive, but attr %s has been found in other groups (%s)" % (agi.attr_id, agi.group_id, agi.attr_id, agi_lookup[agi.network_id][agi.attr_id]))

        agi_i = AttrGroupItem()
        agi_i.network_id = agi.network_id
        agi_i.group_id   = agi.group_id
        agi_i.attr_id    = agi.attr_id

        #Update the lookup table in preparation for the next pass.
        if agi_lookup[agi.network_id].get(agi.attr_id) is None:
            agi_lookup[agi.network_id][agi.attr_id] = [agi.group_id]
        elif agi.group_id not in agi_lookup[agi.network_id][agi.attr_id]:
            agi_lookup[agi.network_id][agi.attr_id].append(agi.group_id)

        db.DBSession.add(agi_i)

        new_agis_i.append(agi_i)
    log.info(agi_lookup)

    db.DBSession.flush()

    return new_agis_i

Response: Add a list of items to the attribute group.


Instruction:
Write a Python 3 script for
deleting the items from the attribute group.

Response:
def delete_attribute_group_items(attributegroupitems, **kwargs):

    """
        remove attribute groups items .
        ** attributegroupitems : a list of items, of the form:
            ```{
                    'attr_id'    : X,
                    'group_id'   : Y,
                    'network_id' : Z,
               }```
    """

    user_id=kwargs.get('user_id')

    log.info("Deleting %s attribute group items", len(attributegroupitems))

    #if there area attributegroupitems from different networks, keep track of those
    #networks to ensure the user actually has permission to remove the items.
    network_lookup = {}

    if not isinstance(attributegroupitems, list):
        raise HydraError("Cannpt add attribute group items. Attributegroupitems must be a list")

    #'agi' = shorthand for 'attribute group item'
    for agi in attributegroupitems:

        network_i = network_lookup.get(agi.network_id)

        if network_i is None:
            network_i = _get_network(agi.network_id)
            network_lookup[agi.network_id] = network_i

        network_i.check_write_permission(user_id)

        agi_i = db.DBSession.query(AttrGroupItem).filter(AttrGroupItem.network_id == agi.network_id,
                                                 AttrGroupItem.group_id == agi.group_id,
                                                 AttrGroupItem.attr_id  == agi.attr_id).first()

        if agi_i is not None:
            db.DBSession.delete(agi_i)

    db.DBSession.flush()

    log.info("Attribute group items deleted")

    return 'OK'


Instruction:
Explain what the following Python 3 code does
def share_network(network_id, usernames, read_only, share,**kwargs):

    user_id = kwargs.get('user_id')
    net_i = _get_network(network_id)
    net_i.check_share_permission(user_id)

    if read_only == 'Y':
        write = 'N'
        share = 'N'
    else:
        write = 'Y'

    if net_i.created_by != int(user_id) and share == 'Y':
        raise HydraError("Cannot share the 'sharing' ability as user %s is not"
                     " the owner of network %s"%
                     (user_id, network_id))

    for username in usernames:
        user_i = _get_user(username)
        #Set the owner ship on the network itself
        net_i.set_owner(user_i.id, write=write, share=share)
        for o in net_i.project.owners:
            if o.user_id == user_i.id:
                break
        else:
            #Give the user read access to the containing project
            net_i.project.set_owner(user_i.id, write='N', share='N')
    db.DBSession.flush()

Response: Share a network with a list of users identified by their usernames.


Instruction:
Explain what the following Python 3 code does
def unshare_network(network_id, usernames,**kwargs):

    user_id = kwargs.get('user_id')
    net_i = _get_network(network_id)
    net_i.check_share_permission(user_id)

    for username in usernames:
        user_i = _get_user(username)
        #Set the owner ship on the network itself

    net_i.unset_owner(user_i.id, write=write, share=share)
    db.DBSession.flush()

Response: Un - Share a network with a list of users identified by their usernames.


Instruction:
Make a summary of the following Python 3 code
def share_project(project_id, usernames, read_only, share,**kwargs):
    user_id = kwargs.get('user_id')

    proj_i = _get_project(project_id)

    #Is the sharing user allowed to share this project?
    proj_i.check_share_permission(int(user_id))

    user_id = int(user_id)

    for owner in proj_i.owners:
        if user_id == owner.user_id:
            break
    else:
       raise HydraError("Permission Denied. Cannot share project.")

    if read_only == 'Y':
        write = 'N'
        share = 'N'
    else:
        write = 'Y'

    if proj_i.created_by != user_id and share == 'Y':
        raise HydraError("Cannot share the 'sharing' ability as user %s is not"
                     " the owner of project %s"%
                     (user_id, project_id))

    for username in usernames:
        user_i = _get_user(username)

        proj_i.set_owner(user_i.id, write=write, share=share)

        for net_i in proj_i.networks:
            net_i.set_owner(user_i.id, write=write, share=share)
    db.DBSession.flush()

Response: Share an entire project with a list of users identifed by usernames.


Instruction:
Create a Python 3 function for
setting permissions on a project to a list of users identifed by usernames.

Response:
def set_project_permission(project_id, usernames, read, write, share,**kwargs):
    """
        Set permissions on a project to a list of users, identifed by
        their usernames.

        The read flag ('Y' or 'N') sets read access, the write
        flag sets write access. If the read flag is 'N', then there is
        automatically no write access or share access.
    """
    user_id = kwargs.get('user_id')

    proj_i = _get_project(project_id)

    #Is the sharing user allowed to share this project?
    proj_i.check_share_permission(user_id)

    #You cannot edit something you cannot see.
    if read == 'N':
        write = 'N'
        share = 'N'

    for username in usernames:
        user_i = _get_user(username)

        #The creator of a project must always have read and write access
        #to their project
        if proj_i.created_by == user_i.id:
            raise HydraError("Cannot set permissions on project %s"
                             " for user %s as this user is the creator." %
                             (project_id, username))

        proj_i.set_owner(user_i.id, read=read, write=write)

        for net_i in proj_i.networks:
            net_i.set_owner(user_i.id, read=read, write=write, share=share)
    db.DBSession.flush()


Instruction:
Explain what the following Python 3 code does
def set_network_permission(network_id, usernames, read, write, share,**kwargs):

    user_id = kwargs.get('user_id')

    net_i = _get_network(network_id)

    #Check if the user is allowed to share this network.
    net_i.check_share_permission(user_id)

    #You cannot edit something you cannot see.
    if read == 'N':
        write = 'N'
        share = 'N'

    for username in usernames:

        user_i = _get_user(username)

        #The creator of a network must always have read and write access
        #to their project
        if net_i.created_by == user_i.id:
            raise HydraError("Cannot set permissions on network %s"
                             " for user %s as tis user is the creator." %
                             (network_id, username))

        net_i.set_owner(user_i.id, read=read, write=write, share=share)
    db.DBSession.flush()

Response: Set permissions on a network to a list of users identifed by usernames.


Instruction:
Implement a function in Python 3 to
hide a particular piece of data by the specified user.

Response:
def hide_dataset(dataset_id, exceptions, read, write, share,**kwargs):
    """
        Hide a particular piece of data so it can only be seen by its owner.
        Only an owner can hide (and unhide) data.
        Data with no owner cannot be hidden.

        The exceptions paramater lists the usernames of those with permission to view the data
        read, write and share indicate whether these users can read, edit and share this data.
    """

    user_id = kwargs.get('user_id')
    dataset_i = _get_dataset(dataset_id)
    #check that I can hide the dataset
    if dataset_i.created_by != int(user_id):
        raise HydraError('Permission denied. '
                        'User %s is not the owner of dataset %s'
                        %(user_id, dataset_i.name))

    dataset_i.hidden = 'Y'
    if exceptions is not None:
        for username in exceptions:
            user_i = _get_user(username)
            dataset_i.set_owner(user_i.id, read=read, write=write, share=share)
    db.DBSession.flush()


Instruction:
Given the following Python 3 function, write the documentation
def unhide_dataset(dataset_id,**kwargs):

    user_id = kwargs.get('user_id')
    dataset_i = _get_dataset(dataset_id)
    #check that I can unhide the dataset
    if dataset_i.created_by != int(user_id):
        raise HydraError('Permission denied. '
                        'User %s is not the owner of dataset %s'
                        %(user_id, dataset_i.name))

    dataset_i.hidden = 'N'
    db.DBSession.flush()

Response: Unhide a particular piece of data from a dataset.


Instruction:
Write a Python 3 function for
getting the project owner entries for all the requested projects.

Response:
def get_all_project_owners(project_ids=None, **kwargs):
    """
        Get the project owner entries for all the requested projects.
        If the project_ids argument is None, return all the owner entries
        for ALL projects
    """

    projowner_qry = db.DBSession.query(ProjectOwner)

    if project_ids is not None:
       projowner_qry = projowner_qry.filter(ProjectOwner.project_id.in_(project_ids))

    project_owners_i = projowner_qry.all()

    return [JSONObject(project_owner_i) for project_owner_i in project_owners_i]


Instruction:
Explain what the following Python 3 code does
def get_all_network_owners(network_ids=None, **kwargs):

    networkowner_qry = db.DBSession.query(NetworkOwner)

    if network_ids is not None:
       networkowner_qry = networkowner_qry.filter(NetworkOwner.network_id.in_(network_ids))

    network_owners_i = networkowner_qry.all()

    return [JSONObject(network_owner_i) for network_owner_i in network_owners_i]

Response: Get the network owner entries for all the requested networks.


Instruction:
Write a Python 3 script for
bulking set the project owner of multiple projects at once.

Response:
def bulk_set_project_owners(project_owners, **kwargs):
    """
        Set the project owner of multiple projects at once.
        Accepts a list of JSONObjects which look like:
            {
             'project_id': XX,
             'user_id'   : YY,
             'view'      : 'Y'/ 'N'
             'edit'      : 'Y'/ 'N'
             'share'      : 'Y'/ 'N'
            }
           """

    project_ids = [po.project_id for po in project_owners]

    existing_projowners = db.DBSession.query(ProjectOwner).filter(ProjectOwner.project_id.in_(project_ids)).all()

    #Create a lookup based on the unique key for this table (project_id, user_id)
    po_lookup = {}

    for po in existing_projowners:
        po_lookup[(po.project_id, po.user_id)] = po

    for project_owner in project_owners:
        #check if the entry is already there
        if po_lookup.get((project_owner.project_id, project_owner.user_id)):
            continue

        new_po = ProjectOwner()
        new_po.project_id = project_owner.project_id
        new_po.user_id    = project_owner.user_id
        new_po.view       = project_owner.view
        new_po.edit       = project_owner.edit
        new_po.share      = project_owner.share

        db.DBSession.add(new_po)

    db.DBSession.flush()


Instruction:
Create a Python 3 function to
bulk set the network owner of multiple networks at once.

Response:
def bulk_set_network_owners(network_owners, **kwargs):
    """
        Set the network owner of multiple networks at once.
        Accepts a list of JSONObjects which look like:
            {
             'network_id': XX,
             'user_id'   : YY,
             'view'      : 'Y'/ 'N'
             'edit'      : 'Y'/ 'N'
             'share'      : 'Y'/ 'N'
            }
           """

    network_ids = [no.network_id for no in network_owners]

    existing_projowners = db.DBSession.query(NetworkOwner).filter(NetworkOwner.network_id.in_(network_ids)).all()

    #Create a lookup based on the unique key for this table (network_id, user_id)
    no_lookup = {}

    for no in existing_projowners:
        no_lookup[(no.network_id, no.user_id)] = no

    for network_owner in network_owners:
        #check if the entry is already there
        if no_lookup.get((network_owner.network_id, network_owner.user_id)):
            continue

        new_no = NetworkOwner()
        new_no.network_id = network_owner.network_id
        new_no.user_id    = network_owner.user_id
        new_no.view       = network_owner.view
        new_no.edit       = network_owner.edit
        new_no.share      = network_owner.share

        db.DBSession.add(new_no)

    db.DBSession.flush()


Instruction:
Can you create a Python 3 function that
gets a single dataset by ID.

Response:
def get_dataset(dataset_id,**kwargs):
    """
        Get a single dataset, by ID
    """

    user_id = int(kwargs.get('user_id'))

    if dataset_id is None:
        return None
    try:
        dataset_rs = db.DBSession.query(Dataset.id,
                Dataset.type,
                Dataset.unit_id,
                Dataset.name,
                Dataset.hidden,
                Dataset.cr_date,
                Dataset.created_by,
                DatasetOwner.user_id,
                null().label('metadata'),
                case([(and_(Dataset.hidden=='Y', DatasetOwner.user_id is not None), None)],
                        else_=Dataset.value).label('value')).filter(
                Dataset.id==dataset_id).outerjoin(DatasetOwner,
                                    and_(DatasetOwner.dataset_id==Dataset.id,
                                    DatasetOwner.user_id==user_id)).one()

        rs_dict = dataset_rs._asdict()

        #convert the value row into a string as it is returned as a binary
        if dataset_rs.value is not None:
            rs_dict['value'] = str(dataset_rs.value)

        if dataset_rs.hidden == 'N' or (dataset_rs.hidden == 'Y' and dataset_rs.user_id is not None):
            metadata = db.DBSession.query(Metadata).filter(Metadata.dataset_id==dataset_id).all()
            rs_dict['metadata'] = metadata
        else:
            rs_dict['metadata'] = []

    except NoResultFound:
        raise HydraError("Dataset %s does not exist."%(dataset_id))

    dataset = namedtuple('Dataset', rs_dict.keys())(**rs_dict)

    return dataset


Instruction:
Can you write a function in Python 3 where it
gets a single dataset by ID.

Response:
def clone_dataset(dataset_id,**kwargs):
    """
        Get a single dataset, by ID
    """

    user_id = int(kwargs.get('user_id'))

    if dataset_id is None:
        return None

    dataset = db.DBSession.query(Dataset).filter(
            Dataset.id==dataset_id).options(joinedload_all('metadata')).first()

    if dataset is None:
        raise HydraError("Dataset %s does not exist."%(dataset_id))

    if dataset is not None and dataset.created_by != user_id:
        owner = db.DBSession.query(DatasetOwner).filter(
                                DatasetOwner.dataset_id==Dataset.id,
                                DatasetOwner.user_id==user_id).first()
        if owner is None:
            raise PermissionError("User %s is not an owner of dataset %s and therefore cannot clone it."%(user_id, dataset_id))

    db.DBSession.expunge(dataset)

    make_transient(dataset)

    dataset.name = dataset.name + "(Clone)"
    dataset.id = None
    dataset.cr_date = None

    #Try to avoid duplicate metadata entries if the entry has been cloned previously
    for m in dataset.metadata:
        if m.key in ("clone_of", "cloned_by"):
            del(m)

    cloned_meta = Metadata()
    cloned_meta.key = "clone_of"
    cloned_meta.value  = str(dataset_id)
    dataset.metadata.append(cloned_meta)
    cloned_meta = Metadata()
    cloned_meta.key = "cloned_by"
    cloned_meta.value  = str(user_id)
    dataset.metadata.append(cloned_meta)

    dataset.set_hash()
    db.DBSession.add(dataset)
    db.DBSession.flush()

    cloned_dataset = db.DBSession.query(Dataset).filter(
            Dataset.id==dataset.id).first()

    return cloned_dataset


Instruction:
Write a Python 3 function for
getting a list of datasets by ID.

Response:
def get_datasets(dataset_ids,**kwargs):
    """
        Get a single dataset, by ID
    """

    user_id = int(kwargs.get('user_id'))
    datasets = []
    if len(dataset_ids) == 0:
        return []
    try:
        dataset_rs = db.DBSession.query(Dataset.id,
                Dataset.type,
                Dataset.unit_id,
                Dataset.name,
                Dataset.hidden,
                Dataset.cr_date,
                Dataset.created_by,
                DatasetOwner.user_id,
                null().label('metadata'),
                case([(and_(Dataset.hidden=='Y', DatasetOwner.user_id is not None), None)],
                        else_=Dataset.value).label('value')).filter(
                Dataset.id.in_(dataset_ids)).outerjoin(DatasetOwner,
                                    and_(DatasetOwner.dataset_id==Dataset.id,
                                    DatasetOwner.user_id==user_id)).all()

        #convert the value row into a string as it is returned as a binary
        for dataset_row in dataset_rs:
            dataset_dict = dataset_row._asdict()

            if dataset_row.value is not None:
                dataset_dict['value'] = str(dataset_row.value)

            if dataset_row.hidden == 'N' or (dataset_row.hidden == 'Y' and dataset_row.user_id is not None):
                metadata = db.DBSession.query(Metadata).filter(Metadata.dataset_id == dataset_row.id).all()
                dataset_dict['metadata'] = metadata
            else:
                dataset_dict['metadata'] = []

            datasets.append(namedtuple('Dataset', dataset_dict.keys())(**dataset_dict))

    except NoResultFound:
        raise ResourceNotFoundError("Datasets not found.")

    return datasets