star

提示

本页面仅包含有关st.cache_resource API的信息。要深入了解缓存及其使用方法,请查看Caching

用于缓存返回全局资源(例如数据库连接、ML模型)的函数的装饰器。

缓存的对象在所有用户、会话和重新运行之间共享。它们必须是线程安全的,因为它们可以同时从多个线程访问。如果线程安全是一个问题,考虑使用st.session_state来存储每个会话的资源。

你可以使用func.clear()清除一个函数的缓存,或者使用st.cache_resource.clear()清除整个缓存。

函数的参数必须是可哈希的才能缓存它。如果你有一个不可哈希的参数(如数据库连接)或一个你想从缓存中排除的参数,请在参数名称前使用下划线前缀。在这种情况下,当所有其他参数与之前的函数调用匹配时,Streamlit 将返回一个缓存的值。或者,你可以使用 hash_funcs 声明自定义哈希函数。

要缓存数据,请使用st.cache_data。了解更多关于缓存的信息,请访问 https://docs.streamlit.io/develop/concepts/architecture/caching

函数签名[来源]

st.cache_resource(func, *, ttl, max_entries, show_spinner, validate, experimental_allow_widgets, hash_funcs=None)

参数

func (callable)

创建缓存资源的函数。Streamlit 会对函数的源代码进行哈希处理。

ttl (float, timedelta, str, or None)

缓存中条目的最大保留时间。可以是以下之一:

  • None 如果缓存条目永不过期(默认)。
  • 一个数字,指定时间(以秒为单位)。
  • 一个字符串,指定时间,格式支持 Pandas的Timedelta构造函数, 例如 "1d", "1.5 days", 或 "1h23s"
  • 一个来自 Python内置的datetime库timedelta 对象, 例如 timedelta(days=1)

max_entries (int or None)

缓存中保留的最大条目数,或为无限制缓存设置为None。当向已满的缓存添加新条目时,最旧的缓存条目将被移除。默认为None。

show_spinner (bool or str)

启用加载动画。默认值为True,当出现“缓存未命中”且正在创建缓存资源时显示加载动画。如果为字符串,show_spinner参数的值将用作加载动画的文本。

validate (callable or None)

一个可选的验证函数,用于缓存数据。每次访问缓存值时都会调用validate。它接收缓存值作为其唯一参数,并且必须返回一个布尔值。如果validate返回False,当前的缓存值将被丢弃,并且装饰的函数将被调用来计算一个新值。这对于检查数据库连接的健康状态等场景非常有用。

experimental_allow_widgets (bool)

删除

缓存的widget重放功能已在1.38版本中移除。请从您的缓存装饰器中移除experimental_allow_widgets参数。此参数将在未来的版本中被移除。

允许在缓存函数中使用widgets。默认为False。

hash_funcs (dict or None)

类型或完全限定名称到哈希函数的映射。 这用于覆盖Streamlit缓存机制内部的哈希器行为:当哈希器遇到一个对象时,它将首先检查其类型是否与此字典中的键匹配,如果匹配,则使用提供的函数为其生成哈希值。请参阅下面的示例以了解如何使用此功能。

示例

import streamlit as st

@st.cache_resource
def get_database_session(url):
    # Create a database session object that points to the URL.
    return session

s1 = get_database_session(SESSION_URL_1)
# Actually executes the function, since this is the first time it was
# encountered.

s2 = get_database_session(SESSION_URL_1)
# Does not execute the function. Instead, returns its previously computed
# value. This means that now the connection object in s1 is the same as in s2.

s3 = get_database_session(SESSION_URL_2)
# This is a different URL, so the function executes.

默认情况下,cache_resource函数的所有参数都必须是可哈希的。 任何以_开头的参数都不会被哈希。您可以将此用作不可哈希参数的“逃生舱口”:

import streamlit as st

@st.cache_resource
def get_database_session(_sessionmaker, url):
    # Create a database connection object that points to the URL.
    return connection

s1 = get_database_session(create_sessionmaker(), DATA_URL_1)
# Actually executes the function, since this is the first time it was
# encountered.

s2 = get_database_session(create_sessionmaker(), DATA_URL_1)
# Does not execute the function. Instead, returns its previously computed
# value - even though the _sessionmaker parameter was different
# in both calls.

cache_resource 函数的缓存可以通过程序清除:

import streamlit as st

@st.cache_resource
def get_database_session(_sessionmaker, url):
    # Create a database connection object that points to the URL.
    return connection

fetch_and_clean_data.clear(_sessionmaker, "https://streamlit.io/")
# Clear the cached entry for the arguments provided.

get_database_session.clear()
# Clear all cached entries for this function.

要覆盖默认的哈希行为,可以传递一个自定义的哈希函数。 你可以通过将一个类型(例如Person)映射到一个哈希 函数(str)来实现,如下所示:

import streamlit as st
from pydantic import BaseModel

class Person(BaseModel):
    name: str

@st.cache_resource(hash_funcs={Person: str})
def get_person_name(person: Person):
    return person.name

或者,您可以将类型的完全限定名称(例如 "__main__.Person")映射到哈希函数:

import streamlit as st
from pydantic import BaseModel

class Person(BaseModel):
    name: str

@st.cache_resource(hash_funcs={"__main__.Person": str})
def get_person_name(person: Person):
    return person.name

清除所有cache_resource缓存。

函数签名[source]

st.cache_resource.clear()

示例

在下面的示例中,按下“清除所有”按钮将清除所有cache_resource缓存。即清除所有使用@st.cache_resource装饰的函数中的缓存全局资源。

import streamlit as st from transformers import BertModel @st.cache_resource def get_database_session(url): # Create a database session object that points to the URL. return session @st.cache_resource def get_model(model_type): # Create a model of the specified type. return BertModel.from_pretrained(model_type) if st.button("Clear All"): # Clears all st.cache_resource caches: st.cache_resource.clear()

清除缓存函数的相关缓存。

如果没有传递参数,Streamlit 将清除为该函数缓存的所有值。如果传递了参数,Streamlit 将仅清除这些参数的缓存值。

函数签名[source]

CachedFunc.clear(*args, **kwargs)

参数

*args (Any)

缓存函数的参数。

**kwargs (Any)

缓存函数的关键字参数。

示例

import streamlit as st
import time

@st.cache_data
def foo(bar):
    time.sleep(2)
    st.write(f"Executed foo({bar}).")
    return bar

if st.button("Clear all cached values for `foo`", on_click=foo.clear):
    foo.clear()

if st.button("Clear the cached value of `foo(1)`"):
    foo.clear(1)

foo(1)
foo(2)

自版本1.16.0以来,缓存的函数可以包含Streamlit命令!例如,您可以这样做:

from transformers import pipeline @st.cache_resource def load_model(): model = pipeline("sentiment-analysis") st.success("Loaded NLP model from Hugging Face!") # 👈 Show a success message return model

众所周知,Streamlit 只会在之前没有缓存的情况下运行此函数。在第一次运行时,st.success 消息将出现在应用程序中。但在后续运行中会发生什么?它仍然会出现!Streamlit 意识到缓存函数内部有一个 st. 命令,在第一次运行时保存它,并在后续运行中重放它。重放静态元素适用于两种缓存装饰器。

你也可以使用这个功能来缓存你的UI的整个部分:

@st.cache_resource def load_model(): st.header("Data analysis") model = torchvision.models.resnet50(weights=ResNet50_Weights.DEFAULT) st.success("Loaded model!") st.write("Turning on evaluation mode...") model.eval() st.write("Here's the model:") return model

你也可以在缓存函数中使用交互式输入小部件,比如st.sliderst.text_input。目前,小部件重放是一个实验性功能。要启用它,你需要设置experimental_allow_widgets参数:

@st.cache_resource(experimental_allow_widgets=True) # 👈 Set the parameter def load_model(): pretrained = st.checkbox("Use pre-trained model:") # 👈 Add a checkbox model = torchvision.models.resnet50(weights=ResNet50_Weights.DEFAULT, pretrained=pretrained) return model

Streamlit 将复选框视为缓存函数的额外输入参数。如果您取消选中它,Streamlit 将检查是否已经为此复选框状态缓存了函数。如果是,它将返回缓存的值。如果不是,它将使用新的滑块值重新运行函数。

在缓存函数中使用小部件非常强大,因为它允许您缓存应用程序的整个部分。但这可能很危险!由于Streamlit将小部件值视为额外的输入参数,它很容易导致内存使用过多。想象一下,您的缓存函数有五个滑块并返回一个100 MB的DataFrame。然后,我们将为这五个滑块值的每个排列添加100 MB到缓存中——即使这些滑块不影响返回的数据!这些添加可能会使您的缓存迅速爆炸。如果您在缓存函数中使用小部件,请注意此限制。我们建议仅在UI的隔离部分使用此功能,其中小部件直接影响缓存的返回值。

priority_high

警告

对缓存函数中小部件的支持目前处于实验阶段。我们可能会随时更改或删除它,恕不另行通知。请谨慎使用!

push_pin

注意

目前有两个小部件在缓存函数中不受支持:st.file_uploaderst.camera_input。我们未来可能会支持它们。如果你需要它们,请随时在GitHub上提出问题

forum

还有问题吗?

我们的 论坛 充满了有用的信息和Streamlit专家。