Gradio Agents 和 MCP Hackathon

获奖者
Gradio logo
  1. 其他教程
  2. 运行后台任务

运行后台任务

介绍

本指南解释了如何从 Gradio 应用运行后台任务。后台任务是你希望在应用的请求-响应生命周期之外执行的操作,可以是一次性执行,也可以是按周期计划执行。后台任务的例子包括定期将数据同步到外部数据库或通过电子邮件发送模型预测报告。

概述

我们将创建一个简单的“Google 表单式”应用程序,用于收集 Gradio 库用户的反馈。我们将使用本地 SQLite 数据库存储数据,但会定期将数据库状态与 HuggingFace 数据集同步,以便用户评论始终得到备份。同步将在每 60 秒运行一次的后台任务中进行。

在演示结束时,你将拥有一个像这样的完全可用的应用程序。

步骤 1 - 编写数据库逻辑 💾

我们的应用程序将存储评论者的姓名、他们对 Gradio 的 1 到 5 分评价,以及他们希望分享的关于该库的任何评论。让我们编写一些代码来创建一个数据库表以存储这些数据。我们还将编写一些函数来向该表插入评论并获取最新的 10 条评论。

我们将使用 sqlite3 库连接到我们的 SQLite 数据库,但 Gradio 可以与任何库配合使用。

代码如下所示:

DB_FILE = "./reviews.db"
db = sqlite3.connect(DB_FILE)

# Create table if it doesn't already exist
try:
    db.execute("SELECT * FROM reviews").fetchall()
    db.close()
except sqlite3.OperationalError:
    db.execute(
        '''
        CREATE TABLE reviews (id INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL,
                              created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP NOT NULL,
                              name TEXT, review INTEGER, comments TEXT)
        ''')
    db.commit()
    db.close()

def get_latest_reviews(db: sqlite3.Connection):
    reviews = db.execute("SELECT * FROM reviews ORDER BY id DESC limit 10").fetchall()
    total_reviews = db.execute("Select COUNT(id) from reviews").fetchone()[0]
    reviews = pd.DataFrame(reviews, columns=["id", "date_created", "name", "review", "comments"])
    return reviews, total_reviews


def add_review(name: str, review: int, comments: str):
    db = sqlite3.connect(DB_FILE)
    cursor = db.cursor()
    cursor.execute("INSERT INTO reviews(name, review, comments) VALUES(?,?,?)", [name, review, comments])
    db.commit()
    reviews, total_reviews = get_latest_reviews(db)
    db.close()
    return reviews, total_reviews

当 Gradio 应用程序加载时,我们还要编写一个函数来加载最新的评论。

def load_data():
    db = sqlite3.connect(DB_FILE)
    reviews, total_reviews = get_latest_reviews(db)
    db.close()
    return reviews, total_reviews

步骤 2 - 创建 Gradio 应用 ⚡

现在我们已经定义了数据库逻辑,我们可以使用 Gradio 创建一个动态网页来收集用户反馈!

with gr.Blocks() as demo:
    with gr.Row():
        with gr.Column():
            name = gr.Textbox(label="Name", placeholder="What is your name?")
            review = gr.Radio(label="How satisfied are you with using gradio?", choices=[1, 2, 3, 4, 5])
            comments = gr.Textbox(label="Comments", lines=10, placeholder="Do you have any feedback on gradio?")
            submit = gr.Button(value="Submit Feedback")
        with gr.Column():
            data = gr.Dataframe(label="Most recently created 10 rows")
            count = gr.Number(label="Total number of reviews")
    submit.click(add_review, [name, review, comments], [data, count])
    demo.load(load_data, None, [data, count])

步骤 3 - 与 HuggingFace 数据集同步 🤗

我们可以在步骤 2 之后调用 demo.launch() 并拥有一个功能齐全的应用程序。然而,我们的数据将存储在本地机器上。如果 SQLite 文件不小心被删除了,我们将丢失所有评论!所以让我们将数据备份到 HuggingFace Hub 上的一个数据集。

在继续之前,请在此处创建一个数据集。

现在,在脚本的顶部,我们将使用 HuggingFace Hub 客户端库连接到我们的数据集并拉取最新的备份。

TOKEN = os.environ.get('HUB_TOKEN')
repo = huggingface_hub.Repository(
    local_dir="data",
    repo_type="dataset",
    clone_from="<name-of-your-dataset>",
    use_auth_token=TOKEN
)
repo.git_pull()

shutil.copyfile("./data/reviews.db", DB_FILE)

请注意,你需要从 HuggingFace 的“设置”选项卡获取访问令牌,上述代码才能正常工作。在脚本中,令牌是通过环境变量安全访问的。

access_token

现在我们将创建一个后台任务,每 60 秒将我们的本地数据库同步到数据集 Hub。我们将使用 AdvancedPythonScheduler 来处理调度。然而,这不是唯一可用的任务调度库。你可以随意使用任何你熟悉的库。

备份数据的函数将如下所示:

from apscheduler.schedulers.background import BackgroundScheduler

def backup_db():
    shutil.copyfile(DB_FILE, "./data/reviews.db")
    db = sqlite3.connect(DB_FILE)
    reviews = db.execute("SELECT * FROM reviews").fetchall()
    pd.DataFrame(reviews).to_csv("./data/reviews.csv", index=False)
    print("updating db")
    repo.push_to_hub(blocking=False, commit_message=f"Updating data at {datetime.datetime.now()}")


scheduler = BackgroundScheduler()
scheduler.add_job(func=backup_db, trigger="interval", seconds=60)
scheduler.start()

步骤 4 (奖励) - 部署到 HuggingFace Spaces

你可以使用 HuggingFace Spaces 平台免费部署此应用程序 ✨

如果你之前没有使用过 Spaces,请遵循此处的先前指南。你需要在指南中使用 HUB_TOKEN 环境变量作为秘密。

结论

恭喜!你已经知道如何按计划从 Gradio 应用运行后台任务了 ⏲️。

此处 查看在 Spaces 上运行的应用程序。完整代码在 此处