def key_from_jwk_dict(jwk_dict, private=None):
    """Load JWK from dictionary

    :param jwk_dict: Dictionary representing a JWK
    """

    # uncouple from the original item
    _jwk_dict = copy.copy(jwk_dict)

    if 'kty' not in _jwk_dict:
        raise MissingValue('kty missing')

    if _jwk_dict['kty'] == 'EC':
        ensure_ec_params(_jwk_dict, private)

        if private is not None and not private:
            # remove private components
            for v in EC_PRIVATE:
                _jwk_dict.pop(v, None)

        if _jwk_dict["crv"] in NIST2SEC:
            curve = NIST2SEC[_jwk_dict["crv"]]()
        else:
            raise UnsupportedAlgorithm(
                "Unknown curve: %s" % (_jwk_dict["crv"]))

        if _jwk_dict.get("d", None) is not None:
            # Ecdsa private key.
            _jwk_dict['priv_key'] = ec.derive_private_key(
                base64url_to_long(_jwk_dict["d"]), curve,
                backends.default_backend())
            _jwk_dict['pub_key'] = _jwk_dict['priv_key'].public_key()
        else:
            # Ecdsa public key.
            ec_pub_numbers = ec.EllipticCurvePublicNumbers(
                base64url_to_long(_jwk_dict["x"]),
                base64url_to_long(_jwk_dict["y"]), curve)
            _jwk_dict['pub_key'] = ec_pub_numbers.public_key(
                backends.default_backend())
        return ECKey(**_jwk_dict)
    elif _jwk_dict['kty'] == 'RSA':
        ensure_rsa_params(_jwk_dict, private)

        if private is not None and not private:
            # remove private components
            for v in RSA_PRIVATE:
                _jwk_dict.pop(v, None)

        rsa_pub_numbers = rsa.RSAPublicNumbers(
            base64url_to_long(_jwk_dict["e"]),
            base64url_to_long(_jwk_dict["n"]))
        if _jwk_dict.get("p", None) is not None:
            # Rsa private key. These MUST be present
            p_long = base64url_to_long(_jwk_dict["p"])
            q_long = base64url_to_long(_jwk_dict["q"])
            d_long = base64url_to_long(_jwk_dict["d"])
            # If not present these can be calculated from the others
            if 'dp' not in _jwk_dict:
                dp_long = rsa_crt_dmp1(d_long, p_long)
            else:
                dp_long = base64url_to_long(_jwk_dict["dp"])
            if 'dq' not in _jwk_dict:
                dq_long = rsa_crt_dmq1(d_long, q_long)
            else:
                dq_long = base64url_to_long(_jwk_dict["dq"])
            if 'qi' not in _jwk_dict:
                qi_long = rsa_crt_iqmp(p_long, q_long)
            else:
                qi_long = base64url_to_long(_jwk_dict["qi"])

            rsa_priv_numbers = rsa.RSAPrivateNumbers(
                p_long, q_long, d_long,
                dp_long, dq_long, qi_long, rsa_pub_numbers)
            _jwk_dict['priv_key'] = rsa_priv_numbers.private_key(
                backends.default_backend())
            _jwk_dict['pub_key'] = _jwk_dict['priv_key'].public_key()
        else:
            _jwk_dict['pub_key'] = rsa_pub_numbers.public_key(
                backends.default_backend())

        if _jwk_dict['kty'] != "RSA":
            raise WrongKeyType('"{}" should have been "RSA"'.format(_jwk_dict[
                                                                        'kty']))
        return RSAKey(**_jwk_dict)
    elif _jwk_dict['kty'] == 'oct':
        if 'key' not in _jwk_dict and 'k' not in _jwk_dict:
            raise MissingValue(
                'There has to be one of "k" or "key" in a symmetric key')

        return SYMKey(**_jwk_dict)
    else:
        raise UnknownKeyType