from typing import Optional
from typing import Union
import struct


def encode_key(
    key: str, value: Optional[Union[int, float, str]] = None, value_type: str = "str"
) -> bytes:
    """Encode given header key to a bytes string.

    Parameters
    ----------
    key : str
        header key
    value : Optional[Union[int, float, str]], optional
        value of the header key, by default None
    value_type : str, optional
        type of the header key, by default "str"

    Returns
    -------
    bytes
        bytes encoded string
    """
    if value is None:
        return struct.pack("I", len(key)) + key.encode()

    if value_type == "str" and isinstance(value, str):
        return (
            struct.pack("I", len(key))
            + key.encode()
            + struct.pack("I", len(value))
            + value.encode()
        )
    return struct.pack("I", len(key)) + key.encode() + struct.pack(value_type, value)