Gaetan Lepage
2026-03-06 19:56:39 +00:00
parent b63911f725
commit 2236517ed2
2 changed files with 180 additions and 21 deletions
@@ -79,41 +79,33 @@ let
nodejs = nodejs_24;
pnpm = pnpm_10.override { inherit nodejs; };
in
buildPythonPackage rec {
buildPythonPackage (finalAttrs: {
pname = "gradio";
version = "6.5.1";
version = "6.8.0";
pyproject = true;
src = fetchFromGitHub {
owner = "gradio-app";
repo = "gradio";
tag = "gradio@${version}";
hash = "sha256-pIcliKcb1eVVMk0ARzWcZGXc6pmI8mGVAvCJZ0JHXUw=";
tag = "gradio@${finalAttrs.version}";
hash = "sha256-ZHglnRs0AXCu9HlVoSO0h5p6SE4al/OLPn0jwZgKVR8=";
};
patches = [
./fix-transformers-pipelines-imports.patch
];
pnpmDeps = fetchPnpmDeps {
inherit
inherit (finalAttrs)
pname
pnpm
version
src
;
inherit pnpm;
fetcherVersion = 3;
hash = "sha256-6Cx0hdVd0srhArvck2Kn9U2fT7aKtTZjgV5b/Usrnoo=";
};
pythonRelaxDeps = [
"aiofiles"
"gradio-client"
"markupsafe"
"pydantic" # Requests >=2.11.10,<=2.12.4. Staging has it, master doesn't.
];
pythonRemoveDeps = [
# this isn't a real runtime dependency
"ruff"
];
nativeBuildInputs = [
zip
nodejs
@@ -128,6 +120,10 @@ buildPythonPackage rec {
hatch-fancy-pypi-readme
];
pythonRelaxDeps = [
"aiofiles"
"tomlkit"
];
dependencies = [
aiofiles
anyio
@@ -191,7 +187,7 @@ buildPythonPackage rec {
# mock calls to `shutil.which(...)`
(writeShellScriptBin "npm" "false")
]
++ optional-dependencies.oauth
++ finalAttrs.passthru.optional-dependencies.oauth
++ pydantic.optional-dependencies.email;
preBuild = ''
@@ -216,6 +212,7 @@ buildPythonPackage rec {
# requires network, it caught our xfail exception
"test_error_analytics_successful"
"TestSnippetExecution"
# Flaky, tries to pin dependency behaviour. Sensitive to dep versions
# These error only affect downstream use of the check dependencies.
@@ -441,9 +438,9 @@ buildPythonPackage rec {
meta = {
homepage = "https://www.gradio.app/";
changelog = "https://github.com/gradio-app/gradio/releases/tag/gradio@${version}";
changelog = "https://github.com/gradio-app/gradio/releases/tag/${finalAttrs.src.tag}";
description = "Python library for easily interacting with trained machine learning models";
license = lib.licenses.asl20;
maintainers = with lib.maintainers; [ pbsds ];
};
}
})
@@ -0,0 +1,162 @@
diff --git a/test/test_pipelines.py b/test/test_pipelines.py
index 1903f758f..c40e6d3b1 100644
--- a/test/test_pipelines.py
+++ b/test/test_pipelines.py
@@ -3,20 +3,6 @@ from unittest.mock import MagicMock
import pytest
import transformers
-from transformers import (
- AudioClassificationPipeline,
- AutomaticSpeechRecognitionPipeline,
- DocumentQuestionAnsweringPipeline,
- FeatureExtractionPipeline,
- FillMaskPipeline,
- ImageClassificationPipeline,
- ObjectDetectionPipeline,
- QuestionAnsweringPipeline,
- TextClassificationPipeline,
- TextGenerationPipeline,
- VisualQuestionAnsweringPipeline,
- ZeroShotClassificationPipeline,
-)
import gradio as gr
from gradio.pipelines_utils import (
@@ -24,6 +10,14 @@ from gradio.pipelines_utils import (
)
+def _get_pipeline_cls(name: str):
+ """Resolve a pipeline class by name from transformers, returning None if it
+ was removed in the installed version."""
+ return getattr(transformers, name, None) or getattr(
+ transformers.pipelines, name, None
+ )
+
+
@pytest.mark.flaky
def test_interface_in_blocks():
pipe1 = transformers.pipeline(model="deepset/roberta-base-squad2") # type: ignore
@@ -50,50 +44,66 @@ def test_transformers_load_from_pipeline():
class TestHandleTransformersPipelines(unittest.TestCase):
+ def _require(self, name: str):
+ """Return the pipeline class or skip the test if it was removed."""
+ cls = _get_pipeline_cls(name)
+ if cls is None:
+ self.skipTest(
+ f"{name} not available in transformers {transformers.__version__}"
+ )
+ return cls
+
def test_audio_classification_pipeline(self):
- pipe = MagicMock(spec=AudioClassificationPipeline)
+ cls = self._require("AudioClassificationPipeline")
+ pipe = MagicMock(spec=cls)
pipeline_info = handle_transformers_pipeline(pipe)
assert pipeline_info is not None
assert pipeline_info["inputs"].label == "Input"
assert pipeline_info["outputs"].label == "Class"
def test_automatic_speech_recognition_pipeline(self):
- pipe = MagicMock(spec=AutomaticSpeechRecognitionPipeline)
+ cls = self._require("AutomaticSpeechRecognitionPipeline")
+ pipe = MagicMock(spec=cls)
pipeline_info = handle_transformers_pipeline(pipe)
assert pipeline_info is not None
assert pipeline_info["inputs"].label == "Input"
assert pipeline_info["outputs"].label == "Output"
def test_object_detection_pipeline(self):
- pipe = MagicMock(spec=ObjectDetectionPipeline)
+ cls = self._require("ObjectDetectionPipeline")
+ pipe = MagicMock(spec=cls)
pipeline_info = handle_transformers_pipeline(pipe)
assert pipeline_info is not None
assert pipeline_info["inputs"].label == "Input Image"
assert pipeline_info["outputs"].label == "Objects Detected"
def test_feature_extraction_pipeline(self):
- pipe = MagicMock(spec=FeatureExtractionPipeline)
+ cls = self._require("FeatureExtractionPipeline")
+ pipe = MagicMock(spec=cls)
pipeline_info = handle_transformers_pipeline(pipe)
assert pipeline_info is not None
assert pipeline_info["inputs"].label == "Input"
assert pipeline_info["outputs"].label == "Output"
def test_fill_mask_pipeline(self):
- pipe = MagicMock(spec=FillMaskPipeline)
+ cls = self._require("FillMaskPipeline")
+ pipe = MagicMock(spec=cls)
pipeline_info = handle_transformers_pipeline(pipe)
assert pipeline_info is not None
assert pipeline_info["inputs"].label == "Input"
assert pipeline_info["outputs"].label == "Classification"
def test_image_classification_pipeline(self):
- pipe = MagicMock(spec=ImageClassificationPipeline)
+ cls = self._require("ImageClassificationPipeline")
+ pipe = MagicMock(spec=cls)
pipeline_info = handle_transformers_pipeline(pipe)
assert pipeline_info is not None
assert pipeline_info["inputs"].label == "Input Image"
assert pipeline_info["outputs"].label == "Classification"
def test_question_answering_pipeline(self):
- pipe = MagicMock(spec=QuestionAnsweringPipeline)
+ cls = self._require("QuestionAnsweringPipeline")
+ pipe = MagicMock(spec=cls)
pipeline_info = handle_transformers_pipeline(pipe)
assert pipeline_info is not None
assert pipeline_info["inputs"][0].label == "Context"
@@ -102,21 +112,24 @@ class TestHandleTransformersPipelines(unittest.TestCase):
assert pipeline_info["outputs"][1].label == "Score"
def test_text_classification_pipeline(self):
- pipe = MagicMock(spec=TextClassificationPipeline)
+ cls = self._require("TextClassificationPipeline")
+ pipe = MagicMock(spec=cls)
pipeline_info = handle_transformers_pipeline(pipe)
assert pipeline_info is not None
assert pipeline_info["inputs"].label == "Input"
assert pipeline_info["outputs"].label == "Classification"
def test_text_generation_pipeline(self):
- pipe = MagicMock(spec=TextGenerationPipeline)
+ cls = self._require("TextGenerationPipeline")
+ pipe = MagicMock(spec=cls)
pipeline_info = handle_transformers_pipeline(pipe)
assert pipeline_info is not None
assert pipeline_info["inputs"].label == "Input"
assert pipeline_info["outputs"].label == "Output"
def test_zero_shot_classification_pipeline(self):
- pipe = MagicMock(spec=ZeroShotClassificationPipeline)
+ cls = self._require("ZeroShotClassificationPipeline")
+ pipe = MagicMock(spec=cls)
pipeline_info = handle_transformers_pipeline(pipe)
assert pipeline_info is not None
assert pipeline_info["inputs"][0].label == "Input"
@@ -127,7 +140,8 @@ class TestHandleTransformersPipelines(unittest.TestCase):
assert pipeline_info["outputs"].label == "Classification"
def test_document_question_answering_pipeline(self):
- pipe = MagicMock(spec=DocumentQuestionAnsweringPipeline)
+ cls = self._require("DocumentQuestionAnsweringPipeline")
+ pipe = MagicMock(spec=cls)
pipeline_info = handle_transformers_pipeline(pipe)
assert pipeline_info is not None
assert pipeline_info["inputs"][0].label == "Input Document"
@@ -135,7 +149,8 @@ class TestHandleTransformersPipelines(unittest.TestCase):
assert pipeline_info["outputs"].label == "Label"
def test_visual_question_answering_pipeline(self):
- pipe = MagicMock(spec=VisualQuestionAnsweringPipeline)
+ cls = self._require("VisualQuestionAnsweringPipeline")
+ pipe = MagicMock(spec=cls)
pipeline_info = handle_transformers_pipeline(pipe)
assert pipeline_info is not None
assert pipeline_info["inputs"][0].label == "Input Image"