
Laboratório de pesquisa em segurança reproduzindo CVE-2023-6572 (GHSA-gqvf-3hgp-5hxv): injeção de comandos no tratamento de workflow_run do gradio-app/gradio em generate-changeset.yml
Artefacto de investigação automatizado — não é o projeto original.
Este repositório é um laboratório descartável construído por um sistema automatizado para uma dissertação de mestrado na Université Laval sobre a reprodução de vulnerabilidades publicadas em workflows do GitHub Actions. É um instantâneo verbatim de
gradio-app/gradiono commit1d986217f6f4fc1829e528d2afe365635788204f(2023-11-03), redistribuído sob a licença do próprio projeto, cujo ficheiro está incluído inalterado neste instantâneo.O projeto original não está envolvido, nunca é alvo, e a vulnerabilidade aqui estudada já é pública. Todos os segredos e variáveis neste repositório são valores fictícios gerados aleatoriamente — nenhuma credencial real está presente. As referências de ações e imagens de runner estão fixadas no que resolveram em 2023-11-03; consulte
pinning.mdna saída do sistema para todas as alterações feitas ao instantâneo.Perguntas ou objeções: [email protected]
Website | Documentation | Guides | Getting Started | Examples | 中文
Gradio é uma biblioteca Python de código aberto usada para criar demonstrações e aplicações web de machine learning e ciência de dados.
Com o Gradio, pode criar rapidamente uma interface de utilizador bonita em torno dos seus modelos de machine learning ou fluxos de trabalho de ciência de dados e permitir que as pessoas "experimentem" arrastando e soltando as suas próprias imagens, colando texto, gravando a própria voz e interagindo com a sua demonstração, tudo através do navegador.

O Gradio é útil para:
Demonstrar os seus modelos de machine learning a clientes/colaboradores/utilizadores/estudantes.
Implementar os seus modelos rapidamente com links partilháveis automáticos e obter feedback sobre o desempenho do modelo.
Depurar o seu modelo interativamente durante o desenvolvimento usando ferramentas de manipulação de entrada integradas.
Pré-requisito: o Gradio requer Python 3.8 ou superior, e é só isso!
Uma das melhores formas de partilhar o seu modelo de machine learning, API ou fluxo de trabalho de ciência de dados com outros é criar uma aplicação interativa que permita aos seus utilizadores ou colegas experimentar a demonstração nos seus navegadores.
O Gradio permite-lhe criar demonstrações e partilhá-las, tudo em Python. E normalmente em apenas algumas linhas de código! Então vamos começar.
Para colocar o Gradio a funcionar com um exemplo simples de "Olá, Mundo", siga estes três passos:
1. Instale o Gradio usando pip:
pip install gradio
2. Execute o código abaixo como um script Python ou num Jupyter Notebook (ou Google Colab):
import gradio as gr
def greet(name):
return "Hello " + name + "!"
demo = gr.Interface(fn=greet, inputs="text", outputs="text")
demo.launch()
Abreviámos o nome importado para gr para melhor legibilidade do código que usa Gradio. Esta é uma convenção amplamente adotada que deve seguir para que qualquer pessoa que trabalhe com o seu código o entenda facilmente.
3. A demonstração abaixo aparecerá automaticamente dentro do Jupyter Notebook, ou abrirá num navegador em http://localhost:7860 se executada a partir de um script:

Ao desenvolver localmente, se quiser executar o código como um script Python, pode usar a CLI do Gradio para iniciar a aplicação em modo de recarga, que proporcionará um desenvolvimento rápido e sem interrupções. Saiba mais sobre recarga no Guia de Recarga Automática.
gradio app.py
Nota: também pode executar python app.py, mas não fornecerá o mecanismo de recarga automática.
InterfaceReparará que, para criar a demonstração, criámos um gr.Interface. Esta classe Interface pode envolver qualquer função Python com uma interface de utilizador. No exemplo acima, vimos uma função simples baseada em texto, mas a função pode ser qualquer coisa, desde um gerador de música a uma calculadora de impostos ou à função de previsão de um modelo de machine learning pré-treinado.
A classe principal Interface é inicializada com três parâmetros obrigatórios:
fn: a função a envolver com uma interface de utilizadorinputs: qual(is) componente(s) usar para a entrada (ex.: "text", "image" ou "audio")outputs: qual(is) componente(s) usar para a saída (ex.: "text", "image" ou "label")Vamos analisar mais de perto estes componentes usados para fornecer entrada e saída.
Vimos alguns componentes simples Textbox nos exemplos anteriores, mas e se quiser alterar a aparência ou o comportamento dos componentes da interface?
Digamos que quer personalizar o campo de texto de entrada — por exemplo, que seja maior e tenha um texto de espaço reservado. Se usarmos a classe real para Textbox em vez do atalho de string, terá acesso a muito mais personalização através dos atributos dos componentes.
import gradio as gr
def greet(name):
return "Hello " + name + "!"
demo = gr.Interface(
fn=greet,
inputs=gr.Textbox(lines=2, placeholder="Name Here..."),
outputs="text",
)
demo.launch()

Suponha que tinha uma função mais complexa, com múltiplas entradas e saídas. No exemplo abaixo, definimos uma função que recebe uma string, um booleano e um número, e devolve uma string e um número. Veja como passar uma lista de componentes de entrada e saída.
import gradio as gr
def greet(name, is_morning, temperature):
salutation = "Good morning" if is_morning else "Good evening"
greeting = f"{salutation} {name}. It is {temperature} degrees today"
celsius = (temperature - 32) * 5 / 9
return greeting, round(celsius, 2)
demo = gr.Interface(
fn=greet,
inputs=["text", "checkbox", gr.Slider(0, 100)],
outputs=["text", "number"],
)
demo.launch()

Basta envolver os componentes numa lista. Cada componente na lista inputs corresponde a um dos parâmetros da função, por ordem. Cada componente na lista outputs corresponde a um dos valores devolvidos pela função, novamente por ordem.
O Gradio suporta muitos tipos de componentes, como Image, DataFrame, Video ou Label. Vamos experimentar uma função de imagem-para-imagem para ter uma ideia destes!
import numpy as np
import gradio as gr
def sepia(input_img):
sepia_filter = np.array([
[0.393, 0.769, 0.189],
[0.349, 0.686, 0.168],
[0.272, 0.534, 0.131]
])
sepia_img = input_img.dot(sepia_filter.T)
sepia_img /= sepia_img.max()
return sepia_img
demo = gr.Interface(sepia, gr.Image(width=200, height=200), "image")
demo.launch()

Ao usar o componente Image como entrada, a sua função receberá um array NumPy com a forma (height, width, 3), onde a última dimensão representa os valores RGB. Devolveremos também uma imagem na forma de um array NumPy.
Também pode definir o tipo de dados usado pelo componente com o argumento de palavra-chave type=. Por exemplo, se quisesse que a sua função recebesse um caminho de ficheiro para uma imagem em vez de um array NumPy, o componente de entrada Image poderia ser escrito como:
gr.Image(type="filepath", shape=...)
Note também que o nosso componente de entrada Image vem com um botão de edição 🖉, que permite recortar e ampliar imagens. Manipular imagens desta forma pode ajudar a revelar enviesamentos ou falhas ocultas num modelo de machine learning!
Pode ler mais sobre os muitos componentes e como usá-los na documentação do Gradio.
O Gradio inclui uma classe de alto nível, gr.ChatInterface, que é semelhante ao gr.Interface, mas é especificamente concebida para interfaces de utilizador de chatbot. A classe gr.ChatInterface também envolve uma função, mas esta função deve ter uma assinatura específica. A função deve receber dois argumentos: message e depois history (os argumentos podem ter qualquer nome, mas devem estar nesta ordem)
message: uma str que representa a entrada do utilizadorhistory: uma list de list que representa as conversas até esse ponto. Cada lista interna consiste em duas str que representam um par: [entrada do utilizador, resposta do bot].A sua função deve devolver uma única resposta em string, que é a resposta do bot à entrada específica do utilizador message.
Fora isso, gr.ChatInterface não tem parâmetros obrigatórios (embora vários estejam disponíveis para personalização da interface).
Aqui está um exemplo simples:
import random
import gradio as gr
def random_response(message, history):
return random.choice(["Yes", "No"])
demo = gr.ChatInterface(random_response)
demo.launch()

O Gradio oferece duas abordagens para criar aplicações:
1. Interface e ChatInterface, que fornecem uma abstração de alto nível para criar demonstrações, como temos vindo a discutir até agora.
2. Blocks, uma API de baixo nível para conceber aplicações web com layouts e fluxos de dados mais flexíveis. O Blocks permite-lhe fazer coisas como suportar múltiplos fluxos de dados e demonstrações, controlar onde os componentes aparecem na página, lidar com fluxos de dados complexos (ex.: saídas podem servir como entradas para outras funções) e atualizar propriedades/visibilidade dos componentes com base na interação do utilizador — tudo ainda em Python. Se esta personalização é o que precisa, experimente Blocks!
Vamos ver um exemplo simples. Note como a API aqui difere do Interface.
import gradio as gr
def greet(name):
return "Hello " + name + "!"
with gr.Blocks() as demo:
name = gr.Textbox(label="Name")
output = gr.Textbox(label="Output Box")
greet_btn = gr.Button("Greet")
greet_btn.click(fn=greet, inputs=name, outputs=output, api_name="greet")
demo.launch()

Pontos a notar:
Blocks são criados com uma cláusula with, e qualquer componente criado dentro desta cláusula é automaticamente adicionado à aplicação.Button, e depois foi adicionado um ouvinte de eventos click a este botão. A API para isto deve parecer familiar! Tal como um Interface, o método click recebe uma função Python, componentes de entrada e componentes de saída.Aqui está uma aplicação para lhe dar uma ideia do que é possível com Blocks:
import numpy as np
import gradio as gr
def flip_text(x):
return x[::-1]
def flip_image(x):
return np.fliplr(x)
with gr.Blocks() as demo:
gr.Markdown("Flip text or image files using this demo.")
with gr.Tab("Flip Text"):
text_input = gr.Textbox()
text_output = gr.Textbox()
text_button = gr.Button("Flip")
with gr.Tab("Flip Image"):
with gr.Row():
image_input = gr.Image()
image_output = gr.Image()
image_button = gr.Button("Flip")
with gr.Accordion("Open for More!"):
gr.Markdown("Look at me...")
text_button.click(flip_text, inputs=text_input, outputs=text_output)
image_button.click(flip_image, inputs=image_input, outputs=image_output)
demo.launch()

Há muito mais a acontecer aqui! Vamos abordar como criar aplicações Blocks complexas como esta na secção construir com blocks para si.
Parabéns, agora já está familiarizado com os fundamentos do Gradio! 🥳 Vá ao nosso próximo guia para aprender mais sobre as principais funcionalidades do Gradio.
O Gradio é construído com muitas bibliotecas de código aberto fantásticas, apoie-as também!
O Gradio é licenciado sob a Apache License 2.0 encontrada no ficheiro LICENSE no diretório raiz deste repositório.
Consulte também o artigo Gradio: Hassle-Free Sharing and Testing of ML Models in the Wild, ICML HILL 2019, e cite-o se usar o Gradio no seu trabalho.
@article{abid2019gradio,
title = {Gradio: Hassle-Free Sharing and Testing of ML Models in the Wild},
author = {Abid, Abubakar and Abdalla, Ali and Abid, Ali and Khan, Dawood and Alfozan, Abdulrahman and Zou, James},
journal = {arXiv preprint arXiv:1906.02569},
year = {2019},
}