Gradio 代理与 MCP 黑客马拉松

获奖者
Gradio logo
  1. 其他教程
  2. 在其他编程语言中使用 Gradio

在其他编程语言中使用 Gradio

核心 `gradio` 库是一个 Python 库。但由于 Python 能够与外部进程交互,你也可以使用 `gradio` 为其他语言编写的程序创建用户界面。通过使用 Python 的 `subprocess` 模块,你可以调用用 C++、Rust 或几乎任何其他语言编写的程序,从而使 `gradio` 成为非 Python 应用程序的灵活 UI 层。

在本文中,我们将通过 Python 的 `subprocess` 模块调用用 C++ 和 Rust 编写的代码,来讲解如何将 `gradio` 与 C++ 和 Rust 集成。我们还将讨论如何与 R 配合使用 Gradio,这甚至更简单,这要归功于 reticulate R 包,它使得在 R 中安装和导入 Python 模块成为可能。

使用 Gradio 和 C++

让我们从一个简单的示例开始,将 C++ 程序集成到 Gradio 应用中。假设我们有以下 C++ 程序,用于两个数字相加:

// add.cpp
#include <iostream>

int main() {
    double a, b;
    std::cin >> a >> b;
    std::cout << a + b << std::endl;
    return 0;
}

该程序从标准输入读取两个数字,将它们相加,然后输出结果。

我们可以使用 Python 的 `subprocess` 模块围绕这个 C++ 程序构建 Gradio 界面。下面是相应的 Python 代码:

import gradio as gr
import subprocess

def add_numbers(a, b):
    process = subprocess.Popen(
        ['./add'], 
        stdin=subprocess.PIPE, 
        stdout=subprocess.PIPE, 
        stderr=subprocess.PIPE
    )
    output, error = process.communicate(input=f"{a} {b}\n".encode())
    
    if error:
        return f"Error: {error.decode()}"
    return float(output.decode().strip())

demo = gr.Interface(
    fn=add_numbers, 
    inputs=[gr.Number(label="Number 1"), gr.Number(label="Number 2")], 
    outputs=gr.Textbox(label="Result")
)

demo.launch()

在这里,`subprocess.Popen` 用于执行编译后的 C++ 程序 (`add`),传递输入值,并捕获输出。你可以通过运行以下命令编译 C++ 程序:

g++ -o add add.cpp

这个例子展示了使用 `subprocess` 从 Python 调用 C++ 并围绕它构建 Gradio 界面是多么容易。

使用 Gradio 和 Rust

现在,我们来看另一个例子:调用 Rust 程序来对图像应用深褐色滤镜。Rust 代码可能如下所示:

// sepia.rs
extern crate image;

use image::{GenericImageView, ImageBuffer, Rgba};

fn sepia_filter(input: &str, output: &str) {
    let img = image::open(input).unwrap();
    let (width, height) = img.dimensions();
    let mut img_buf = ImageBuffer::new(width, height);

    for (x, y, pixel) in img.pixels() {
        let (r, g, b, a) = (pixel[0] as f32, pixel[1] as f32, pixel[2] as f32, pixel[3]);
        let tr = (0.393 * r + 0.769 * g + 0.189 * b).min(255.0);
        let tg = (0.349 * r + 0.686 * g + 0.168 * b).min(255.0);
        let tb = (0.272 * r + 0.534 * g + 0.131 * b).min(255.0);
        img_buf.put_pixel(x, y, Rgba([tr as u8, tg as u8, tb as u8, a]));
    }

    img_buf.save(output).unwrap();
}

fn main() {
    let args: Vec<String> = std::env::args().collect();
    if args.len() != 3 {
        eprintln!("Usage: sepia <input_file> <output_file>");
        return;
    }
    sepia_filter(&args[1], &args[2]);
}

这个 Rust 程序对图像应用深褐色滤镜。它接受两个命令行参数:输入图像路径和输出图像路径。你可以使用以下命令编译此程序:

cargo build --release

现在,我们可以从 Python 调用此 Rust 程序,并使用 Gradio 构建界面:

import gradio as gr
import subprocess

def apply_sepia(input_path):
    output_path = "output.png"
    
    process = subprocess.Popen(
        ['./target/release/sepia', input_path, output_path], 
        stdout=subprocess.PIPE, 
        stderr=subprocess.PIPE
    )
    process.wait()
    
    return output_path

demo = gr.Interface(
    fn=apply_sepia, 
    inputs=gr.Image(type="filepath", label="Input Image"), 
    outputs=gr.Image(label="Sepia Image")
)

demo.launch()

在这里,当用户上传图像并点击提交时,Gradio 会调用 Rust 二进制文件 (`sepia`) 来处理图像,并将经过深褐色滤镜处理的输出返回给 Gradio。

此设置展示了如何将用 Rust 编写的性能关键或专用代码集成到 Gradio 界面中。

使用 Gradio 和 R(通过 `reticulate`)

由于 `reticulate` 包,将 Gradio 与 R 集成特别简单,它允许你在 R 中直接运行 Python 代码。让我们来看一个在 R 中使用 Gradio 的例子。

安装

首先,你需要在 R 中安装 `reticulate` 包:

install.packages("reticulate")

安装后,你可以使用该包直接从 R 脚本内部运行 Gradio。

library(reticulate)

py_install("gradio", pip = TRUE)

gr <- import("gradio") # import gradio as gr

构建 Gradio 应用程序

安装并导入 gradio 后,我们现在可以访问 gradio 的应用程序构建方法。让我们为一个返回问候语的 R 函数构建一个简单的应用程序:

greeting <- \(name) paste("Hello", name)

app <- gr$Interface(
  fn = greeting,
  inputs = gr$Text(label = "Name"),
  outputs = gr$Text(label = "Greeting"),
  title = "Hello! &#128515 &#128075"
)

app$launch(server_name = "localhost", 
           server_port = as.integer(3000))

感谢 @IfeanyiIdiaye 为此部分做出的贡献。你可以在这里查看更多示例,包括使用 Gradio Blocks 在 R 中构建机器学习应用程序。