Instruction:
Make a summary of the following Python 3 code
def energy(context, features):
    fritz = context.obj
    fritz.login()

    for actor in fritz.get_actors():
        if actor.temperature is not None:
            click.echo("{} ({}): {:.2f} Watt current, {:.3f} wH total, {:.2f} °C".format(
                actor.name.encode('utf-8'),
                actor.actor_id,
                (actor.get_power() or 0.0) / 1000,
                (actor.get_energy() or 0.0) / 100,
                actor.temperature
            ))
        else:
            click.echo("{} ({}): {:.2f} Watt current, {:.3f} wH total, offline".format(
                actor.name.encode('utf-8'),
                actor.actor_id,
                (actor.get_power() or 0.0) / 1000,
                (actor.get_energy() or 0.0) / 100
            ))
        if features:
            click.echo("  Features: PowerMeter: {}, Temperatur: {}, Switch: {}".format(
                actor.has_powermeter, actor.has_temperature, actor.has_switch
            ))

Response: Display energy stats of all actors


Instruction:
Implement a function in Python 3 to
connect to a carbon server and display statistics of all actors and actors in a single node.

Response:
def graphite(context, server, port, interval, prefix):
    """Display energy stats of all actors"""
    fritz = context.obj
    fritz.login()
    sid_ttl = time.time() + 600

    # Find actors and create carbon keys
    click.echo(" * Requesting actors list")
    simple_chars = re.compile('[^A-Za-z0-9]+')
    actors = fritz.get_actors()
    keys = {}
    for actor in actors:
        keys[actor.name] = "{}.{}".format(
            prefix,
            simple_chars.sub('_', actor.name)
        )

    # Connect to carbon
    click.echo(" * Trying to connect to carbon")
    timeout = 2
    sock = socket.socket()
    sock.settimeout(timeout)
    try:
        sock.connect((server, port))
    except socket.timeout:
        raise Exception("Took over {} second(s) to connect to {}".format(
            timeout, server
        ))
    except Exception as error:
        raise Exception("unknown exception while connecting to {} - {}".format(
            server, error
        ))

    def send(key, value):
        """Send a key-value-pair to carbon"""
        now = int(time.time())
        payload = "{} {} {}\n".format(key, value, now)
        sock.sendall(payload)

    while True:
        if time.time() > sid_ttl:
            click.echo(" * Requesting new SID")
            fritz.login()
            sid_ttl = time.time() + 600

        click.echo(" * Requesting statistics")
        for actor in actors:
            power = actor.get_power()
            total = actor.get_energy()
            click.echo("   -> {}: {:.2f} Watt current, {:.3f} wH total".format(
                actor.name, power / 1000, total / 100
            ))

            send(keys[actor.name] + '.current', power)
            send(keys[actor.name] + '.total', total)

        time.sleep(interval)


Instruction:
How would you explain what the following Python 3 function does
def switch_on(context, ain):
    context.obj.login()
    actor = context.obj.get_actor_by_ain(ain)
    if actor:
        click.echo("Switching {} on".format(actor.name))
        actor.switch_on()
    else:
        click.echo("Actor not found: {}".format(ain))

Response: Switch an actor s power to ON


Instruction:
Write a Python 3 script to
switch the state of an actor

Response:
def switch_state(context, ain):
    """Get an actor's power state"""
    context.obj.login()
    actor = context.obj.get_actor_by_ain(ain)
    if actor:
        click.echo("State for {} is: {}".format(ain,'ON' if actor.get_state() else 'OFF'))
    else:
        click.echo("Actor not found: {}".format(ain))


Instruction:
Make a summary of the following Python 3 code
def switch_toggle(context, ain):
    context.obj.login()
    actor = context.obj.get_actor_by_ain(ain)
    if actor:
        if actor.get_state():
            actor.switch_off()
            click.echo("State for {} is now OFF".format(ain))
        else:
            actor.switch_on()
            click.echo("State for {} is now ON".format(ain))
    else:
        click.echo("Actor not found: {}".format(ain))

Response: Toggle an actor s power state


Instruction:
How would you implement a function in Python 3 that
shows system logs since last reboot

Response:
def logs(context, format):
    """Show system logs since last reboot"""
    fritz = context.obj
    fritz.login()

    messages = fritz.get_logs()
    if format == "plain":
        for msg in messages:
            merged = "{} {} {}".format(msg.date, msg.time, msg.message.encode("UTF-8"))
            click.echo(merged)

    if format == "json":
        entries = [msg._asdict() for msg in messages]
        click.echo(json.dumps({
            "entries": entries,
        }))


Instruction:
Can you write a function in Python 3 where it
returns the current power usage in milliWatts.

Response:
def get_power(self):
        """
        Returns the current power usage in milliWatts.
        Attention: Returns None if the value can't be queried or is unknown.
        """
        value = self.box.homeautoswitch("getswitchpower", self.actor_id)
        return int(value) if value.isdigit() else None


Instruction:
How would you explain what the following Python 3 function does
def get_energy(self):
        value = self.box.homeautoswitch("getswitchenergy", self.actor_id)
        return int(value) if value.isdigit() else None

Response: Returns the consumed energy since the start of the statistics in Wh.


Instruction:
Can you generate the documentation for the following Python 3 function
def get_temperature(self):
        #raise NotImplementedError("This should work according to the AVM docs, but don't...")
        value = self.box.homeautoswitch("gettemperature", self.actor_id)
        if value.isdigit():
            self.temperature = float(value)/10
        else:
            self.temperature = None
        return self.temperature

Response: Returns the current environment temperature.


Instruction:
Create a Python 3 function for
returning the actual target temperature.

Response:
def get_target_temperature(self):
        """
        Returns the actual target temperature.
        Attention: Returns None if the value can't be queried or is unknown.
        """
        value = self.box.homeautoswitch("gethkrtsoll", self.actor_id)
        self.target_temperature = self.__get_temp(value)
        return self.target_temperature


Instruction:
How would you explain what the following Python 3 function does
def set_temperature(self, temp):

        # Temperature is send to fritz.box a little weird
        param = 16 + ( ( temp - 8 ) * 2 )
        if param < 16:
            param = 253
            logger.info("Actor " + self.name + ": Temperature control set to off")
        elif param >= 56:
            param = 254
            logger.info("Actor " + self.name + ": Temperature control set to on")
        else:
            logger.info("Actor " + self.name + ": Temperature control set to " + str(temp))

        return self.box.homeautoswitch("sethkrtsoll", self.actor_id, param)

Response: Sets the temperature in celcius


Instruction:
Can you generate the documentation for the following Python 3 function
def get_openshift_base_uri(self):
        deprecated_key = "openshift_uri"
        key = "openshift_url"
        val = self._get_value(deprecated_key, self.conf_section, deprecated_key)
        if val is not None:
            warnings.warn("%r is deprecated, use %r instead" % (deprecated_key, key))
            return val
        return self._get_value(key, self.conf_section, key)

Response: Get the OpenShift base URI from the configuration file.


Instruction:
How would you explain what the following Python 3 function does
def get_builder_openshift_url(self):
        key = "builder_openshift_url"
        url = self._get_deprecated(key, self.conf_section, key)
        if url is None:
            logger.warning("%r not found, falling back to get_openshift_base_uri()", key)
            url = self.get_openshift_base_uri()
        return url

Response: url of OpenShift where builder will connect


Instruction:
Can you tell what is the following Python 3 function doing
def generate_nodeselector_dict(self, nodeselector_str):
        nodeselector = {}
        if nodeselector_str and nodeselector_str != 'none':
            constraints = [x.strip() for x in nodeselector_str.split(',')]
            raw_nodeselector = dict([constraint.split('=', 1) for constraint in constraints])
            nodeselector = dict([k.strip(), v.strip()] for (k, v) in raw_nodeselector.items())

        return nodeselector

Response: helper method for generating nodeselector dict


Instruction:
Make a summary of the following Python 3 code
def get_platform_node_selector(self, platform):
        nodeselector = {}
        if platform:
            nodeselector_str = self._get_value("node_selector." + platform, self.conf_section,
                                               "node_selector." + platform)
            nodeselector = self.generate_nodeselector_dict(nodeselector_str)

        return nodeselector

Response: search the configuration for entries of the form node_selector. platform


Instruction:
Can you tell what is the following Python 3 function doing
def load(self):

        self._validate()
        self._logger.logging_load()
        self.encoding = get_file_encoding(self.source, self.encoding)

        if six.PY3:
            self._csv_reader = csv.reader(
                io.open(self.source, "r", encoding=self.encoding),
                delimiter=self.delimiter,
                quotechar=self.quotechar,
                strict=True,
                skipinitialspace=True,
            )
        else:
            self._csv_reader = csv.reader(
                _utf_8_encoder(io.open(self.source, "r", encoding=self.encoding)),
                delimiter=self.delimiter,
                quotechar=self.quotechar,
                strict=True,
                skipinitialspace=True,
            )

        formatter = CsvTableFormatter(self._to_data_matrix())
        formatter.accept(self)

        return formatter.to_table_data()

Response: Loads the table data from a CSV file.


Instruction:
How would you implement a function in Python 3 that
loads the table data from a CSV file.

Response:
def load(self):
        """
        Extract tabular data as |TableData| instances from a CSV text object.
        |load_source_desc_text|

        :return:
            Loaded table data.
            |load_table_name_desc|

            ===================  ========================================
            Format specifier     Value after the replacement
            ===================  ========================================
            ``%(filename)s``     ``""``
            ``%(format_name)s``  ``"csv"``
            ``%(format_id)s``    |format_id_desc|
            ``%(global_id)s``    |global_id|
            ===================  ========================================
        :rtype: |TableData| iterator
        :raises pytablereader.DataError:
            If the CSV data is invalid.

        .. seealso::
            :py:func:`csv.reader`
        """

        self._validate()
        self._logger.logging_load()

        self._csv_reader = csv.reader(
            six.StringIO(self.source.strip()),
            delimiter=self.delimiter,
            quotechar=self.quotechar,
            strict=True,
            skipinitialspace=True,
        )
        formatter = CsvTableFormatter(self._to_data_matrix())
        formatter.accept(self)

        return formatter.to_table_data()


Instruction:
Can you write a function in Python 3 where it
sets parameters according to specification

Response:
def set_params(self, **kwargs):
        """
        set parameters according to specification

        these parameters are accepted:

        :param pulp_secret: str, resource name of pulp secret
        :param koji_target: str, koji tag with packages used to build the image
        :param kojiroot: str, URL from which koji packages are fetched
        :param kojihub: str, URL of the koji hub
        :param koji_certs_secret: str, resource name of secret that holds the koji certificates
        :param koji_task_id: int, Koji Task that created this build config
        :param flatpak: if we should build a Flatpak OCI Image
        :param filesystem_koji_task_id: int, Koji Task that created the base filesystem
        :param pulp_registry: str, name of pulp registry in dockpulp.conf
        :param sources_command: str, command used to fetch dist-git sources
        :param architecture: str, architecture we are building for
        :param vendor: str, vendor name
        :param build_host: str, host the build will run on or None for auto
        :param authoritative_registry: str, the docker registry authoritative for this image
        :param distribution_scope: str, distribution scope for this image
                                   (private, authoritative-source-only, restricted, public)
        :param use_auth: bool, use auth from atomic-reactor?
        :param platform_node_selector: dict, a nodeselector for a specific platform
        :param platform_descriptors: dict, platforms and their archiectures and enable_v1 settings
        :param scratch_build_node_selector: dict, a nodeselector for scratch builds
        :param explicit_build_node_selector: dict, a nodeselector for explicit builds
        :param auto_build_node_selector: dict, a nodeselector for auto builds
        :param isolated_build_node_selector: dict, a nodeselector for isolated builds
        :param is_auto: bool, indicates if build is auto build
        :param parent_images_digests: dict, mapping image names with tags to platform specific
                                      digests, example:
                                      {'registry.fedorahosted.org/fedora:29': {
                                          x86_64': 'registry.fedorahosted.org/fedora@sha256:....'}
                                      }
        """

        # Here we cater to the koji "scratch" build type, this will disable
        # all plugins that might cause importing of data to koji
        self.scratch = kwargs.pop('scratch', False)
        # When true, it indicates build was automatically started by
        # OpenShift via a trigger, for instance ImageChangeTrigger
        self.is_auto = kwargs.pop('is_auto', False)
        # An isolated build is meant to patch a certain release and not
        # update transient tags in container registry
        self.isolated = kwargs.pop('isolated', False)

        self.validate_build_variation()

        self.base_image = kwargs.get('base_image')
        self.platform_node_selector = kwargs.get('platform_node_selector', {})
        self.platform_descriptors = kwargs.get('platform_descriptors', {})
        self.scratch_build_node_selector = kwargs.get('scratch_build_node_selector', {})
        self.explicit_build_node_selector = kwargs.get('explicit_build_node_selector', {})
        self.auto_build_node_selector = kwargs.get('auto_build_node_selector', {})
        self.isolated_build_node_selector = kwargs.get('isolated_build_node_selector', {})

        logger.debug("setting params '%s' for %s", kwargs, self.spec)
        self.spec.set_params(**kwargs)
        self.osbs_api = kwargs.pop('osbs_api')


Instruction:
Can you tell what is the following Python 3 function doing
def has_ist_trigger(self):
        triggers = self.template['spec'].get('triggers', [])
        if not triggers:
            return False
        for trigger in triggers:
            if trigger['type'] == 'ImageChange' and \
                    trigger['imageChange']['from']['kind'] == 'ImageStreamTag':
                return True
        return False

Response: Return True if this BuildConfig has ImageStreamTag trigger.


Instruction:
Explain what the following Python 3 code does
def set_secret_for_plugin(self, secret, plugin=None, mount_path=None):
        has_plugin_conf = False
        if plugin is not None:
            has_plugin_conf = self.dj.dock_json_has_plugin_conf(plugin[0],
                                                                plugin[1])
        if 'secrets' in self.template['spec']['strategy']['customStrategy']:
            if not plugin or has_plugin_conf:

                custom = self.template['spec']['strategy']['customStrategy']
                if mount_path:
                    secret_path = mount_path
                else:
                    secret_path = os.path.join(SECRETS_PATH, secret)

                logger.info("Configuring %s secret at %s", secret, secret_path)
                existing = [secret_mount for secret_mount in custom['secrets']
                            if secret_mount['secretSource']['name'] == secret]
                if existing:
                    logger.debug("secret %s already set", secret)
                else:
                    custom['secrets'].append({
                        'secretSource': {
                            'name': secret,
                        },
                        'mountPath': secret_path,
                    })

                # there's no need to set args if no plugin secret specified
                # this is used in tag_and_push plugin, as it sets secret path
                # for each registry separately
                if plugin and plugin[2] is not None:
                    self.dj.dock_json_set_arg(*(plugin + (secret_path,)))
            else:
                logger.debug("not setting secret for unused plugin %s",
                             plugin[1])

Response: Sets secret for a specific plugin


Instruction:
Can you generate a brief explanation for the following Python 3 code
def set_secrets(self, secrets):
        secret_set = False
        for (plugin, secret) in secrets.items():
            if not isinstance(plugin, tuple) or len(plugin) != 3:
                raise ValueError('got "%s" as secrets key, need 3-tuple' % plugin)
            if secret is not None:
                if isinstance(secret, list):
                    for secret_item in secret:
                        self.set_secret_for_plugin(secret_item, plugin=plugin)
                else:
                    self.set_secret_for_plugin(secret, plugin=plugin)
                secret_set = True

        if not secret_set:
            # remove references to secret if no secret was set
            if 'secrets' in self.template['spec']['strategy']['customStrategy']:
                del self.template['spec']['strategy']['customStrategy']['secrets']

Response: Sets the secrets for the current instance of the class.


Instruction:
Explain what the following Python 3 code does
def remove_tag_and_push_registries(tag_and_push_registries, version):
        registries = [uri
                      for uri, regdict in tag_and_push_registries.items()
                      if regdict['version'] == version]
        for registry in registries:
            logger.info("removing %s registry: %s", version, registry)
            del tag_and_push_registries[registry]

Response: Remove matching entries from tag_and_push_registries.


Instruction:
Write a Python 3 script to
adjust the internal state of the registry API versions based on the supported registry API versions.

Response:
def adjust_for_registry_api_versions(self):
        """
        Enable/disable plugins depending on supported registry API versions
        """
        versions = self.spec.registry_api_versions.value

        if 'v2' not in versions:
            raise OsbsValidationException('v1-only docker registry API is not supported')

        try:
            push_conf = self.dj.dock_json_get_plugin_conf('postbuild_plugins',
                                                          'tag_and_push')
            tag_and_push_registries = push_conf['args']['registries']
        except (KeyError, IndexError):
            tag_and_push_registries = {}

        if 'v1' not in versions:
            # Remove v1-only plugins
            for phase, name in [('postbuild_plugins', 'pulp_push')]:
                logger.info("removing v1-only plugin: %s", name)
                self.dj.remove_plugin(phase, name)

            # remove extra tag_and_push config
            self.remove_tag_and_push_registries(tag_and_push_registries, 'v1')

        # Remove 'version' from tag_and_push plugin config as it's no
        # longer needed
        for regdict in tag_and_push_registries.values():
            if 'version' in regdict:
                del regdict['version']


Instruction:
Create a Python 3 function to
remove trigger - related plugins when needed

Response:
def adjust_for_triggers(self):
        """Remove trigger-related plugins when needed

        If there are no triggers defined, it's assumed the
        feature is disabled and all trigger-related plugins
        are removed.

        If there are triggers defined, and this is a custom
        base image, some trigger-related plugins do not apply.

        Additionally, this method ensures that custom base
        images never have triggers since triggering a base
        image rebuild is not a valid scenario.
        """
        triggers = self.template['spec'].get('triggers', [])

        remove_plugins = [
            ("prebuild_plugins", "check_and_set_rebuild"),
            ("prebuild_plugins", "stop_autorebuild_if_disabled"),
        ]

        should_remove = False
        if triggers and (self.is_custom_base_image() or self.is_from_scratch_image()):
            if self.is_custom_base_image():
                msg = "removing %s from request because custom base image"
            elif self.is_from_scratch_image():
                msg = 'removing %s from request because FROM scratch image'
            del self.template['spec']['triggers']
            should_remove = True

        elif not triggers:
            msg = "removing %s from request because there are no triggers"
            should_remove = True

        if should_remove:
            for when, which in remove_plugins:
                logger.info(msg, which)
                self.dj.remove_plugin(when, which)


Instruction:
Can you write a function in Python 3 where it
adjusts the metadata for scratch builds.

Response:
def adjust_for_scratch(self):
        """
        Remove certain plugins in order to handle the "scratch build"
        scenario. Scratch builds must not affect subsequent builds,
        and should not be imported into Koji.
        """
        if self.scratch:
            self.template['spec'].pop('triggers', None)

            remove_plugins = [
                ("prebuild_plugins", "koji_parent"),
                ("postbuild_plugins", "compress"),  # required only to make an archive for Koji
                ("postbuild_plugins", "pulp_pull"),  # required only to make an archive for Koji
                ("postbuild_plugins", "koji_upload"),
                ("postbuild_plugins", "fetch_worker_metadata"),
                ("postbuild_plugins", "compare_components"),
                ("postbuild_plugins", "import_image"),
                ("exit_plugins", "koji_promote"),
                ("exit_plugins", "koji_import"),
                ("exit_plugins", "koji_tag_build"),
                ("exit_plugins", "remove_worker_metadata"),
                ("exit_plugins", "import_image"),
            ]

            if not self.has_tag_suffixes_placeholder():
                remove_plugins.append(("postbuild_plugins", "tag_from_config"))

            for when, which in remove_plugins:
                logger.info("removing %s from scratch build request",
                            which)
                self.dj.remove_plugin(when, which)

            if self.dj.dock_json_has_plugin_conf('postbuild_plugins',
                                                 'tag_by_labels'):
                self.dj.dock_json_set_arg('postbuild_plugins', 'tag_by_labels',
                                          'unique_tag_only', True)

            self.set_label('scratch', 'true')


Instruction:
Can you tell what is the following Python 3 function doing
def adjust_for_custom_base_image(self):
        plugins = []
        if self.is_custom_base_image():
            # Plugins irrelevant to building base images.
            plugins.append(("prebuild_plugins", "pull_base_image"))
            plugins.append(("prebuild_plugins", "koji_parent"))
            plugins.append(("prebuild_plugins", "inject_parent_image"))
            msg = "removing %s from custom image build request"
        else:
            # Plugins not needed for building non base images.
            plugins.append(("prebuild_plugins", "add_filesystem"))
            msg = "removing %s from non custom image build request"

        for when, which in plugins:
            logger.info(msg, which)
            self.dj.remove_plugin(when, which)

Response: Disable plugins to handle builds depending on whether this is a custom base image.


Instruction:
How would you explain what the following Python 3 function does
def render_koji(self):
        phase = 'prebuild_plugins'
        plugin = 'koji'
        if not self.dj.dock_json_has_plugin_conf(phase, plugin):
            return

        if self.spec.yum_repourls.value:
            logger.info("removing koji from request "
                        "because there is yum repo specified")
            self.dj.remove_plugin(phase, plugin)
        elif not (self.spec.koji_target.value and
                  self.spec.kojiroot.value and
                  self.spec.kojihub.value):
            logger.info("removing koji from request as not specified")
            self.dj.remove_plugin(phase, plugin)
        else:
            self.dj.dock_json_set_arg(phase, plugin,
                                      "target", self.spec.koji_target.value)
            self.dj.dock_json_set_arg(phase, plugin,
                                      "root", self.spec.kojiroot.value)
            self.dj.dock_json_set_arg(phase, plugin,
                                      "hub", self.spec.kojihub.value)
            if self.spec.proxy.value:
                self.dj.dock_json_set_arg(phase, plugin,
                                          "proxy", self.spec.proxy.value)

Response: Render koji from yum repo if yum repo is specified.


Instruction:
Can you tell what is the following Python 3 function doing
def render_bump_release(self):
        phase = 'prebuild_plugins'
        plugin = 'bump_release'
        if not self.dj.dock_json_has_plugin_conf(phase, plugin):
            return

        if self.spec.release.value:
            logger.info('removing %s from request as release already specified',
                        plugin)
            self.dj.remove_plugin(phase, plugin)
            return

        hub = self.spec.kojihub.value
        if not hub:
            logger.info('removing %s from request as koji hub not specified',
                        plugin)
            self.dj.remove_plugin(phase, plugin)
            return

        self.dj.dock_json_set_arg(phase, plugin, 'hub', hub)

        # For flatpak, we want a name-version-release of
        # <name>-<stream>-<module_build_version>.<n>, where the .<n> makes
        # sure that the build is unique in Koji
        if self.spec.flatpak.value:
            self.dj.dock_json_set_arg(phase, plugin, 'append', True)

Response: If the bump_release plugin is present, configure it


Instruction:
Here you have a function in Python 3, explain what it does
def render_pulp_pull(self):
        # pulp_pull is a multi-phase plugin
        phases = ('postbuild_plugins', 'exit_plugins')
        plugin = 'pulp_pull'
        for phase in phases:
            if not self.dj.dock_json_has_plugin_conf(phase, plugin):
                continue

            pulp_registry = self.spec.pulp_registry.value
            if not pulp_registry:
                logger.info("removing %s from request, requires pulp_registry", pulp_registry)
                self.dj.remove_plugin(phase, plugin)
                continue

            if not self.spec.kojihub.value:
                logger.info('Removing %s because no kojihub was specified', plugin)
                self.dj.remove_plugin(phase, plugin)
                continue

            if self.spec.prefer_schema1_digest.value is not None:
                self.dj.dock_json_set_arg(phase, 'pulp_pull',
                                          'expect_v2schema2',
                                          not self.spec.prefer_schema1_digest.value)

Response: Render the pulp pull request.


Instruction:
Implement a Python 3 function for
rendering the pulp sync plugin.

Response:
def render_pulp_sync(self):
        """
        If a pulp registry is specified, use the pulp plugin as well as the
        delete_from_registry to delete the image after sync
        """
        if not self.dj.dock_json_has_plugin_conf('postbuild_plugins',
                                                 'pulp_sync'):
            return

        pulp_registry = self.spec.pulp_registry.value

        # Find which registry to use
        docker_registry = None
        registry_secret = None
        registries = zip_longest(self.spec.registry_uris.value,
                                 self.spec.registry_secrets.value)
        for registry, secret in registries:
            if registry.version == 'v2':
                # First specified v2 registry is the one we'll tell pulp
                # to sync from. Keep the http prefix -- pulp wants it.
                docker_registry = registry.uri
                registry_secret = secret
                logger.info("using docker v2 registry %s for pulp_sync",
                            docker_registry)
                break

        if pulp_registry and docker_registry:
            self.dj.dock_json_set_arg('postbuild_plugins', 'pulp_sync',
                                      'pulp_registry_name', pulp_registry)

            self.dj.dock_json_set_arg('postbuild_plugins', 'pulp_sync',
                                      'docker_registry', docker_registry)

            if registry_secret:
                self.set_secret_for_plugin(registry_secret,
                                           plugin=('postbuild_plugins',
                                                   'pulp_sync',
                                                   'registry_secret_path'))

            # Verify we have a pulp secret
            if self.spec.pulp_secret.value is None:
                raise OsbsValidationException("Pulp registry specified "
                                              "but no auth config")

            source_registry = self.spec.source_registry_uri.value
            perform_delete = (source_registry is None or
                              source_registry.docker_uri != registry.docker_uri)
            if perform_delete:
                push_conf = self.dj.dock_json_get_plugin_conf('exit_plugins',
                                                              'delete_from_registry')
                args = push_conf.setdefault('args', {})
                delete_registries = args.setdefault('registries', {})
                placeholder = '{{REGISTRY_URI}}'

                # use passed in params like 'insecure' if available
                if placeholder in delete_registries:
                    regdict = delete_registries[placeholder].copy()
                    del delete_registries[placeholder]
                else:
                    regdict = {}

                if registry_secret:
                    regdict['secret'] = \
                        os.path.join(SECRETS_PATH, registry_secret)
                    # tag_and_push configured the registry secret, no neet to set it again

                delete_registries[docker_registry] = regdict

                self.dj.dock_json_set_arg('exit_plugins', 'delete_from_registry',
                                          'registries', delete_registries)
            else:
                logger.info("removing delete_from_registry from request, "
                            "source and target registry are identical")
                self.dj.remove_plugin("exit_plugins", "delete_from_registry")
        else:
            # If no pulp registry is specified, don't run the pulp plugin
            logger.info("removing pulp_sync+delete_from_registry from request, "
                        "requires pulp_registry and a v2 registry")
            self.dj.remove_plugin("postbuild_plugins", "pulp_sync")
            self.dj.remove_plugin("exit_plugins", "delete_from_registry")


Instruction:
Write a Python 3 script for
rendering the pulp_tag plugin.

Response:
def render_pulp_tag(self):
        """
        Configure the pulp_tag plugin.
        """
        if not self.dj.dock_json_has_plugin_conf('postbuild_plugins',
                                                 'pulp_tag'):
            return

        pulp_registry = self.spec.pulp_registry.value
        if pulp_registry:
            self.dj.dock_json_set_arg('postbuild_plugins', 'pulp_tag',
                                      'pulp_registry_name', pulp_registry)

            # Verify we have either a secret or username/password
            if self.spec.pulp_secret.value is None:
                conf = self.dj.dock_json_get_plugin_conf('postbuild_plugins',
                                                         'pulp_tag')
                args = conf.get('args', {})
                if 'username' not in args:
                    raise OsbsValidationException("Pulp registry specified "
                                                  "but no auth config")
        else:
            # If no pulp registry is specified, don't run the pulp plugin
            logger.info("removing pulp_tag from request, "
                        "requires pulp_registry")
            self.dj.remove_plugin("postbuild_plugins", "pulp_tag")


Instruction:
How would you code a function in Python 3 to
render the group_manifests plugin.

Response:
def render_group_manifests(self):
        """
        Configure the group_manifests plugin. Group is always set to false for now.
        """
        if not self.dj.dock_json_has_plugin_conf('postbuild_plugins', 'group_manifests'):
            return

        push_conf = self.dj.dock_json_get_plugin_conf('postbuild_plugins',
                                                      'group_manifests')
        args = push_conf.setdefault('args', {})
        # modify registries in place
        registries = args.setdefault('registries', {})
        placeholder = '{{REGISTRY_URI}}'

        if placeholder in registries:
            for registry, secret in zip_longest(self.spec.registry_uris.value,
                                                self.spec.registry_secrets.value):
                if not registry.uri:
                    continue
                regdict = registries[placeholder].copy()
                regdict['version'] = registry.version
                if secret:
                    regdict['secret'] = os.path.join(SECRETS_PATH, secret)
                registries[registry.docker_uri] = regdict
            del registries[placeholder]

        self.dj.dock_json_set_arg('postbuild_plugins', 'group_manifests',
                                  'group', self.spec.group_manifests.value)
        goarch = {}
        for platform, architecture in self.platform_descriptors.items():
            goarch[platform] = architecture['architecture']
        self.dj.dock_json_set_arg('postbuild_plugins', 'group_manifests',
                                  'goarch', goarch)


Instruction:
Can you generate the documentation for the following Python 3 function
def render_import_image(self, use_auth=None):
        # import_image is a multi-phase plugin
        phases = ('postbuild_plugins', 'exit_plugins')
        plugin = 'import_image'

        for phase in phases:
            if self.spec.imagestream_name.value is None or self.spec.imagestream_url.value is None:
                logger.info("removing %s from request, "
                            "registry or repo url is not defined", plugin)
                self.dj.remove_plugin(phase, plugin)
                continue

            if self.dj.dock_json_has_plugin_conf(phase, plugin):
                self.dj.dock_json_set_arg(phase, plugin, 'imagestream',
                                          self.spec.imagestream_name.value)
                self.dj.dock_json_set_arg(phase, plugin, 'docker_image_repo',
                                          self.spec.imagestream_url.value)
                self.dj.dock_json_set_arg(phase, plugin, 'url',
                                          self.spec.builder_openshift_url.value)
                self.dj.dock_json_set_arg(phase, plugin, 'build_json_dir',
                                          self.spec.builder_build_json_dir.value)

                use_auth = self.spec.use_auth.value
                if use_auth is not None:
                    self.dj.dock_json_set_arg(phase, plugin, 'use_auth', use_auth)

                if self.spec.imagestream_insecure_registry.value:
                    self.dj.dock_json_set_arg(phase, plugin, 'insecure_registry', True)

Response: Configure the import_image plugin


Instruction:
Can you write a function in Python 3 where it
renders site - specific customizations.

Response:
def render_customizations(self):
        """
        Customize prod_inner for site specific customizations
        """

        disable_plugins = self.customize_conf.get('disable_plugins', [])
        if not disable_plugins:
            logger.debug("No site-specific plugins to disable")
        else:
            for plugin_dict in disable_plugins:
                try:
                    self.dj.remove_plugin(
                        plugin_dict['plugin_type'],
                        plugin_dict['plugin_name']
                    )
                    logger.debug(
                        "site-specific plugin disabled -> Type:{} Name:{}".format(
                            plugin_dict['plugin_type'],
                            plugin_dict['plugin_name']
                        )
                    )
                except KeyError:
                    # Malformed config
                    logger.debug("Invalid custom configuration found for disable_plugins")

        enable_plugins = self.customize_conf.get('enable_plugins', [])
        if not enable_plugins:
            logger.debug("No site-specific plugins to enable")
        else:
            for plugin_dict in enable_plugins:
                try:
                    self.dj.add_plugin(
                        plugin_dict['plugin_type'],
                        plugin_dict['plugin_name'],
                        plugin_dict['plugin_args']
                    )
                    logger.debug(
                        "site-specific plugin enabled -> Type:{} Name:{} Args: {}".format(
                            plugin_dict['plugin_type'],
                            plugin_dict['plugin_name'],
                            plugin_dict['plugin_args']
                        )
                    )
                except KeyError:
                    # Malformed config
                    logger.debug("Invalid custom configuration found for enable_plugins")


Instruction:
How would you code a function in Python 3 to
set the Build / BuildConfig object name

Response:
def render_name(self, name, image_tag, platform):
        """Sets the Build/BuildConfig object name"""

        if self.scratch or self.isolated:
            name = image_tag
            # Platform name may contain characters not allowed by OpenShift.
            if platform:
                platform_suffix = '-{}'.format(platform)
                if name.endswith(platform_suffix):
                    name = name[:-len(platform_suffix)]

            _, salt, timestamp = name.rsplit('-', 2)

            if self.scratch:
                name = 'scratch-{}-{}'.format(salt, timestamp)
            elif self.isolated:
                name = 'isolated-{}-{}'.format(salt, timestamp)

        # !IMPORTANT! can't be too long: https://github.com/openshift/origin/issues/733
        self.template['metadata']['name'] = name


Instruction:
Explain what the following Python 3 code does
def get_terminal_size():
    try:
        rows, columns = subprocess.check_output(['stty', 'size']).split()
    except subprocess.CalledProcessError:
        # not attached to terminal
        logger.info("not attached to terminal")
        return 0, 0
    logger.debug("console size is %s %s", rows, columns)
    return int(rows), int(columns)

Response: get size of console


Instruction:
Write a Python 3 script to
get size of longest value in specific column

Response:
def _longest_val_in_column(self, col):
        """
        get size of longest value in specific column

        :param col: str, column name
        :return int
        """
        try:
            # +2 is for implicit separator
            return max([len(x[col]) for x in self.table if x[col]]) + 2
        except KeyError:
            logger.error("there is no column %r", col)
            raise


Instruction:
Create a Python 3 function to
initialize all values based on input .

Response:
def _init(self):
        """
        initialize all values based on provided input

        :return: None
        """
        self.col_count = len(self.col_list)
        # list of lengths of longest entries in columns
        self.col_longest = self.get_all_longest_col_lengths()
        self.data_length = sum(self.col_longest.values())

        if self.terminal_width > 0:
            # free space is space which should be equeally distributed for all columns
            # self.terminal_width -- terminal is our canvas
            #  - self.data_length -- substract length of content (the actual data)
            #  - self.col_count + 1 -- table lines are not part of free space, their width is
            #                          (number of columns - 1)
            self.total_free_space = (self.terminal_width - self.data_length) - self.col_count + 1
            if self.total_free_space <= 0:
                self.total_free_space = None
            else:
                self.default_column_space = self.total_free_space // self.col_count
                self.default_column_space_remainder = self.total_free_space % self.col_count
                logger.debug("total free space: %d, column space: %d, remainder: %d, columns: %d",
                             self.total_free_space, self.default_column_space,
                             self.default_column_space_remainder, self.col_count)
        else:
            self.total_free_space = None


Instruction:
Here you have a function in Python 3, explain what it does
def _count_sizes(self):
        format_list = []
        header_sepa_format_list = []
        # actual widths of columns
        self.col_widths = {}

        for col in self.col_list:
            col_length = self.col_longest[col]
            col_width = col_length + self._separate()
            # -2 is for implicit separator -- spaces around
            format_list.append(" {%s:%d} " % (col, col_width - 2))
            header_sepa_format_list.append("{%s:%d}" % (col, col_width))
            self.col_widths[col] = col_width

        logger.debug("column widths %s", self.col_widths)

        self.format_str = "|".join(format_list)

        self.header_format_str = "+".join(header_sepa_format_list)
        self.header_data = {}
        for k in self.col_widths:
            self.header_data[k] = "-" * self.col_widths[k]

Response: Counts the number of columns needed to display whole table.


Instruction:
How would you explain what the following Python 3 function does
def get_all_longest_col_lengths(self):
        response = {}
        for col in self.col_list:
            response[col] = self._longest_val_in_column(col)
        return response

Response: iterate over all columns and get their longest values


Instruction:
How would you explain what the following Python 3 function does
def _separate(self):
        if self.total_free_space is None:
            return 0
        else:
            sepa = self.default_column_space
            # we need to distribute remainders
            if self.default_column_space_remainder > 0:
                sepa += 1
                self.default_column_space_remainder -= 1
            logger.debug("remainder: %d, separator: %d",
                         self.default_column_space_remainder, sepa)
            return sepa

Response: get a width of separator for current column


Instruction:
Explain what the following Python 3 code does
def render(self):
        print(self.format_str.format(**self.header), file=sys.stderr)
        print(self.header_format_str.format(**self.header_data), file=sys.stderr)
        for row in self.data:
            print(self.format_str.format(**row))

Response:
print provided table

        :return: None


Instruction:
Explain what the following Python 3 code does
def _validate_source_data(self):

        try:
            jsonschema.validate(self._buffer, self._schema)
        except jsonschema.ValidationError as e:
            raise ValidationError(e)

Response: Validate the source data.


Instruction:
Can you generate the documentation for the following Python 3 function
def to_table_data(self):

        self._validate_source_data()
        self._loader.inc_table_count()

        yield TableData(
            self._make_table_name(),
            ["key", "value"],
            [record for record in self._buffer.items()],
            dp_extractor=self._loader.dp_extractor,
            type_hints=self._extract_type_hints(),
        )

Response: Yields a generator that yields TableData objects.


Instruction:
Can you create a Python 3 function that
yields a generator that yields TableData objects.

Response:
def to_table_data(self):
        """
        :raises ValueError:
        :raises pytablereader.error.ValidationError:
        """

        self._validate_source_data()

        for table_key, json_records in six.iteritems(self._buffer):
            attr_name_set = set()
            for json_record in json_records:
                attr_name_set = attr_name_set.union(six.viewkeys(json_record))
            headers = sorted(attr_name_set)

            self._loader.inc_table_count()
            self._table_key = table_key

            yield TableData(
                self._make_table_name(),
                headers,
                json_records,
                dp_extractor=self._loader.dp_extractor,
                type_hints=self._extract_type_hints(headers),
            )


Instruction:
Make a summary of the following Python 3 code
def to_table_data(self):

        self._validate_source_data()

        for table_key, json_records in six.iteritems(self._buffer):
            headers = sorted(six.viewkeys(json_records))

            self._loader.inc_table_count()
            self._table_key = table_key

            yield TableData(
                self._make_table_name(),
                headers,
                zip(*[json_records.get(header) for header in headers]),
                dp_extractor=self._loader.dp_extractor,
                type_hints=self._extract_type_hints(headers),
            )

Response: Yields a generator that yields TableData objects.


Instruction:
Make a summary of the following Python 3 code
def to_table_data(self):

        self._validate_source_data()

        for table_key, json_records in six.iteritems(self._buffer):
            self._loader.inc_table_count()
            self._table_key = table_key

            yield TableData(
                self._make_table_name(),
                ["key", "value"],
                [record for record in json_records.items()],
                dp_extractor=self._loader.dp_extractor,
                type_hints=self._extract_type_hints(),
            )

Response: Yields a generator that yields TableData objects.


Instruction:
How would you explain what the following Python 3 function does
def set_params(self, **kwargs):

        # Here we cater to the koji "scratch" build type, this will disable
        # all plugins that might cause importing of data to koji
        self.scratch = kwargs.get('scratch')
        # When true, it indicates build was automatically started by
        # OpenShift via a trigger, for instance ImageChangeTrigger
        self.is_auto = kwargs.pop('is_auto', False)
        # An isolated build is meant to patch a certain release and not
        # update transient tags in container registry
        self.isolated = kwargs.get('isolated')

        self.osbs_api = kwargs.pop('osbs_api', None)
        self.validate_build_variation()

        self.base_image = kwargs.get('base_image')
        self.platform_node_selector = kwargs.get('platform_node_selector', {})
        self.scratch_build_node_selector = kwargs.get('scratch_build_node_selector', {})
        self.explicit_build_node_selector = kwargs.get('explicit_build_node_selector', {})
        self.auto_build_node_selector = kwargs.get('auto_build_node_selector', {})
        self.isolated_build_node_selector = kwargs.get('isolated_build_node_selector', {})

        logger.debug("now setting params '%s' for user_params", kwargs)
        self.user_params.set_params(**kwargs)

        self.source_registry = None
        self.organization = None

Response: set parameters in the user parameters


Instruction:
Write a Python 3 function that can
set data from reactor config

Response:
def set_data_from_reactor_config(self):
        """
        Sets data from reactor config
        """
        reactor_config_override = self.user_params.reactor_config_override.value
        reactor_config_map = self.user_params.reactor_config_map.value
        data = None

        if reactor_config_override:
            data = reactor_config_override
        elif reactor_config_map:
            config_map = self.osbs_api.get_config_map(reactor_config_map)
            data = config_map.get_data_by_key('config.yaml')

        if not data:
            if self.user_params.flatpak.value:
                raise OsbsValidationException("flatpak_base_image must be provided")
            else:
                return

        source_registry_key = 'source_registry'
        registry_organization_key = 'registries_organization'
        req_secrets_key = 'required_secrets'
        token_secrets_key = 'worker_token_secrets'
        flatpak_key = 'flatpak'
        flatpak_base_image_key = 'base_image'

        if source_registry_key in data:
            self.source_registry = data[source_registry_key]
        if registry_organization_key in data:
            self.organization = data[registry_organization_key]

        if self.user_params.flatpak.value:
            flatpack_base_image = data.get(flatpak_key, {}).get(flatpak_base_image_key, None)
            if flatpack_base_image:
                self.base_image = flatpack_base_image
                self.user_params.base_image.value = flatpack_base_image
            else:
                raise OsbsValidationException("flatpak_base_image must be provided")

        required_secrets = data.get(req_secrets_key, [])
        token_secrets = data.get(token_secrets_key, [])
        self._set_required_secrets(required_secrets, token_secrets)


Instruction:
Can you tell what is the following Python 3 function doing
def _set_required_secrets(self, required_secrets, token_secrets):
        if self.user_params.build_type.value == BUILD_TYPE_ORCHESTRATOR:
            required_secrets += token_secrets

        if not required_secrets:
            return

        secrets = self.template['spec']['strategy']['customStrategy'].setdefault('secrets', [])
        existing = set(secret_mount['secretSource']['name'] for secret_mount in secrets)
        required_secrets = set(required_secrets)

        already_set = required_secrets.intersection(existing)
        if already_set:
            logger.debug("secrets %s are already set", already_set)

        for secret in required_secrets - existing:
            secret_path = os.path.join(SECRETS_PATH, secret)
            logger.info("Configuring %s secret at %s", secret, secret_path)

            secrets.append({
                'secretSource': {
                    'name': secret,
                },
                'mountPath': secret_path,
            })

Response: Sets the required secrets for the current user.


Instruction:
Given the following Python 3 function, write the documentation
def remove_plugin(self, phase, name, reason=None):
        for p in self.template[phase]:
            if p.get('name') == name:
                self.template[phase].remove(p)
                if reason:
                    logger.info('Removing {}:{}, {}'.format(phase, name, reason))
                break

Response: Remove a plugin from the config


Instruction:
Explain what the following Python 3 code does
def add_plugin(self, phase, name, args, reason=None):
        plugin_modified = False

        for plugin in self.template[phase]:
            if plugin['name'] == name:
                plugin['args'] = args
                plugin_modified = True

        if not plugin_modified:
            self.template[phase].append({"name": name, "args": args})
            if reason:
                logger.info('{}:{} with args {}, {}'.format(phase, name, args, reason))

Response: Add a new plugin to the config.


Instruction:
Create a Python 3 function for
getting the configuration for a plugin.

Response:
def get_plugin_conf(self, phase, name):
        """
        Return the configuration for a plugin.

        Raises KeyError if there are no plugins of that type.
        Raises IndexError if the named plugin is not listed.
        """
        match = [x for x in self.template[phase] if x.get('name') == name]
        return match[0]


Instruction:
Make a summary of the following Python 3 code
def has_plugin_conf(self, phase, name):
        try:
            self.get_plugin_conf(phase, name)
            return True
        except (KeyError, IndexError):
            return False

Response: Check whether a plugin is configured.


Instruction:
Can you generate the documentation for the following Python 3 function
def adjust_for_scratch(self):
        if self.user_params.scratch.value:
            remove_plugins = [
                ("prebuild_plugins", "koji_parent"),
                ("postbuild_plugins", "compress"),  # required only to make an archive for Koji
                ("postbuild_plugins", "pulp_pull"),  # required only to make an archive for Koji
                ("postbuild_plugins", "compare_components"),
                ("postbuild_plugins", "import_image"),
                ("exit_plugins", "koji_promote"),
                ("exit_plugins", "koji_tag_build"),
                ("exit_plugins", "import_image"),
                ("prebuild_plugins", "check_and_set_rebuild"),
                ("prebuild_plugins", "stop_autorebuild_if_disabled")
            ]

            if not self.has_tag_suffixes_placeholder():
                remove_plugins.append(("postbuild_plugins", "tag_from_config"))

            for when, which in remove_plugins:
                self.pt.remove_plugin(when, which, 'removed from scratch build request')

Response: Remove certain plugins in order to handle the scratch build scenario.


Instruction:
Write a Python 3 function for
removing certain plugins in order to handle the isolated build scenario.

Response:
def adjust_for_isolated(self):
        """
        Remove certain plugins in order to handle the "isolated build"
        scenario.
        """
        if self.user_params.isolated.value:
            remove_plugins = [
                ("prebuild_plugins", "check_and_set_rebuild"),
                ("prebuild_plugins", "stop_autorebuild_if_disabled")
            ]

            for when, which in remove_plugins:
                self.pt.remove_plugin(when, which, 'removed from isolated build request')


Instruction:
How would you explain what the following Python 3 function does
def adjust_for_flatpak(self):
        if self.user_params.flatpak.value:
            remove_plugins = [
                ("prebuild_plugins", "resolve_composes"),
                # We'll extract the filesystem anyways for a Flatpak instead of exporting
                # the docker image directly, so squash just slows things down.
                ("prepublish_plugins", "squash"),
                # Pulp can't currently handle Flatpaks, which are OCI images
                ("postbuild_plugins", "pulp_push"),
                ("postbuild_plugins", "pulp_tag"),
                ("postbuild_plugins", "pulp_sync"),
                ("exit_plugins", "pulp_publish"),
                ("exit_plugins", "pulp_pull"),
                # delete_from_registry is used for deleting builds from the temporary registry
                # that pulp_sync mirrors from.
                ("exit_plugins", "delete_from_registry"),
            ]
            for when, which in remove_plugins:
                self.pt.remove_plugin(when, which, 'not needed for flatpak build')

Response: Adjusts the internal state of the internal state of the internal state of the Flatpaks.


Instruction:
Can you implement a function in Python 3 that
renders customizations for site user specified customizations.

Response:
def render_customizations(self):
        """
        Customize template for site user specified customizations
        """
        disable_plugins = self.pt.customize_conf.get('disable_plugins', [])
        if not disable_plugins:
            logger.debug('No site-user specified plugins to disable')
        else:
            for plugin in disable_plugins:
                try:
                    self.pt.remove_plugin(plugin['plugin_type'], plugin['plugin_name'],
                                          'disabled at user request')
                except KeyError:
                    # Malformed config
                    logger.info('Invalid custom configuration found for disable_plugins')

        enable_plugins = self.pt.customize_conf.get('enable_plugins', [])
        if not enable_plugins:
            logger.debug('No site-user specified plugins to enable"')
        else:
            for plugin in enable_plugins:
                try:
                    msg = 'enabled at user request'
                    self.pt.add_plugin(plugin['plugin_type'], plugin['plugin_name'],
                                       plugin['plugin_args'], msg)
                except KeyError:
                    # Malformed config
                    logger.info('Invalid custom configuration found for enable_plugins')


Instruction:
Write a Python 3 script to
render koji if there is yum repo in user params don t pick stuff from koji

Response:
def render_koji(self):
        """
        if there is yum repo in user params, don't pick stuff from koji
        """
        phase = 'prebuild_plugins'
        plugin = 'koji'
        if not self.pt.has_plugin_conf(phase, plugin):
            return

        if self.user_params.yum_repourls.value:
            self.pt.remove_plugin(phase, plugin, 'there is a yum repo user parameter')
        elif not self.pt.set_plugin_arg_valid(phase, plugin, "target",
                                              self.user_params.koji_target.value):
            self.pt.remove_plugin(phase, plugin, 'no koji target supplied in user parameters')


Instruction:
Can you generate a brief explanation for the following Python 3 code
def render_check_and_set_platforms(self):
        phase = 'prebuild_plugins'
        plugin = 'check_and_set_platforms'
        if not self.pt.has_plugin_conf(phase, plugin):
            return

        if self.user_params.koji_target.value:
            self.pt.set_plugin_arg(phase, plugin, "koji_target",
                                   self.user_params.koji_target.value)

Response: If the check_and_set_platforms plugin is present, configure it


Instruction:
Make a summary of the following Python 3 code
def render_import_image(self, use_auth=None):
        # import_image is a multi-phase plugin
        if self.user_params.imagestream_name.value is None:
            self.pt.remove_plugin('exit_plugins', 'import_image',
                                  'imagestream not in user parameters')
        elif self.pt.has_plugin_conf('exit_plugins', 'import_image'):
            self.pt.set_plugin_arg('exit_plugins', 'import_image', 'imagestream',
                                   self.user_params.imagestream_name.value)

Response: Render the import_image plugin


Instruction:
Can you generate a brief explanation for the following Python 3 code
def get_user(self, username="~"):
        url = self._build_url("users/%s/" % username, _prepend_namespace=False)
        response = self._get(url)
        check_response(response)
        return response

Response: get user info about user


Instruction:
Can you generate the documentation for the following Python 3 function
def create_build(self, build_json):
        url = self._build_url("builds/")
        logger.debug(build_json)
        return self._post(url, data=json.dumps(build_json),
                          headers={"Content-Type": "application/json"})

Response: Creates a build for the given build_json.


Instruction:
Explain what the following Python 3 code does
def get_all_build_configs_by_labels(self, label_selectors):
        labels = ['%s=%s' % (field, value) for field, value in label_selectors]
        labels = ','.join(labels)
        url = self._build_url("buildconfigs/", labelSelector=labels)
        return self._get(url).json()['items']

Response: Returns all builds matching a given set of label selectors.


Instruction:
Can you tell what is the following Python 3 function doing
def get_build_config_by_labels(self, label_selectors):
        items = self.get_all_build_configs_by_labels(label_selectors)

        if not items:
            raise OsbsException(
                "Build config not found for labels: %r" %
                (label_selectors, ))
        if len(items) > 1:
            raise OsbsException(
                "More than one build config found for labels: %r" %
                (label_selectors, ))

        return items[0]

Response: Returns a build config matching the given label selectors. This method will raise OsbsException if more than one build config is found.


Instruction:
Write a Python 3 script to
return a build config matching the given label selectors filtering against a predetermined value.

Response:
def get_build_config_by_labels_filtered(self, label_selectors, filter_key, filter_value):
        """
        Returns a build config matching the given label selectors, filtering against
        another predetermined value. This method will raise OsbsException
        if not exactly one build config is found after filtering.
        """
        items = self.get_all_build_configs_by_labels(label_selectors)

        if filter_value is not None:
            build_configs = []
            for build_config in items:
                match_value = graceful_chain_get(build_config, *filter_key.split('.'))
                if filter_value == match_value:
                    build_configs.append(build_config)
            items = build_configs

        if not items:
            raise OsbsException(
                "Build config not found for labels: %r" %
                (label_selectors, ))
        if len(items) > 1:
            raise OsbsException(
                "More than one build config found for labels: %r" %
                (label_selectors, ))
        return items[0]


Instruction:
Create a Python 3 function to
create a build config for the specified build_config_json.

Response:
def create_build_config(self, build_config_json):
        """
        :return:
        """
        url = self._build_url("buildconfigs/")
        return self._post(url, data=build_config_json,
                          headers={"Content-Type": "application/json"})


Instruction:
Implement a function in Python 3 to
stream logs from build_id build_id.

Response:
def stream_logs(self, build_id):
        """
        stream logs from build

        :param build_id: str
        :return: iterator
        """
        kwargs = {'follow': 1}

        # If connection is closed within this many seconds, give up:
        min_idle_timeout = 60

        # Stream logs, but be careful of the connection closing
        # due to idle timeout. In that case, try again until the
        # call returns more quickly than a reasonable timeout
        # would be set to.
        last_activity = time.time()
        while True:
            buildlogs_url = self._build_url("builds/%s/log/" % build_id,
                                            **kwargs)
            try:
                response = self._get(buildlogs_url, stream=1,
                                     headers={'Connection': 'close'})
                check_response(response)

                for line in response.iter_lines():
                    last_activity = time.time()
                    yield line
            # NOTE1: If self._get causes ChunkedEncodingError, ConnectionError,
            # or IncompleteRead to be raised, they'll be wrapped in
            # OsbsNetworkException or OsbsException
            # NOTE2: If iter_lines causes ChunkedEncodingError
            # or IncompleteRead to be raised, it'll simply be silenced.
            # NOTE3: An exception may be raised from
            # check_response(). In this case, exception will be
            # wrapped in OsbsException or OsbsNetworkException,
            # inspect cause to detect ConnectionError.
            except OsbsException as exc:
                if not isinstance(exc.cause, ConnectionError):
                    raise

            idle = time.time() - last_activity
            logger.debug("connection closed after %ds", idle)
            if idle < min_idle_timeout:
                # Finish output
                return

            since = int(idle - 1)
            logger.debug("fetching logs starting from %ds ago", since)
            kwargs['sinceSeconds'] = since


Instruction:
Write a Python 3 function that can
stream logs from build

Response:
def logs(self, build_id, follow=False, build_json=None, wait_if_missing=False):
        """
        provide logs from build

        :param build_id: str
        :param follow: bool, fetch logs as they come?
        :param build_json: dict, to save one get-build query
        :param wait_if_missing: bool, if build doesn't exist, wait
        :return: None, str or iterator
        """
        # does build exist?
        try:
            build_json = build_json or self.get_build(build_id).json()
        except OsbsResponseException as ex:
            if ex.status_code == 404:
                if not wait_if_missing:
                    raise OsbsException("Build '%s' doesn't exist." % build_id)
            else:
                raise

        if follow or wait_if_missing:
            build_json = self.wait_for_build_to_get_scheduled(build_id)

        br = BuildResponse(build_json)

        # When build is in new or pending state, openshift responds with 500
        if br.is_pending():
            return

        if follow:
            return self.stream_logs(build_id)

        buildlogs_url = self._build_url("builds/%s/log/" % build_id)
        response = self._get(buildlogs_url, headers={'Connection': 'close'})
        check_response(response)
        return response.content


Instruction:
Implement a function in Python 3 to
list builds for a given Koji Task ID and optionally a given set of labels.

Response:
def list_builds(self, build_config_id=None, koji_task_id=None,
                    field_selector=None, labels=None):
        """
        List builds matching criteria

        :param build_config_id: str, only list builds created from BuildConfig
        :param koji_task_id: str, only list builds for Koji Task ID
        :param field_selector: str, field selector for query
        :return: HttpResponse
        """
        query = {}
        selector = '{key}={value}'

        label = {}
        if labels is not None:
            label.update(labels)

        if build_config_id is not None:
            label['buildconfig'] = build_config_id

        if koji_task_id is not None:
            label['koji-task-id'] = str(koji_task_id)

        if label:
            query['labelSelector'] = ','.join([selector.format(key=key,
                                                               value=value)
                                               for key, value in label.items()])

        if field_selector is not None:
            query['fieldSelector'] = field_selector
        url = self._build_url("builds/", **query)
        return self._get(url)


Instruction:
Create a Python 3 function to
create a resource quota for a resource.

Response:
def create_resource_quota(self, name, quota_json):
        """
        Prevent builds being scheduled and wait for running builds to finish.

        :return:
        """

        url = self._build_k8s_url("resourcequotas/")
        response = self._post(url, data=json.dumps(quota_json),
                              headers={"Content-Type": "application/json"})
        if response.status_code == http_client.CONFLICT:
            url = self._build_k8s_url("resourcequotas/%s" % name)
            response = self._put(url, data=json.dumps(quota_json),
                                 headers={"Content-Type": "application/json"})

        check_response(response)
        return response


Instruction:
How would you implement a function in Python 3 that
waits for a build to finish

Response:
def wait(self, build_id, states):
        """
        :param build_id: wait for build to finish

        :return:
        """
        logger.info("watching build '%s'", build_id)
        for changetype, obj in self.watch_resource("builds", build_id):
            try:
                obj_name = obj["metadata"]["name"]
            except KeyError:
                logger.error("'object' doesn't have any name")
                continue
            try:
                obj_status = obj["status"]["phase"]
            except KeyError:
                logger.error("'object' doesn't have any status")
                continue
            else:
                obj_status_lower = obj_status.lower()
            logger.info("object has changed: '%s', status: '%s', name: '%s'",
                        changetype, obj_status, obj_name)
            if obj_name == build_id:
                logger.info("matching build found")
                logger.debug("is %s in %s?", repr(obj_status_lower), states)
                if obj_status_lower in states:
                    logger.debug("Yes, build is in the state I'm waiting for.")
                    return obj
                else:
                    logger.debug("No, build is not in the state I'm "
                                 "waiting for.")
            else:
                logger.info("The build %r isn't me %r", obj_name, build_id)

        # I'm not sure how we can end up here since there are two possible scenarios:
        #   1. our object was found and we are returning in the loop
        #   2. our object was not found and we keep waiting (in the loop)
        # Therefore, let's raise here
        logger.warning("build '%s' was not found during wait", build_id)
        raise OsbsWatchBuildNotFound("build '%s' was not found and response stream ended" %
                                     build_id)


Instruction:
Can you generate a brief explanation for the following Python 3 code
def adjust_attributes_on_object(self, collection, name, things, values, how):
        url = self._build_url("%s/%s" % (collection, name))
        response = self._get(url)
        logger.debug("before modification: %s", response.content)
        build_json = response.json()
        how(build_json['metadata'], things, values)
        response = self._put(url, data=json.dumps(build_json), use_json=True)
        check_response(response)
        return response

Response: adjusts labels or annotations on object name


Instruction:
Can you generate a brief explanation for the following Python 3 code
def update_annotations_on_build(self, build_id, annotations):
        return self.adjust_attributes_on_object('builds', build_id,
                                                'annotations', annotations,
                                                self._update_metadata_things)

Response: set annotations on build object


Instruction:
Can you write a function in Python 3 where it
imports an image into a ImageStream.

Response:
def import_image(self, name, stream_import, tags=None):
        """
        Import image tags from a Docker registry into an ImageStream

        :return: bool, whether tags were imported
        """

        # Get the JSON for the ImageStream
        imagestream_json = self.get_image_stream(name).json()
        logger.debug("imagestream: %r", imagestream_json)

        if 'dockerImageRepository' in imagestream_json.get('spec', {}):
            logger.debug("Removing 'dockerImageRepository' from ImageStream %s", name)
            source_repo = imagestream_json['spec'].pop('dockerImageRepository')
            imagestream_json['metadata']['annotations'][ANNOTATION_SOURCE_REPO] = source_repo
            imagestream_json = self.update_image_stream(name, imagestream_json).json()

        # Note the tags before import
        oldtags = imagestream_json.get('status', {}).get('tags', [])
        logger.debug("tags before import: %r", oldtags)

        stream_import['metadata']['name'] = name
        stream_import['spec']['images'] = []
        tags_set = set(tags) if tags else set()
        for tag in imagestream_json.get('spec', {}).get('tags', []):
            if tags_set and tag['name'] not in tags_set:
                continue

            image_import = {
                'from': tag['from'],
                'to': {'name': tag['name']},
                'importPolicy': tag.get('importPolicy'),
                'referencePolicy': tag.get('referencePolicy'),
            }
            stream_import['spec']['images'].append(image_import)

        if not stream_import['spec']['images']:
            logger.debug('No tags to import')
            return False

        import_url = self._build_url("imagestreamimports/")
        import_response = self._post(import_url, data=json.dumps(stream_import),
                                     use_json=True)
        self._check_import_image_response(import_response)

        new_tags = [
            image['tag']
            for image in import_response.json().get('status', {}).get('images', [])]
        logger.debug("tags after import: %r", new_tags)

        return True


Instruction:
How would you code a function in Python 3 to
import tags from a Docker registry into an ImageStream.

Response:
def import_image_tags(self, name, stream_import, tags, repository, insecure):
        """
        Import image tags from a Docker registry into an ImageStream

        :return: bool, whether tags were imported
        """

        # Get the JSON for the ImageStream
        imagestream_json = self.get_image_stream(name).json()
        logger.debug("imagestream: %r", imagestream_json)
        changed = False

        # existence of dockerImageRepository is limiting how many tags are updated
        if 'dockerImageRepository' in imagestream_json.get('spec', {}):
            logger.debug("Removing 'dockerImageRepository' from ImageStream %s", name)
            imagestream_json['spec'].pop('dockerImageRepository')
            changed = True
        all_annotations = imagestream_json.get('metadata', {}).get('annotations', {})
        # remove annotations about registry, since method will get them as arguments
        for annotation in ANNOTATION_SOURCE_REPO, ANNOTATION_INSECURE_REPO:
            if annotation in all_annotations:
                imagestream_json['metadata']['annotations'].pop(annotation)
                changed = True

        if changed:
            imagestream_json = self.update_image_stream(name, imagestream_json).json()

        # Note the tags before import
        oldtags = imagestream_json.get('status', {}).get('tags', [])
        logger.debug("tags before import: %r", oldtags)

        stream_import['metadata']['name'] = name
        stream_import['spec']['images'] = []
        tags_set = set(tags) if tags else set()

        if not tags_set:
            logger.debug('No tags to import')
            return False

        for tag in tags_set:
            image_import = {
                'from': {"kind": "DockerImage",
                         "name": '{}:{}'.format(repository, tag)},
                'to': {'name': tag},
                'importPolicy': {'insecure': insecure},
                # referencePolicy will default to "type: source"
                # so we don't have to explicitly set it
            }
            stream_import['spec']['images'].append(image_import)

        import_url = self._build_url("imagestreamimports/")
        import_response = self._post(import_url, data=json.dumps(stream_import),
                                     use_json=True)
        self._check_import_image_response(import_response)

        new_tags = [
            image['tag']
            for image in import_response.json().get('status', {}).get('images', [])]
        logger.debug("tags after import: %r", new_tags)

        return True


Instruction:
Can you generate the documentation for the following Python 3 function
def str_on_2_unicode_on_3(s):

    if not PY3:
        return str(s)
    else:  # 3+
        if not isinstance(s, str):
            return str(s, encoding="utf-8")
        return s

Response: str on 2 unicode on 3


Instruction:
Here you have a function in Python 3, explain what it does
def load(self):

        formatter = JsonLinesTableFormatter(self.load_dict())
        formatter.accept(self)

        return formatter.to_table_data()

Response: Loads the tabular data from a Line - Delimited JSON file.


Instruction:
Can you create a Python 3 function that
loads the table data from a Google Spreadsheet.

Response:
def load(self):
        """
        Load table data from a Google Spreadsheet.

        This method consider :py:attr:`.source` as a path to the
        credential JSON file to access Google Sheets API.

        The method automatically search the header row start from
        :py:attr:`.start_row`. The condition of the header row is that
        all of the columns have value (except empty columns).

        :return:
            Loaded table data. Return one |TableData| for each sheet in
            the workbook. The table name for data will be determined by
            :py:meth:`~.GoogleSheetsTableLoader.make_table_name`.
        :rtype: iterator of |TableData|
        :raises pytablereader.DataError:
            If the header row is not found.
        :raises pytablereader.OpenError:
            If the spread sheet not found.
        """

        import gspread
        from oauth2client.service_account import ServiceAccountCredentials

        self._validate_table_name()
        self._validate_title()

        scope = ["https://spreadsheets.google.com/feeds", "https://www.googleapis.com/auth/drive"]
        credentials = ServiceAccountCredentials.from_json_keyfile_name(self.source, scope)

        gc = gspread.authorize(credentials)
        try:
            for worksheet in gc.open(self.title).worksheets():
                self._worksheet = worksheet
                self.__all_values = [row for row in worksheet.get_all_values()]

                if self._is_empty_sheet():
                    continue

                try:
                    self.__strip_empty_col()
                except ValueError:
                    continue

                value_matrix = self.__all_values[self._get_start_row_idx() :]
                try:
                    headers = value_matrix[0]
                    rows = value_matrix[1:]
                except IndexError:
                    continue

                self.inc_table_count()

                yield TableData(
                    self.make_table_name(),
                    headers,
                    rows,
                    dp_extractor=self.dp_extractor,
                    type_hints=self._extract_type_hints(headers),
                )
        except gspread.exceptions.SpreadsheetNotFound:
            raise OpenError("spreadsheet '{}' not found".format(self.title))
        except gspread.exceptions.APIError as e:
            raise APIError(e)


Instruction:
How would you code a function in Python 3 to
set the log level of this module.

Response:
def set_log_level(log_level):
    """
    Set logging level of this module. Using
    `logbook <https://logbook.readthedocs.io/en/stable/>`__ module for logging.

    :param int log_level:
        One of the log level of
        `logbook <https://logbook.readthedocs.io/en/stable/api/base.html>`__.
        Disabled logging if ``log_level`` is ``logbook.NOTSET``.
    :raises LookupError: If ``log_level`` is an invalid value.
    """

    if not LOGBOOK_INSTALLED:
        return

    # validate log level
    logbook.get_level_name(log_level)

    if log_level == logger.level:
        return

    if log_level == logbook.NOTSET:
        set_logger(is_enable=False)
    else:
        set_logger(is_enable=True)

    logger.level = log_level
    dataproperty.set_log_level(log_level)

    try:
        import simplesqlite

        simplesqlite.set_log_level(log_level)
    except ImportError:
        pass


Instruction:
Implement a Python 3 function for
updating the values of the buildconfig with values from new BuildConfig.

Response:
def buildconfig_update(orig, new, remove_nonexistent_keys=False):
    """Performs update of given `orig` BuildConfig with values from `new` BuildConfig.
    Both BuildConfigs have to be represented as `dict`s.

    This function:
    - adds all key/value pairs to `orig` from `new` that are missing
    - replaces values in `orig` for keys that are in both
    - removes key/value pairs from `orig` for keys that are not in `new`,
      but only in dicts nested inside `strategy` key
      (see https://github.com/projectatomic/osbs-client/pull/273#issuecomment-148038314)
    """
    if isinstance(orig, dict) and isinstance(new, dict):
        clean_triggers(orig, new)
        if remove_nonexistent_keys:
            missing = set(orig.keys()) - set(new.keys())
            for k in missing:
                orig.pop(k)
        for k, v in new.items():
            if k == 'strategy':
                remove_nonexistent_keys = True
            if isinstance(orig.get(k), dict) and isinstance(v, dict):
                buildconfig_update(orig[k], v, remove_nonexistent_keys)
            else:
                orig[k] = v


Instruction:
Make a summary of the following Python 3 code
def checkout_git_repo(git_url, target_dir=None, commit=None, retry_times=GIT_MAX_RETRIES,
                      branch=None, depth=None):
    """
    clone provided git repo to target_dir, optionally checkout provided commit
    yield the ClonedRepoData and delete the repo when finished

    :param git_url: str, git repo to clone
    :param target_dir: str, filesystem path where the repo should be cloned
    :param commit: str, commit to checkout, SHA-1 or ref
    :param retry_times: int, number of retries for git clone
    :param branch: str, optional branch of the commit, required if depth is provided
    :param depth: int, optional expected depth
    :return: str, int, commit ID of HEAD
    """
    tmpdir = tempfile.mkdtemp()
    target_dir = target_dir or os.path.join(tmpdir, "repo")
    try:
        yield clone_git_repo(git_url, target_dir, commit, retry_times, branch, depth)
    finally:
        shutil.rmtree(tmpdir)

Response: checkout a git repo to target_dir optionally checkout provided commit


Instruction:
Create a Python 3 function to
clone a git repo to target_dir optionally checkout commit.

Response:
def clone_git_repo(git_url, target_dir=None, commit=None, retry_times=GIT_MAX_RETRIES, branch=None,
                   depth=None):
    """
    clone provided git repo to target_dir, optionally checkout provided commit

    :param git_url: str, git repo to clone
    :param target_dir: str, filesystem path where the repo should be cloned
    :param commit: str, commit to checkout, SHA-1 or ref
    :param retry_times: int, number of retries for git clone
    :param branch: str, optional branch of the commit, required if depth is provided
    :param depth: int, optional expected depth
    :return: str, int, commit ID of HEAD
    """
    retry_delay = GIT_BACKOFF_FACTOR
    target_dir = target_dir or os.path.join(tempfile.mkdtemp(), "repo")
    commit = commit or "master"
    logger.info("cloning git repo '%s'", git_url)
    logger.debug("url = '%s', dir = '%s', commit = '%s'",
                 git_url, target_dir, commit)

    cmd = ["git", "clone"]
    if branch:
        cmd += ["-b", branch, "--single-branch"]
        if depth:
            cmd += ["--depth", str(depth)]
    elif depth:
        logger.warning("branch not provided for %s, depth setting ignored", git_url)
        depth = None

    cmd += [git_url, target_dir]

    logger.debug("cloning '%s'", cmd)
    repo_commit = ''
    repo_depth = None
    for counter in range(retry_times + 1):
        try:
            # we are using check_output, even though we aren't using
            # the return value, but we will get 'output' in exception
            subprocess.check_output(cmd, stderr=subprocess.STDOUT)
            repo_commit, repo_depth = reset_git_repo(target_dir, commit, depth)
            break
        except subprocess.CalledProcessError as exc:
            if counter != retry_times:
                logger.info("retrying command '%s':\n '%s'", cmd, exc.output)
                time.sleep(retry_delay * (2 ** counter))
            else:
                raise OsbsException("Unable to clone git repo '%s' "
                                    "branch '%s'" % (git_url, branch),
                                    cause=exc, traceback=sys.exc_info()[2])

    return ClonedRepoData(target_dir, repo_commit, repo_depth)


Instruction:
Given the following Python 3 function, write the documentation
def get_imagestreamtag_from_image(image):
    ret = image

    # Remove the registry part
    ret = strip_registry_from_image(image)

    # ImageStream names cannot contain '/'
    ret = ret.replace('/', '-')

    # If there is no ':' suffix value, add one
    if ret.find(':') == -1:
        ret += ":latest"

    return ret

Response: Returns ImageStreamTag give a FROM value from the Dockerfile


Instruction:
Explain what the following Python 3 code does
def get_time_from_rfc3339(rfc3339):

    try:
        # py 3

        dt = dateutil.parser.parse(rfc3339, ignoretz=False)
        return dt.timestamp()
    except NameError:
        # py 2

        # Decode the RFC 3339 date with no fractional seconds (the
        # format Origin provides). Note that this will fail to parse
        # valid ISO8601 timestamps not in this exact format.
        time_tuple = strptime(rfc3339, '%Y-%m-%dT%H:%M:%SZ')
        return timegm(time_tuple)

Response: Returns a time tuple from an ISO 3339 - formatted time string


Instruction:
Can you create a Python 3 function that
sanitizes a string for OpenShift.

Response:
def sanitize_strings_for_openshift(str1, str2='', limit=LABEL_MAX_CHARS, separator='-',
                                   label=True):
    """
    OpenShift requires labels to be no more than 64 characters and forbids any characters other
    than alphanumerics, ., and -. BuildConfig names are similar, but cannot contain /.

    Sanitize and concatanate one or two strings to meet OpenShift's requirements. include an
    equal number of characters from both strings if the combined length is more than the limit.
    """
    filter_chars = VALID_LABEL_CHARS if label else VALID_BUILD_CONFIG_NAME_CHARS
    str1_san = ''.join(filter(filter_chars.match, list(str1)))
    str2_san = ''.join(filter(filter_chars.match, list(str2)))

    str1_chars = []
    str2_chars = []
    groups = ((str1_san, str1_chars), (str2_san, str2_chars))

    size = len(separator)
    limit = min(limit, LABEL_MAX_CHARS)

    for i in range(max(len(str1_san), len(str2_san))):
        for group, group_chars in groups:
            if i < len(group):
                group_chars.append(group[i])
                size += 1
                if size >= limit:
                    break
        else:
            continue
        break

    final_str1 = ''.join(str1_chars).strip(separator)
    final_str2 = ''.join(str2_chars).strip(separator)
    return separator.join(filter(None, (final_str1, final_str2)))


Instruction:
Here you have a function in Python 3, explain what it does
def make_name_from_git(repo, branch, limit=53, separator='-', hash_size=5):

    branch = branch or 'unknown'
    full = urlparse(repo).path.lstrip('/') + branch
    repo = git_repo_humanish_part_from_uri(repo)
    shaval = sha256(full.encode('utf-8')).hexdigest()
    hash_str = shaval[:hash_size]
    limit = limit - len(hash_str) - 1

    sanitized = sanitize_strings_for_openshift(repo, branch, limit, separator, False)
    return separator.join(filter(None, (sanitized, hash_str)))

Response: Make a build name from a git repository and branch.


Instruction:
Can you implement a function in Python 3 that
wraps the result of make_name_from_git in a suffix and postfix adding separators for each.

Response:
def wrap_name_from_git(prefix, suffix, *args, **kwargs):
    """
    wraps the result of make_name_from_git in a suffix and postfix
    adding separators for each.

    see docstring for make_name_from_git for a full list of parameters
    """
    # 64 is maximum length allowed by OpenShift
    # 2 is the number of dashes that will be added
    prefix = ''.join(filter(VALID_BUILD_CONFIG_NAME_CHARS.match, list(prefix)))
    suffix = ''.join(filter(VALID_BUILD_CONFIG_NAME_CHARS.match, list(suffix)))
    kwargs['limit'] = kwargs.get('limit', 64) - len(prefix) - len(suffix) - 2
    name_from_git = make_name_from_git(*args, **kwargs)
    return '-'.join([prefix, name_from_git, suffix])


Instruction:
Can you create a Python 3 function that
sanitizes the version of the older setuptools.

Response:
def sanitize_version(version):
    """
    Take parse_version() output and standardize output from older
    setuptools' parse_version() to match current setuptools.
    """
    if hasattr(version, 'base_version'):
        if version.base_version:
            parts = version.base_version.split('.')
        else:
            parts = []
    else:
            parts = []
            for part in version:
                if part.startswith('*'):
                    break
                parts.append(part)
    parts = [int(p) for p in parts]

    if len(parts) < 3:
        parts += [0] * (3 - len(parts))

    major, minor, micro = parts[:3]
    cleaned_version = '{}.{}.{}'.format(major, minor, micro)
    return cleaned_version


Instruction:
Create a Python 3 function to
return the most preferred name of a label

Response:
def get_name(self, label_type):
        """
        returns the most preferred label name
        if there isn't any correct name in the list
        it will return newest label name
        """
        if label_type in self._label_values:
            return self._label_values[label_type][0]
        else:
            return Labels.LABEL_NAMES[label_type][0]


Instruction:
Create a Python 3 function for
returning dictionary indexed by old label name.

Response:
def get_new_names_by_old():
        """Return dictionary, new label name indexed by old label name."""
        newdict = {}

        for label_type, label_names in Labels.LABEL_NAMES.items():
            for oldname in label_names[1:]:
                newdict[oldname] = Labels.LABEL_NAMES[label_type][0]
        return newdict


Instruction:
Here you have a function in Python 3, explain what it does
def get_name_and_value(self, label_type):
        if label_type in self._label_values:
            return self._label_values[label_type]
        else:
            return (label_type, self._df_labels[label_type])

Response: Return tuple of label name and value for label type.


Instruction:
Can you create a Python 3 function that
initializes kerberos credential cache with ticket - granting ticket that is valid for at least a specific hour.

Response:
def kerberos_ccache_init(principal, keytab_file, ccache_file=None):
    """
    Checks whether kerberos credential cache has ticket-granting ticket that is valid for at least
    an hour.

    Default ccache is used unless ccache_file is provided. In that case, KRB5CCNAME environment
    variable is set to the value of ccache_file if we successfully obtain the ticket.
    """
    tgt_valid = False
    env = {"LC_ALL": "C"}  # klist uses locales to format date on RHEL7+
    if ccache_file:
        env["KRB5CCNAME"] = ccache_file

    # check if we have tgt that is valid more than one hour
    rc, klist, _ = run(["klist"], extraenv=env)
    if rc == 0:
        for line in klist.splitlines():
            m = re.match(KLIST_TGT_RE, line)
            if m:
                year = m.group("year")
                if len(year) == 2:
                    year = "20" + year

                expires = datetime.datetime(
                    int(year), int(m.group("month")), int(m.group("day")),
                    int(m.group("hour")), int(m.group("minute")), int(m.group("second"))
                )

                if expires - datetime.datetime.now() > datetime.timedelta(hours=1):
                    logger.debug("Valid TGT found, not renewing")
                    tgt_valid = True
                    break

    if not tgt_valid:
        logger.debug("Retrieving kerberos TGT")
        rc, out, err = run(["kinit", "-k", "-t", keytab_file, principal], extraenv=env)
        if rc != 0:
            raise OsbsException("kinit returned %s:\nstdout: %s\nstderr: %s" % (rc, out, err))

    if ccache_file:
        os.environ["KRB5CCNAME"] = ccache_file


Instruction:
Implement a function in Python 3 to
load the table data from a SQLite database file.

Response:
def load(self):
        """
        Extract tabular data as |TableData| instances from a SQLite database
        file. |load_source_desc_file|

        :return:
            Loaded table data iterator.
            |load_table_name_desc|

            ===================  ==============================================
            Format specifier     Value after the replacement
            ===================  ==============================================
            ``%(filename)s``     |filename_desc|
            ``%(key)s``          ``%(format_name)s%(format_id)s``
            ``%(format_name)s``  ``"sqlite"``
            ``%(format_id)s``    |format_id_desc|
            ``%(global_id)s``    |global_id|
            ===================  ==============================================
        :rtype: |TableData| iterator
        :raises pytablereader.DataError:
            If the SQLite database file data is invalid or empty.
        """

        self._validate()

        formatter = SqliteTableFormatter(self.source)
        formatter.accept(self)

        return formatter.to_table_data()


Instruction:
Create a Python 3 function to
find the data stored in the ConfigMap and return the json of the data that was passed into the ConfigMap on creation

Response:
def get_data(self):
        """
        Find the data stored in the config_map

        :return: dict, the json of the data data that was passed into the ConfigMap on creation
        """
        data = graceful_chain_get(self.json, "data")
        if data is None:
            return {}

        data_dict = {}
        for key in data:
            if self.is_yaml(key):
                data_dict[key] = yaml.load(data[key])
            else:
                data_dict[key] = json.loads(data[key])

        return data_dict


Instruction:
Can you tell what is the following Python 3 function doing
def get_data_by_key(self, name):
        data = graceful_chain_get(self.json, "data")

        if data is None or name not in data:
            return {}

        if self.is_yaml(name):
            return yaml.load(data[name]) or {}
        return json.loads(data[name])

Response: Find the object stored by a JSON string at key name


Instruction:
How would you code a function in Python 3 to
yield a generator that yields TableData objects.

Response:
def to_table_data(self):
        """
        :raises ValueError:
        :raises pytablereader.error.ValidationError:
        """

        self._validate_source_data()

        header_list = []
        for json_record in self._buffer:
            for key in json_record:
                if key not in header_list:
                    header_list.append(key)

        self._loader.inc_table_count()

        yield TableData(
            self._make_table_name(),
            header_list,
            self._buffer,
            dp_extractor=self._loader.dp_extractor,
            type_hints=self._extract_type_hints(header_list),
        )


Instruction:
How would you implement a function in Python 3 that
lists builds with matching fields

Response:
def list_builds(self, field_selector=None, koji_task_id=None, running=None,
                    labels=None):
        """
        List builds with matching fields

        :param field_selector: str, field selector for Builds
        :param koji_task_id: str, only list builds for Koji Task ID
        :return: BuildResponse list
        """

        if running:
            running_fs = ",".join(["status!={status}".format(status=status.capitalize())
                                  for status in BUILD_FINISHED_STATES])
            if not field_selector:
                field_selector = running_fs
            else:
                field_selector = ','.join([field_selector, running_fs])
        response = self.os.list_builds(field_selector=field_selector,
                                       koji_task_id=koji_task_id, labels=labels)
        serialized_response = response.json()
        build_list = []
        for build in serialized_response["items"]:
            build_list.append(BuildResponse(build, self))

        return build_list


Instruction:
Write a Python 3 function that can
get the pod for a build

Response:
def get_pod_for_build(self, build_id):
        """
        :return: PodResponse object for pod relating to the build
        """
        pods = self.os.list_pods(label='openshift.io/build.name=%s' % build_id)
        serialized_response = pods.json()
        pod_list = [PodResponse(pod) for pod in serialized_response["items"]]
        if not pod_list:
            raise OsbsException("No pod for build")
        elif len(pod_list) != 1:
            raise OsbsException("Only one pod expected but %d returned",
                                len(pod_list))
        return pod_list[0]