
Sicherheitsforschungs-Labor, das CVE-2023-6572 (GHSA-gqvf-3hgp-5hxv) reproduziert: Befehlsinjektion in der workflow_run-Verarbeitung von generate-changeset.yml in gradio-app/gradio
Automatisiertes Forschungsartefakt — nicht das Upstream-Projekt.
Dieses Repository ist ein Wegwerf-Labor, das von einer automatisierten Testumgebung für eine Masterarbeit an der Université Laval zur Reproduktion veröffentlichter GitHub-Actions-Workflow-Schwachstellen erstellt wurde. Es ist eine wörtliche Momentaufnahme von
gradio-app/gradiobeim Commit1d986217f6f4fc1829e528d2afe365635788204f(2023-11-03), weiterverbreitet unter der eigenen Lizenz des Projekts, deren Datei unverändert in dieser Momentaufnahme enthalten ist.Das Upstream-Projekt ist nicht beteiligt, wird niemals angegriffen, und die hier untersuchte Schwachstelle ist bereits öffentlich bekannt. Jedes Geheimnis und jede Variable in diesem Repository ist ein zufällig generierter Dummy-Wert — es sind keine echten Anmeldedaten vorhanden. Aktionsreferenzen und Runner-Images sind auf das fixiert, was sie am 2023-11-03 aufgelöst haben; siehe
pinning.mdin der Testumgebungsausgabe für jede an der Momentaufnahme vorgenommene Änderung.Fragen oder Einwände: [email protected]
Website | Dokumentation | Anleitungen | Erste Schritte | Beispiele | 中文
Gradio ist eine Open-Source-Python-Bibliothek, mit der Machine-Learning- und Data-Science-Demos sowie Webanwendungen erstellt werden.
Mit Gradio kannst du schnell eine schöne Benutzeroberfläche um deine Machine-Learning-Modelle oder deinen Data-Science-Workflow erstellen und es Menschen ermöglichen, sie "auszuprobieren", indem sie eigene Bilder per Drag-and-Drop einfügen, Text einfügen, ihre eigene Stimme aufnehmen und mit deiner Demo interagieren — alles über den Browser.

Gradio ist nützlich für:
Demonstrieren deiner Machine-Learning-Modelle für Kunden/Mitarbeiter/Nutzer/Studierende.
Bereitstellen deiner Modelle schnell mit automatischen teilbaren Links und Erhalten von Feedback zur Modellleistung.
Debuggen deines Modells interaktiv während der Entwicklung mit integrierten Werkzeugen zur Eingabemanipulation.
Voraussetzung: Gradio benötigt Python 3.8 oder höher, das ist alles!
Eine der besten Möglichkeiten, dein Machine-Learning-Modell, deine API oder deinen Data-Science-Workflow mit anderen zu teilen, ist die Erstellung einer interaktiven App, die es deinen Nutzern oder Kollegen ermöglicht, die Demo in ihrem Browser auszuprobieren.
Gradio ermöglicht es dir, Demos zu erstellen und zu teilen, alles in Python. Und das meist mit nur wenigen Zeilen Code! Also lass uns loslegen.
Um Gradio mit einem einfachen "Hallo, Welt"-Beispiel zum Laufen zu bringen, folge diesen drei Schritten:
1. Installiere Gradio mit pip:
pip install gradio
2. Führe den folgenden Code als Python-Skript oder in einem Jupyter-Notebook aus (oder Google Colab):
import gradio as gr
def greet(name):
return "Hello " + name + "!"
demo = gr.Interface(fn=greet, inputs="text", outputs="text")
demo.launch()
Wir kürzen den importierten Namen zu gr, um die Lesbarkeit des Codes mit Gradio zu verbessern. Dies ist eine weit verbreitete Konvention, der du folgen solltest, damit jeder, der mit deinem Code arbeitet, ihn leicht verstehen kann.
3. Die folgende Demo erscheint automatisch im Jupyter-Notebook oder öffnet sich in einem Browser unter http://localhost:7860, wenn sie aus einem Skript ausgeführt wird:

Wenn du lokal entwickelst und den Code als Python-Skript ausführen möchtest, kannst du die Gradio-CLI verwenden, um die Anwendung im Reload-Modus zu starten, was eine nahtlose und schnelle Entwicklung ermöglicht. Erfahre mehr über das Neuladen im Auto-Reloading-Guide.
gradio app.py
Hinweis: Du kannst auch python app.py ausführen, aber das bietet keinen automatischen Reload-Mechanismus.
Interface-KlasseDu wirst feststellen, dass wir zur Erstellung der Demo ein gr.Interface erstellt haben. Diese Interface-Klasse kann jede Python-Funktion mit einer Benutzeroberfläche umhüllen. Im obigen Beispiel haben wir eine einfache textbasierte Funktion gesehen, aber die Funktion könnte alles sein, von einem Musikgenerator über einen Steuerrechner bis hin zur Vorhersagefunktion eines vortrainierten Machine-Learning-Modells.
Die zentrale Interface-Klasse wird mit drei erforderlichen Parametern initialisiert:
fn: die Funktion, um die eine Benutzeroberfläche gelegt wirdinputs: welche Komponente(n) für die Eingabe verwendet werden (z. B. "text", "image" oder "audio")outputs: welche Komponente(n) für die Ausgabe verwendet werden (z. B. "text", "image" oder "label")Schauen wir uns diese Komponenten, die für Eingabe und Ausgabe verwendet werden, genauer an.
Wir haben in den vorherigen Beispielen einige einfache Textbox-Komponenten gesehen, aber was, wenn du ändern möchtest, wie die UI-Komponenten aussehen oder sich verhalten?
Angenommen, du möchtest das Eingabetextfeld anpassen — zum Beispiel größer machen und einen Textplatzhalter hinzufügen. Wenn wir die eigentliche Klasse für Textbox anstelle der String-Verknüpfung verwenden, hast du über Komponentenattribute viel mehr Anpassungsmöglichkeiten.
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()

Angenommen, du hast eine komplexere Funktion mit mehreren Eingaben und Ausgaben. Im folgenden Beispiel definieren wir eine Funktion, die einen String, einen Boolean und eine Zahl entgegennimmt und einen String und eine Zahl zurückgibt. Schau dir an, wie du eine Liste von Eingabe- und Ausgabekomponenten übergibst.
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()

Du umschließt die Komponenten einfach in einer Liste. Jede Komponente in der inputs-Liste entspricht einem der Parameter der Funktion, in der Reihenfolge. Jede Komponente in der outputs-Liste entspricht einem der von der Funktion zurückgegebenen Werte, ebenfalls in der Reihenfolge.
Gradio unterstützt viele Arten von Komponenten, wie Image, DataFrame, Video oder Label. Probieren wir eine Bild-zu-Bild-Funktion aus, um ein Gefühl dafür zu bekommen!
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()

Wenn die Image-Komponente als Eingabe verwendet wird, erhält deine Funktion ein NumPy-Array mit der Form (height, width, 3), wobei die letzte Dimension die RGB-Werte darstellt. Wir geben auch ein Bild in Form eines NumPy-Arrays zurück.
Du kannst auch den von der Komponente verwendeten Datentyp mit dem Schlüsselwortargument type= festlegen. Wenn du zum Beispiel möchtest, dass deine Funktion einen Dateipfad zu einem Bild anstelle eines NumPy-Arrays erhält, könnte die Eingabe-Image-Komponente wie folgt geschrieben werden:
gr.Image(type="filepath", shape=...)
Beachte auch, dass unsere Eingabe-Image-Komponente über eine Bearbeitungsschaltfläche 🖉 verfügt, die das Zuschneiden und Zoomen von Bildern ermöglicht. Das Manipulieren von Bildern auf diese Weise kann helfen, Verzerrungen oder versteckte Fehler in einem Machine-Learning-Modell aufzudecken!
Du kannst mehr über die vielen Komponenten und deren Verwendung in der Gradio-Dokumentation lesen.
Gradio enthält eine High-Level-Klasse, gr.ChatInterface, die gr.Interface ähnelt, aber speziell für Chatbot-Benutzeroberflächen entwickelt wurde. Die gr.ChatInterface-Klasse umhüllt ebenfalls eine Funktion, aber diese Funktion muss eine bestimmte Signatur haben. Die Funktion sollte zwei Argumente entgegennehmen: message und dann history (die Argumente können beliebig benannt werden, müssen aber in dieser Reihenfolge stehen)
message: ein str, das die Eingabe des Benutzers darstellthistory: eine list von list, die die bisherigen Unterhaltungen darstellt. Jede innere Liste besteht aus zwei str, die ein Paar darstellen: [Benutzereingabe, Bot-Antwort].Deine Funktion sollte eine einzelne String-Antwort zurückgeben, die die Antwort des Bots auf die jeweilige Benutzereingabe message ist.
Abgesehen davon hat gr.ChatInterface keine erforderlichen Parameter (obwohl mehrere zur Anpassung der Benutzeroberfläche verfügbar sind).
Hier ist ein Spielzeugbeispiel:
import random
import gradio as gr
def random_response(message, history):
return random.choice(["Yes", "No"])
demo = gr.ChatInterface(random_response)
demo.launch()

Du kannst hier mehr über gr.ChatInterface lesen.
Gradio bietet zwei Ansätze zum Erstellen von Apps:
1. Interface und ChatInterface, die eine High-Level-Abstraktion zum Erstellen von Demos bieten, die wir bisher besprochen haben.
2. Blocks, eine Low-Level-API zum Entwerfen von Web-Apps mit flexibleren Layouts und Datenflüssen. Blocks ermöglicht dir Dinge wie mehrere Datenflüsse und Demos, die Steuerung, wo Komponenten auf der Seite erscheinen, die Handhabung komplexer Datenflüsse (z. B. können Ausgaben als Eingaben für andere Funktionen dienen) und das Aktualisieren von Eigenschaften/Sichtbarkeit von Komponenten basierend auf Benutzerinteraktion — weiterhin alles in Python. Wenn du diese Anpassungsfähigkeit benötigst, probiere Blocks aus!
Schauen wir uns ein einfaches Beispiel an. Beachte, wie sich die API hier von Interface unterscheidet.
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()

Dinge, die du beachten solltest:
Blocks werden mit einer with-Klausel erstellt, und jede in dieser Klausel erstellte Komponente wird automatisch zur App hinzugefügt.Button wurde erstellt und dann ein click-Event-Listener zu diesem Button hinzugefügt. Die API dafür sollte vertraut aussehen! Wie ein Interface nimmt die click-Methode eine Python-Funktion, Eingabekomponenten und Ausgabekomponenten entgegen.Hier ist eine App, die dir einen Vorgeschmack darauf gibt, was mit Blocks möglich ist:
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()

Hier passiert viel mehr! Wir werden behandeln, wie man komplexe Blocks-Apps wie diese im Abschnitt building with blocks erstellt.
Glückwunsch, du bist jetzt mit den Grundlagen von Gradio vertraut! 🥳 Gehe zu unserem nächsten Guide, um mehr über die wichtigsten Funktionen von Gradio zu erfahren.
Gradio ist mit vielen wunderbaren Open-Source-Bibliotheken gebaut, bitte unterstütze auch sie!
Gradio ist unter der Apache-Lizenz 2.0 lizenziert, die in der Datei LICENSE im Stammverzeichnis dieses Repositorys zu finden ist.
Schau dir auch das Paper Gradio: Hassle-Free Sharing and Testing of ML Models in the Wild, ICML HILL 2019 an und zitiere es bitte, wenn du Gradio in deiner Arbeit verwendest.
@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},
}