def process_composite(self, response):
        """
        Process a composite response.
        composites do not have inter item separators as they appear joined.
        We need to respect the universal options too.
        """
        composite = response["composite"]

        # if the composite is of not Composite make it one so we can simplify
        # it.
        if not isinstance(composite, Composite):
            composite = Composite(composite)

        # simplify and get underlying list.
        composite = composite.simplify().get_content()
        response["composite"] = composite

        if not isinstance(composite, list):
            raise Exception('expecting "composite" key in response')
        # if list is empty nothing to do
        if not len(composite):
            return
        if "full_text" in response:
            err = 'conflicting "full_text" and "composite" in response'
            raise Exception(err)

        # set markup
        if "markup" in self.py3status_module_options:
            markup = self.py3status_module_options["markup"]
            for item in composite:
                item["markup"] = markup

        # set universal options on last component
        composite[-1].update(self.i3bar_module_options)
        # update all components
        color = response.get("color")
        urgent = response.get("urgent")
        composite_length = len(response["composite"]) - 1
        for index, item in enumerate(response["composite"]):
            # validate the response
            if "full_text" not in item:
                raise KeyError('missing "full_text" key in response')
            # make sure all components have a name
            if "name" not in item:
                instance_index = item.get("index", index)
                item["instance"] = f"{self.module_inst} {instance_index}"
                item["name"] = self.module_name
            # hide separator for all inner components unless existing
            if index != composite_length:
                if "separator" not in item:
                    item["separator"] = False
                    item["separator_block_width"] = 0
            # If a color was supplied for the composite and a composite
            # part does not supply a color, use the composite color.
            if color and "color" not in item:
                item["color"] = color
            # Remove any none color from our output
            if hasattr(item.get("color"), "none_setting"):
                del item["color"]

            # set background and border colors. set left/right border widths
            # only on first/last composites and no border width for inner
            # composites or we will see border lines between composites.
            for key, value in self.i3bar_gaps_module_options.items():
                if (key == "border_left" and index != 0) or (
                    key == "border_right" and index != composite_length
                ):
                    item[key] = 0
                else:
                    item[key] = value

            # set urgent based on available user-defined settings
            if not self.allow_urgent:
                if "urgent" in item:
                    del item["urgent"]
            elif urgent:
                if self.i3bar_gaps_urgent_options:
                    # set background and border colors. set left/right border widths
                    # only on first/last composites and no border width for inner
                    # composites or we will see border lines between composites.
                    for key, value in self.i3bar_gaps_urgent_options.items():
                        if (key == "border_left" and index != 0) or (
                            key == "border_right" and index != composite_length
                        ):
                            item[key] = 0
                        elif key == "foreground":
                            item["color"] = value
                        else:
                            item[key] = value
                    if "urgent" in item:
                        del item["urgent"]
                else:
                    item["urgent"] = urgent

        # set min_length
        if "min_length" in self.py3status_module_options:
            min_length = self.py3status_module_options["min_length"]

            # get length, skip if length exceeds min_length
            length = sum(len(x["full_text"]) for x in response["composite"])
            if length >= min_length:
                return

            # sometimes we go under min_length to pad both side evenly,
            # we will add extra space on either side to honor min_length
            padding = min_length // 2 - length // 2
            offset = min_length - ((padding * 2) + length)

            # set position
            position = self.py3status_module_options.get("position", "left")
            if position == "center":
                left = right = " " * padding
                if self.random_int:
                    left += " " * offset
                else:
                    right += " " * offset
            elif position == "left":
                left, right = "", " " * (padding * 2 + offset)
            elif position == "right":
                right, left = "", " " * (padding * 2 + offset)

            # padding
            if left:
                response["composite"][0]["full_text"] = left + response["composite"][0]["full_text"]
            if right:
                response["composite"][-1]["full_text"] += right

        Process a composite response.
        composites do not have inter item separators as they appear joined.
        We need to respect the universal options too.
        
py3status/module.py