You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Python中能否缓存joserfc.jwk.RSAKey.import_key的(string,key)?Pickle存key失败

解决pytest中joserfc RSAKey缓存的pickle序列化问题

问题原因

你遇到的pickle错误,是因为joserfc.jwk.RSAKey内部包含了cryptography库的底层Rust绑定对象(cryptography.hazmat.bindings._rust.openssl.rsa.RSAPrivateKey),这类和系统底层资源绑定的对象不支持pickle序列化,直接缓存key对象会失败。

下面是几种可行的解决方案:

方案1:内存级缓存(单测试会话复用)

用functools.lru_cache给import_key做一层包装,在单次pytest运行会话内,重复的密钥字符串会直接返回缓存好的key对象,不用重复解析,速度最快:

from functools import lru_cache
import joserfc.jwk

@lru_cache(maxsize=None)
def get_cached_rsa_key(key_string: str) -> joserfc.jwk.RSAKey:
    return joserfc.jwk.RSAKey.import_key(key_string)

之后测试代码里统一调用get_cached_rsa_key(your_key_string)即可,重复的密钥字符串只会被解析一次。

方案2:持久化缓存(跨测试会话复用)

如果需要跨多次pytest运行复用缓存,不要直接存key对象,而是将key导出为可序列化的PEM字符串,缓存字符串后再按需重新导入:

用自定义文件缓存

import pickle
import joserfc.jwk
from pathlib import Path

CACHE_FILE = Path("rsa_key_cache.pkl")

# 加载已有缓存
try:
    with open(CACHE_FILE, "rb") as f:
        _rsa_cache = pickle.load(f)
except (FileNotFoundError, EOFError):
    _rsa_cache = {}

def get_cached_rsa_key(key_string: str) -> joserfc.jwk.RSAKey:
    if key_string in _rsa_cache:
        return joserfc.jwk.RSAKey.import_key(_rsa_cache[key_string])
    
    key = joserfc.jwk.RSAKey.import_key(key_string)
    # 将key导出为PEM字符串存入缓存
    _rsa_cache[key_string] = key.export_to_pem()
    
    # 持久化缓存到文件
    with open(CACHE_FILE, "wb") as f:
        pickle.dump(_rsa_cache, f)
    
    return key

用pytest自带缓存机制

利用pytest内置的cache fixture实现跨会话缓存,无需自己管理文件:

import joserfc.jwk

def get_cached_rsa_key(key_string: str, request) -> joserfc.jwk.RSAKey:
    # 用哈希值作为缓存键,避免长字符串占用空间
    cache_key = f"rsa_keys/{hash(key_string)}"
    cached_pem = request.config.cache.get(cache_key, None)
    
    if cached_pem:
        return joserfc.jwk.RSAKey.import_key(cached_pem)
    
    key = joserfc.jwk.RSAKey.import_key(key_string)
    request.config.cache.set(cache_key, key.export_to_pem())
    return key

使用时在测试函数中传入request fixture即可:

def test_something(request):
    key_str = "your_rsa_key_string"
    key = get_cached_rsa_key(key_str, request)
    # 执行测试逻辑

内容的提问来源于stack exchange,提问作者Jon Jagger

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.15 07:16:00