diff --git a/.changeset/afraid-cougars-rescue.md b/.changeset/afraid-cougars-rescue.md new file mode 100644 index 000000000000..69ee770c78be --- /dev/null +++ b/.changeset/afraid-cougars-rescue.md @@ -0,0 +1,5 @@ +--- +"gradio": minor +--- + +feat:Better test dir check diff --git a/.changeset/bright-planes-divide.md b/.changeset/bright-planes-divide.md new file mode 100644 index 000000000000..1751b8cce923 --- /dev/null +++ b/.changeset/bright-planes-divide.md @@ -0,0 +1,5 @@ +--- +"gradio": patch +--- + +fix: ensure all relevant packages are available to the custom component CLI diff --git a/.changeset/bright-yaks-wink.md b/.changeset/bright-yaks-wink.md new file mode 100644 index 000000000000..73eecc59132e --- /dev/null +++ b/.changeset/bright-yaks-wink.md @@ -0,0 +1,5 @@ +--- +"gradio": minor +--- + +feat:V4: Some misc fixes diff --git a/.changeset/cold-hoops-heal.md b/.changeset/cold-hoops-heal.md new file mode 100644 index 000000000000..2658d22210c6 --- /dev/null +++ b/.changeset/cold-hoops-heal.md @@ -0,0 +1,12 @@ +--- +"@gradio/atoms": minor +"@gradio/column": minor +"@gradio/icons": minor +"@gradio/statustracker": minor +"@gradio/tooltip": minor +"@gradio/upload": minor +"@gradio/utils": minor +"gradio": minor +--- + +feat:release first version \ No newline at end of file diff --git a/.changeset/cold-lemons-roll.md b/.changeset/cold-lemons-roll.md new file mode 100644 index 000000000000..828bc1ddb3c0 --- /dev/null +++ b/.changeset/cold-lemons-roll.md @@ -0,0 +1,33 @@ +--- +"@gradio/accordion": minor +"@gradio/annotatedimage": minor +"@gradio/app": minor +"@gradio/audio": minor +"@gradio/chatbot": minor +"@gradio/checkbox": minor +"@gradio/checkboxgroup": minor +"@gradio/code": minor +"@gradio/colorpicker": minor +"@gradio/dataframe": minor +"@gradio/dropdown": minor +"@gradio/fallback": minor +"@gradio/file": minor +"@gradio/gallery": minor +"@gradio/highlightedtext": minor +"@gradio/html": minor +"@gradio/image": minor +"@gradio/json": minor +"@gradio/label": minor +"@gradio/markdown": minor +"@gradio/model3d": minor +"@gradio/number": minor +"@gradio/plot": minor +"@gradio/radio": minor +"@gradio/slider": minor +"@gradio/statustracker": minor +"@gradio/textbox": minor +"@gradio/video": minor +"gradio": minor +--- + +feat:fix build and broken imports diff --git a/.changeset/dark-cups-see.md b/.changeset/dark-cups-see.md new file mode 100644 index 000000000000..50f8ea879105 --- /dev/null +++ b/.changeset/dark-cups-see.md @@ -0,0 +1,5 @@ +--- +"@gradio/preview": minor +--- + +feat:Fix windows paths diff --git a/.changeset/dirty-ghosts-tickle.md b/.changeset/dirty-ghosts-tickle.md new file mode 100644 index 000000000000..84898c9d8508 --- /dev/null +++ b/.changeset/dirty-ghosts-tickle.md @@ -0,0 +1,5 @@ +--- +"gradio": minor +--- + +feat:Patch fixes diff --git a/.changeset/dry-points-join.md b/.changeset/dry-points-join.md new file mode 100644 index 000000000000..2b84d8430c35 --- /dev/null +++ b/.changeset/dry-points-join.md @@ -0,0 +1,5 @@ +--- +"gradio": minor +--- + +feat:Fix js deps in cli and add gradio-preview artifacts to build diff --git a/.changeset/easy-mirrors-retire.md b/.changeset/easy-mirrors-retire.md new file mode 100644 index 000000000000..a0db5ba43f6e --- /dev/null +++ b/.changeset/easy-mirrors-retire.md @@ -0,0 +1,5 @@ +--- +"gradio": minor +--- + +feat:Add docstring to trigger release diff --git a/.changeset/eleven-steaks-tan.md b/.changeset/eleven-steaks-tan.md new file mode 100644 index 000000000000..11956f6d6e90 --- /dev/null +++ b/.changeset/eleven-steaks-tan.md @@ -0,0 +1,6 @@ +--- +"@gradio/preview": minor +"gradio": minor +--- + +feat:Add host to dev mode for vite diff --git a/.changeset/empty-bobcats-judge.md b/.changeset/empty-bobcats-judge.md new file mode 100644 index 000000000000..96175a056119 --- /dev/null +++ b/.changeset/empty-bobcats-judge.md @@ -0,0 +1,5 @@ +--- +"gradio": minor +--- + +feat:Make layout components templateable diff --git a/.changeset/fresh-ears-pump.md b/.changeset/fresh-ears-pump.md new file mode 100644 index 000000000000..b7b7f8bd4270 --- /dev/null +++ b/.changeset/fresh-ears-pump.md @@ -0,0 +1,5 @@ +--- +"gradio": minor +--- + +feat:Use overrides diff --git a/.changeset/great-rice-grab.md b/.changeset/great-rice-grab.md new file mode 100644 index 000000000000..057c68e7d98b --- /dev/null +++ b/.changeset/great-rice-grab.md @@ -0,0 +1,6 @@ +--- +"@gradio/preview": minor +"gradio": minor +--- + +feat:Use tags to identify custom component dirs and ignore uninstalled components diff --git a/.changeset/heavy-animals-think.md b/.changeset/heavy-animals-think.md new file mode 100644 index 000000000000..7e2e4b1952a1 --- /dev/null +++ b/.changeset/heavy-animals-think.md @@ -0,0 +1,6 @@ +--- +"@gradio/app": patch +"gradio": patch +--- + +feat:Fix windows ci build diff --git a/.changeset/hip-drinks-bow.md b/.changeset/hip-drinks-bow.md new file mode 100644 index 000000000000..2bf10b687857 --- /dev/null +++ b/.changeset/hip-drinks-bow.md @@ -0,0 +1,8 @@ +--- +"@gradio/app": minor +"@gradio/image": minor +"@gradio/theme": minor +"gradio": minor +--- + +feat:image fixes diff --git a/.changeset/hungry-melons-pump.md b/.changeset/hungry-melons-pump.md new file mode 100644 index 000000000000..94f8be5f73fd --- /dev/null +++ b/.changeset/hungry-melons-pump.md @@ -0,0 +1,10 @@ +--- +"@gradio/app": minor +"@gradio/dataset": minor +"@gradio/preview": minor +"@gradio/state": minor +"gradio": minor +"newnewtext": minor +--- + +feat: Adds the ability to build the frontend and backend of custom components in preparation for publishing to pypi using `gradio_component build`. diff --git a/.changeset/icy-cars-boil.md b/.changeset/icy-cars-boil.md new file mode 100644 index 000000000000..5c263477f7b2 --- /dev/null +++ b/.changeset/icy-cars-boil.md @@ -0,0 +1,6 @@ +--- +"@gradio/audio": minor +"gradio": minor +--- + +feat:Fix deployed demos on v4 branch diff --git a/.changeset/large-banks-push.md b/.changeset/large-banks-push.md new file mode 100644 index 000000000000..91840ae7e2db --- /dev/null +++ b/.changeset/large-banks-push.md @@ -0,0 +1,5 @@ +--- +"gradio": minor +--- + +feat:Use path to npm executable in subprocess diff --git a/.changeset/lazy-aliens-drive.md b/.changeset/lazy-aliens-drive.md new file mode 100644 index 000000000000..88cf59e83001 --- /dev/null +++ b/.changeset/lazy-aliens-drive.md @@ -0,0 +1,6 @@ +--- +"@gradio/theme": patch +"gradio": patch +--- + +feat:Publish js theme diff --git a/.changeset/lovely-news-speak.md b/.changeset/lovely-news-speak.md new file mode 100644 index 000000000000..9ab44daaf6a3 --- /dev/null +++ b/.changeset/lovely-news-speak.md @@ -0,0 +1,6 @@ +--- +"gradio": minor +"gradio_client": minor +--- + +feat:V4 fix typing diff --git a/.changeset/modern-forks-march.md b/.changeset/modern-forks-march.md new file mode 100644 index 000000000000..938d03bc3166 --- /dev/null +++ b/.changeset/modern-forks-march.md @@ -0,0 +1,5 @@ +--- +"gradio": minor +--- + +feat:Set api=False for cancel events diff --git a/.changeset/nasty-dryers-show.md b/.changeset/nasty-dryers-show.md new file mode 100644 index 000000000000..6b7f852e16dd --- /dev/null +++ b/.changeset/nasty-dryers-show.md @@ -0,0 +1,5 @@ +--- +"gradio": minor +--- + +feat:Use full path to executables in CLI diff --git a/.changeset/nice-actors-write.md b/.changeset/nice-actors-write.md new file mode 100644 index 000000000000..5e25404577f7 --- /dev/null +++ b/.changeset/nice-actors-write.md @@ -0,0 +1,5 @@ +--- +"gradio": minor +--- + +feat:Fix component regex diff --git a/.changeset/old-heads-give.md b/.changeset/old-heads-give.md new file mode 100644 index 000000000000..7212fdff8c4a --- /dev/null +++ b/.changeset/old-heads-give.md @@ -0,0 +1,5 @@ +--- +"gradio": minor +--- + +feat:Add Error + test diff --git a/.changeset/plain-groups-win.md b/.changeset/plain-groups-win.md new file mode 100644 index 000000000000..bb5d2f473f76 --- /dev/null +++ b/.changeset/plain-groups-win.md @@ -0,0 +1,6 @@ +--- +"gradio": minor +"gradio_client": minor +--- + +feat:Fix python unit tests for v4 diff --git a/.changeset/plenty-teeth-clap.md b/.changeset/plenty-teeth-clap.md new file mode 100644 index 000000000000..595c4fda7d44 --- /dev/null +++ b/.changeset/plenty-teeth-clap.md @@ -0,0 +1,5 @@ +--- +"gradio": minor +--- + +feat:Fix template remaining components diff --git a/.changeset/pre.json b/.changeset/pre.json new file mode 100644 index 000000000000..4de969e63932 --- /dev/null +++ b/.changeset/pre.json @@ -0,0 +1,104 @@ +{ + "mode": "pre", + "tag": "beta", + "initialVersions": { + "@gradio/client": "0.3.1", + "gradio_client": "0.5.0", + "gradio": "3.43.2", + "@gradio/cdn-test": "0.0.0", + "@gradio/spaces-test": "0.0.1", + "website": "0.4.0", + "@gradio/accordion": "0.0.4", + "@gradio/annotatedimage": "0.1.2", + "@gradio/app": "1.4.3", + "@gradio/atoms": "0.1.2", + "@gradio/audio": "0.3.2", + "@gradio/box": "0.0.4", + "@gradio/button": "0.1.3", + "@gradio/chatbot": "0.3.1", + "@gradio/checkbox": "0.1.3", + "@gradio/checkboxgroup": "0.1.2", + "@gradio/code": "0.1.2", + "@gradio/colorpicker": "0.1.2", + "@gradio/column": "0.0.1", + "@gradio/dataframe": "0.2.2", + "@gradio/dropdown": "0.1.3", + "@gradio/file": "0.1.2", + "@gradio/form": "0.0.5", + "@gradio/gallery": "0.3.2", + "@gradio/group": "0.0.1", + "@gradio/highlightedtext": "0.2.3", + "@gradio/html": "0.0.4", + "@gradio/icons": "0.1.0", + "@gradio/image": "0.2.2", + "@gradio/json": "0.0.5", + "@gradio/label": "0.1.2", + "@gradio/lite": "0.3.1", + "@gradio/markdown": "0.2.0", + "@gradio/model3d": "0.2.1", + "@gradio/number": "0.2.2", + "@gradio/plot": "0.1.2", + "@gradio/radio": "0.1.2", + "@gradio/row": "0.0.1", + "@gradio/slider": "0.1.2", + "@gradio/state": "0.0.1", + "@gradio/statustracker": "0.2.0", + "@gradio/tabitem": "0.0.4", + "@gradio/tabs": "0.0.5", + "@gradio/textbox": "0.2.0", + "@gradio/theme": "0.1.0", + "@gradio/timeseries": "0.0.5", + "@gradio/tooltip": "0.0.1", + "@gradio/tootils": "0.0.2", + "@gradio/upload": "0.2.1", + "@gradio/uploadbutton": "0.0.5", + "@gradio/utils": "0.1.1", + "@gradio/video": "0.0.6", + "@gradio/wasm": "0.0.1", + "@gradio/fallback": "0.1.1", + "@gradio/preview": "0.0.2" + }, + "changesets": [ + "afraid-cougars-rescue", + "bright-planes-divide", + "chatty-adults-reply", + "chubby-hounds-itch", + "cold-hoops-heal", + "cold-lemons-roll", + "cold-lights-trade", + "dark-cups-see", + "dirty-ghosts-tickle", + "dry-points-join", + "easy-mirrors-retire", + "empty-bobcats-judge", + "fresh-ears-pump", + "great-mammals-lead", + "heavy-animals-think", + "hip-drinks-bow", + "hot-words-sin", + "large-banks-push", + "lazy-aliens-drive", + "lovely-news-speak", + "lovely-radios-worry", + "many-tips-create", + "nice-actors-write", + "old-heads-give", + "plain-groups-win", + "plenty-teeth-clap", + "puny-papayas-bake", + "purple-jokes-shake", + "real-items-cover", + "rich-points-dance", + "sad-ears-sink", + "sad-eels-sink", + "short-clouds-see", + "silver-beers-refuse", + "slick-pants-stand", + "smart-groups-study", + "some-shoes-relate", + "strong-peas-tell", + "three-trams-sniff", + "true-bugs-shine", + "wet-places-hunt" + ] +} diff --git a/.changeset/public-chairs-chew.md b/.changeset/public-chairs-chew.md new file mode 100644 index 000000000000..c22b75e29b68 --- /dev/null +++ b/.changeset/public-chairs-chew.md @@ -0,0 +1,5 @@ +--- +"@gradio/preview": minor +--- + +feat:In dev/build use full path to python/gradio executables diff --git a/.changeset/purple-jokes-shake.md b/.changeset/purple-jokes-shake.md new file mode 100644 index 000000000000..86a7d6c99380 --- /dev/null +++ b/.changeset/purple-jokes-shake.md @@ -0,0 +1,5 @@ +--- +"gradio": minor +--- + +feat:backend linting diff --git a/.changeset/real-spoons-pick.md b/.changeset/real-spoons-pick.md new file mode 100644 index 000000000000..1c6b500e6dee --- /dev/null +++ b/.changeset/real-spoons-pick.md @@ -0,0 +1,6 @@ +--- +"@gradio/preview": patch +"gradio": patch +--- + +fix:Better logs in dev mode diff --git a/.changeset/sad-ears-sink.md b/.changeset/sad-ears-sink.md new file mode 100644 index 000000000000..7e205bbc7ec4 --- /dev/null +++ b/.changeset/sad-ears-sink.md @@ -0,0 +1,7 @@ +--- +"@gradio/preview": minor +"@gradio/utils": minor +"gradio": minor +--- + +feat:Fix esbuild diff --git a/.changeset/sad-eels-sink.md b/.changeset/sad-eels-sink.md new file mode 100644 index 000000000000..4d2fc8609738 --- /dev/null +++ b/.changeset/sad-eels-sink.md @@ -0,0 +1,7 @@ +--- +"@gradio/preview": minor +"@gradio/utils": minor +"gradio": minor +--- + +feat:Fix esbuild \ No newline at end of file diff --git a/.changeset/short-clouds-see.md b/.changeset/short-clouds-see.md new file mode 100644 index 000000000000..b42755253b08 --- /dev/null +++ b/.changeset/short-clouds-see.md @@ -0,0 +1,6 @@ +--- +"@gradio/preview": minor +"gradio": minor +--- + +feat:Fix front-end imports + other misc fixes diff --git a/.changeset/silver-beers-refuse.md b/.changeset/silver-beers-refuse.md new file mode 100644 index 000000000000..a111d4ce39e6 --- /dev/null +++ b/.changeset/silver-beers-refuse.md @@ -0,0 +1,41 @@ +--- +"@gradio/audio": patch +"@gradio/box": patch +"@gradio/button": patch +"@gradio/chatbot": patch +"@gradio/checkbox": patch +"@gradio/checkboxgroup": patch +"@gradio/code": patch +"@gradio/colorpicker": patch +"@gradio/column": patch +"@gradio/dataframe": patch +"@gradio/dropdown": patch +"@gradio/fallback": patch +"@gradio/file": patch +"@gradio/form": patch +"@gradio/gallery": patch +"@gradio/group": patch +"@gradio/highlightedtext": patch +"@gradio/html": patch +"@gradio/image": patch +"@gradio/json": patch +"@gradio/label": patch +"@gradio/markdown": patch +"@gradio/model3d": patch +"@gradio/number": patch +"@gradio/plot": patch +"@gradio/preview": patch +"@gradio/radio": patch +"@gradio/row": patch +"@gradio/slider": patch +"@gradio/state": patch +"@gradio/tabitem": patch +"@gradio/tabs": patch +"@gradio/textbox": patch +"@gradio/tootils": patch +"@gradio/uploadbutton": patch +"@gradio/video": patch +"gradio": patch +--- + +feat:Publish all components to npm diff --git a/.changeset/slick-bats-study.md b/.changeset/slick-bats-study.md new file mode 100644 index 000000000000..f7096d564313 --- /dev/null +++ b/.changeset/slick-bats-study.md @@ -0,0 +1,6 @@ +--- +"gradio": minor +"gradio_client": minor +--- + +feat:Simplify how files are handled in components in 4.0 diff --git a/.changeset/slick-pants-stand.md b/.changeset/slick-pants-stand.md new file mode 100644 index 000000000000..b9b2298a8d7c --- /dev/null +++ b/.changeset/slick-pants-stand.md @@ -0,0 +1,5 @@ +--- +"gradio": minor +--- + +feat:Add overwrite flag to create command diff --git a/.changeset/smart-groups-study.md b/.changeset/smart-groups-study.md new file mode 100644 index 000000000000..2e26def430ef --- /dev/null +++ b/.changeset/smart-groups-study.md @@ -0,0 +1,42 @@ +--- +"@gradio/accordion": minor +"@gradio/annotatedimage": minor +"@gradio/app": minor +"@gradio/atoms": minor +"@gradio/audio": minor +"@gradio/button": minor +"@gradio/chatbot": minor +"@gradio/checkbox": minor +"@gradio/checkboxgroup": minor +"@gradio/code": minor +"@gradio/colorpicker": minor +"@gradio/dataframe": minor +"@gradio/dropdown": minor +"@gradio/fallback": minor +"@gradio/file": minor +"@gradio/gallery": minor +"@gradio/highlightedtext": minor +"@gradio/html": minor +"@gradio/image": minor +"@gradio/json": minor +"@gradio/label": minor +"@gradio/markdown": minor +"@gradio/model3d": minor +"@gradio/number": minor +"@gradio/plot": minor +"@gradio/preview": minor +"@gradio/radio": minor +"@gradio/slider": minor +"@gradio/statustracker": minor +"@gradio/textbox": minor +"@gradio/theme": minor +"@gradio/tootils": minor +"@gradio/upload": minor +"@gradio/uploadbutton": minor +"@gradio/utils": minor +"@gradio/video": minor +"gradio": minor +"gradio_client": minor +--- + +feat:Custom components diff --git a/.changeset/some-shoes-relate.md b/.changeset/some-shoes-relate.md new file mode 100644 index 000000000000..490c8e6db083 --- /dev/null +++ b/.changeset/some-shoes-relate.md @@ -0,0 +1,5 @@ +--- +"gradio": minor +--- + +feat:Fix layout templates diff --git a/.changeset/strong-peas-tell.md b/.changeset/strong-peas-tell.md new file mode 100644 index 000000000000..5792439a778e --- /dev/null +++ b/.changeset/strong-peas-tell.md @@ -0,0 +1,6 @@ +--- +"@gradio/app": minor +"gradio": minor +--- + +feat:Fix build and file route diff --git a/.changeset/tame-chairs-tan.md b/.changeset/tame-chairs-tan.md new file mode 100644 index 000000000000..6714bd3b388e --- /dev/null +++ b/.changeset/tame-chairs-tan.md @@ -0,0 +1,5 @@ +--- +"gradio": minor +--- + +feat:Name Endpoints if api_name is None diff --git a/.changeset/three-trams-sniff.md b/.changeset/three-trams-sniff.md new file mode 100644 index 000000000000..074ff8fbace5 --- /dev/null +++ b/.changeset/three-trams-sniff.md @@ -0,0 +1,5 @@ +--- +"gradio": minor +--- + +feat:Some minor v4 fixes diff --git a/.changeset/true-bugs-shine.md b/.changeset/true-bugs-shine.md new file mode 100644 index 000000000000..efd4620c8234 --- /dev/null +++ b/.changeset/true-bugs-shine.md @@ -0,0 +1,6 @@ +--- +"gradio": minor +"gradio_client": minor +--- + +feat:Support call method diff --git a/.changeset/twenty-gifts-tickle.md b/.changeset/twenty-gifts-tickle.md new file mode 100644 index 000000000000..b3ba02e3dd43 --- /dev/null +++ b/.changeset/twenty-gifts-tickle.md @@ -0,0 +1,6 @@ +--- +"gradio": minor +"gradio_client": minor +--- + +feat:Rename gradio_component to gradio component diff --git a/.changeset/two-games-dress.md b/.changeset/two-games-dress.md new file mode 100644 index 000000000000..c4ab877006dd --- /dev/null +++ b/.changeset/two-games-dress.md @@ -0,0 +1,6 @@ +--- +"@gradio/app": minor +"gradio": minor +--- + +fix:Reinstate types that were removed in error in #5832. diff --git a/.changeset/two-mirrors-nail.md b/.changeset/two-mirrors-nail.md new file mode 100644 index 000000000000..c70eed94d044 --- /dev/null +++ b/.changeset/two-mirrors-nail.md @@ -0,0 +1,5 @@ +--- +"gradio": minor +--- + +feat:V4: Use async version of shutil in upload route diff --git a/.changeset/vast-terms-rhyme.md b/.changeset/vast-terms-rhyme.md new file mode 100644 index 000000000000..b203aae5cc70 --- /dev/null +++ b/.changeset/vast-terms-rhyme.md @@ -0,0 +1,5 @@ +--- +"gradio": minor +--- + +feat:V4: Set cache dir for some component tests diff --git a/.changeset/wet-places-hunt.md b/.changeset/wet-places-hunt.md new file mode 100644 index 000000000000..9ce5d8730313 --- /dev/null +++ b/.changeset/wet-places-hunt.md @@ -0,0 +1,5 @@ +--- +"gradio": minor +--- + +feat:--overwrite deletes previous content diff --git a/.config/copy_frontend.py b/.config/copy_frontend.py new file mode 100644 index 000000000000..acfdfb20c923 --- /dev/null +++ b/.config/copy_frontend.py @@ -0,0 +1,38 @@ +from __future__ import annotations + +import shutil +import pathlib +from typing import Any + +from hatchling.builders.hooks.plugin.interface import BuildHookInterface + + +class BuildHook(BuildHookInterface): + def initialize(self, version: str, build_data: dict[str, Any]) -> None: + NOT_COMPONENT = [ + "app", + "node_modules", + "storybook", + "playwright-report", + "wasm", + "workbench", + "tooltils", + ] + for entry in (pathlib.Path(self.root) / "js").iterdir(): + if ( + entry.is_dir() + and not str(entry.name).startswith("_") + and not str(entry.name) in NOT_COMPONENT + ): + shutil.copytree( + str(entry), + str(pathlib.Path("gradio") / "_frontend_code" / entry.name), + ignore=lambda d, names: ["node_modules"], + dirs_exist_ok=True, + ) + shutil.copytree( + str(pathlib.Path(self.root) / "client" / "js"), + str(pathlib.Path("gradio") / "_frontend_code" / "client"), + ignore=lambda d, names: ["node_modules"], + dirs_exist_ok=True, + ) diff --git a/.config/eslint.config.js b/.config/eslint.config.js index 41f34981991b..8f4c57e68674 100644 --- a/.config/eslint.config.js +++ b/.config/eslint.config.js @@ -18,7 +18,7 @@ const js_rules_disabled = Object.fromEntries( const js_rules = { ...js_rules_disabled, - "no-console": ["error", { allow: ["warn", "error", "debug"] }], + "no-console": ["error", { allow: ["warn", "error", "debug", "info"] }], "no-constant-condition": "error", "no-dupe-args": "error", "no-extra-boolean-cast": "error", @@ -60,7 +60,8 @@ export default [ "js/app/test/**/*", "**/*vite.config.ts", "**/_website/**/*", - "**/_spaces-test/**/*" + "**/_spaces-test/**/*", + "**/preview/test/**/*" ] }, { diff --git a/.config/playwright/index.html b/.config/playwright/index.html deleted file mode 100644 index 229f296a9e5a..000000000000 --- a/.config/playwright/index.html +++ /dev/null @@ -1,12 +0,0 @@ - - -
- - -I am red
',\n", " 'I am blue
',\n", " ]\n", " )\n", " ),\n", " gr.Gallery(\n", " value=lambda: images\n", " ),\n", " gr.Model3D(value=random_model3d),\n", " gr.Plot(value=random_plot),\n", " gr.Markdown(value=lambda: f\"### {random.choice(['Hello', 'Hi', 'Goodbye!'])}\"),\n", "]\n", "\n", "\n", "def evaluate_values(*args):\n", " are_false = []\n", " for a in args:\n", " if isinstance(a, (pd.DataFrame, np.ndarray)):\n", " are_false.append(not a.any().any())\n", " elif isinstance(a, str) and a.startswith(\"#\"):\n", " are_false.append(a == \"#000000\")\n", " else:\n", " are_false.append(not a)\n", " return all(are_false)\n", "\n", "\n", "with gr.Blocks() as demo:\n", " for i, component in enumerate(components):\n", " component.label = f\"component_{str(i).zfill(2)}\"\n", " component.render()\n", " clear = gr.ClearButton(value=\"Clear\", components=components)\n", " result = gr.Textbox(label=\"Are all cleared?\")\n", " hide = gr.Button(value=\"Hide\")\n", " reveal = gr.Button(value=\"Reveal\")\n", " hide.click(\n", " lambda: [c.__class__(visible=False) for c in components],\n", " inputs=[],\n", " outputs=components\n", " )\n", " reveal.click(\n", " lambda: [c.__class__(visible=True) for c in components],\n", " inputs=[],\n", " outputs=components\n", " )\n", " get_value = gr.Button(value=\"Get Values\")\n", " get_value.click(evaluate_values, components, result)\n", "\n", "\n", "if __name__ == \"__main__\":\n", " demo.launch()\n"]}], "metadata": {}, "nbformat": 4, "nbformat_minor": 5} \ No newline at end of file +<<<<<<< HEAD +{"cells": [{"cell_type": "markdown", "id": 302934307671667531413257853548643485645, "metadata": {}, "source": ["# Gradio Demo: clear_components"]}, {"cell_type": "code", "execution_count": null, "id": 272996653310673477252411125948039410165, "metadata": {}, "outputs": [], "source": ["!pip install -q gradio "]}, {"cell_type": "code", "execution_count": null, "id": 288918539441861185822528903084949547379, "metadata": {}, "outputs": [], "source": ["# Downloading files from the demo repo\n", "import os\n", "!wget -q https://github.com/gradio-app/gradio/raw/main/demo/clear_components/__init__.py"]}, {"cell_type": "code", "execution_count": null, "id": 44380577570523278879349135829904343037, "metadata": {}, "outputs": [], "source": ["import gradio as gr\n", "from datetime import datetime\n", "import os\n", "import random\n", "import string\n", "import pandas as pd\n", "\n", "import numpy as np\n", "import matplotlib.pyplot as plt\n", "\n", "\n", "\n", "def random_plot():\n", " start_year = 2020\n", " x = np.arange(start_year, start_year + 5)\n", " year_count = x.shape[0]\n", " plt_format = \"-\"\n", " fig = plt.figure()\n", " ax = fig.add_subplot(111)\n", " series = np.arange(0, year_count, dtype=float)\n", " series = series**2\n", " series += np.random.rand(year_count)\n", " ax.plot(x, series, plt_format)\n", " return fig\n", "\n", "\n", "images = [\n", " \"https://images.unsplash.com/photo-1507003211169-0a1dd7228f2d?ixlib=rb-1.2.1&ixid=MnwxMjA3fDB8MHxwaG90by1wYWdlfHx8fGVufDB8fHx8&auto=format&fit=crop&w=387&q=80\",\n", " \"https://images.unsplash.com/photo-1554151228-14d9def656e4?ixlib=rb-1.2.1&ixid=MnwxMjA3fDB8MHxwaG90by1wYWdlfHx8fGVufDB8fHx8&auto=format&fit=crop&w=386&q=80\",\n", " \"https://images.unsplash.com/photo-1542909168-82c3e7fdca5c?ixlib=rb-1.2.1&ixid=MnwxMjA3fDB8MHxzZWFyY2h8MXx8aHVtYW4lMjBmYWNlfGVufDB8fDB8fA%3D%3D&w=1000&q=80\",\n", "]\n", "file_dir = os.path.join(os.path.abspath(''), \"..\", \"kitchen_sink\", \"files\")\n", "model3d_dir = os.path.join(os.path.abspath(''), \"..\", \"model3D\", \"files\")\n", "highlighted_text_output_1 = [\n", " {\n", " \"entity\": \"I-LOC\",\n", " \"score\": 0.9988978,\n", " \"index\": 2,\n", " \"word\": \"Chicago\",\n", " \"start\": 5,\n", " \"end\": 12,\n", " },\n", " {\n", " \"entity\": \"I-MISC\",\n", " \"score\": 0.9958592,\n", " \"index\": 5,\n", " \"word\": \"Pakistani\",\n", " \"start\": 22,\n", " \"end\": 31,\n", " },\n", "]\n", "highlighted_text_output_2 = [\n", " {\n", " \"entity\": \"I-LOC\",\n", " \"score\": 0.9988978,\n", " \"index\": 2,\n", " \"word\": \"Chicago\",\n", " \"start\": 5,\n", " \"end\": 12,\n", " },\n", " {\n", " \"entity\": \"I-LOC\",\n", " \"score\": 0.9958592,\n", " \"index\": 5,\n", " \"word\": \"Pakistan\",\n", " \"start\": 22,\n", " \"end\": 30,\n", " },\n", "]\n", "\n", "highlighted_text = \"Does Chicago have any Pakistani restaurants\"\n", "\n", "\n", "def random_model3d():\n", " model_3d = random.choice(\n", " [os.path.join(model3d_dir, model) for model in os.listdir(model3d_dir) if model != \"source.txt\"]\n", " )\n", " return model_3d\n", "\n", "\n", "\n", "components = [\n", " gr.Textbox(value=lambda: datetime.now(), label=\"Current Time\"),\n", " gr.Number(value=lambda: random.random(), label=\"Random Percentage\"),\n", " gr.Slider(minimum=0, maximum=100, randomize=True, label=\"Slider with randomize\"),\n", " gr.Slider(\n", " minimum=0,\n", " maximum=1,\n", " value=lambda: random.random(),\n", " label=\"Slider with value func\",\n", " ),\n", " gr.Checkbox(value=lambda: random.random() > 0.5, label=\"Random Checkbox\"),\n", " gr.CheckboxGroup(\n", " choices=[\"a\", \"b\", \"c\", \"d\"],\n", " value=lambda: random.choice([\"a\", \"b\", \"c\", \"d\"]),\n", " label=\"Random CheckboxGroup\",\n", " ),\n", " gr.Radio(\n", " choices=list(string.ascii_lowercase),\n", " value=lambda: random.choice(string.ascii_lowercase),\n", " ),\n", " gr.Dropdown(\n", " choices=[\"a\", \"b\", \"c\", \"d\", \"e\"],\n", " value=lambda: random.choice([\"a\", \"b\", \"c\"]),\n", " ),\n", " gr.Image(\n", " value=lambda: random.choice(images)\n", " ),\n", " gr.Video(value=lambda: os.path.join(file_dir, \"world.mp4\")),\n", " gr.Audio(value=lambda: os.path.join(file_dir, \"cantina.wav\")),\n", " gr.File(\n", " value=lambda: random.choice(\n", " [os.path.join(file_dir, img) for img in os.listdir(file_dir)]\n", " )\n", " ),\n", " gr.Dataframe(\n", " value=lambda: pd.DataFrame({\"random_number_rows\": range(5)}, columns=[\"one\", \"two\", \"three\"])\n", " ),\n", " gr.ColorPicker(value=lambda: random.choice([\"#000000\", \"#ff0000\", \"#0000FF\"])),\n", " gr.Label(value=lambda: random.choice([\"Pedestrian\", \"Car\", \"Cyclist\"])),\n", " gr.HighlightedText(\n", " value=lambda: random.choice(\n", " [\n", " {\"text\": highlighted_text, \"entities\": highlighted_text_output_1},\n", " {\"text\": highlighted_text, \"entities\": highlighted_text_output_2},\n", " ]\n", " ),\n", " ),\n", " gr.JSON(value=lambda: random.choice([{\"a\": 1}, {\"b\": 2}])),\n", " gr.HTML(\n", " value=lambda: random.choice(\n", " [\n", " 'I am red
',\n", " 'I am blue
',\n", " ]\n", " )\n", " ),\n", " gr.Gallery(\n", " value=lambda: images\n", " ),\n", " gr.Model3D(value=random_model3d),\n", " gr.Plot(value=random_plot),\n", " gr.Markdown(value=lambda: f\"### {random.choice(['Hello', 'Hi', 'Goodbye!'])}\"),\n", "]\n", "\n", "\n", "def evaluate_values(*args):\n", " are_false = []\n", " for a in args:\n", " if isinstance(a, (pd.DataFrame, np.ndarray)):\n", " are_false.append(not a.any().any())\n", " elif isinstance(a, str) and a.startswith(\"#\"):\n", " are_false.append(a == \"#000000\")\n", " else:\n", " are_false.append(not a)\n", " return all(are_false)\n", "\n", "\n", "with gr.Blocks() as demo:\n", " for i, component in enumerate(components):\n", " component.label = f\"component_{str(i).zfill(2)}\"\n", " component.render()\n", " clear = gr.ClearButton(value=\"Clear\", components=components)\n", " result = gr.Textbox(label=\"Are all cleared?\")\n", " hide = gr.Button(value=\"Hide\")\n", " reveal = gr.Button(value=\"Reveal\")\n", " hide.click(\n", " lambda: [c.__class__(visible=False) for c in components],\n", " inputs=[],\n", " outputs=components\n", " )\n", " reveal.click(\n", " lambda: [c.__class__(visible=True) for c in components],\n", " inputs=[],\n", " outputs=components\n", " )\n", " get_value = gr.Button(value=\"Get Values\")\n", " get_value.click(evaluate_values, components, result)\n", "\n", "\n", "if __name__ == \"__main__\":\n", " demo.launch()\n"]}], "metadata": {}, "nbformat": 4, "nbformat_minor": 5} +======= +{"cells": [{"cell_type": "markdown", "id": "302934307671667531413257853548643485645", "metadata": {}, "source": ["# Gradio Demo: clear_components"]}, {"cell_type": "code", "execution_count": null, "id": "272996653310673477252411125948039410165", "metadata": {}, "outputs": [], "source": ["!pip install -q gradio "]}, {"cell_type": "code", "execution_count": null, "id": "288918539441861185822528903084949547379", "metadata": {}, "outputs": [], "source": ["# Downloading files from the demo repo\n", "import os\n", "!wget -q https://github.com/gradio-app/gradio/raw/main/demo/clear_components/__init__.py"]}, {"cell_type": "code", "execution_count": null, "id": "44380577570523278879349135829904343037", "metadata": {}, "outputs": [], "source": ["import gradio as gr\n", "from datetime import datetime\n", "import os\n", "import random\n", "import string\n", "import pandas as pd\n", "\n", "import numpy as np\n", "import matplotlib.pyplot as plt\n", "\n", "\n", "\n", "def random_plot():\n", " start_year = 2020\n", " x = np.arange(start_year, start_year + 5)\n", " year_count = x.shape[0]\n", " plt_format = \"-\"\n", " fig = plt.figure()\n", " ax = fig.add_subplot(111)\n", " series = np.arange(0, year_count, dtype=float)\n", " series = series**2\n", " series += np.random.rand(year_count)\n", " ax.plot(x, series, plt_format)\n", " return fig\n", "\n", "\n", "images = [\n", " \"https://images.unsplash.com/photo-1507003211169-0a1dd7228f2d?ixlib=rb-1.2.1&ixid=MnwxMjA3fDB8MHxwaG90by1wYWdlfHx8fGVufDB8fHx8&auto=format&fit=crop&w=387&q=80\",\n", " \"https://images.unsplash.com/photo-1554151228-14d9def656e4?ixlib=rb-1.2.1&ixid=MnwxMjA3fDB8MHxwaG90by1wYWdlfHx8fGVufDB8fHx8&auto=format&fit=crop&w=386&q=80\",\n", " \"https://images.unsplash.com/photo-1542909168-82c3e7fdca5c?ixlib=rb-1.2.1&ixid=MnwxMjA3fDB8MHxzZWFyY2h8MXx8aHVtYW4lMjBmYWNlfGVufDB8fDB8fA%3D%3D&w=1000&q=80\",\n", "]\n", "file_dir = os.path.join(os.path.abspath(''), \"..\", \"kitchen_sink\", \"files\")\n", "model3d_dir = os.path.join(os.path.abspath(''), \"..\", \"model3D\", \"files\")\n", "highlighted_text_output_1 = [\n", " {\n", " \"entity\": \"I-LOC\",\n", " \"score\": 0.9988978,\n", " \"index\": 2,\n", " \"word\": \"Chicago\",\n", " \"start\": 5,\n", " \"end\": 12,\n", " },\n", " {\n", " \"entity\": \"I-MISC\",\n", " \"score\": 0.9958592,\n", " \"index\": 5,\n", " \"word\": \"Pakistani\",\n", " \"start\": 22,\n", " \"end\": 31,\n", " },\n", "]\n", "highlighted_text_output_2 = [\n", " {\n", " \"entity\": \"I-LOC\",\n", " \"score\": 0.9988978,\n", " \"index\": 2,\n", " \"word\": \"Chicago\",\n", " \"start\": 5,\n", " \"end\": 12,\n", " },\n", " {\n", " \"entity\": \"I-LOC\",\n", " \"score\": 0.9958592,\n", " \"index\": 5,\n", " \"word\": \"Pakistan\",\n", " \"start\": 22,\n", " \"end\": 30,\n", " },\n", "]\n", "\n", "highlighted_text = \"Does Chicago have any Pakistani restaurants\"\n", "\n", "\n", "def random_model3d():\n", " model_3d = random.choice(\n", " [os.path.join(model3d_dir, model) for model in os.listdir(model3d_dir) if model != \"source.txt\"]\n", " )\n", " return model_3d\n", "\n", "\n", "\n", "components = [\n", " gr.Textbox(value=lambda: datetime.now(), label=\"Current Time\"),\n", " gr.Number(value=lambda: random.random(), label=\"Random Percentage\"),\n", " gr.Slider(minimum=0, maximum=100, randomize=True, label=\"Slider with randomize\"),\n", " gr.Slider(\n", " minimum=0,\n", " maximum=1,\n", " value=lambda: random.random(),\n", " label=\"Slider with value func\",\n", " ),\n", " gr.Checkbox(value=lambda: random.random() > 0.5, label=\"Random Checkbox\"),\n", " gr.CheckboxGroup(\n", " choices=[\"a\", \"b\", \"c\", \"d\"],\n", " value=lambda: random.choice([\"a\", \"b\", \"c\", \"d\"]),\n", " label=\"Random CheckboxGroup\",\n", " ),\n", " gr.Radio(\n", " choices=list(string.ascii_lowercase),\n", " value=lambda: random.choice(string.ascii_lowercase),\n", " ),\n", " gr.Dropdown(\n", " choices=[\"a\", \"b\", \"c\", \"d\", \"e\"],\n", " value=lambda: random.choice([\"a\", \"b\", \"c\"]),\n", " ),\n", " gr.Image(\n", " value=lambda: random.choice(images)\n", " ),\n", " gr.Video(value=lambda: os.path.join(file_dir, \"world.mp4\")),\n", " gr.Audio(value=lambda: os.path.join(file_dir, \"cantina.wav\")),\n", " gr.File(\n", " value=lambda: random.choice(\n", " [os.path.join(file_dir, img) for img in os.listdir(file_dir)]\n", " )\n", " ),\n", " gr.Dataframe(\n", " value=lambda: pd.DataFrame({\"random_number_rows\": range(5)}, columns=[\"one\", \"two\", \"three\"])\n", " ),\n", " gr.Timeseries(value=lambda: os.path.join(file_dir, \"time.csv\")),\n", " gr.ColorPicker(value=lambda: random.choice([\"#000000\", \"#ff0000\", \"#0000FF\"])),\n", " gr.Label(value=lambda: random.choice([\"Pedestrian\", \"Car\", \"Cyclist\"])),\n", " gr.HighlightedText(\n", " value=lambda: random.choice(\n", " [\n", " {\"text\": highlighted_text, \"entities\": highlighted_text_output_1},\n", " {\"text\": highlighted_text, \"entities\": highlighted_text_output_2},\n", " ]\n", " ),\n", " ),\n", " gr.JSON(value=lambda: random.choice([{\"a\": 1}, {\"b\": 2}])),\n", " gr.HTML(\n", " value=lambda: random.choice(\n", " [\n", " 'I am red
',\n", " 'I am blue
',\n", " ]\n", " )\n", " ),\n", " gr.Gallery(\n", " value=lambda: images\n", " ),\n", " gr.Model3D(value=random_model3d),\n", " gr.Plot(value=random_plot),\n", " gr.Markdown(value=lambda: f\"### {random.choice(['Hello', 'Hi', 'Goodbye!'])}\"),\n", "]\n", "\n", "\n", "def evaluate_values(*args):\n", " are_false = []\n", " for a in args:\n", " if isinstance(a, (pd.DataFrame, np.ndarray)):\n", " are_false.append(not a.any().any())\n", " elif isinstance(a, str) and a.startswith(\"#\"):\n", " are_false.append(a == \"#000000\")\n", " else:\n", " are_false.append(not a)\n", " return all(are_false)\n", "\n", "\n", "with gr.Blocks() as demo:\n", " for i, component in enumerate(components):\n", " component.label = f\"component_{str(i).zfill(2)}\"\n", " component.render()\n", " clear = gr.ClearButton(value=\"Clear\", components=components)\n", " result = gr.Textbox(label=\"Are all cleared?\")\n", " hide = gr.Button(value=\"Hide\")\n", " reveal = gr.Button(value=\"Reveal\")\n", " hide.click(\n", " lambda: [c.__class__(visible=False) for c in components],\n", " inputs=[],\n", " outputs=components\n", " )\n", " reveal.click(\n", " lambda: [c.__class__(visible=True) for c in components],\n", " inputs=[],\n", " outputs=components\n", " )\n", " get_value = gr.Button(value=\"Get Values\")\n", " get_value.click(evaluate_values, components, result)\n", "\n", "\n", "if __name__ == \"__main__\":\n", " demo.launch()\n"]}], "metadata": {}, "nbformat": 4, "nbformat_minor": 5} +>>>>>>> main diff --git a/demo/clear_components/run.py b/demo/clear_components/run.py index d3eb8361fec2..d60e73621d6f 100644 --- a/demo/clear_components/run.py +++ b/demo/clear_components/run.py @@ -116,7 +116,6 @@ def random_model3d(): gr.Dataframe( value=lambda: pd.DataFrame({"random_number_rows": range(5)}, columns=["one", "two", "three"]) ), - gr.Timeseries(value=lambda: os.path.join(file_dir, "time.csv")), gr.ColorPicker(value=lambda: random.choice(["#000000", "#ff0000", "#0000FF"])), gr.Label(value=lambda: random.choice(["Pedestrian", "Car", "Cyclist"])), gr.HighlightedText( diff --git a/demo/clustering/run.ipynb b/demo/clustering/run.ipynb index 46792c26f798..b21a4c5d6ff9 100644 --- a/demo/clustering/run.ipynb +++ b/demo/clustering/run.ipynb @@ -1 +1,5 @@ -{"cells": [{"cell_type": "markdown", "id": "302934307671667531413257853548643485645", "metadata": {}, "source": ["# Gradio Demo: clustering\n", "### This demo built with Blocks generates 9 plots based on the input.\n", " "]}, {"cell_type": "code", "execution_count": null, "id": "272996653310673477252411125948039410165", "metadata": {}, "outputs": [], "source": ["!pip install -q gradio matplotlib>=3.5.2 scikit-learn>=1.0.1 "]}, {"cell_type": "code", "execution_count": null, "id": "288918539441861185822528903084949547379", "metadata": {}, "outputs": [], "source": ["import gradio as gr\n", "import math\n", "from functools import partial\n", "import matplotlib.pyplot as plt\n", "import numpy as np\n", "from sklearn.cluster import (\n", " AgglomerativeClustering, Birch, DBSCAN, KMeans, MeanShift, OPTICS, SpectralClustering, estimate_bandwidth\n", ")\n", "from sklearn.datasets import make_blobs, make_circles, make_moons\n", "from sklearn.mixture import GaussianMixture\n", "from sklearn.neighbors import kneighbors_graph\n", "from sklearn.preprocessing import StandardScaler\n", "\n", "plt.style.use('seaborn-v0_8')\n", "SEED = 0\n", "MAX_CLUSTERS = 10\n", "N_SAMPLES = 1000\n", "N_COLS = 3\n", "FIGSIZE = 7, 7 # does not affect size in webpage\n", "COLORS = [\n", " 'blue', 'orange', 'green', 'red', 'purple', 'brown', 'pink', 'gray', 'olive', 'cyan'\n", "]\n", "if len(COLORS) <= MAX_CLUSTERS:\n", " raise ValueError(\"Not enough different colors for all clusters\")\n", "np.random.seed(SEED)\n", "\n", "\n", "def normalize(X):\n", " return StandardScaler().fit_transform(X)\n", "\n", "def get_regular(n_clusters):\n", " # spiral pattern\n", " centers = [\n", " [0, 0],\n", " [1, 0],\n", " [1, 1],\n", " [0, 1],\n", " [-1, 1],\n", " [-1, 0],\n", " [-1, -1],\n", " [0, -1],\n", " [1, -1],\n", " [2, -1],\n", " ][:n_clusters]\n", " assert len(centers) == n_clusters\n", " X, labels = make_blobs(n_samples=N_SAMPLES, centers=centers, cluster_std=0.25, random_state=SEED)\n", " return normalize(X), labels\n", "\n", "\n", "def get_circles(n_clusters):\n", " X, labels = make_circles(n_samples=N_SAMPLES, factor=0.5, noise=0.05, random_state=SEED)\n", " return normalize(X), labels\n", "\n", "\n", "def get_moons(n_clusters):\n", " X, labels = make_moons(n_samples=N_SAMPLES, noise=0.05, random_state=SEED)\n", " return normalize(X), labels\n", "\n", "\n", "def get_noise(n_clusters):\n", " np.random.seed(SEED)\n", " X, labels = np.random.rand(N_SAMPLES, 2), np.random.randint(0, n_clusters, size=(N_SAMPLES,))\n", " return normalize(X), labels\n", "\n", "\n", "def get_anisotropic(n_clusters):\n", " X, labels = make_blobs(n_samples=N_SAMPLES, centers=n_clusters, random_state=170)\n", " transformation = [[0.6, -0.6], [-0.4, 0.8]]\n", " X = np.dot(X, transformation)\n", " return X, labels\n", "\n", "\n", "def get_varied(n_clusters):\n", " cluster_std = [1.0, 2.5, 0.5, 1.0, 2.5, 0.5, 1.0, 2.5, 0.5, 1.0][:n_clusters]\n", " assert len(cluster_std) == n_clusters\n", " X, labels = make_blobs(\n", " n_samples=N_SAMPLES, centers=n_clusters, cluster_std=cluster_std, random_state=SEED\n", " )\n", " return normalize(X), labels\n", "\n", "\n", "def get_spiral(n_clusters):\n", " # from https://scikit-learn.org/stable/auto_examples/cluster/plot_agglomerative_clustering.html\n", " np.random.seed(SEED)\n", " t = 1.5 * np.pi * (1 + 3 * np.random.rand(1, N_SAMPLES))\n", " x = t * np.cos(t)\n", " y = t * np.sin(t)\n", " X = np.concatenate((x, y))\n", " X += 0.7 * np.random.randn(2, N_SAMPLES)\n", " X = np.ascontiguousarray(X.T)\n", "\n", " labels = np.zeros(N_SAMPLES, dtype=int)\n", " return normalize(X), labels\n", "\n", "\n", "DATA_MAPPING = {\n", " 'regular': get_regular,\n", " 'circles': get_circles,\n", " 'moons': get_moons,\n", " 'spiral': get_spiral,\n", " 'noise': get_noise,\n", " 'anisotropic': get_anisotropic,\n", " 'varied': get_varied,\n", "}\n", "\n", "\n", "def get_groundtruth_model(X, labels, n_clusters, **kwargs):\n", " # dummy model to show true label distribution\n", " class Dummy:\n", " def __init__(self, y):\n", " self.labels_ = labels\n", "\n", " return Dummy(labels)\n", "\n", "\n", "def get_kmeans(X, labels, n_clusters, **kwargs):\n", " model = KMeans(init=\"k-means++\", n_clusters=n_clusters, n_init=10, random_state=SEED)\n", " model.set_params(**kwargs)\n", " return model.fit(X)\n", "\n", "\n", "def get_dbscan(X, labels, n_clusters, **kwargs):\n", " model = DBSCAN(eps=0.3)\n", " model.set_params(**kwargs)\n", " return model.fit(X)\n", "\n", "\n", "def get_agglomerative(X, labels, n_clusters, **kwargs):\n", " connectivity = kneighbors_graph(\n", " X, n_neighbors=n_clusters, include_self=False\n", " )\n", " # make connectivity symmetric\n", " connectivity = 0.5 * (connectivity + connectivity.T)\n", " model = AgglomerativeClustering(\n", " n_clusters=n_clusters, linkage=\"ward\", connectivity=connectivity\n", " )\n", " model.set_params(**kwargs)\n", " return model.fit(X)\n", "\n", "\n", "def get_meanshift(X, labels, n_clusters, **kwargs):\n", " bandwidth = estimate_bandwidth(X, quantile=0.25)\n", " model = MeanShift(bandwidth=bandwidth, bin_seeding=True)\n", " model.set_params(**kwargs)\n", " return model.fit(X)\n", "\n", "\n", "def get_spectral(X, labels, n_clusters, **kwargs):\n", " model = SpectralClustering(\n", " n_clusters=n_clusters,\n", " eigen_solver=\"arpack\",\n", " affinity=\"nearest_neighbors\",\n", " )\n", " model.set_params(**kwargs)\n", " return model.fit(X)\n", "\n", "\n", "def get_optics(X, labels, n_clusters, **kwargs):\n", " model = OPTICS(\n", " min_samples=7,\n", " xi=0.05,\n", " min_cluster_size=0.1,\n", " )\n", " model.set_params(**kwargs)\n", " return model.fit(X)\n", "\n", "\n", "def get_birch(X, labels, n_clusters, **kwargs):\n", " model = Birch(n_clusters=n_clusters)\n", " model.set_params(**kwargs)\n", " return model.fit(X)\n", "\n", "\n", "def get_gaussianmixture(X, labels, n_clusters, **kwargs):\n", " model = GaussianMixture(\n", " n_components=n_clusters, covariance_type=\"full\", random_state=SEED,\n", " )\n", " model.set_params(**kwargs)\n", " return model.fit(X)\n", "\n", "\n", "MODEL_MAPPING = {\n", " 'True labels': get_groundtruth_model,\n", " 'KMeans': get_kmeans,\n", " 'DBSCAN': get_dbscan,\n", " 'MeanShift': get_meanshift,\n", " 'SpectralClustering': get_spectral,\n", " 'OPTICS': get_optics,\n", " 'Birch': get_birch,\n", " 'GaussianMixture': get_gaussianmixture,\n", " 'AgglomerativeClustering': get_agglomerative,\n", "}\n", "\n", "\n", "def plot_clusters(ax, X, labels):\n", " set_clusters = set(labels)\n", " set_clusters.discard(-1) # -1 signifiies outliers, which we plot separately\n", " for label, color in zip(sorted(set_clusters), COLORS):\n", " idx = labels == label\n", " if not sum(idx):\n", " continue\n", " ax.scatter(X[idx, 0], X[idx, 1], color=color)\n", "\n", " # show outliers (if any)\n", " idx = labels == -1\n", " if sum(idx):\n", " ax.scatter(X[idx, 0], X[idx, 1], c='k', marker='x')\n", "\n", " ax.grid(None)\n", " ax.set_xticks([])\n", " ax.set_yticks([])\n", " return ax\n", "\n", "\n", "def cluster(dataset: str, n_clusters: int, clustering_algorithm: str):\n", " if isinstance(n_clusters, dict):\n", " n_clusters = n_clusters['value']\n", " else:\n", " n_clusters = int(n_clusters)\n", "\n", " X, labels = DATA_MAPPING[dataset](n_clusters)\n", " model = MODEL_MAPPING[clustering_algorithm](X, labels, n_clusters=n_clusters)\n", " if hasattr(model, \"labels_\"):\n", " y_pred = model.labels_.astype(int)\n", " else:\n", " y_pred = model.predict(X)\n", "\n", " fig, ax = plt.subplots(figsize=FIGSIZE)\n", "\n", " plot_clusters(ax, X, y_pred)\n", " ax.set_title(clustering_algorithm, fontsize=16)\n", "\n", " return fig\n", "\n", "\n", "title = \"Clustering with Scikit-learn\"\n", "description = (\n", " \"This example shows how different clustering algorithms work. Simply pick \"\n", " \"the dataset and the number of clusters to see how the clustering algorithms work. \"\n", " \"Colored circles are (predicted) labels and black x are outliers.\"\n", ")\n", "\n", "\n", "def iter_grid(n_rows, n_cols):\n", " # create a grid using gradio Block\n", " for _ in range(n_rows):\n", " with gr.Row():\n", " for _ in range(n_cols):\n", " with gr.Column():\n", " yield\n", "\n", "with gr.Blocks(title=title) as demo:\n", " gr.HTML(f\"{title}\")\n", " gr.Markdown(description)\n", "\n", " input_models = list(MODEL_MAPPING)\n", " input_data = gr.Radio(\n", " list(DATA_MAPPING),\n", " value=\"regular\",\n", " label=\"dataset\"\n", " )\n", " input_n_clusters = gr.Slider(\n", " minimum=1,\n", " maximum=MAX_CLUSTERS,\n", " value=4,\n", " step=1,\n", " label='Number of clusters'\n", " )\n", " n_rows = int(math.ceil(len(input_models) / N_COLS))\n", " counter = 0\n", " for _ in iter_grid(n_rows, N_COLS):\n", " if counter >= len(input_models):\n", " break\n", "\n", " input_model = input_models[counter]\n", " plot = gr.Plot(label=input_model)\n", " fn = partial(cluster, clustering_algorithm=input_model)\n", " input_data.change(fn=fn, inputs=[input_data, input_n_clusters], outputs=plot)\n", " input_n_clusters.change(fn=fn, inputs=[input_data, input_n_clusters], outputs=plot)\n", " counter += 1\n", "\n", "demo.launch()\n"]}], "metadata": {}, "nbformat": 4, "nbformat_minor": 5} \ No newline at end of file +<<<<<<< HEAD +{"cells": [{"cell_type": "markdown", "id": 302934307671667531413257853548643485645, "metadata": {}, "source": ["# Gradio Demo: clustering\n", "### This demo built with Blocks generates 9 plots based on the input.\n", " "]}, {"cell_type": "code", "execution_count": null, "id": 272996653310673477252411125948039410165, "metadata": {}, "outputs": [], "source": ["!pip install -q gradio matplotlib>=3.5.2 scikit-learn>=1.0.1 "]}, {"cell_type": "code", "execution_count": null, "id": 288918539441861185822528903084949547379, "metadata": {}, "outputs": [], "source": ["import gradio as gr\n", "import math\n", "from functools import partial\n", "import matplotlib.pyplot as plt\n", "import numpy as np\n", "from sklearn.cluster import (\n", " AgglomerativeClustering, Birch, DBSCAN, KMeans, MeanShift, OPTICS, SpectralClustering, estimate_bandwidth\n", ")\n", "from sklearn.datasets import make_blobs, make_circles, make_moons\n", "from sklearn.mixture import GaussianMixture\n", "from sklearn.neighbors import kneighbors_graph\n", "from sklearn.preprocessing import StandardScaler\n", "\n", "plt.style.use('seaborn-v0_8')\n", "SEED = 0\n", "MAX_CLUSTERS = 10\n", "N_SAMPLES = 1000\n", "N_COLS = 3\n", "FIGSIZE = 7, 7 # does not affect size in webpage\n", "COLORS = [\n", " 'blue', 'orange', 'green', 'red', 'purple', 'brown', 'pink', 'gray', 'olive', 'cyan'\n", "]\n", "if len(COLORS) <= MAX_CLUSTERS:\n", " raise ValueError(\"Not enough different colors for all clusters\")\n", "np.random.seed(SEED)\n", "\n", "\n", "def normalize(X):\n", " return StandardScaler().fit_transform(X)\n", "\n", "def get_regular(n_clusters):\n", " # spiral pattern\n", " centers = [\n", " [0, 0],\n", " [1, 0],\n", " [1, 1],\n", " [0, 1],\n", " [-1, 1],\n", " [-1, 0],\n", " [-1, -1],\n", " [0, -1],\n", " [1, -1],\n", " [2, -1],\n", " ][:n_clusters]\n", " assert len(centers) == n_clusters\n", " X, labels = make_blobs(n_samples=N_SAMPLES, centers=centers, cluster_std=0.25, random_state=SEED)\n", " return normalize(X), labels\n", "\n", "\n", "def get_circles(n_clusters):\n", " X, labels = make_circles(n_samples=N_SAMPLES, factor=0.5, noise=0.05, random_state=SEED)\n", " return normalize(X), labels\n", "\n", "\n", "def get_moons(n_clusters):\n", " X, labels = make_moons(n_samples=N_SAMPLES, noise=0.05, random_state=SEED)\n", " return normalize(X), labels\n", "\n", "\n", "def get_noise(n_clusters):\n", " np.random.seed(SEED)\n", " X, labels = np.random.rand(N_SAMPLES, 2), np.random.randint(0, n_clusters, size=(N_SAMPLES,))\n", " return normalize(X), labels\n", "\n", "\n", "def get_anisotropic(n_clusters):\n", " X, labels = make_blobs(n_samples=N_SAMPLES, centers=n_clusters, random_state=170)\n", " transformation = [[0.6, -0.6], [-0.4, 0.8]]\n", " X = np.dot(X, transformation)\n", " return X, labels\n", "\n", "\n", "def get_varied(n_clusters):\n", " cluster_std = [1.0, 2.5, 0.5, 1.0, 2.5, 0.5, 1.0, 2.5, 0.5, 1.0][:n_clusters]\n", " assert len(cluster_std) == n_clusters\n", " X, labels = make_blobs(\n", " n_samples=N_SAMPLES, centers=n_clusters, cluster_std=cluster_std, random_state=SEED\n", " )\n", " return normalize(X), labels\n", "\n", "\n", "def get_spiral(n_clusters):\n", " # from https://scikit-learn.org/stable/auto_examples/cluster/plot_agglomerative_clustering.html\n", " np.random.seed(SEED)\n", " t = 1.5 * np.pi * (1 + 3 * np.random.rand(1, N_SAMPLES))\n", " x = t * np.cos(t)\n", " y = t * np.sin(t)\n", " X = np.concatenate((x, y))\n", " X += 0.7 * np.random.randn(2, N_SAMPLES)\n", " X = np.ascontiguousarray(X.T)\n", "\n", " labels = np.zeros(N_SAMPLES, dtype=int)\n", " return normalize(X), labels\n", "\n", "\n", "DATA_MAPPING = {\n", " 'regular': get_regular,\n", " 'circles': get_circles,\n", " 'moons': get_moons,\n", " 'spiral': get_spiral,\n", " 'noise': get_noise,\n", " 'anisotropic': get_anisotropic,\n", " 'varied': get_varied,\n", "}\n", "\n", "\n", "def get_groundtruth_model(X, labels, n_clusters, **kwargs):\n", " # dummy model to show true label distribution\n", " class Dummy:\n", " def __init__(self, y):\n", " self.labels_ = labels\n", "\n", " return Dummy(labels)\n", "\n", "\n", "def get_kmeans(X, labels, n_clusters, **kwargs):\n", " model = KMeans(init=\"k-means++\", n_clusters=n_clusters, n_init=10, random_state=SEED)\n", " model.set_params(**kwargs)\n", " return model.fit(X)\n", "\n", "\n", "def get_dbscan(X, labels, n_clusters, **kwargs):\n", " model = DBSCAN(eps=0.3)\n", " model.set_params(**kwargs)\n", " return model.fit(X)\n", "\n", "\n", "def get_agglomerative(X, labels, n_clusters, **kwargs):\n", " connectivity = kneighbors_graph(\n", " X, n_neighbors=n_clusters, include_self=False\n", " )\n", " # make connectivity symmetric\n", " connectivity = 0.5 * (connectivity + connectivity.T)\n", " model = AgglomerativeClustering(\n", " n_clusters=n_clusters, linkage=\"ward\", connectivity=connectivity\n", " )\n", " model.set_params(**kwargs)\n", " return model.fit(X)\n", "\n", "\n", "def get_meanshift(X, labels, n_clusters, **kwargs):\n", " bandwidth = estimate_bandwidth(X, quantile=0.25)\n", " model = MeanShift(bandwidth=bandwidth, bin_seeding=True)\n", " model.set_params(**kwargs)\n", " return model.fit(X)\n", "\n", "\n", "def get_spectral(X, labels, n_clusters, **kwargs):\n", " model = SpectralClustering(\n", " n_clusters=n_clusters,\n", " eigen_solver=\"arpack\",\n", " affinity=\"nearest_neighbors\",\n", " )\n", " model.set_params(**kwargs)\n", " return model.fit(X)\n", "\n", "\n", "def get_optics(X, labels, n_clusters, **kwargs):\n", " model = OPTICS(\n", " min_samples=7,\n", " xi=0.05,\n", " min_cluster_size=0.1,\n", " )\n", " model.set_params(**kwargs)\n", " return model.fit(X)\n", "\n", "\n", "def get_birch(X, labels, n_clusters, **kwargs):\n", " model = Birch(n_clusters=n_clusters)\n", " model.set_params(**kwargs)\n", " return model.fit(X)\n", "\n", "\n", "def get_gaussianmixture(X, labels, n_clusters, **kwargs):\n", " model = GaussianMixture(\n", " n_components=n_clusters, covariance_type=\"full\", random_state=SEED,\n", " )\n", " model.set_params(**kwargs)\n", " return model.fit(X)\n", "\n", "\n", "MODEL_MAPPING = {\n", " 'True labels': get_groundtruth_model,\n", " 'KMeans': get_kmeans,\n", " 'DBSCAN': get_dbscan,\n", " 'MeanShift': get_meanshift,\n", " 'SpectralClustering': get_spectral,\n", " 'OPTICS': get_optics,\n", " 'Birch': get_birch,\n", " 'GaussianMixture': get_gaussianmixture,\n", " 'AgglomerativeClustering': get_agglomerative,\n", "}\n", "\n", "\n", "def plot_clusters(ax, X, labels):\n", " set_clusters = set(labels)\n", " set_clusters.discard(-1) # -1 signifiies outliers, which we plot separately\n", " for label, color in zip(sorted(set_clusters), COLORS):\n", " idx = labels == label\n", " if not sum(idx):\n", " continue\n", " ax.scatter(X[idx, 0], X[idx, 1], color=color)\n", "\n", " # show outliers (if any)\n", " idx = labels == -1\n", " if sum(idx):\n", " ax.scatter(X[idx, 0], X[idx, 1], c='k', marker='x')\n", "\n", " ax.grid(None)\n", " ax.set_xticks([])\n", " ax.set_yticks([])\n", " return ax\n", "\n", "\n", "def cluster(dataset: str, n_clusters: int, clustering_algorithm: str):\n", " if isinstance(n_clusters, dict):\n", " n_clusters = n_clusters['value']\n", " else:\n", " n_clusters = int(n_clusters)\n", "\n", " X, labels = DATA_MAPPING[dataset](n_clusters)\n", " model = MODEL_MAPPING[clustering_algorithm](X, labels, n_clusters=n_clusters)\n", " if hasattr(model, \"labels_\"):\n", " y_pred = model.labels_.astype(int)\n", " else:\n", " y_pred = model.predict(X)\n", "\n", " fig, ax = plt.subplots(figsize=FIGSIZE)\n", "\n", " plot_clusters(ax, X, y_pred)\n", " ax.set_title(clustering_algorithm, fontsize=16)\n", "\n", " return fig\n", "\n", "\n", "title = \"Clustering with Scikit-learn\"\n", "description = (\n", " \"This example shows how different clustering algorithms work. Simply pick \"\n", " \"the dataset and the number of clusters to see how the clustering algorithms work. \"\n", " \"Colored circles are (predicted) labels and black x are outliers.\"\n", ")\n", "\n", "\n", "def iter_grid(n_rows, n_cols):\n", " # create a grid using gradio Block\n", " for _ in range(n_rows):\n", " with gr.Row():\n", " for _ in range(n_cols):\n", " with gr.Column():\n", " yield\n", "\n", "with gr.Blocks(title=title) as demo:\n", " gr.HTML(f\"{title}\")\n", " gr.Markdown(description)\n", "\n", " input_models = list(MODEL_MAPPING)\n", " input_data = gr.Radio(\n", " list(DATA_MAPPING),\n", " value=\"regular\",\n", " label=\"dataset\"\n", " )\n", " input_n_clusters = gr.Slider(\n", " minimum=1,\n", " maximum=MAX_CLUSTERS,\n", " value=4,\n", " step=1,\n", " label='Number of clusters'\n", " )\n", " n_rows = int(math.ceil(len(input_models) / N_COLS))\n", " counter = 0\n", " for _ in iter_grid(n_rows, N_COLS):\n", " if counter >= len(input_models):\n", " break\n", "\n", " input_model = input_models[counter]\n", " plot = gr.Plot(label=input_model)\n", " fn = partial(cluster, clustering_algorithm=input_model)\n", " input_data.change(fn=fn, inputs=[input_data, input_n_clusters], outputs=plot)\n", " input_n_clusters.change(fn=fn, inputs=[input_data, input_n_clusters], outputs=plot)\n", " counter += 1\n", "\n", "demo.launch()\n"]}], "metadata": {}, "nbformat": 4, "nbformat_minor": 5} +======= +{"cells": [{"cell_type": "markdown", "id": "302934307671667531413257853548643485645", "metadata": {}, "source": ["# Gradio Demo: clustering\n", "### This demo built with Blocks generates 9 plots based on the input.\n", " "]}, {"cell_type": "code", "execution_count": null, "id": "272996653310673477252411125948039410165", "metadata": {}, "outputs": [], "source": ["!pip install -q gradio matplotlib>=3.5.2 scikit-learn>=1.0.1 "]}, {"cell_type": "code", "execution_count": null, "id": "288918539441861185822528903084949547379", "metadata": {}, "outputs": [], "source": ["import gradio as gr\n", "import math\n", "from functools import partial\n", "import matplotlib.pyplot as plt\n", "import numpy as np\n", "from sklearn.cluster import (\n", " AgglomerativeClustering, Birch, DBSCAN, KMeans, MeanShift, OPTICS, SpectralClustering, estimate_bandwidth\n", ")\n", "from sklearn.datasets import make_blobs, make_circles, make_moons\n", "from sklearn.mixture import GaussianMixture\n", "from sklearn.neighbors import kneighbors_graph\n", "from sklearn.preprocessing import StandardScaler\n", "\n", "plt.style.use('seaborn-v0_8')\n", "SEED = 0\n", "MAX_CLUSTERS = 10\n", "N_SAMPLES = 1000\n", "N_COLS = 3\n", "FIGSIZE = 7, 7 # does not affect size in webpage\n", "COLORS = [\n", " 'blue', 'orange', 'green', 'red', 'purple', 'brown', 'pink', 'gray', 'olive', 'cyan'\n", "]\n", "if len(COLORS) <= MAX_CLUSTERS:\n", " raise ValueError(\"Not enough different colors for all clusters\")\n", "np.random.seed(SEED)\n", "\n", "\n", "def normalize(X):\n", " return StandardScaler().fit_transform(X)\n", "\n", "def get_regular(n_clusters):\n", " # spiral pattern\n", " centers = [\n", " [0, 0],\n", " [1, 0],\n", " [1, 1],\n", " [0, 1],\n", " [-1, 1],\n", " [-1, 0],\n", " [-1, -1],\n", " [0, -1],\n", " [1, -1],\n", " [2, -1],\n", " ][:n_clusters]\n", " assert len(centers) == n_clusters\n", " X, labels = make_blobs(n_samples=N_SAMPLES, centers=centers, cluster_std=0.25, random_state=SEED)\n", " return normalize(X), labels\n", "\n", "\n", "def get_circles(n_clusters):\n", " X, labels = make_circles(n_samples=N_SAMPLES, factor=0.5, noise=0.05, random_state=SEED)\n", " return normalize(X), labels\n", "\n", "\n", "def get_moons(n_clusters):\n", " X, labels = make_moons(n_samples=N_SAMPLES, noise=0.05, random_state=SEED)\n", " return normalize(X), labels\n", "\n", "\n", "def get_noise(n_clusters):\n", " np.random.seed(SEED)\n", " X, labels = np.random.rand(N_SAMPLES, 2), np.random.randint(0, n_clusters, size=(N_SAMPLES,))\n", " return normalize(X), labels\n", "\n", "\n", "def get_anisotropic(n_clusters):\n", " X, labels = make_blobs(n_samples=N_SAMPLES, centers=n_clusters, random_state=170)\n", " transformation = [[0.6, -0.6], [-0.4, 0.8]]\n", " X = np.dot(X, transformation)\n", " return X, labels\n", "\n", "\n", "def get_varied(n_clusters):\n", " cluster_std = [1.0, 2.5, 0.5, 1.0, 2.5, 0.5, 1.0, 2.5, 0.5, 1.0][:n_clusters]\n", " assert len(cluster_std) == n_clusters\n", " X, labels = make_blobs(\n", " n_samples=N_SAMPLES, centers=n_clusters, cluster_std=cluster_std, random_state=SEED\n", " )\n", " return normalize(X), labels\n", "\n", "\n", "def get_spiral(n_clusters):\n", " # from https://scikit-learn.org/stable/auto_examples/cluster/plot_agglomerative_clustering.html\n", " np.random.seed(SEED)\n", " t = 1.5 * np.pi * (1 + 3 * np.random.rand(1, N_SAMPLES))\n", " x = t * np.cos(t)\n", " y = t * np.sin(t)\n", " X = np.concatenate((x, y))\n", " X += 0.7 * np.random.randn(2, N_SAMPLES)\n", " X = np.ascontiguousarray(X.T)\n", "\n", " labels = np.zeros(N_SAMPLES, dtype=int)\n", " return normalize(X), labels\n", "\n", "\n", "DATA_MAPPING = {\n", " 'regular': get_regular,\n", " 'circles': get_circles,\n", " 'moons': get_moons,\n", " 'spiral': get_spiral,\n", " 'noise': get_noise,\n", " 'anisotropic': get_anisotropic,\n", " 'varied': get_varied,\n", "}\n", "\n", "\n", "def get_groundtruth_model(X, labels, n_clusters, **kwargs):\n", " # dummy model to show true label distribution\n", " class Dummy:\n", " def __init__(self, y):\n", " self.labels_ = labels\n", "\n", " return Dummy(labels)\n", "\n", "\n", "def get_kmeans(X, labels, n_clusters, **kwargs):\n", " model = KMeans(init=\"k-means++\", n_clusters=n_clusters, n_init=10, random_state=SEED)\n", " model.set_params(**kwargs)\n", " return model.fit(X)\n", "\n", "\n", "def get_dbscan(X, labels, n_clusters, **kwargs):\n", " model = DBSCAN(eps=0.3)\n", " model.set_params(**kwargs)\n", " return model.fit(X)\n", "\n", "\n", "def get_agglomerative(X, labels, n_clusters, **kwargs):\n", " connectivity = kneighbors_graph(\n", " X, n_neighbors=n_clusters, include_self=False\n", " )\n", " # make connectivity symmetric\n", " connectivity = 0.5 * (connectivity + connectivity.T)\n", " model = AgglomerativeClustering(\n", " n_clusters=n_clusters, linkage=\"ward\", connectivity=connectivity\n", " )\n", " model.set_params(**kwargs)\n", " return model.fit(X)\n", "\n", "\n", "def get_meanshift(X, labels, n_clusters, **kwargs):\n", " bandwidth = estimate_bandwidth(X, quantile=0.25)\n", " model = MeanShift(bandwidth=bandwidth, bin_seeding=True)\n", " model.set_params(**kwargs)\n", " return model.fit(X)\n", "\n", "\n", "def get_spectral(X, labels, n_clusters, **kwargs):\n", " model = SpectralClustering(\n", " n_clusters=n_clusters,\n", " eigen_solver=\"arpack\",\n", " affinity=\"nearest_neighbors\",\n", " )\n", " model.set_params(**kwargs)\n", " return model.fit(X)\n", "\n", "\n", "def get_optics(X, labels, n_clusters, **kwargs):\n", " model = OPTICS(\n", " min_samples=7,\n", " xi=0.05,\n", " min_cluster_size=0.1,\n", " )\n", " model.set_params(**kwargs)\n", " return model.fit(X)\n", "\n", "\n", "def get_birch(X, labels, n_clusters, **kwargs):\n", " model = Birch(n_clusters=n_clusters)\n", " model.set_params(**kwargs)\n", " return model.fit(X)\n", "\n", "\n", "def get_gaussianmixture(X, labels, n_clusters, **kwargs):\n", " model = GaussianMixture(\n", " n_components=n_clusters, covariance_type=\"full\", random_state=SEED,\n", " )\n", " model.set_params(**kwargs)\n", " return model.fit(X)\n", "\n", "\n", "MODEL_MAPPING = {\n", " 'True labels': get_groundtruth_model,\n", " 'KMeans': get_kmeans,\n", " 'DBSCAN': get_dbscan,\n", " 'MeanShift': get_meanshift,\n", " 'SpectralClustering': get_spectral,\n", " 'OPTICS': get_optics,\n", " 'Birch': get_birch,\n", " 'GaussianMixture': get_gaussianmixture,\n", " 'AgglomerativeClustering': get_agglomerative,\n", "}\n", "\n", "\n", "def plot_clusters(ax, X, labels):\n", " set_clusters = set(labels)\n", " set_clusters.discard(-1) # -1 signifiies outliers, which we plot separately\n", " for label, color in zip(sorted(set_clusters), COLORS):\n", " idx = labels == label\n", " if not sum(idx):\n", " continue\n", " ax.scatter(X[idx, 0], X[idx, 1], color=color)\n", "\n", " # show outliers (if any)\n", " idx = labels == -1\n", " if sum(idx):\n", " ax.scatter(X[idx, 0], X[idx, 1], c='k', marker='x')\n", "\n", " ax.grid(None)\n", " ax.set_xticks([])\n", " ax.set_yticks([])\n", " return ax\n", "\n", "\n", "def cluster(dataset: str, n_clusters: int, clustering_algorithm: str):\n", " if isinstance(n_clusters, dict):\n", " n_clusters = n_clusters['value']\n", " else:\n", " n_clusters = int(n_clusters)\n", "\n", " X, labels = DATA_MAPPING[dataset](n_clusters)\n", " model = MODEL_MAPPING[clustering_algorithm](X, labels, n_clusters=n_clusters)\n", " if hasattr(model, \"labels_\"):\n", " y_pred = model.labels_.astype(int)\n", " else:\n", " y_pred = model.predict(X)\n", "\n", " fig, ax = plt.subplots(figsize=FIGSIZE)\n", "\n", " plot_clusters(ax, X, y_pred)\n", " ax.set_title(clustering_algorithm, fontsize=16)\n", "\n", " return fig\n", "\n", "\n", "title = \"Clustering with Scikit-learn\"\n", "description = (\n", " \"This example shows how different clustering algorithms work. Simply pick \"\n", " \"the dataset and the number of clusters to see how the clustering algorithms work. \"\n", " \"Colored circles are (predicted) labels and black x are outliers.\"\n", ")\n", "\n", "\n", "def iter_grid(n_rows, n_cols):\n", " # create a grid using gradio Block\n", " for _ in range(n_rows):\n", " with gr.Row():\n", " for _ in range(n_cols):\n", " with gr.Column():\n", " yield\n", "\n", "with gr.Blocks(title=title) as demo:\n", " gr.HTML(f\"{title}\")\n", " gr.Markdown(description)\n", "\n", " input_models = list(MODEL_MAPPING)\n", " input_data = gr.Radio(\n", " list(DATA_MAPPING),\n", " value=\"regular\",\n", " label=\"dataset\"\n", " )\n", " input_n_clusters = gr.Slider(\n", " minimum=1,\n", " maximum=MAX_CLUSTERS,\n", " value=4,\n", " step=1,\n", " label='Number of clusters'\n", " )\n", " n_rows = int(math.ceil(len(input_models) / N_COLS))\n", " counter = 0\n", " for _ in iter_grid(n_rows, N_COLS):\n", " if counter >= len(input_models):\n", " break\n", "\n", " input_model = input_models[counter]\n", " plot = gr.Plot(label=input_model)\n", " fn = partial(cluster, clustering_algorithm=input_model)\n", " input_data.change(fn=fn, inputs=[input_data, input_n_clusters], outputs=plot)\n", " input_n_clusters.change(fn=fn, inputs=[input_data, input_n_clusters], outputs=plot)\n", " counter += 1\n", "\n", "demo.launch()\n"]}], "metadata": {}, "nbformat": 4, "nbformat_minor": 5} +>>>>>>> main diff --git a/demo/dashboard/run.ipynb b/demo/dashboard/run.ipynb index ca4d20de0769..453dad0ee04a 100644 --- a/demo/dashboard/run.ipynb +++ b/demo/dashboard/run.ipynb @@ -1 +1 @@ -{"cells": [{"cell_type": "markdown", "id": "302934307671667531413257853548643485645", "metadata": {}, "source": ["# Gradio Demo: dashboard\n", "### This demo shows how you can build an interactive dashboard with gradio. Click on a python library on the left hand side and then on the right hand side click on the metric you'd like to see plot over time. Data is pulled from HuggingFace Hub datasets.\n", " "]}, {"cell_type": "code", "execution_count": null, "id": "272996653310673477252411125948039410165", "metadata": {}, "outputs": [], "source": ["!pip install -q gradio plotly"]}, {"cell_type": "code", "execution_count": null, "id": "288918539441861185822528903084949547379", "metadata": {}, "outputs": [], "source": ["# Downloading files from the demo repo\n", "import os\n", "!wget -q https://github.com/gradio-app/gradio/raw/main/demo/dashboard/helpers.py"]}, {"cell_type": "code", "execution_count": null, "id": "44380577570523278879349135829904343037", "metadata": {}, "outputs": [], "source": ["import gradio as gr\n", "import pandas as pd\n", "import plotly.express as px\n", "from helpers import *\n", "\n", "\n", "LIBRARIES = [\"accelerate\", \"datasets\", \"diffusers\", \"evaluate\", \"gradio\", \"hub_docs\",\n", " \"huggingface_hub\", \"optimum\", \"pytorch_image_models\", \"tokenizers\", \"transformers\"]\n", "\n", "\n", "def create_pip_plot(libraries, pip_choices):\n", " if \"Pip\" not in pip_choices:\n", " return gr.Plot(visible=False)\n", " output = retrieve_pip_installs(libraries, \"Cumulated\" in pip_choices)\n", " df = pd.DataFrame(output).melt(id_vars=\"day\")\n", " plot = px.line(df, x=\"day\", y=\"value\", color=\"variable\",\n", " title=\"Pip installs\")\n", " plot.update_layout(legend=dict(x=0.5, y=0.99), title_x=0.5, legend_title_text=\"\")\n", " return gr.Plot(value=plot, visible=True)\n", "\n", "\n", "def create_star_plot(libraries, star_choices):\n", " if \"Stars\" not in star_choices:\n", " return gr.Plot(visible=False)\n", " output = retrieve_stars(libraries, \"Week over Week\" in star_choices)\n", " df = pd.DataFrame(output).melt(id_vars=\"day\")\n", " plot = px.line(df, x=\"day\", y=\"value\", color=\"variable\",\n", " title=\"Number of stargazers\")\n", " plot.update_layout(legend=dict(x=0.5, y=0.99), title_x=0.5, legend_title_text=\"\")\n", " return gr.Plot(value=plot, visible=True)\n", "\n", "\n", "def create_issue_plot(libraries, issue_choices):\n", " if \"Issue\" not in issue_choices:\n", " return gr.Plot(visible=False)\n", " output = retrieve_issues(libraries,\n", " exclude_org_members=\"Exclude org members\" in issue_choices,\n", " week_over_week=\"Week over Week\" in issue_choices)\n", " df = pd.DataFrame(output).melt(id_vars=\"day\")\n", " plot = px.line(df, x=\"day\", y=\"value\", color=\"variable\",\n", " title=\"Cumulated number of issues, PRs, and comments\",\n", " )\n", " plot.update_layout(legend=dict(x=0.5, y=0.99), title_x=0.5, legend_title_text=\"\")\n", " return gr.Plot(value=plot, visible=True)\n", "\n", "\n", "with gr.Blocks() as demo:\n", " with gr.Row():\n", " with gr.Column():\n", " gr.Markdown(\"## Select libraries to display\")\n", " libraries = gr.CheckboxGroup(choices=LIBRARIES, show_label=False)\n", " with gr.Column():\n", " gr.Markdown(\"## Select graphs to display\")\n", " pip = gr.CheckboxGroup(choices=[\"Pip\", \"Cumulated\"], show_label=False)\n", " stars = gr.CheckboxGroup(choices=[\"Stars\", \"Week over Week\"], show_label=False)\n", " issues = gr.CheckboxGroup(choices=[\"Issue\", \"Exclude org members\", \"week over week\"], show_label=False)\n", " with gr.Row():\n", " fetch = gr.Button(value=\"Fetch\")\n", " with gr.Row():\n", " with gr.Column():\n", " pip_plot = gr.Plot(visible=False)\n", " star_plot = gr.Plot(visible=False)\n", " issue_plot = gr.Plot(visible=False)\n", "\n", " fetch.click(create_pip_plot, inputs=[libraries, pip], outputs=pip_plot)\n", " fetch.click(create_star_plot, inputs=[libraries, stars], outputs=star_plot)\n", " fetch.click(create_issue_plot, inputs=[libraries, issues], outputs=issue_plot)\n", "\n", "\n", "if __name__ == \"__main__\":\n", " demo.launch()"]}], "metadata": {}, "nbformat": 4, "nbformat_minor": 5} \ No newline at end of file +{"cells": [{"cell_type": "markdown", "id": "302934307671667531413257853548643485645", "metadata": {}, "source": ["# Gradio Demo: dashboard\n", "### This demo shows how you can build an interactive dashboard with gradio. Click on a python library on the left hand side and then on the right hand side click on the metric you'd like to see plot over time. Data is pulled from HuggingFace Hub datasets.\n", " "]}, {"cell_type": "code", "execution_count": null, "id": "272996653310673477252411125948039410165", "metadata": {}, "outputs": [], "source": ["!pip install -q gradio plotly"]}, {"cell_type": "code", "execution_count": null, "id": "288918539441861185822528903084949547379", "metadata": {}, "outputs": [], "source": ["# Downloading files from the demo repo\n", "import os\n", "!wget -q https://github.com/gradio-app/gradio/raw/main/demo/dashboard/helpers.py"]}, {"cell_type": "code", "execution_count": null, "id": "44380577570523278879349135829904343037", "metadata": {}, "outputs": [], "source": ["import gradio as gr\n", "import pandas as pd\n", "import plotly.express as px\n", "from helpers import *\n", "\n", "\n", "LIBRARIES = [\"accelerate\", \"datasets\", \"diffusers\", \"evaluate\", \"gradio\", \"hub_docs\",\n", " \"huggingface_hub\", \"optimum\", \"pytorch_image_models\", \"tokenizers\", \"transformers\"]\n", "\n", "\n", "def create_pip_plot(libraries, pip_choices):\n", " if \"Pip\" not in pip_choices:\n", " return gr.Plot(visible=False)\n", " output = retrieve_pip_installs(libraries, \"Cumulated\" in pip_choices)\n", " df = pd.DataFrame(output).melt(id_vars=\"day\")\n", " plot = px.line(df, x=\"day\", y=\"value\", color=\"variable\",\n", " title=\"Pip installs\")\n", " plot.update_layout(legend=dict(x=0.5, y=0.99), title_x=0.5, legend_title_text=\"\")\n", " return gr.Plot(value=plot, visible=True)\n", "\n", "\n", "def create_star_plot(libraries, star_choices):\n", " if \"Stars\" not in star_choices:\n", " return gr.Plot(visible=False)\n", " output = retrieve_stars(libraries, \"Week over Week\" in star_choices)\n", " df = pd.DataFrame(output).melt(id_vars=\"day\")\n", " plot = px.line(df, x=\"day\", y=\"value\", color=\"variable\",\n", " title=\"Number of stargazers\")\n", " plot.update_layout(legend=dict(x=0.5, y=0.99), title_x=0.5, legend_title_text=\"\")\n", " return gr.Plot(value=plot, visible=True)\n", "\n", "\n", "def create_issue_plot(libraries, issue_choices):\n", " if \"Issue\" not in issue_choices:\n", " return gr.Plot(visible=False)\n", " output = retrieve_issues(libraries,\n", " exclude_org_members=\"Exclude org members\" in issue_choices,\n", " week_over_week=\"Week over Week\" in issue_choices)\n", " df = pd.DataFrame(output).melt(id_vars=\"day\")\n", " plot = px.line(df, x=\"day\", y=\"value\", color=\"variable\",\n", " title=\"Cumulated number of issues, PRs, and comments\",\n", " )\n", " plot.update_layout(legend=dict(x=0.5, y=0.99), title_x=0.5, legend_title_text=\"\")\n", " return gr.Plot(value=plot, visible=True)\n", "\n", "\n", "with gr.Blocks() as demo:\n", " with gr.Row():\n", " with gr.Column():\n", " gr.Markdown(\"## Select libraries to display\")\n", " libraries = gr.CheckboxGroup(choices=LIBRARIES, show_label=False)\n", " with gr.Column():\n", " gr.Markdown(\"## Select graphs to display\")\n", " pip = gr.CheckboxGroup(choices=[\"Pip\", \"Cumulated\"], show_label=False)\n", " stars = gr.CheckboxGroup(choices=[\"Stars\", \"Week over Week\"], show_label=False)\n", " issues = gr.CheckboxGroup(choices=[\"Issue\", \"Exclude org members\", \"week over week\"], show_label=False)\n", " with gr.Row():\n", " fetch = gr.Button(value=\"Fetch\")\n", " with gr.Row():\n", " with gr.Column():\n", " pip_plot = gr.Plot(visible=False)\n", " star_plot = gr.Plot(visible=False)\n", " issue_plot = gr.Plot(visible=False)\n", "\n", " fetch.click(create_pip_plot, inputs=[libraries, pip], outputs=pip_plot)\n", " fetch.click(create_star_plot, inputs=[libraries, stars], outputs=star_plot)\n", " fetch.click(create_issue_plot, inputs=[libraries, issues], outputs=issue_plot)\n", "\n", "\n", "if __name__ == \"__main__\":\n", " demo.launch()"]}], "metadata": {}, "nbformat": 4, "nbformat_minor": 5} diff --git a/demo/dataframe_colorful/run.ipynb b/demo/dataframe_colorful/run.ipynb index 83a30371f132..e7df93c5aa22 100644 --- a/demo/dataframe_colorful/run.ipynb +++ b/demo/dataframe_colorful/run.ipynb @@ -1 +1,5 @@ -{"cells": [{"cell_type": "markdown", "id": "302934307671667531413257853548643485645", "metadata": {}, "source": ["# Gradio Demo: dataframe_colorful"]}, {"cell_type": "code", "execution_count": null, "id": "272996653310673477252411125948039410165", "metadata": {}, "outputs": [], "source": ["!pip install -q gradio "]}, {"cell_type": "code", "execution_count": null, "id": "288918539441861185822528903084949547379", "metadata": {}, "outputs": [], "source": ["import pandas as pd \n", "import gradio as gr\n", "\n", "df = pd.DataFrame({\"A\" : [14, 4, 5, 4, 1], \n", "\t\t\t\t\"B\" : [5, 2, 54, 3, 2], \n", "\t\t\t\t\"C\" : [20, 20, 7, 3, 8], \n", "\t\t\t\t\"D\" : [14, 3, 6, 2, 6], \n", "\t\t\t\t\"E\" : [23, 45, 64, 32, 23]}) \n", "\n", "t = df.style.highlight_max(color = 'lightgreen', axis = 0)\n", "\n", "with gr.Blocks() as demo:\n", " gr.Dataframe(t)\n", " \n", "if __name__ == \"__main__\":\n", " demo.launch()"]}], "metadata": {}, "nbformat": 4, "nbformat_minor": 5} \ No newline at end of file +<<<<<<< HEAD +{"cells": [{"cell_type": "markdown", "id": 302934307671667531413257853548643485645, "metadata": {}, "source": ["# Gradio Demo: dataframe_colorful"]}, {"cell_type": "code", "execution_count": null, "id": 272996653310673477252411125948039410165, "metadata": {}, "outputs": [], "source": ["!pip install -q gradio "]}, {"cell_type": "code", "execution_count": null, "id": 288918539441861185822528903084949547379, "metadata": {}, "outputs": [], "source": ["import pandas as pd \n", "import gradio as gr\n", "\n", "df = pd.DataFrame({\"A\" : [14, 4, 5, 4, 1], \n", "\t\t\t\t\"B\" : [5, 2, 54, 3, 2], \n", "\t\t\t\t\"C\" : [20, 20, 7, 3, 8], \n", "\t\t\t\t\"D\" : [14, 3, 6, 2, 6], \n", "\t\t\t\t\"E\" : [23, 45, 64, 32, 23]}) \n", "\n", "t = df.style.highlight_max(color = 'lightgreen', axis = 0)\n", "\n", "with gr.Blocks() as demo:\n", " gr.Dataframe(t)\n", " \n", "if __name__ == \"__main__\":\n", " demo.launch()"]}], "metadata": {}, "nbformat": 4, "nbformat_minor": 5} +======= +{"cells": [{"cell_type": "markdown", "id": "302934307671667531413257853548643485645", "metadata": {}, "source": ["# Gradio Demo: dataframe_colorful"]}, {"cell_type": "code", "execution_count": null, "id": "272996653310673477252411125948039410165", "metadata": {}, "outputs": [], "source": ["!pip install -q gradio "]}, {"cell_type": "code", "execution_count": null, "id": "288918539441861185822528903084949547379", "metadata": {}, "outputs": [], "source": ["import pandas as pd \n", "import gradio as gr\n", "\n", "df = pd.DataFrame({\"A\" : [14, 4, 5, 4, 1], \n", "\t\t\t\t\"B\" : [5, 2, 54, 3, 2], \n", "\t\t\t\t\"C\" : [20, 20, 7, 3, 8], \n", "\t\t\t\t\"D\" : [14, 3, 6, 2, 6], \n", "\t\t\t\t\"E\" : [23, 45, 64, 32, 23]}) \n", "\n", "t = df.style.highlight_max(color = 'lightgreen', axis = 0)\n", "\n", "with gr.Blocks() as demo:\n", " gr.Dataframe(t)\n", " \n", "if __name__ == \"__main__\":\n", " demo.launch()"]}], "metadata": {}, "nbformat": 4, "nbformat_minor": 5} +>>>>>>> main diff --git a/demo/file_explorer/run.ipynb b/demo/file_explorer/run.ipynb index 34a79bc6e0a0..50d6410edf6f 100644 --- a/demo/file_explorer/run.ipynb +++ b/demo/file_explorer/run.ipynb @@ -1 +1,5 @@ -{"cells": [{"cell_type": "markdown", "id": "302934307671667531413257853548643485645", "metadata": {}, "source": ["# Gradio Demo: file_explorer"]}, {"cell_type": "code", "execution_count": null, "id": "272996653310673477252411125948039410165", "metadata": {}, "outputs": [], "source": ["!pip install -q gradio "]}, {"cell_type": "code", "execution_count": null, "id": "288918539441861185822528903084949547379", "metadata": {}, "outputs": [], "source": ["import gradio as gr\n", "from pathlib import Path\n", "\n", "current_file_path = Path(__file__).resolve()\n", "relative_path = \"path/to/file\"\n", "absolute_path = (current_file_path.parent / \"..\" / \"..\" / \"gradio\").resolve()\n", "\n", "\n", "def get_file_content(file):\n", " return (file,)\n", "\n", "\n", "with gr.Blocks() as demo:\n", " gr.Markdown('### `FileExplorer` to `FileExplorer` -- `file_count=\"multiple\"`')\n", " submit_btn = gr.Button(\"Select\")\n", " with gr.Row():\n", " file = gr.FileExplorer(\n", " glob=\"**/{components,themes}/*.py\",\n", " # value=[\"themes/utils\"],\n", " root=absolute_path,\n", " ignore_glob=\"**/__init__.py\",\n", " )\n", "\n", " file2 = gr.FileExplorer(\n", " glob=\"**/{components,themes}/**/*.py\",\n", " root=absolute_path,\n", " ignore_glob=\"**/__init__.py\",\n", " )\n", " submit_btn.click(lambda x: x, file, file2)\n", "\n", " gr.Markdown(\"---\")\n", " gr.Markdown('### `FileExplorer` to `Code` -- `file_count=\"single\"`')\n", " with gr.Group():\n", " with gr.Row():\n", " file_3 = gr.FileExplorer(\n", " scale=1,\n", " glob=\"**/{components,themes}/**/*.py\",\n", " value=[\"themes/utils\"],\n", " file_count=\"single\",\n", " root=absolute_path,\n", " ignore_glob=\"**/__init__.py\",\n", " elem_id=\"file\",\n", " )\n", "\n", " code = gr.Code(lines=30, scale=2, language=\"python\")\n", "\n", " file_3.change(get_file_content, file_3, code)\n", "\n", "\n", "if __name__ == \"__main__\":\n", " demo.launch()\n"]}], "metadata": {}, "nbformat": 4, "nbformat_minor": 5} \ No newline at end of file +<<<<<<< HEAD +{"cells": [{"cell_type": "markdown", "id": 302934307671667531413257853548643485645, "metadata": {}, "source": ["# Gradio Demo: file_explorer"]}, {"cell_type": "code", "execution_count": null, "id": 272996653310673477252411125948039410165, "metadata": {}, "outputs": [], "source": ["!pip install -q gradio "]}, {"cell_type": "code", "execution_count": null, "id": 288918539441861185822528903084949547379, "metadata": {}, "outputs": [], "source": ["import gradio as gr\n", "from pathlib import Path\n", "\n", "current_file_path = Path(__file__).resolve()\n", "relative_path = \"path/to/file\"\n", "absolute_path = (current_file_path.parent / \"..\" / \"..\" / \"gradio\").resolve()\n", "\n", "\n", "def get_file_content(file):\n", " return (file,)\n", "\n", "\n", "with gr.Blocks() as demo:\n", " gr.Markdown('### `FileExplorer` to `FileExplorer` -- `file_count=\"multiple\"`')\n", " submit_btn = gr.Button(\"Select\")\n", " with gr.Row():\n", " file = gr.FileExplorer(\n", " glob=\"**/{components,themes}/*.py\",\n", " # value=[\"themes/utils\"],\n", " root=absolute_path,\n", " ignore_glob=\"**/__init__.py\",\n", " )\n", "\n", " file2 = gr.FileExplorer(\n", " glob=\"**/{components,themes}/**/*.py\",\n", " root=absolute_path,\n", " ignore_glob=\"**/__init__.py\",\n", " )\n", " submit_btn.click(lambda x: x, file, file2)\n", "\n", " gr.Markdown(\"---\")\n", " gr.Markdown('### `FileExplorer` to `Code` -- `file_count=\"single\"`')\n", " with gr.Group():\n", " with gr.Row():\n", " file_3 = gr.FileExplorer(\n", " scale=1,\n", " glob=\"**/{components,themes}/**/*.py\",\n", " value=[\"themes/utils\"],\n", " file_count=\"single\",\n", " root=absolute_path,\n", " ignore_glob=\"**/__init__.py\",\n", " elem_id=\"file\",\n", " )\n", "\n", " code = gr.Code(lines=30, scale=2, language=\"python\")\n", "\n", " file_3.change(get_file_content, file_3, code)\n", "\n", "\n", "if __name__ == \"__main__\":\n", " demo.launch()\n"]}], "metadata": {}, "nbformat": 4, "nbformat_minor": 5} +======= +{"cells": [{"cell_type": "markdown", "id": "302934307671667531413257853548643485645", "metadata": {}, "source": ["# Gradio Demo: file_explorer"]}, {"cell_type": "code", "execution_count": null, "id": "272996653310673477252411125948039410165", "metadata": {}, "outputs": [], "source": ["!pip install -q gradio "]}, {"cell_type": "code", "execution_count": null, "id": "288918539441861185822528903084949547379", "metadata": {}, "outputs": [], "source": ["import gradio as gr\n", "from pathlib import Path\n", "\n", "current_file_path = Path(__file__).resolve()\n", "relative_path = \"path/to/file\"\n", "absolute_path = (current_file_path.parent / \"..\" / \"..\" / \"gradio\").resolve()\n", "\n", "\n", "def get_file_content(file):\n", " return (file,)\n", "\n", "\n", "with gr.Blocks() as demo:\n", " gr.Markdown('### `FileExplorer` to `FileExplorer` -- `file_count=\"multiple\"`')\n", " submit_btn = gr.Button(\"Select\")\n", " with gr.Row():\n", " file = gr.FileExplorer(\n", " glob=\"**/{components,themes}/*.py\",\n", " # value=[\"themes/utils\"],\n", " root=absolute_path,\n", " ignore_glob=\"**/__init__.py\",\n", " )\n", "\n", " file2 = gr.FileExplorer(\n", " glob=\"**/{components,themes}/**/*.py\",\n", " root=absolute_path,\n", " ignore_glob=\"**/__init__.py\",\n", " )\n", " submit_btn.click(lambda x: x, file, file2)\n", "\n", " gr.Markdown(\"---\")\n", " gr.Markdown('### `FileExplorer` to `Code` -- `file_count=\"single\"`')\n", " with gr.Group():\n", " with gr.Row():\n", " file_3 = gr.FileExplorer(\n", " scale=1,\n", " glob=\"**/{components,themes}/**/*.py\",\n", " value=[\"themes/utils\"],\n", " file_count=\"single\",\n", " root=absolute_path,\n", " ignore_glob=\"**/__init__.py\",\n", " elem_id=\"file\",\n", " )\n", "\n", " code = gr.Code(lines=30, scale=2, language=\"python\")\n", "\n", " file_3.change(get_file_content, file_3, code)\n", "\n", "\n", "if __name__ == \"__main__\":\n", " demo.launch()\n"]}], "metadata": {}, "nbformat": 4, "nbformat_minor": 5} +>>>>>>> main diff --git a/demo/file_explorer_component/run.ipynb b/demo/file_explorer_component/run.ipynb index e57e663503a4..3502445a74f1 100644 --- a/demo/file_explorer_component/run.ipynb +++ b/demo/file_explorer_component/run.ipynb @@ -1 +1,5 @@ -{"cells": [{"cell_type": "markdown", "id": "302934307671667531413257853548643485645", "metadata": {}, "source": ["# Gradio Demo: file_explorer_component"]}, {"cell_type": "code", "execution_count": null, "id": "272996653310673477252411125948039410165", "metadata": {}, "outputs": [], "source": ["!pip install -q gradio "]}, {"cell_type": "code", "execution_count": null, "id": "288918539441861185822528903084949547379", "metadata": {}, "outputs": [], "source": ["import gradio as gr \n", "\n", "with gr.Blocks() as demo:\n", " gr.FileExplorer()\n", "\n", "demo.launch()"]}], "metadata": {}, "nbformat": 4, "nbformat_minor": 5} \ No newline at end of file +<<<<<<< HEAD +{"cells": [{"cell_type": "markdown", "id": 302934307671667531413257853548643485645, "metadata": {}, "source": ["# Gradio Demo: file_explorer_component"]}, {"cell_type": "code", "execution_count": null, "id": 272996653310673477252411125948039410165, "metadata": {}, "outputs": [], "source": ["!pip install -q gradio "]}, {"cell_type": "code", "execution_count": null, "id": 288918539441861185822528903084949547379, "metadata": {}, "outputs": [], "source": ["import gradio as gr \n", "\n", "with gr.Blocks() as demo:\n", " gr.FileExplorer()\n", "\n", "demo.launch()"]}], "metadata": {}, "nbformat": 4, "nbformat_minor": 5} +======= +{"cells": [{"cell_type": "markdown", "id": "302934307671667531413257853548643485645", "metadata": {}, "source": ["# Gradio Demo: file_explorer_component"]}, {"cell_type": "code", "execution_count": null, "id": "272996653310673477252411125948039410165", "metadata": {}, "outputs": [], "source": ["!pip install -q gradio "]}, {"cell_type": "code", "execution_count": null, "id": "288918539441861185822528903084949547379", "metadata": {}, "outputs": [], "source": ["import gradio as gr \n", "\n", "with gr.Blocks() as demo:\n", " gr.FileExplorer()\n", "\n", "demo.launch()"]}], "metadata": {}, "nbformat": 4, "nbformat_minor": 5} +>>>>>>> main diff --git a/demo/fraud_detector/run.ipynb b/demo/fraud_detector/run.ipynb index 8d3e7611981f..8b4a2b35dfc5 100644 --- a/demo/fraud_detector/run.ipynb +++ b/demo/fraud_detector/run.ipynb @@ -1 +1,5 @@ -{"cells": [{"cell_type": "markdown", "id": "302934307671667531413257853548643485645", "metadata": {}, "source": ["# Gradio Demo: fraud_detector"]}, {"cell_type": "code", "execution_count": null, "id": "272996653310673477252411125948039410165", "metadata": {}, "outputs": [], "source": ["!pip install -q gradio pandas"]}, {"cell_type": "code", "execution_count": null, "id": "288918539441861185822528903084949547379", "metadata": {}, "outputs": [], "source": ["# Downloading files from the demo repo\n", "import os\n", "!wget -q https://github.com/gradio-app/gradio/raw/main/demo/fraud_detector/fraud.csv"]}, {"cell_type": "code", "execution_count": null, "id": "44380577570523278879349135829904343037", "metadata": {}, "outputs": [], "source": ["import random\n", "import os\n", "import gradio as gr\n", "\n", "\n", "def fraud_detector(card_activity, categories, sensitivity):\n", " activity_range = random.randint(0, 100)\n", " drop_columns = [\n", " column for column in [\"retail\", \"food\", \"other\"] if column not in categories\n", " ]\n", " if len(drop_columns):\n", " card_activity.drop(columns=drop_columns, inplace=True)\n", " return (\n", " card_activity,\n", " card_activity,\n", " {\"fraud\": activity_range / 100.0, \"not fraud\": 1 - activity_range / 100.0},\n", " )\n", "\n", "\n", "demo = gr.Interface(\n", " fraud_detector,\n", " [\n", " gr.Timeseries(x=\"time\", y=[\"retail\", \"food\", \"other\"]),\n", " gr.CheckboxGroup(\n", " [\"retail\", \"food\", \"other\"], value=[\"retail\", \"food\", \"other\"]\n", " ),\n", " gr.Slider(1, 3),\n", " ],\n", " [\n", " \"dataframe\",\n", " gr.Timeseries(x=\"time\", y=[\"retail\", \"food\", \"other\"]),\n", " gr.Label(label=\"Fraud Level\"),\n", " ],\n", " examples=[\n", " [os.path.join(os.path.abspath(''), \"fraud.csv\"), [\"retail\", \"food\", \"other\"], 1.0],\n", " ],\n", ")\n", "if __name__ == \"__main__\":\n", " demo.launch()\n"]}], "metadata": {}, "nbformat": 4, "nbformat_minor": 5} \ No newline at end of file +<<<<<<< HEAD +{"cells": [{"cell_type": "markdown", "id": 302934307671667531413257853548643485645, "metadata": {}, "source": ["# Gradio Demo: fraud_detector"]}, {"cell_type": "code", "execution_count": null, "id": 272996653310673477252411125948039410165, "metadata": {}, "outputs": [], "source": ["!pip install -q gradio pandas"]}, {"cell_type": "code", "execution_count": null, "id": 288918539441861185822528903084949547379, "metadata": {}, "outputs": [], "source": ["# Downloading files from the demo repo\n", "import os\n", "!wget -q https://github.com/gradio-app/gradio/raw/main/demo/fraud_detector/fraud.csv"]}, {"cell_type": "code", "execution_count": null, "id": 44380577570523278879349135829904343037, "metadata": {}, "outputs": [], "source": ["import random\n", "import os\n", "import gradio as gr\n", "\n", "\n", "def fraud_detector(card_activity, categories, sensitivity):\n", " activity_range = random.randint(0, 100)\n", " drop_columns = [\n", " column for column in [\"retail\", \"food\", \"other\"] if column not in categories\n", " ]\n", " if len(drop_columns):\n", " card_activity.drop(columns=drop_columns, inplace=True)\n", " return (\n", " card_activity,\n", " card_activity,\n", " {\"fraud\": activity_range / 100.0, \"not fraud\": 1 - activity_range / 100.0},\n", " )\n", "\n", "\n", "demo = gr.Interface(\n", " fraud_detector,\n", " [\n", " gr.CheckboxGroup(\n", " [\"retail\", \"food\", \"other\"], value=[\"retail\", \"food\", \"other\"]\n", " ),\n", " gr.Slider(1, 3),\n", " ],\n", " [\n", " \"dataframe\",\n", " gr.Label(label=\"Fraud Level\"),\n", " ],\n", " examples=[\n", " [os.path.join(os.path.abspath(''), \"fraud.csv\"), [\"retail\", \"food\", \"other\"], 1.0],\n", " ],\n", ")\n", "if __name__ == \"__main__\":\n", " demo.launch()\n"]}], "metadata": {}, "nbformat": 4, "nbformat_minor": 5} +======= +{"cells": [{"cell_type": "markdown", "id": "302934307671667531413257853548643485645", "metadata": {}, "source": ["# Gradio Demo: fraud_detector"]}, {"cell_type": "code", "execution_count": null, "id": "272996653310673477252411125948039410165", "metadata": {}, "outputs": [], "source": ["!pip install -q gradio pandas"]}, {"cell_type": "code", "execution_count": null, "id": "288918539441861185822528903084949547379", "metadata": {}, "outputs": [], "source": ["# Downloading files from the demo repo\n", "import os\n", "!wget -q https://github.com/gradio-app/gradio/raw/main/demo/fraud_detector/fraud.csv"]}, {"cell_type": "code", "execution_count": null, "id": "44380577570523278879349135829904343037", "metadata": {}, "outputs": [], "source": ["import random\n", "import os\n", "import gradio as gr\n", "\n", "\n", "def fraud_detector(card_activity, categories, sensitivity):\n", " activity_range = random.randint(0, 100)\n", " drop_columns = [\n", " column for column in [\"retail\", \"food\", \"other\"] if column not in categories\n", " ]\n", " if len(drop_columns):\n", " card_activity.drop(columns=drop_columns, inplace=True)\n", " return (\n", " card_activity,\n", " card_activity,\n", " {\"fraud\": activity_range / 100.0, \"not fraud\": 1 - activity_range / 100.0},\n", " )\n", "\n", "\n", "demo = gr.Interface(\n", " fraud_detector,\n", " [\n", " gr.Timeseries(x=\"time\", y=[\"retail\", \"food\", \"other\"]),\n", " gr.CheckboxGroup(\n", " [\"retail\", \"food\", \"other\"], value=[\"retail\", \"food\", \"other\"]\n", " ),\n", " gr.Slider(1, 3),\n", " ],\n", " [\n", " \"dataframe\",\n", " gr.Timeseries(x=\"time\", y=[\"retail\", \"food\", \"other\"]),\n", " gr.Label(label=\"Fraud Level\"),\n", " ],\n", " examples=[\n", " [os.path.join(os.path.abspath(''), \"fraud.csv\"), [\"retail\", \"food\", \"other\"], 1.0],\n", " ],\n", ")\n", "if __name__ == \"__main__\":\n", " demo.launch()\n"]}], "metadata": {}, "nbformat": 4, "nbformat_minor": 5} +>>>>>>> main diff --git a/demo/fraud_detector/run.py b/demo/fraud_detector/run.py index d5384b8ed05e..3425cb8f1872 100644 --- a/demo/fraud_detector/run.py +++ b/demo/fraud_detector/run.py @@ -20,7 +20,6 @@ def fraud_detector(card_activity, categories, sensitivity): demo = gr.Interface( fraud_detector, [ - gr.Timeseries(x="time", y=["retail", "food", "other"]), gr.CheckboxGroup( ["retail", "food", "other"], value=["retail", "food", "other"] ), @@ -28,7 +27,6 @@ def fraud_detector(card_activity, categories, sensitivity): ], [ "dataframe", - gr.Timeseries(x="time", y=["retail", "food", "other"]), gr.Label(label="Fraud Level"), ], examples=[ diff --git a/demo/gender_sentence_custom_interpretation/run.ipynb b/demo/gender_sentence_custom_interpretation/run.ipynb index 18d613c06a26..2dc98cc29013 100644 --- a/demo/gender_sentence_custom_interpretation/run.ipynb +++ b/demo/gender_sentence_custom_interpretation/run.ipynb @@ -1 +1,5 @@ -{"cells": [{"cell_type": "markdown", "id": "302934307671667531413257853548643485645", "metadata": {}, "source": ["# Gradio Demo: gender_sentence_custom_interpretation"]}, {"cell_type": "code", "execution_count": null, "id": "272996653310673477252411125948039410165", "metadata": {}, "outputs": [], "source": ["!pip install -q gradio "]}, {"cell_type": "code", "execution_count": null, "id": "288918539441861185822528903084949547379", "metadata": {}, "outputs": [], "source": ["import re\n", "\n", "import gradio as gr\n", "\n", "male_words, female_words = [\"he\", \"his\", \"him\"], [\"she\", \"hers\", \"her\"]\n", "\n", "\n", "def gender_of_sentence(sentence):\n", " male_count = len([word for word in sentence.split() if word.lower() in male_words])\n", " female_count = len(\n", " [word for word in sentence.split() if word.lower() in female_words]\n", " )\n", " total = max(male_count + female_count, 1)\n", " return {\"male\": male_count / total, \"female\": female_count / total}\n", "\n", "\n", "# Number of arguments to interpretation function must\n", "# match number of inputs to prediction function\n", "def interpret_gender(sentence):\n", " result = gender_of_sentence(sentence)\n", " is_male = result[\"male\"] > result[\"female\"]\n", " interpretation = []\n", " for word in re.split(\"( )\", sentence):\n", " score = 0\n", " token = word.lower()\n", " if (is_male and token in male_words) or (not is_male and token in female_words):\n", " score = 1\n", " elif (is_male and token in female_words) or (\n", " not is_male and token in male_words\n", " ):\n", " score = -1\n", " interpretation.append((word, score))\n", " # Output must be a list of lists containing the same number of elements as inputs\n", " # Each element corresponds to the interpretation scores for the given input\n", " return [interpretation]\n", "\n", "\n", "demo = gr.Interface(\n", " fn=gender_of_sentence,\n", " inputs=gr.Textbox(value=\"She went to his house to get her keys.\"),\n", " outputs=\"label\",\n", " interpretation=interpret_gender,\n", ")\n", "\n", "if __name__ == \"__main__\":\n", " demo.launch()\n"]}], "metadata": {}, "nbformat": 4, "nbformat_minor": 5} \ No newline at end of file +<<<<<<< HEAD +{"cells": [{"cell_type": "markdown", "id": 302934307671667531413257853548643485645, "metadata": {}, "source": ["# Gradio Demo: gender_sentence_custom_interpretation"]}, {"cell_type": "code", "execution_count": null, "id": 272996653310673477252411125948039410165, "metadata": {}, "outputs": [], "source": ["!pip install -q gradio "]}, {"cell_type": "code", "execution_count": null, "id": 288918539441861185822528903084949547379, "metadata": {}, "outputs": [], "source": ["import re\n", "\n", "import gradio as gr\n", "\n", "male_words, female_words = [\"he\", \"his\", \"him\"], [\"she\", \"hers\", \"her\"]\n", "\n", "\n", "def gender_of_sentence(sentence):\n", " male_count = len([word for word in sentence.split() if word.lower() in male_words])\n", " female_count = len(\n", " [word for word in sentence.split() if word.lower() in female_words]\n", " )\n", " total = max(male_count + female_count, 1)\n", " return {\"male\": male_count / total, \"female\": female_count / total}\n", "\n", "\n", "# Number of arguments to interpretation function must\n", "# match number of inputs to prediction function\n", "def interpret_gender(sentence):\n", " result = gender_of_sentence(sentence)\n", " is_male = result[\"male\"] > result[\"female\"]\n", " interpretation = []\n", " for word in re.split(\"( )\", sentence):\n", " score = 0\n", " token = word.lower()\n", " if (is_male and token in male_words) or (not is_male and token in female_words):\n", " score = 1\n", " elif (is_male and token in female_words) or (\n", " not is_male and token in male_words\n", " ):\n", " score = -1\n", " interpretation.append((word, score))\n", " # Output must be a list of lists containing the same number of elements as inputs\n", " # Each element corresponds to the interpretation scores for the given input\n", " return [interpretation]\n", "\n", "\n", "demo = gr.Interface(\n", " fn=gender_of_sentence,\n", " inputs=gr.Textbox(value=\"She went to his house to get her keys.\"),\n", " outputs=\"label\",\n", ")\n", "\n", "if __name__ == \"__main__\":\n", " demo.launch()\n"]}], "metadata": {}, "nbformat": 4, "nbformat_minor": 5} +======= +{"cells": [{"cell_type": "markdown", "id": "302934307671667531413257853548643485645", "metadata": {}, "source": ["# Gradio Demo: gender_sentence_custom_interpretation"]}, {"cell_type": "code", "execution_count": null, "id": "272996653310673477252411125948039410165", "metadata": {}, "outputs": [], "source": ["!pip install -q gradio "]}, {"cell_type": "code", "execution_count": null, "id": "288918539441861185822528903084949547379", "metadata": {}, "outputs": [], "source": ["import re\n", "\n", "import gradio as gr\n", "\n", "male_words, female_words = [\"he\", \"his\", \"him\"], [\"she\", \"hers\", \"her\"]\n", "\n", "\n", "def gender_of_sentence(sentence):\n", " male_count = len([word for word in sentence.split() if word.lower() in male_words])\n", " female_count = len(\n", " [word for word in sentence.split() if word.lower() in female_words]\n", " )\n", " total = max(male_count + female_count, 1)\n", " return {\"male\": male_count / total, \"female\": female_count / total}\n", "\n", "\n", "# Number of arguments to interpretation function must\n", "# match number of inputs to prediction function\n", "def interpret_gender(sentence):\n", " result = gender_of_sentence(sentence)\n", " is_male = result[\"male\"] > result[\"female\"]\n", " interpretation = []\n", " for word in re.split(\"( )\", sentence):\n", " score = 0\n", " token = word.lower()\n", " if (is_male and token in male_words) or (not is_male and token in female_words):\n", " score = 1\n", " elif (is_male and token in female_words) or (\n", " not is_male and token in male_words\n", " ):\n", " score = -1\n", " interpretation.append((word, score))\n", " # Output must be a list of lists containing the same number of elements as inputs\n", " # Each element corresponds to the interpretation scores for the given input\n", " return [interpretation]\n", "\n", "\n", "demo = gr.Interface(\n", " fn=gender_of_sentence,\n", " inputs=gr.Textbox(value=\"She went to his house to get her keys.\"),\n", " outputs=\"label\",\n", " interpretation=interpret_gender,\n", ")\n", "\n", "if __name__ == \"__main__\":\n", " demo.launch()\n"]}], "metadata": {}, "nbformat": 4, "nbformat_minor": 5} +>>>>>>> main diff --git a/demo/gender_sentence_custom_interpretation/run.py b/demo/gender_sentence_custom_interpretation/run.py index 93a8f6c6cf48..0b57effcc702 100644 --- a/demo/gender_sentence_custom_interpretation/run.py +++ b/demo/gender_sentence_custom_interpretation/run.py @@ -39,7 +39,6 @@ def interpret_gender(sentence): fn=gender_of_sentence, inputs=gr.Textbox(value="She went to his house to get her keys."), outputs="label", - interpretation=interpret_gender, ) if __name__ == "__main__": diff --git a/demo/gender_sentence_default_interpretation/run.ipynb b/demo/gender_sentence_default_interpretation/run.ipynb index 8c441b18a762..d9b9fa5ff614 100644 --- a/demo/gender_sentence_default_interpretation/run.ipynb +++ b/demo/gender_sentence_default_interpretation/run.ipynb @@ -1 +1,5 @@ -{"cells": [{"cell_type": "markdown", "id": "302934307671667531413257853548643485645", "metadata": {}, "source": ["# Gradio Demo: gender_sentence_default_interpretation"]}, {"cell_type": "code", "execution_count": null, "id": "272996653310673477252411125948039410165", "metadata": {}, "outputs": [], "source": ["!pip install -q gradio "]}, {"cell_type": "code", "execution_count": null, "id": "288918539441861185822528903084949547379", "metadata": {}, "outputs": [], "source": ["import gradio as gr\n", "\n", "male_words, female_words = [\"he\", \"his\", \"him\"], [\"she\", \"hers\", \"her\"]\n", "\n", "\n", "def gender_of_sentence(sentence):\n", " male_count = len([word for word in sentence.split() if word.lower() in male_words])\n", " female_count = len(\n", " [word for word in sentence.split() if word.lower() in female_words]\n", " )\n", " total = max(male_count + female_count, 1)\n", " return {\"male\": male_count / total, \"female\": female_count / total}\n", "\n", "\n", "demo = gr.Interface(\n", " fn=gender_of_sentence,\n", " inputs=gr.Textbox(value=\"She went to his house to get her keys.\"),\n", " outputs=\"label\",\n", " interpretation=\"default\",\n", ")\n", "\n", "if __name__ == \"__main__\":\n", " demo.launch()\n"]}], "metadata": {}, "nbformat": 4, "nbformat_minor": 5} \ No newline at end of file +<<<<<<< HEAD +{"cells": [{"cell_type": "markdown", "id": 302934307671667531413257853548643485645, "metadata": {}, "source": ["# Gradio Demo: gender_sentence_default_interpretation"]}, {"cell_type": "code", "execution_count": null, "id": 272996653310673477252411125948039410165, "metadata": {}, "outputs": [], "source": ["!pip install -q gradio "]}, {"cell_type": "code", "execution_count": null, "id": 288918539441861185822528903084949547379, "metadata": {}, "outputs": [], "source": ["import gradio as gr\n", "\n", "male_words, female_words = [\"he\", \"his\", \"him\"], [\"she\", \"hers\", \"her\"]\n", "\n", "\n", "def gender_of_sentence(sentence):\n", " male_count = len([word for word in sentence.split() if word.lower() in male_words])\n", " female_count = len(\n", " [word for word in sentence.split() if word.lower() in female_words]\n", " )\n", " total = max(male_count + female_count, 1)\n", " return {\"male\": male_count / total, \"female\": female_count / total}\n", "\n", "\n", "demo = gr.Interface(\n", " fn=gender_of_sentence,\n", " inputs=gr.Textbox(value=\"She went to his house to get her keys.\"),\n", " outputs=\"label\",\n", ")\n", "\n", "if __name__ == \"__main__\":\n", " demo.launch()\n"]}], "metadata": {}, "nbformat": 4, "nbformat_minor": 5} +======= +{"cells": [{"cell_type": "markdown", "id": "302934307671667531413257853548643485645", "metadata": {}, "source": ["# Gradio Demo: gender_sentence_default_interpretation"]}, {"cell_type": "code", "execution_count": null, "id": "272996653310673477252411125948039410165", "metadata": {}, "outputs": [], "source": ["!pip install -q gradio "]}, {"cell_type": "code", "execution_count": null, "id": "288918539441861185822528903084949547379", "metadata": {}, "outputs": [], "source": ["import gradio as gr\n", "\n", "male_words, female_words = [\"he\", \"his\", \"him\"], [\"she\", \"hers\", \"her\"]\n", "\n", "\n", "def gender_of_sentence(sentence):\n", " male_count = len([word for word in sentence.split() if word.lower() in male_words])\n", " female_count = len(\n", " [word for word in sentence.split() if word.lower() in female_words]\n", " )\n", " total = max(male_count + female_count, 1)\n", " return {\"male\": male_count / total, \"female\": female_count / total}\n", "\n", "\n", "demo = gr.Interface(\n", " fn=gender_of_sentence,\n", " inputs=gr.Textbox(value=\"She went to his house to get her keys.\"),\n", " outputs=\"label\",\n", " interpretation=\"default\",\n", ")\n", "\n", "if __name__ == \"__main__\":\n", " demo.launch()\n"]}], "metadata": {}, "nbformat": 4, "nbformat_minor": 5} +>>>>>>> main diff --git a/demo/gender_sentence_default_interpretation/run.py b/demo/gender_sentence_default_interpretation/run.py index 99312fda6c52..c37567f38cb7 100644 --- a/demo/gender_sentence_default_interpretation/run.py +++ b/demo/gender_sentence_default_interpretation/run.py @@ -16,7 +16,6 @@ def gender_of_sentence(sentence): fn=gender_of_sentence, inputs=gr.Textbox(value="She went to his house to get her keys."), outputs="label", - interpretation="default", ) if __name__ == "__main__": diff --git a/demo/hello_blocks/run.ipynb b/demo/hello_blocks/run.ipynb index 9d509b14150e..3aed150583cb 100644 --- a/demo/hello_blocks/run.ipynb +++ b/demo/hello_blocks/run.ipynb @@ -1 +1,5 @@ -{"cells": [{"cell_type": "markdown", "id": "302934307671667531413257853548643485645", "metadata": {}, "source": ["# Gradio Demo: hello_blocks"]}, {"cell_type": "code", "execution_count": null, "id": "272996653310673477252411125948039410165", "metadata": {}, "outputs": [], "source": ["!pip install -q gradio "]}, {"cell_type": "code", "execution_count": null, "id": "288918539441861185822528903084949547379", "metadata": {}, "outputs": [], "source": ["import gradio as gr\n", "\n", "def greet(name):\n", " return \"Hello \" + name + \"!\"\n", "\n", "with gr.Blocks() as demo:\n", " name = gr.Textbox(label=\"Name\")\n", " output = gr.Textbox(label=\"Output Box\")\n", " greet_btn = gr.Button(\"Greet\")\n", " greet_btn.click(fn=greet, inputs=name, outputs=output, api_name=\"greet\")\n", "\n", "if __name__ == \"__main__\":\n", " demo.launch()\n"]}], "metadata": {}, "nbformat": 4, "nbformat_minor": 5} \ No newline at end of file +<<<<<<< HEAD +{"cells": [{"cell_type": "markdown", "id": 302934307671667531413257853548643485645, "metadata": {}, "source": ["# Gradio Demo: hello_blocks"]}, {"cell_type": "code", "execution_count": null, "id": 272996653310673477252411125948039410165, "metadata": {}, "outputs": [], "source": ["!pip install -q gradio "]}, {"cell_type": "code", "execution_count": null, "id": 288918539441861185822528903084949547379, "metadata": {}, "outputs": [], "source": ["import gradio as gr\n", "\n", "\n", "def greet(name):\n", " return \"Hello \" + name + \"!\"\n", "\n", "\n", "with gr.Blocks() as demo:\n", " name = gr.Textbox(label=\"Name\")\n", " output = gr.Textbox(label=\"Output Box\")\n", " greet_btn = gr.Button(\"Greet\")\n", " greet_btn.click(fn=greet, inputs=name, outputs=output, api_name=\"greet\")\n", "\n", "if __name__ == \"__main__\":\n", " demo.launch()\n"]}], "metadata": {}, "nbformat": 4, "nbformat_minor": 5} +======= +{"cells": [{"cell_type": "markdown", "id": "302934307671667531413257853548643485645", "metadata": {}, "source": ["# Gradio Demo: hello_blocks"]}, {"cell_type": "code", "execution_count": null, "id": "272996653310673477252411125948039410165", "metadata": {}, "outputs": [], "source": ["!pip install -q gradio "]}, {"cell_type": "code", "execution_count": null, "id": "288918539441861185822528903084949547379", "metadata": {}, "outputs": [], "source": ["import gradio as gr\n", "\n", "def greet(name):\n", " return \"Hello \" + name + \"!\"\n", "\n", "with gr.Blocks() as demo:\n", " name = gr.Textbox(label=\"Name\")\n", " output = gr.Textbox(label=\"Output Box\")\n", " greet_btn = gr.Button(\"Greet\")\n", " greet_btn.click(fn=greet, inputs=name, outputs=output, api_name=\"greet\")\n", "\n", "if __name__ == \"__main__\":\n", " demo.launch()\n"]}], "metadata": {}, "nbformat": 4, "nbformat_minor": 5} +>>>>>>> main diff --git a/demo/hello_blocks/run.py b/demo/hello_blocks/run.py index bfb65715686a..f11bca19f42a 100644 --- a/demo/hello_blocks/run.py +++ b/demo/hello_blocks/run.py @@ -1,8 +1,10 @@ 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") diff --git a/demo/hello_login/run.ipynb b/demo/hello_login/run.ipynb index 785decc44924..6739331e37d2 100644 --- a/demo/hello_login/run.ipynb +++ b/demo/hello_login/run.ipynb @@ -1 +1,5 @@ -{"cells": [{"cell_type": "markdown", "id": "302934307671667531413257853548643485645", "metadata": {}, "source": ["# Gradio Demo: hello_login"]}, {"cell_type": "code", "execution_count": null, "id": "272996653310673477252411125948039410165", "metadata": {}, "outputs": [], "source": ["!pip install -q gradio "]}, {"cell_type": "code", "execution_count": null, "id": "288918539441861185822528903084949547379", "metadata": {}, "outputs": [], "source": ["import gradio as gr\n", "\n", "user_db = {\"admin\": \"admin\", \"foo\": \"bar\"}\n", "\n", "\n", "def greet(name):\n", " return \"Hello \" + name + \"!!\"\n", "\n", "\n", "demo = gr.Interface(fn=greet, inputs=\"text\", outputs=\"text\")\n", "if __name__ == \"__main__\":\n", " demo.launch(enable_queue=False,\n", " auth=lambda u, p: user_db.get(u) == p,\n", " auth_message=\"This is a welcome message\")\n"]}], "metadata": {}, "nbformat": 4, "nbformat_minor": 5} \ No newline at end of file +<<<<<<< HEAD +{"cells": [{"cell_type": "markdown", "id": 302934307671667531413257853548643485645, "metadata": {}, "source": ["# Gradio Demo: hello_login"]}, {"cell_type": "code", "execution_count": null, "id": 272996653310673477252411125948039410165, "metadata": {}, "outputs": [], "source": ["!pip install -q gradio "]}, {"cell_type": "code", "execution_count": null, "id": 288918539441861185822528903084949547379, "metadata": {}, "outputs": [], "source": ["import gradio as gr\n", "import argparse\n", "import sys\n", "\n", "parser = argparse.ArgumentParser()\n", "parser.add_argument(\"--name\", type=str, default=\"User\")\n", "args, unknown = parser.parse_known_args()\n", "print(sys.argv)\n", "\n", "with gr.Blocks() as demo:\n", " gr.Markdown(f\"# Greetings {args.name}!\")\n", " inp = gr.Textbox()\n", " out = gr.Textbox()\n", "\n", " inp.change(fn=lambda x: x, inputs=inp, outputs=out)\n", "\n", "if __name__ == \"__main__\":\n", " demo.launch()"]}], "metadata": {}, "nbformat": 4, "nbformat_minor": 5} +======= +{"cells": [{"cell_type": "markdown", "id": "302934307671667531413257853548643485645", "metadata": {}, "source": ["# Gradio Demo: hello_login"]}, {"cell_type": "code", "execution_count": null, "id": "272996653310673477252411125948039410165", "metadata": {}, "outputs": [], "source": ["!pip install -q gradio "]}, {"cell_type": "code", "execution_count": null, "id": "288918539441861185822528903084949547379", "metadata": {}, "outputs": [], "source": ["import gradio as gr\n", "\n", "user_db = {\"admin\": \"admin\", \"foo\": \"bar\"}\n", "\n", "\n", "def greet(name):\n", " return \"Hello \" + name + \"!!\"\n", "\n", "\n", "demo = gr.Interface(fn=greet, inputs=\"text\", outputs=\"text\")\n", "if __name__ == \"__main__\":\n", " demo.launch(enable_queue=False,\n", " auth=lambda u, p: user_db.get(u) == p,\n", " auth_message=\"This is a welcome message\")\n"]}], "metadata": {}, "nbformat": 4, "nbformat_minor": 5} +>>>>>>> main diff --git a/demo/hello_login/run.py b/demo/hello_login/run.py index c3e4d2ecd79b..0acefb17bc5c 100644 --- a/demo/hello_login/run.py +++ b/demo/hello_login/run.py @@ -1,14 +1,18 @@ import gradio as gr +import argparse +import sys -user_db = {"admin": "admin", "foo": "bar"} +parser = argparse.ArgumentParser() +parser.add_argument("--name", type=str, default="User") +args, unknown = parser.parse_known_args() +print(sys.argv) +with gr.Blocks() as demo: + gr.Markdown(f"# Greetings {args.name}!") + inp = gr.Textbox() + out = gr.Textbox() -def greet(name): - return "Hello " + name + "!!" + inp.change(fn=lambda x: x, inputs=inp, outputs=out) - -demo = gr.Interface(fn=greet, inputs="text", outputs="text") if __name__ == "__main__": - demo.launch(enable_queue=False, - auth=lambda u, p: user_db.get(u) == p, - auth_message="This is a welcome message") + demo.launch() \ No newline at end of file diff --git a/demo/hello_world/run.ipynb b/demo/hello_world/run.ipynb index cd37f6a7abc9..2f9bffd2afd2 100644 --- a/demo/hello_world/run.ipynb +++ b/demo/hello_world/run.ipynb @@ -1 +1,5 @@ -{"cells": [{"cell_type": "markdown", "id": "302934307671667531413257853548643485645", "metadata": {}, "source": ["# Gradio Demo: hello_world\n", "### The simplest possible Gradio demo. It wraps a 'Hello {name}!' function in an Interface that accepts and returns text.\n", " "]}, {"cell_type": "code", "execution_count": null, "id": "272996653310673477252411125948039410165", "metadata": {}, "outputs": [], "source": ["!pip install -q gradio "]}, {"cell_type": "code", "execution_count": null, "id": "288918539441861185822528903084949547379", "metadata": {}, "outputs": [], "source": ["import gradio as gr\n", "\n", "def greet(name):\n", " return \"Hello \" + name + \"!\"\n", "\n", "demo = gr.Interface(fn=greet, inputs=\"text\", outputs=\"text\")\n", " \n", "if __name__ == \"__main__\":\n", " demo.launch() "]}], "metadata": {}, "nbformat": 4, "nbformat_minor": 5} \ No newline at end of file +<<<<<<< HEAD +{"cells": [{"cell_type": "markdown", "id": 302934307671667531413257853548643485645, "metadata": {}, "source": ["# Gradio Demo: hello_world\n", "### The simplest possible Gradio demo. It wraps a 'Hello {name}!' function in an Interface that accepts and returns text.\n", " "]}, {"cell_type": "code", "execution_count": null, "id": 272996653310673477252411125948039410165, "metadata": {}, "outputs": [], "source": ["!pip install -q gradio "]}, {"cell_type": "code", "execution_count": null, "id": 288918539441861185822528903084949547379, "metadata": {}, "outputs": [], "source": ["import gradio as gr\n", "\n", "def greet(name):\n", " return \"Hello \" + name + \"!\"\n", "\n", "demo = gr.Interface(fn=greet, inputs=\"text\", outputs=\"text\")\n", " \n", "if __name__ == \"__main__\":\n", " demo.launch(show_api=False) "]}], "metadata": {}, "nbformat": 4, "nbformat_minor": 5} +======= +{"cells": [{"cell_type": "markdown", "id": "302934307671667531413257853548643485645", "metadata": {}, "source": ["# Gradio Demo: hello_world\n", "### The simplest possible Gradio demo. It wraps a 'Hello {name}!' function in an Interface that accepts and returns text.\n", " "]}, {"cell_type": "code", "execution_count": null, "id": "272996653310673477252411125948039410165", "metadata": {}, "outputs": [], "source": ["!pip install -q gradio "]}, {"cell_type": "code", "execution_count": null, "id": "288918539441861185822528903084949547379", "metadata": {}, "outputs": [], "source": ["import gradio as gr\n", "\n", "def greet(name):\n", " return \"Hello \" + name + \"!\"\n", "\n", "demo = gr.Interface(fn=greet, inputs=\"text\", outputs=\"text\")\n", " \n", "if __name__ == \"__main__\":\n", " demo.launch() "]}], "metadata": {}, "nbformat": 4, "nbformat_minor": 5} +>>>>>>> main diff --git a/demo/hello_world/run.py b/demo/hello_world/run.py index 4e5dbfbceec5..0642e39f1fb6 100644 --- a/demo/hello_world/run.py +++ b/demo/hello_world/run.py @@ -6,4 +6,4 @@ def greet(name): demo = gr.Interface(fn=greet, inputs="text", outputs="text") if __name__ == "__main__": - demo.launch() \ No newline at end of file + demo.launch(show_api=False) \ No newline at end of file diff --git a/demo/highlightedtext_component/run.ipynb b/demo/highlightedtext_component/run.ipynb index 812cabbbb5f0..ff22ebe451d3 100644 --- a/demo/highlightedtext_component/run.ipynb +++ b/demo/highlightedtext_component/run.ipynb @@ -1 +1,5 @@ -{"cells": [{"cell_type": "markdown", "id": "302934307671667531413257853548643485645", "metadata": {}, "source": ["# Gradio Demo: highlightedtext_component"]}, {"cell_type": "code", "execution_count": null, "id": "272996653310673477252411125948039410165", "metadata": {}, "outputs": [], "source": ["!pip install -q gradio "]}, {"cell_type": "code", "execution_count": null, "id": "288918539441861185822528903084949547379", "metadata": {}, "outputs": [], "source": ["import gradio as gr \n", "\n", "with gr.Blocks() as demo:\n", " gr.HighlightedText(value=[(\"Text\",\"Label 1\"),(\"to be\",\"Label 2\"),(\"highlighted\",\"Label 3\")])\n", "\n", "demo.launch()"]}], "metadata": {}, "nbformat": 4, "nbformat_minor": 5} \ No newline at end of file +<<<<<<< HEAD +{"cells": [{"cell_type": "markdown", "id": 302934307671667531413257853548643485645, "metadata": {}, "source": ["# Gradio Demo: highlightedtext_component"]}, {"cell_type": "code", "execution_count": null, "id": 272996653310673477252411125948039410165, "metadata": {}, "outputs": [], "source": ["!pip install -q gradio "]}, {"cell_type": "code", "execution_count": null, "id": 288918539441861185822528903084949547379, "metadata": {}, "outputs": [], "source": ["import gradio as gr\n", "\n", "with gr.Blocks() as demo:\n", " gr.HighlightedText(\n", " combine_adjacent=True,\n", " )\n", "\n", "demo.launch()\n"]}], "metadata": {}, "nbformat": 4, "nbformat_minor": 5} +======= +{"cells": [{"cell_type": "markdown", "id": "302934307671667531413257853548643485645", "metadata": {}, "source": ["# Gradio Demo: highlightedtext_component"]}, {"cell_type": "code", "execution_count": null, "id": "272996653310673477252411125948039410165", "metadata": {}, "outputs": [], "source": ["!pip install -q gradio "]}, {"cell_type": "code", "execution_count": null, "id": "288918539441861185822528903084949547379", "metadata": {}, "outputs": [], "source": ["import gradio as gr \n", "\n", "with gr.Blocks() as demo:\n", " gr.HighlightedText(value=[(\"Text\",\"Label 1\"),(\"to be\",\"Label 2\"),(\"highlighted\",\"Label 3\")])\n", "\n", "demo.launch()"]}], "metadata": {}, "nbformat": 4, "nbformat_minor": 5} +>>>>>>> main diff --git a/demo/highlightedtext_component/run.py b/demo/highlightedtext_component/run.py index 4bd90ef5f610..dd3fda76d4ef 100644 --- a/demo/highlightedtext_component/run.py +++ b/demo/highlightedtext_component/run.py @@ -1,6 +1,8 @@ -import gradio as gr +import gradio as gr with gr.Blocks() as demo: - gr.HighlightedText(value=[("Text","Label 1"),("to be","Label 2"),("highlighted","Label 3")]) + gr.HighlightedText( + combine_adjacent=True, + ) -demo.launch() \ No newline at end of file +demo.launch() diff --git a/demo/interface_random_slider/run.ipynb b/demo/interface_random_slider/run.ipynb index ec405b219438..ef67d768a250 100644 --- a/demo/interface_random_slider/run.ipynb +++ b/demo/interface_random_slider/run.ipynb @@ -1 +1,5 @@ -{"cells": [{"cell_type": "markdown", "id": "302934307671667531413257853548643485645", "metadata": {}, "source": ["# Gradio Demo: interface_random_slider"]}, {"cell_type": "code", "execution_count": null, "id": "272996653310673477252411125948039410165", "metadata": {}, "outputs": [], "source": ["!pip install -q gradio "]}, {"cell_type": "code", "execution_count": null, "id": "288918539441861185822528903084949547379", "metadata": {}, "outputs": [], "source": ["import gradio as gr\n", "\n", "\n", "def func(slider_1, slider_2, *args):\n", " return slider_1 + slider_2 * 5\n", "\n", "\n", "demo = gr.Interface(\n", " func,\n", " [\n", " gr.Slider(minimum=1.5, maximum=250000.89, randomize=True, label=\"Random Big Range\"),\n", " gr.Slider(minimum=-1, maximum=1, randomize=True, step=0.05, label=\"Random only multiple of 0.05 allowed\"),\n", " gr.Slider(minimum=0, maximum=1, randomize=True, step=0.25, label=\"Random only multiples of 0.25 allowed\"),\n", " gr.Slider(minimum=-100, maximum=100, randomize=True, step=3, label=\"Random between -100 and 100 step 3\"),\n", " gr.Slider(minimum=-100, maximum=100, randomize=True, label=\"Random between -100 and 100\"),\n", " gr.Slider(value=0.25, minimum=5, maximum=30, step=-1),\n", " ],\n", " \"number\",\n", " interpretation=\"default\"\n", ")\n", "\n", "if __name__ == \"__main__\":\n", " demo.launch()\n"]}], "metadata": {}, "nbformat": 4, "nbformat_minor": 5} \ No newline at end of file +<<<<<<< HEAD +{"cells": [{"cell_type": "markdown", "id": 302934307671667531413257853548643485645, "metadata": {}, "source": ["# Gradio Demo: interface_random_slider"]}, {"cell_type": "code", "execution_count": null, "id": 272996653310673477252411125948039410165, "metadata": {}, "outputs": [], "source": ["!pip install -q gradio "]}, {"cell_type": "code", "execution_count": null, "id": 288918539441861185822528903084949547379, "metadata": {}, "outputs": [], "source": ["import gradio as gr\n", "\n", "\n", "def func(slider_1, slider_2, *args):\n", " return slider_1 + slider_2 * 5\n", "\n", "\n", "demo = gr.Interface(\n", " func,\n", " [\n", " gr.Slider(minimum=1.5, maximum=250000.89, randomize=True, label=\"Random Big Range\"),\n", " gr.Slider(minimum=-1, maximum=1, randomize=True, step=0.05, label=\"Random only multiple of 0.05 allowed\"),\n", " gr.Slider(minimum=0, maximum=1, randomize=True, step=0.25, label=\"Random only multiples of 0.25 allowed\"),\n", " gr.Slider(minimum=-100, maximum=100, randomize=True, step=3, label=\"Random between -100 and 100 step 3\"),\n", " gr.Slider(minimum=-100, maximum=100, randomize=True, label=\"Random between -100 and 100\"),\n", " gr.Slider(value=0.25, minimum=5, maximum=30, step=-1),\n", " ],\n", " \"number\",\n", ")\n", "\n", "if __name__ == \"__main__\":\n", " demo.launch()\n"]}], "metadata": {}, "nbformat": 4, "nbformat_minor": 5} +======= +{"cells": [{"cell_type": "markdown", "id": "302934307671667531413257853548643485645", "metadata": {}, "source": ["# Gradio Demo: interface_random_slider"]}, {"cell_type": "code", "execution_count": null, "id": "272996653310673477252411125948039410165", "metadata": {}, "outputs": [], "source": ["!pip install -q gradio "]}, {"cell_type": "code", "execution_count": null, "id": "288918539441861185822528903084949547379", "metadata": {}, "outputs": [], "source": ["import gradio as gr\n", "\n", "\n", "def func(slider_1, slider_2, *args):\n", " return slider_1 + slider_2 * 5\n", "\n", "\n", "demo = gr.Interface(\n", " func,\n", " [\n", " gr.Slider(minimum=1.5, maximum=250000.89, randomize=True, label=\"Random Big Range\"),\n", " gr.Slider(minimum=-1, maximum=1, randomize=True, step=0.05, label=\"Random only multiple of 0.05 allowed\"),\n", " gr.Slider(minimum=0, maximum=1, randomize=True, step=0.25, label=\"Random only multiples of 0.25 allowed\"),\n", " gr.Slider(minimum=-100, maximum=100, randomize=True, step=3, label=\"Random between -100 and 100 step 3\"),\n", " gr.Slider(minimum=-100, maximum=100, randomize=True, label=\"Random between -100 and 100\"),\n", " gr.Slider(value=0.25, minimum=5, maximum=30, step=-1),\n", " ],\n", " \"number\",\n", " interpretation=\"default\"\n", ")\n", "\n", "if __name__ == \"__main__\":\n", " demo.launch()\n"]}], "metadata": {}, "nbformat": 4, "nbformat_minor": 5} +>>>>>>> main diff --git a/demo/interface_random_slider/run.py b/demo/interface_random_slider/run.py index df5a0f21bec6..5d199f706615 100644 --- a/demo/interface_random_slider/run.py +++ b/demo/interface_random_slider/run.py @@ -16,7 +16,6 @@ def func(slider_1, slider_2, *args): gr.Slider(value=0.25, minimum=5, maximum=30, step=-1), ], "number", - interpretation="default" ) if __name__ == "__main__": diff --git a/demo/interface_series/run.ipynb b/demo/interface_series/run.ipynb index 4b9e0d8789f6..0ed5fe48fcde 100644 --- a/demo/interface_series/run.ipynb +++ b/demo/interface_series/run.ipynb @@ -1 +1,5 @@ -{"cells": [{"cell_type": "markdown", "id": "302934307671667531413257853548643485645", "metadata": {}, "source": ["# Gradio Demo: interface_series"]}, {"cell_type": "code", "execution_count": null, "id": "272996653310673477252411125948039410165", "metadata": {}, "outputs": [], "source": ["!pip install -q gradio "]}, {"cell_type": "code", "execution_count": null, "id": "288918539441861185822528903084949547379", "metadata": {}, "outputs": [], "source": ["import gradio as gr\n", "\n", "get_name = gr.Interface(lambda name: name, inputs=\"textbox\", outputs=\"textbox\")\n", "prepend_hello = gr.Interface(lambda name: f\"Hello {name}!\", inputs=\"textbox\", outputs=\"textbox\")\n", "append_nice = gr.Interface(lambda greeting: f\"{greeting} Nice to meet you!\",\n", " inputs=\"textbox\", outputs=gr.Textbox(label=\"Greeting\"))\n", "demo = gr.Series(get_name, prepend_hello, append_nice)\n", "\n", "if __name__ == \"__main__\":\n", " demo.launch()"]}], "metadata": {}, "nbformat": 4, "nbformat_minor": 5} \ No newline at end of file +<<<<<<< HEAD +{"cells": [{"cell_type": "markdown", "id": 302934307671667531413257853548643485645, "metadata": {}, "source": ["# Gradio Demo: interface_series"]}, {"cell_type": "code", "execution_count": null, "id": 272996653310673477252411125948039410165, "metadata": {}, "outputs": [], "source": ["!pip install -q gradio "]}, {"cell_type": "code", "execution_count": null, "id": 288918539441861185822528903084949547379, "metadata": {}, "outputs": [], "source": ["import gradio as gr\n", "\n", "get_name = gr.Interface(lambda name: name, inputs=\"textbox\", outputs=\"textbox\")\n", "prepend_hello = gr.Interface(lambda name: f\"Hello {name}!\", inputs=\"textbox\", outputs=\"textbox\")\n", "append_nice = gr.Interface(lambda greeting: f\"Nice to meet you!\",\n", " inputs=\"textbox\", outputs=gr.Textbox(label=\"Greeting\"))\n", "translator = gr.Interface(lambda s: \"https://gradio-builds.s3.amazonaws.com/diffusion_image/cute_dog.jpg\", gr.Textbox(), gr.Image())\n", "demo = gr.Series(get_name, translator, append_nice)\n", "\n", "if __name__ == \"__main__\":\n", " demo.launch()"]}], "metadata": {}, "nbformat": 4, "nbformat_minor": 5} +======= +{"cells": [{"cell_type": "markdown", "id": "302934307671667531413257853548643485645", "metadata": {}, "source": ["# Gradio Demo: interface_series"]}, {"cell_type": "code", "execution_count": null, "id": "272996653310673477252411125948039410165", "metadata": {}, "outputs": [], "source": ["!pip install -q gradio "]}, {"cell_type": "code", "execution_count": null, "id": "288918539441861185822528903084949547379", "metadata": {}, "outputs": [], "source": ["import gradio as gr\n", "\n", "get_name = gr.Interface(lambda name: name, inputs=\"textbox\", outputs=\"textbox\")\n", "prepend_hello = gr.Interface(lambda name: f\"Hello {name}!\", inputs=\"textbox\", outputs=\"textbox\")\n", "append_nice = gr.Interface(lambda greeting: f\"{greeting} Nice to meet you!\",\n", " inputs=\"textbox\", outputs=gr.Textbox(label=\"Greeting\"))\n", "demo = gr.Series(get_name, prepend_hello, append_nice)\n", "\n", "if __name__ == \"__main__\":\n", " demo.launch()"]}], "metadata": {}, "nbformat": 4, "nbformat_minor": 5} +>>>>>>> main diff --git a/demo/interface_series/run.py b/demo/interface_series/run.py index ac942ff94b23..dbad6acd6115 100644 --- a/demo/interface_series/run.py +++ b/demo/interface_series/run.py @@ -2,9 +2,10 @@ get_name = gr.Interface(lambda name: name, inputs="textbox", outputs="textbox") prepend_hello = gr.Interface(lambda name: f"Hello {name}!", inputs="textbox", outputs="textbox") -append_nice = gr.Interface(lambda greeting: f"{greeting} Nice to meet you!", +append_nice = gr.Interface(lambda greeting: f"Nice to meet you!", inputs="textbox", outputs=gr.Textbox(label="Greeting")) -demo = gr.Series(get_name, prepend_hello, append_nice) +translator = gr.Interface(lambda s: "https://gradio-builds.s3.amazonaws.com/diffusion_image/cute_dog.jpg", gr.Textbox(), gr.Image()) +demo = gr.Series(get_name, translator, append_nice) if __name__ == "__main__": demo.launch() \ No newline at end of file diff --git a/demo/interface_series_load/run.ipynb b/demo/interface_series_load/run.ipynb index 1d80f3ff3843..9d8f3cd13537 100644 --- a/demo/interface_series_load/run.ipynb +++ b/demo/interface_series_load/run.ipynb @@ -1 +1,5 @@ -{"cells": [{"cell_type": "markdown", "id": "302934307671667531413257853548643485645", "metadata": {}, "source": ["# Gradio Demo: interface_series_load"]}, {"cell_type": "code", "execution_count": null, "id": "272996653310673477252411125948039410165", "metadata": {}, "outputs": [], "source": ["!pip install -q gradio "]}, {"cell_type": "code", "execution_count": null, "id": "288918539441861185822528903084949547379", "metadata": {}, "outputs": [], "source": ["import gradio as gr\n", "\n", "generator = gr.load(\"huggingface/gpt2\")\n", "translator = gr.load(\"huggingface/t5-small\")\n", "\n", "demo = gr.Series(generator, translator, description=\"This demo combines two Spaces: a text generator (`huggingface/gpt2`) and a text translator (`huggingface/t5-small`). The first Space takes a prompt as input and generates a text. The second Space takes the generated text as input and translates it into another language.\")\n", "\n", "if __name__ == \"__main__\":\n", " demo.launch()"]}], "metadata": {}, "nbformat": 4, "nbformat_minor": 5} \ No newline at end of file +<<<<<<< HEAD +{"cells": [{"cell_type": "markdown", "id": 302934307671667531413257853548643485645, "metadata": {}, "source": ["# Gradio Demo: interface_series_load"]}, {"cell_type": "code", "execution_count": null, "id": 272996653310673477252411125948039410165, "metadata": {}, "outputs": [], "source": ["!pip install -q gradio "]}, {"cell_type": "code", "execution_count": null, "id": 288918539441861185822528903084949547379, "metadata": {}, "outputs": [], "source": ["import gradio as gr\n", "import numpy as np\n", "\n", "generator = gr.load(\"huggingface/gpt2\")\n", "\n", "\n", "translator = gr.Interface(lambda s: \"https://gradio-builds.s3.amazonaws.com/diffusion_image/cute_dog.jpg\", gr.Textbox(), gr.Image())\n", "\n", "demo = gr.Series(generator, translator, description=\"This demo combines two Spaces: a text generator (`huggingface/gpt2`) and a text translator (`huggingface/t5-small`). The first Space takes a prompt as input and generates a text. The second Space takes the generated text as input and translates it into another language.\")\n", "\n", "if __name__ == \"__main__\":\n", " demo.launch()"]}], "metadata": {}, "nbformat": 4, "nbformat_minor": 5} +======= +{"cells": [{"cell_type": "markdown", "id": "302934307671667531413257853548643485645", "metadata": {}, "source": ["# Gradio Demo: interface_series_load"]}, {"cell_type": "code", "execution_count": null, "id": "272996653310673477252411125948039410165", "metadata": {}, "outputs": [], "source": ["!pip install -q gradio "]}, {"cell_type": "code", "execution_count": null, "id": "288918539441861185822528903084949547379", "metadata": {}, "outputs": [], "source": ["import gradio as gr\n", "\n", "generator = gr.load(\"huggingface/gpt2\")\n", "translator = gr.load(\"huggingface/t5-small\")\n", "\n", "demo = gr.Series(generator, translator, description=\"This demo combines two Spaces: a text generator (`huggingface/gpt2`) and a text translator (`huggingface/t5-small`). The first Space takes a prompt as input and generates a text. The second Space takes the generated text as input and translates it into another language.\")\n", "\n", "if __name__ == \"__main__\":\n", " demo.launch()"]}], "metadata": {}, "nbformat": 4, "nbformat_minor": 5} +>>>>>>> main diff --git a/demo/interface_series_load/run.py b/demo/interface_series_load/run.py index 13703ccadbf8..e7131fd5b8de 100644 --- a/demo/interface_series_load/run.py +++ b/demo/interface_series_load/run.py @@ -1,7 +1,10 @@ import gradio as gr +import numpy as np generator = gr.load("huggingface/gpt2") -translator = gr.load("huggingface/t5-small") + + +translator = gr.Interface(lambda s: "https://gradio-builds.s3.amazonaws.com/diffusion_image/cute_dog.jpg", gr.Textbox(), gr.Image()) demo = gr.Series(generator, translator, description="This demo combines two Spaces: a text generator (`huggingface/gpt2`) and a text translator (`huggingface/t5-small`). The first Space takes a prompt as input and generates a text. The second Space takes the generated text as input and translates it into another language.") diff --git a/demo/kitchen_sink/run.ipynb b/demo/kitchen_sink/run.ipynb index 86eff63c2897..5e7685ae595d 100644 --- a/demo/kitchen_sink/run.ipynb +++ b/demo/kitchen_sink/run.ipynb @@ -1 +1,5 @@ -{"cells": [{"cell_type": "markdown", "id": "302934307671667531413257853548643485645", "metadata": {}, "source": ["# Gradio Demo: kitchen_sink"]}, {"cell_type": "code", "execution_count": null, "id": "272996653310673477252411125948039410165", "metadata": {}, "outputs": [], "source": ["!pip install -q gradio "]}, {"cell_type": "code", "execution_count": null, "id": "288918539441861185822528903084949547379", "metadata": {}, "outputs": [], "source": ["# Downloading files from the demo repo\n", "import os\n", "os.mkdir('files')\n", "!wget -q -O files/cantina.wav https://github.com/gradio-app/gradio/raw/main/demo/kitchen_sink/files/cantina.wav\n", "!wget -q -O files/cheetah1.jpg https://github.com/gradio-app/gradio/raw/main/demo/kitchen_sink/files/cheetah1.jpg\n", "!wget -q -O files/lion.jpg https://github.com/gradio-app/gradio/raw/main/demo/kitchen_sink/files/lion.jpg\n", "!wget -q -O files/logo.png https://github.com/gradio-app/gradio/raw/main/demo/kitchen_sink/files/logo.png\n", "!wget -q -O files/time.csv https://github.com/gradio-app/gradio/raw/main/demo/kitchen_sink/files/time.csv\n", "!wget -q -O files/titanic.csv https://github.com/gradio-app/gradio/raw/main/demo/kitchen_sink/files/titanic.csv\n", "!wget -q -O files/tower.jpg https://github.com/gradio-app/gradio/raw/main/demo/kitchen_sink/files/tower.jpg\n", "!wget -q -O files/world.mp4 https://github.com/gradio-app/gradio/raw/main/demo/kitchen_sink/files/world.mp4"]}, {"cell_type": "code", "execution_count": null, "id": "44380577570523278879349135829904343037", "metadata": {}, "outputs": [], "source": ["import os\n", "import json\n", "\n", "import numpy as np\n", "\n", "import gradio as gr\n", "\n", "CHOICES = [\"foo\", \"bar\", \"baz\"]\n", "JSONOBJ = \"\"\"{\"items\":{\"item\":[{\"id\": \"0001\",\"type\": null,\"is_good\": false,\"ppu\": 0.55,\"batters\":{\"batter\":[{ \"id\": \"1001\", \"type\": \"Regular\" },{ \"id\": \"1002\", \"type\": \"Chocolate\" },{ \"id\": \"1003\", \"type\": \"Blueberry\" },{ \"id\": \"1004\", \"type\": \"Devil's Food\" }]},\"topping\":[{ \"id\": \"5001\", \"type\": \"None\" },{ \"id\": \"5002\", \"type\": \"Glazed\" },{ \"id\": \"5005\", \"type\": \"Sugar\" },{ \"id\": \"5007\", \"type\": \"Powdered Sugar\" },{ \"id\": \"5006\", \"type\": \"Chocolate with Sprinkles\" },{ \"id\": \"5003\", \"type\": \"Chocolate\" },{ \"id\": \"5004\", \"type\": \"Maple\" }]}]}}\"\"\"\n", "\n", "\n", "def fn(\n", " text1,\n", " text2,\n", " num,\n", " slider1,\n", " slider2,\n", " single_checkbox,\n", " checkboxes,\n", " radio,\n", " dropdown,\n", " multi_dropdown,\n", " im1,\n", " im2,\n", " im3,\n", " im4,\n", " video,\n", " audio1,\n", " audio2,\n", " file,\n", " df1,\n", " df2,\n", "):\n", " return (\n", " (text1 if single_checkbox else text2)\n", " + \", selected:\"\n", " + \", \".join(checkboxes), # Text\n", " {\n", " \"positive\": num / (num + slider1 + slider2),\n", " \"negative\": slider1 / (num + slider1 + slider2),\n", " \"neutral\": slider2 / (num + slider1 + slider2),\n", " }, # Label\n", " (audio1[0], np.flipud(audio1[1]))\n", " if audio1 is not None\n", " else os.path.join(os.path.abspath(''), \"files/cantina.wav\"), # Audio\n", " np.flipud(im1)\n", " if im1 is not None\n", " else os.path.join(os.path.abspath(''), \"files/cheetah1.jpg\"), # Image\n", " video\n", " if video is not None\n", " else os.path.join(os.path.abspath(''), \"files/world.mp4\"), # Video\n", " [\n", " (\"The\", \"art\"),\n", " (\"quick brown\", \"adj\"),\n", " (\"fox\", \"nn\"),\n", " (\"jumped\", \"vrb\"),\n", " (\"testing testing testing\", None),\n", " (\"over\", \"prp\"),\n", " (\"the\", \"art\"),\n", " (\"testing\", None),\n", " (\"lazy\", \"adj\"),\n", " (\"dogs\", \"nn\"),\n", " (\".\", \"punc\"),\n", " ]\n", " + [(f\"test {x}\", f\"test {x}\") for x in range(10)], # HighlightedText\n", " # [(\"The testing testing testing\", None), (\"quick brown\", 0.2), (\"fox\", 1), (\"jumped\", -1), (\"testing testing testing\", 0), (\"over\", 0), (\"the\", 0), (\"testing\", 0), (\"lazy\", 1), (\"dogs\", 0), (\".\", 1)] + [(f\"test {x}\", x/10) for x in range(-10, 10)], # HighlightedText\n", " [\n", " (\"The testing testing testing\", None),\n", " (\"over\", 0.6),\n", " (\"the\", 0.2),\n", " (\"testing\", None),\n", " (\"lazy\", -0.1),\n", " (\"dogs\", 0.4),\n", " (\".\", 0),\n", " ]\n", " + [(f\"test\", x / 10) for x in range(-10, 10)], # HighlightedText\n", " json.loads(JSONOBJ), # JSON\n", " \"\", # HTML\n", " os.path.join(os.path.abspath(''), \"files/titanic.csv\"),\n", " df1, # Dataframe\n", " np.random.randint(0, 10, (4, 4)), # Dataframe\n", " df2, # Timeseries\n", " )\n", "\n", "\n", "demo = gr.Interface(\n", " fn,\n", " inputs=[\n", " gr.Textbox(value=\"Lorem ipsum\", label=\"Textbox\"),\n", " gr.Textbox(lines=3, placeholder=\"Type here..\", label=\"Textbox 2\"),\n", " gr.Number(label=\"Number\", value=42),\n", " gr.Slider(10, 20, value=15, label=\"Slider: 10 - 20\"),\n", " gr.Slider(maximum=20, step=0.04, label=\"Slider: step @ 0.04\"),\n", " gr.Checkbox(label=\"Checkbox\"),\n", " gr.CheckboxGroup(label=\"CheckboxGroup\", choices=CHOICES, value=CHOICES[0:2]),\n", " gr.Radio(label=\"Radio\", choices=CHOICES, value=CHOICES[2]),\n", " gr.Dropdown(label=\"Dropdown\", choices=CHOICES),\n", " gr.Dropdown(label=\"Multiselect Dropdown (Max choice: 2)\", choices=CHOICES, multiselect=True, max_choices=2),\n", " gr.Image(label=\"Image\"),\n", " gr.Image(label=\"Image w/ Cropper\", tool=\"select\"),\n", " gr.Image(label=\"Sketchpad\", source=\"canvas\"),\n", " gr.Image(label=\"Webcam\", source=\"webcam\"),\n", " gr.Video(label=\"Video\"),\n", " gr.Audio(label=\"Audio\"),\n", " gr.Audio(label=\"Microphone\", source=\"microphone\"),\n", " gr.File(label=\"File\"),\n", " gr.Dataframe(label=\"Dataframe\", headers=[\"Name\", \"Age\", \"Gender\"]),\n", " gr.Timeseries(x=\"time\", y=[\"price\", \"value\"], colors=[\"pink\", \"purple\"]),\n", " ],\n", " outputs=[\n", " gr.Textbox(label=\"Textbox\"),\n", " gr.Label(label=\"Label\"),\n", " gr.Audio(label=\"Audio\"),\n", " gr.Image(label=\"Image\"),\n", " gr.Video(label=\"Video\"),\n", " gr.HighlightedText(label=\"HighlightedText\", \n", " color_map={\"punc\": \"pink\", \"test 0\": \"blue\"}\n", " ),\n", " gr.HighlightedText(label=\"HighlightedText\", show_legend=True),\n", " gr.JSON(label=\"JSON\"),\n", " gr.HTML(label=\"HTML\"),\n", " gr.File(label=\"File\"),\n", " gr.Dataframe(label=\"Dataframe\"),\n", " gr.Dataframe(label=\"Numpy\"),\n", " gr.Timeseries(x=\"time\", y=[\"price\", \"value\"], label=\"Timeseries\"),\n", " ],\n", " examples=[\n", " [\n", " \"the quick brown fox\",\n", " \"jumps over the lazy dog\",\n", " 10,\n", " 12,\n", " 4,\n", " True,\n", " [\"foo\", \"baz\"],\n", " \"baz\",\n", " \"bar\",\n", " [\"foo\", \"bar\"],\n", " os.path.join(os.path.abspath(''), \"files/cheetah1.jpg\"),\n", " os.path.join(os.path.abspath(''), \"files/cheetah1.jpg\"),\n", " os.path.join(os.path.abspath(''), \"files/cheetah1.jpg\"),\n", " os.path.join(os.path.abspath(''), \"files/cheetah1.jpg\"),\n", " os.path.join(os.path.abspath(''), \"files/world.mp4\"),\n", " os.path.join(os.path.abspath(''), \"files/cantina.wav\"),\n", " os.path.join(os.path.abspath(''), \"files/cantina.wav\"),\n", " os.path.join(os.path.abspath(''), \"files/titanic.csv\"),\n", " [[1, 2, 3, 4], [4, 5, 6, 7], [8, 9, 1, 2], [3, 4, 5, 6]],\n", " os.path.join(os.path.abspath(''), \"files/time.csv\"),\n", " ]\n", " ]\n", " * 3,\n", " title=\"Kitchen Sink\",\n", " description=\"Try out all the components!\",\n", " article=\"Learn more about [Gradio](http://gradio.app)\",\n", " cache_examples=True,\n", ")\n", "\n", "if __name__ == \"__main__\":\n", " demo.launch()"]}], "metadata": {}, "nbformat": 4, "nbformat_minor": 5} \ No newline at end of file +<<<<<<< HEAD +{"cells": [{"cell_type": "markdown", "id": 302934307671667531413257853548643485645, "metadata": {}, "source": ["# Gradio Demo: kitchen_sink"]}, {"cell_type": "code", "execution_count": null, "id": 272996653310673477252411125948039410165, "metadata": {}, "outputs": [], "source": ["!pip install -q gradio "]}, {"cell_type": "code", "execution_count": null, "id": 288918539441861185822528903084949547379, "metadata": {}, "outputs": [], "source": ["# Downloading files from the demo repo\n", "import os\n", "os.mkdir('files')\n", "!wget -q -O files/cantina.wav https://github.com/gradio-app/gradio/raw/main/demo/kitchen_sink/files/cantina.wav\n", "!wget -q -O files/cheetah1.jpg https://github.com/gradio-app/gradio/raw/main/demo/kitchen_sink/files/cheetah1.jpg\n", "!wget -q -O files/lion.jpg https://github.com/gradio-app/gradio/raw/main/demo/kitchen_sink/files/lion.jpg\n", "!wget -q -O files/logo.png https://github.com/gradio-app/gradio/raw/main/demo/kitchen_sink/files/logo.png\n", "!wget -q -O files/time.csv https://github.com/gradio-app/gradio/raw/main/demo/kitchen_sink/files/time.csv\n", "!wget -q -O files/titanic.csv https://github.com/gradio-app/gradio/raw/main/demo/kitchen_sink/files/titanic.csv\n", "!wget -q -O files/tower.jpg https://github.com/gradio-app/gradio/raw/main/demo/kitchen_sink/files/tower.jpg\n", "!wget -q -O files/world.mp4 https://github.com/gradio-app/gradio/raw/main/demo/kitchen_sink/files/world.mp4"]}, {"cell_type": "code", "execution_count": null, "id": 44380577570523278879349135829904343037, "metadata": {}, "outputs": [], "source": ["import os\n", "import json\n", "\n", "import numpy as np\n", "\n", "import gradio as gr\n", "\n", "CHOICES = [\"foo\", \"bar\", \"baz\"]\n", "JSONOBJ = \"\"\"{\"items\":{\"item\":[{\"id\": \"0001\",\"type\": null,\"is_good\": false,\"ppu\": 0.55,\"batters\":{\"batter\":[{ \"id\": \"1001\", \"type\": \"Regular\" },{ \"id\": \"1002\", \"type\": \"Chocolate\" },{ \"id\": \"1003\", \"type\": \"Blueberry\" },{ \"id\": \"1004\", \"type\": \"Devil's Food\" }]},\"topping\":[{ \"id\": \"5001\", \"type\": \"None\" },{ \"id\": \"5002\", \"type\": \"Glazed\" },{ \"id\": \"5005\", \"type\": \"Sugar\" },{ \"id\": \"5007\", \"type\": \"Powdered Sugar\" },{ \"id\": \"5006\", \"type\": \"Chocolate with Sprinkles\" },{ \"id\": \"5003\", \"type\": \"Chocolate\" },{ \"id\": \"5004\", \"type\": \"Maple\" }]}]}}\"\"\"\n", "\n", "\n", "def fn(\n", " text1,\n", " text2,\n", " num,\n", " slider1,\n", " slider2,\n", " single_checkbox,\n", " checkboxes,\n", " radio,\n", " dropdown,\n", " multi_dropdown,\n", " im1,\n", " im2,\n", " im3,\n", " im4,\n", " video,\n", " audio1,\n", " audio2,\n", " file,\n", " df1,\n", "):\n", " return (\n", " (text1 if single_checkbox else text2)\n", " + \", selected:\"\n", " + \", \".join(checkboxes), # Text\n", " {\n", " \"positive\": num / (num + slider1 + slider2),\n", " \"negative\": slider1 / (num + slider1 + slider2),\n", " \"neutral\": slider2 / (num + slider1 + slider2),\n", " }, # Label\n", " (audio1[0], np.flipud(audio1[1]))\n", " if audio1 is not None\n", " else os.path.join(os.path.abspath(''), \"files/cantina.wav\"), # Audio\n", " np.flipud(im1)\n", " if im1 is not None\n", " else os.path.join(os.path.abspath(''), \"files/cheetah1.jpg\"), # Image\n", " video\n", " if video is not None\n", " else os.path.join(os.path.abspath(''), \"files/world.mp4\"), # Video\n", " [\n", " (\"The\", \"art\"),\n", " (\"quick brown\", \"adj\"),\n", " (\"fox\", \"nn\"),\n", " (\"jumped\", \"vrb\"),\n", " (\"testing testing testing\", None),\n", " (\"over\", \"prp\"),\n", " (\"the\", \"art\"),\n", " (\"testing\", None),\n", " (\"lazy\", \"adj\"),\n", " (\"dogs\", \"nn\"),\n", " (\".\", \"punc\"),\n", " ]\n", " + [(f\"test {x}\", f\"test {x}\") for x in range(10)], # HighlightedText\n", " # [(\"The testing testing testing\", None), (\"quick brown\", 0.2), (\"fox\", 1), (\"jumped\", -1), (\"testing testing testing\", 0), (\"over\", 0), (\"the\", 0), (\"testing\", 0), (\"lazy\", 1), (\"dogs\", 0), (\".\", 1)] + [(f\"test {x}\", x/10) for x in range(-10, 10)], # HighlightedText\n", " [\n", " (\"The testing testing testing\", None),\n", " (\"over\", 0.6),\n", " (\"the\", 0.2),\n", " (\"testing\", None),\n", " (\"lazy\", -0.1),\n", " (\"dogs\", 0.4),\n", " (\".\", 0),\n", " ]\n", " + [(f\"test\", x / 10) for x in range(-10, 10)], # HighlightedText\n", " json.loads(JSONOBJ), # JSON\n", " \"\", # HTML\n", " os.path.join(os.path.abspath(''), \"files/titanic.csv\"),\n", " df1, # Dataframe\n", " np.random.randint(0, 10, (4, 4)), # Dataframe\n", " )\n", "\n", "\n", "demo = gr.Interface(\n", " fn,\n", " inputs=[\n", " gr.Textbox(value=\"Lorem ipsum\", label=\"Textbox\"),\n", " gr.Textbox(lines=3, placeholder=\"Type here..\", label=\"Textbox 2\"),\n", " gr.Number(label=\"Number\", value=42),\n", " gr.Slider(10, 20, value=15, label=\"Slider: 10 - 20\"),\n", " gr.Slider(maximum=20, step=0.04, label=\"Slider: step @ 0.04\"),\n", " gr.Checkbox(label=\"Checkbox\"),\n", " gr.CheckboxGroup(label=\"CheckboxGroup\", choices=CHOICES, value=CHOICES[0:2]),\n", " gr.Radio(label=\"Radio\", choices=CHOICES, value=CHOICES[2]),\n", " gr.Dropdown(label=\"Dropdown\", choices=CHOICES),\n", " gr.Dropdown(\n", " label=\"Multiselect Dropdown (Max choice: 2)\",\n", " choices=CHOICES,\n", " multiselect=True,\n", " max_choices=2,\n", " ),\n", " gr.Image(label=\"Image\"),\n", " gr.Image(label=\"Image w/ Cropper\", tool=\"select\"),\n", " gr.Image(label=\"Sketchpad\", source=\"canvas\"),\n", " gr.Image(label=\"Webcam\", source=\"webcam\"),\n", " gr.Video(label=\"Video\"),\n", " gr.Audio(label=\"Audio\"),\n", " gr.Audio(label=\"Microphone\", source=\"microphone\"),\n", " gr.File(label=\"File\"),\n", " gr.Dataframe(label=\"Dataframe\", headers=[\"Name\", \"Age\", \"Gender\"]),\n", " ],\n", " outputs=[\n", " gr.Textbox(label=\"Textbox\"),\n", " gr.Label(label=\"Label\"),\n", " gr.Audio(label=\"Audio\"),\n", " gr.Image(label=\"Image\"),\n", " gr.Video(label=\"Video\"),\n", " gr.HighlightedText(\n", " label=\"HighlightedText\", color_map={\"punc\": \"pink\", \"test 0\": \"blue\"}\n", " ),\n", " gr.HighlightedText(label=\"HighlightedText\", show_legend=True),\n", " gr.JSON(label=\"JSON\"),\n", " gr.HTML(label=\"HTML\"),\n", " gr.File(label=\"File\"),\n", " gr.Dataframe(label=\"Dataframe\"),\n", " gr.Dataframe(label=\"Numpy\"),\n", " ],\n", " examples=[\n", " [\n", " \"the quick brown fox\",\n", " \"jumps over the lazy dog\",\n", " 10,\n", " 12,\n", " 4,\n", " True,\n", " [\"foo\", \"baz\"],\n", " \"baz\",\n", " \"bar\",\n", " [\"foo\", \"bar\"],\n", " os.path.join(os.path.abspath(''), \"files/cheetah1.jpg\"),\n", " os.path.join(os.path.abspath(''), \"files/cheetah1.jpg\"),\n", " os.path.join(os.path.abspath(''), \"files/cheetah1.jpg\"),\n", " os.path.join(os.path.abspath(''), \"files/cheetah1.jpg\"),\n", " os.path.join(os.path.abspath(''), \"files/world.mp4\"),\n", " os.path.join(os.path.abspath(''), \"files/cantina.wav\"),\n", " os.path.join(os.path.abspath(''), \"files/cantina.wav\"),\n", " os.path.join(os.path.abspath(''), \"files/titanic.csv\"),\n", " [[1, 2, 3, 4], [4, 5, 6, 7], [8, 9, 1, 2], [3, 4, 5, 6]],\n", " ]\n", " ]\n", " * 3,\n", " title=\"Kitchen Sink\",\n", " description=\"Try out all the components!\",\n", " article=\"Learn more about [Gradio](http://gradio.app)\",\n", " cache_examples=True,\n", ")\n", "\n", "if __name__ == \"__main__\":\n", " demo.launch()\n"]}], "metadata": {}, "nbformat": 4, "nbformat_minor": 5} +======= +{"cells": [{"cell_type": "markdown", "id": "302934307671667531413257853548643485645", "metadata": {}, "source": ["# Gradio Demo: kitchen_sink"]}, {"cell_type": "code", "execution_count": null, "id": "272996653310673477252411125948039410165", "metadata": {}, "outputs": [], "source": ["!pip install -q gradio "]}, {"cell_type": "code", "execution_count": null, "id": "288918539441861185822528903084949547379", "metadata": {}, "outputs": [], "source": ["# Downloading files from the demo repo\n", "import os\n", "os.mkdir('files')\n", "!wget -q -O files/cantina.wav https://github.com/gradio-app/gradio/raw/main/demo/kitchen_sink/files/cantina.wav\n", "!wget -q -O files/cheetah1.jpg https://github.com/gradio-app/gradio/raw/main/demo/kitchen_sink/files/cheetah1.jpg\n", "!wget -q -O files/lion.jpg https://github.com/gradio-app/gradio/raw/main/demo/kitchen_sink/files/lion.jpg\n", "!wget -q -O files/logo.png https://github.com/gradio-app/gradio/raw/main/demo/kitchen_sink/files/logo.png\n", "!wget -q -O files/time.csv https://github.com/gradio-app/gradio/raw/main/demo/kitchen_sink/files/time.csv\n", "!wget -q -O files/titanic.csv https://github.com/gradio-app/gradio/raw/main/demo/kitchen_sink/files/titanic.csv\n", "!wget -q -O files/tower.jpg https://github.com/gradio-app/gradio/raw/main/demo/kitchen_sink/files/tower.jpg\n", "!wget -q -O files/world.mp4 https://github.com/gradio-app/gradio/raw/main/demo/kitchen_sink/files/world.mp4"]}, {"cell_type": "code", "execution_count": null, "id": "44380577570523278879349135829904343037", "metadata": {}, "outputs": [], "source": ["import os\n", "import json\n", "\n", "import numpy as np\n", "\n", "import gradio as gr\n", "\n", "CHOICES = [\"foo\", \"bar\", \"baz\"]\n", "JSONOBJ = \"\"\"{\"items\":{\"item\":[{\"id\": \"0001\",\"type\": null,\"is_good\": false,\"ppu\": 0.55,\"batters\":{\"batter\":[{ \"id\": \"1001\", \"type\": \"Regular\" },{ \"id\": \"1002\", \"type\": \"Chocolate\" },{ \"id\": \"1003\", \"type\": \"Blueberry\" },{ \"id\": \"1004\", \"type\": \"Devil's Food\" }]},\"topping\":[{ \"id\": \"5001\", \"type\": \"None\" },{ \"id\": \"5002\", \"type\": \"Glazed\" },{ \"id\": \"5005\", \"type\": \"Sugar\" },{ \"id\": \"5007\", \"type\": \"Powdered Sugar\" },{ \"id\": \"5006\", \"type\": \"Chocolate with Sprinkles\" },{ \"id\": \"5003\", \"type\": \"Chocolate\" },{ \"id\": \"5004\", \"type\": \"Maple\" }]}]}}\"\"\"\n", "\n", "\n", "def fn(\n", " text1,\n", " text2,\n", " num,\n", " slider1,\n", " slider2,\n", " single_checkbox,\n", " checkboxes,\n", " radio,\n", " dropdown,\n", " multi_dropdown,\n", " im1,\n", " im2,\n", " im3,\n", " im4,\n", " video,\n", " audio1,\n", " audio2,\n", " file,\n", " df1,\n", " df2,\n", "):\n", " return (\n", " (text1 if single_checkbox else text2)\n", " + \", selected:\"\n", " + \", \".join(checkboxes), # Text\n", " {\n", " \"positive\": num / (num + slider1 + slider2),\n", " \"negative\": slider1 / (num + slider1 + slider2),\n", " \"neutral\": slider2 / (num + slider1 + slider2),\n", " }, # Label\n", " (audio1[0], np.flipud(audio1[1]))\n", " if audio1 is not None\n", " else os.path.join(os.path.abspath(''), \"files/cantina.wav\"), # Audio\n", " np.flipud(im1)\n", " if im1 is not None\n", " else os.path.join(os.path.abspath(''), \"files/cheetah1.jpg\"), # Image\n", " video\n", " if video is not None\n", " else os.path.join(os.path.abspath(''), \"files/world.mp4\"), # Video\n", " [\n", " (\"The\", \"art\"),\n", " (\"quick brown\", \"adj\"),\n", " (\"fox\", \"nn\"),\n", " (\"jumped\", \"vrb\"),\n", " (\"testing testing testing\", None),\n", " (\"over\", \"prp\"),\n", " (\"the\", \"art\"),\n", " (\"testing\", None),\n", " (\"lazy\", \"adj\"),\n", " (\"dogs\", \"nn\"),\n", " (\".\", \"punc\"),\n", " ]\n", " + [(f\"test {x}\", f\"test {x}\") for x in range(10)], # HighlightedText\n", " # [(\"The testing testing testing\", None), (\"quick brown\", 0.2), (\"fox\", 1), (\"jumped\", -1), (\"testing testing testing\", 0), (\"over\", 0), (\"the\", 0), (\"testing\", 0), (\"lazy\", 1), (\"dogs\", 0), (\".\", 1)] + [(f\"test {x}\", x/10) for x in range(-10, 10)], # HighlightedText\n", " [\n", " (\"The testing testing testing\", None),\n", " (\"over\", 0.6),\n", " (\"the\", 0.2),\n", " (\"testing\", None),\n", " (\"lazy\", -0.1),\n", " (\"dogs\", 0.4),\n", " (\".\", 0),\n", " ]\n", " + [(f\"test\", x / 10) for x in range(-10, 10)], # HighlightedText\n", " json.loads(JSONOBJ), # JSON\n", " \"\", # HTML\n", " os.path.join(os.path.abspath(''), \"files/titanic.csv\"),\n", " df1, # Dataframe\n", " np.random.randint(0, 10, (4, 4)), # Dataframe\n", " df2, # Timeseries\n", " )\n", "\n", "\n", "demo = gr.Interface(\n", " fn,\n", " inputs=[\n", " gr.Textbox(value=\"Lorem ipsum\", label=\"Textbox\"),\n", " gr.Textbox(lines=3, placeholder=\"Type here..\", label=\"Textbox 2\"),\n", " gr.Number(label=\"Number\", value=42),\n", " gr.Slider(10, 20, value=15, label=\"Slider: 10 - 20\"),\n", " gr.Slider(maximum=20, step=0.04, label=\"Slider: step @ 0.04\"),\n", " gr.Checkbox(label=\"Checkbox\"),\n", " gr.CheckboxGroup(label=\"CheckboxGroup\", choices=CHOICES, value=CHOICES[0:2]),\n", " gr.Radio(label=\"Radio\", choices=CHOICES, value=CHOICES[2]),\n", " gr.Dropdown(label=\"Dropdown\", choices=CHOICES),\n", " gr.Dropdown(label=\"Multiselect Dropdown (Max choice: 2)\", choices=CHOICES, multiselect=True, max_choices=2),\n", " gr.Image(label=\"Image\"),\n", " gr.Image(label=\"Image w/ Cropper\", tool=\"select\"),\n", " gr.Image(label=\"Sketchpad\", source=\"canvas\"),\n", " gr.Image(label=\"Webcam\", source=\"webcam\"),\n", " gr.Video(label=\"Video\"),\n", " gr.Audio(label=\"Audio\"),\n", " gr.Audio(label=\"Microphone\", source=\"microphone\"),\n", " gr.File(label=\"File\"),\n", " gr.Dataframe(label=\"Dataframe\", headers=[\"Name\", \"Age\", \"Gender\"]),\n", " gr.Timeseries(x=\"time\", y=[\"price\", \"value\"], colors=[\"pink\", \"purple\"]),\n", " ],\n", " outputs=[\n", " gr.Textbox(label=\"Textbox\"),\n", " gr.Label(label=\"Label\"),\n", " gr.Audio(label=\"Audio\"),\n", " gr.Image(label=\"Image\"),\n", " gr.Video(label=\"Video\"),\n", " gr.HighlightedText(label=\"HighlightedText\", \n", " color_map={\"punc\": \"pink\", \"test 0\": \"blue\"}\n", " ),\n", " gr.HighlightedText(label=\"HighlightedText\", show_legend=True),\n", " gr.JSON(label=\"JSON\"),\n", " gr.HTML(label=\"HTML\"),\n", " gr.File(label=\"File\"),\n", " gr.Dataframe(label=\"Dataframe\"),\n", " gr.Dataframe(label=\"Numpy\"),\n", " gr.Timeseries(x=\"time\", y=[\"price\", \"value\"], label=\"Timeseries\"),\n", " ],\n", " examples=[\n", " [\n", " \"the quick brown fox\",\n", " \"jumps over the lazy dog\",\n", " 10,\n", " 12,\n", " 4,\n", " True,\n", " [\"foo\", \"baz\"],\n", " \"baz\",\n", " \"bar\",\n", " [\"foo\", \"bar\"],\n", " os.path.join(os.path.abspath(''), \"files/cheetah1.jpg\"),\n", " os.path.join(os.path.abspath(''), \"files/cheetah1.jpg\"),\n", " os.path.join(os.path.abspath(''), \"files/cheetah1.jpg\"),\n", " os.path.join(os.path.abspath(''), \"files/cheetah1.jpg\"),\n", " os.path.join(os.path.abspath(''), \"files/world.mp4\"),\n", " os.path.join(os.path.abspath(''), \"files/cantina.wav\"),\n", " os.path.join(os.path.abspath(''), \"files/cantina.wav\"),\n", " os.path.join(os.path.abspath(''), \"files/titanic.csv\"),\n", " [[1, 2, 3, 4], [4, 5, 6, 7], [8, 9, 1, 2], [3, 4, 5, 6]],\n", " os.path.join(os.path.abspath(''), \"files/time.csv\"),\n", " ]\n", " ]\n", " * 3,\n", " title=\"Kitchen Sink\",\n", " description=\"Try out all the components!\",\n", " article=\"Learn more about [Gradio](http://gradio.app)\",\n", " cache_examples=True,\n", ")\n", "\n", "if __name__ == \"__main__\":\n", " demo.launch()"]}], "metadata": {}, "nbformat": 4, "nbformat_minor": 5} +>>>>>>> main diff --git a/demo/kitchen_sink/run.py b/demo/kitchen_sink/run.py index 70a27150060f..bc5343244c8c 100755 --- a/demo/kitchen_sink/run.py +++ b/demo/kitchen_sink/run.py @@ -29,7 +29,6 @@ def fn( audio2, file, df1, - df2, ): return ( (text1 if single_checkbox else text2) @@ -81,7 +80,6 @@ def fn( os.path.join(os.path.dirname(__file__), "files/titanic.csv"), df1, # Dataframe np.random.randint(0, 10, (4, 4)), # Dataframe - df2, # Timeseries ) @@ -97,7 +95,12 @@ def fn( gr.CheckboxGroup(label="CheckboxGroup", choices=CHOICES, value=CHOICES[0:2]), gr.Radio(label="Radio", choices=CHOICES, value=CHOICES[2]), gr.Dropdown(label="Dropdown", choices=CHOICES), - gr.Dropdown(label="Multiselect Dropdown (Max choice: 2)", choices=CHOICES, multiselect=True, max_choices=2), + gr.Dropdown( + label="Multiselect Dropdown (Max choice: 2)", + choices=CHOICES, + multiselect=True, + max_choices=2, + ), gr.Image(label="Image"), gr.Image(label="Image w/ Cropper", tool="select"), gr.Image(label="Sketchpad", source="canvas"), @@ -107,7 +110,6 @@ def fn( gr.Audio(label="Microphone", source="microphone"), gr.File(label="File"), gr.Dataframe(label="Dataframe", headers=["Name", "Age", "Gender"]), - gr.Timeseries(x="time", y=["price", "value"], colors=["pink", "purple"]), ], outputs=[ gr.Textbox(label="Textbox"), @@ -115,8 +117,8 @@ def fn( gr.Audio(label="Audio"), gr.Image(label="Image"), gr.Video(label="Video"), - gr.HighlightedText(label="HighlightedText", - color_map={"punc": "pink", "test 0": "blue"} + gr.HighlightedText( + label="HighlightedText", color_map={"punc": "pink", "test 0": "blue"} ), gr.HighlightedText(label="HighlightedText", show_legend=True), gr.JSON(label="JSON"), @@ -124,7 +126,6 @@ def fn( gr.File(label="File"), gr.Dataframe(label="Dataframe"), gr.Dataframe(label="Numpy"), - gr.Timeseries(x="time", y=["price", "value"], label="Timeseries"), ], examples=[ [ @@ -147,7 +148,6 @@ def fn( os.path.join(os.path.dirname(__file__), "files/cantina.wav"), os.path.join(os.path.dirname(__file__), "files/titanic.csv"), [[1, 2, 3, 4], [4, 5, 6, 7], [8, 9, 1, 2], [3, 4, 5, 6]], - os.path.join(os.path.dirname(__file__), "files/time.csv"), ] ] * 3, @@ -158,4 +158,4 @@ def fn( ) if __name__ == "__main__": - demo.launch() \ No newline at end of file + demo.launch() diff --git a/demo/kitchen_sink_random/run.py b/demo/kitchen_sink_random/run.py index 41c92d8a8db7..5b4440e94984 100644 --- a/demo/kitchen_sink_random/run.py +++ b/demo/kitchen_sink_random/run.py @@ -59,9 +59,7 @@ {"random_number_rows": range(random.randint(0, 10))} ) ), - gr.Timeseries(value=lambda: os.path.join(file_dir, "time.csv")), gr.State(value=lambda: random.choice(string.ascii_lowercase)), - gr.Button(value=lambda: random.choice(["Run", "Go", "predict"])), gr.ColorPicker(value=lambda: random.choice(["#000000", "#ff0000", "#0000FF"])), gr.Label(value=lambda: random.choice(["Pedestrian", "Car", "Cyclist"])), gr.HighlightedText( diff --git a/demo/model3D/run.ipynb b/demo/model3D/run.ipynb index 7ea65d26b593..53e4ceea0a1a 100644 --- a/demo/model3D/run.ipynb +++ b/demo/model3D/run.ipynb @@ -1 +1,5 @@ -{"cells": [{"cell_type": "markdown", "id": "302934307671667531413257853548643485645", "metadata": {}, "source": ["# Gradio Demo: model3D"]}, {"cell_type": "code", "execution_count": null, "id": "272996653310673477252411125948039410165", "metadata": {}, "outputs": [], "source": ["!pip install -q gradio "]}, {"cell_type": "code", "execution_count": null, "id": "288918539441861185822528903084949547379", "metadata": {}, "outputs": [], "source": ["# Downloading files from the demo repo\n", "import os\n", "os.mkdir('files')\n", "!wget -q -O files/Bunny.obj https://github.com/gradio-app/gradio/raw/main/demo/model3D/files/Bunny.obj\n", "!wget -q -O files/Duck.glb https://github.com/gradio-app/gradio/raw/main/demo/model3D/files/Duck.glb\n", "!wget -q -O files/Fox.gltf https://github.com/gradio-app/gradio/raw/main/demo/model3D/files/Fox.gltf\n", "!wget -q -O files/face.obj https://github.com/gradio-app/gradio/raw/main/demo/model3D/files/face.obj\n", "!wget -q -O files/source.txt https://github.com/gradio-app/gradio/raw/main/demo/model3D/files/source.txt"]}, {"cell_type": "code", "execution_count": null, "id": "44380577570523278879349135829904343037", "metadata": {}, "outputs": [], "source": ["import gradio as gr\n", "import os\n", "\n", "\n", "def load_mesh(mesh_file_name):\n", " return mesh_file_name\n", "\n", "\n", "demo = gr.Interface(\n", " fn=load_mesh,\n", " inputs=gr.Model3D(),\n", " outputs=gr.Model3D(\n", " clear_color=[0.0, 0.0, 0.0, 0.0], label=\"3D Model\"),\n", " examples=[\n", " [os.path.join(os.path.abspath(''), \"files/Bunny.obj\")],\n", " [os.path.join(os.path.abspath(''), \"files/Duck.glb\")],\n", " [os.path.join(os.path.abspath(''), \"files/Fox.gltf\")],\n", " [os.path.join(os.path.abspath(''), \"files/face.obj\")],\n", " ],\n", ")\n", "\n", "if __name__ == \"__main__\":\n", " demo.launch()\n"]}], "metadata": {}, "nbformat": 4, "nbformat_minor": 5} \ No newline at end of file +<<<<<<< HEAD +{"cells": [{"cell_type": "markdown", "id": 302934307671667531413257853548643485645, "metadata": {}, "source": ["# Gradio Demo: model3D"]}, {"cell_type": "code", "execution_count": null, "id": 272996653310673477252411125948039410165, "metadata": {}, "outputs": [], "source": ["!pip install -q gradio "]}, {"cell_type": "code", "execution_count": null, "id": 288918539441861185822528903084949547379, "metadata": {}, "outputs": [], "source": ["# Downloading files from the demo repo\n", "import os\n", "os.mkdir('files')\n", "!wget -q -O files/Bunny.obj https://github.com/gradio-app/gradio/raw/main/demo/model3D/files/Bunny.obj\n", "!wget -q -O files/Duck.glb https://github.com/gradio-app/gradio/raw/main/demo/model3D/files/Duck.glb\n", "!wget -q -O files/Fox.gltf https://github.com/gradio-app/gradio/raw/main/demo/model3D/files/Fox.gltf\n", "!wget -q -O files/face.obj https://github.com/gradio-app/gradio/raw/main/demo/model3D/files/face.obj\n", "!wget -q -O files/source.txt https://github.com/gradio-app/gradio/raw/main/demo/model3D/files/source.txt"]}, {"cell_type": "code", "execution_count": null, "id": 44380577570523278879349135829904343037, "metadata": {}, "outputs": [], "source": ["import gradio as gr\n", "import os\n", "\n", "\n", "def load_mesh(mesh_file_name):\n", " return mesh_file_name\n", "\n", "\n", "demo = gr.Interface(\n", " fn=load_mesh,\n", " inputs=gr.Model3D(),\n", " outputs=gr.Model3D(\n", " clear_color=[0.0, 0.0, 0.0, 0.0], label=\"3D Model\"),\n", " examples=[\n", " [os.path.join(os.path.abspath(''), \"files/Bunny.obj\")],\n", " [os.path.join(os.path.abspath(''), \"files/Duck.glb\")],\n", " [os.path.join(os.path.abspath(''), \"files/Fox.gltf\")],\n", " [os.path.join(os.path.abspath(''), \"files/face.obj\")],\n", " ],\n", " cache_examples=True\n", ")\n", "\n", "if __name__ == \"__main__\":\n", " demo.launch()\n"]}], "metadata": {}, "nbformat": 4, "nbformat_minor": 5} +======= +{"cells": [{"cell_type": "markdown", "id": "302934307671667531413257853548643485645", "metadata": {}, "source": ["# Gradio Demo: model3D"]}, {"cell_type": "code", "execution_count": null, "id": "272996653310673477252411125948039410165", "metadata": {}, "outputs": [], "source": ["!pip install -q gradio "]}, {"cell_type": "code", "execution_count": null, "id": "288918539441861185822528903084949547379", "metadata": {}, "outputs": [], "source": ["# Downloading files from the demo repo\n", "import os\n", "os.mkdir('files')\n", "!wget -q -O files/Bunny.obj https://github.com/gradio-app/gradio/raw/main/demo/model3D/files/Bunny.obj\n", "!wget -q -O files/Duck.glb https://github.com/gradio-app/gradio/raw/main/demo/model3D/files/Duck.glb\n", "!wget -q -O files/Fox.gltf https://github.com/gradio-app/gradio/raw/main/demo/model3D/files/Fox.gltf\n", "!wget -q -O files/face.obj https://github.com/gradio-app/gradio/raw/main/demo/model3D/files/face.obj\n", "!wget -q -O files/source.txt https://github.com/gradio-app/gradio/raw/main/demo/model3D/files/source.txt"]}, {"cell_type": "code", "execution_count": null, "id": "44380577570523278879349135829904343037", "metadata": {}, "outputs": [], "source": ["import gradio as gr\n", "import os\n", "\n", "\n", "def load_mesh(mesh_file_name):\n", " return mesh_file_name\n", "\n", "\n", "demo = gr.Interface(\n", " fn=load_mesh,\n", " inputs=gr.Model3D(),\n", " outputs=gr.Model3D(\n", " clear_color=[0.0, 0.0, 0.0, 0.0], label=\"3D Model\"),\n", " examples=[\n", " [os.path.join(os.path.abspath(''), \"files/Bunny.obj\")],\n", " [os.path.join(os.path.abspath(''), \"files/Duck.glb\")],\n", " [os.path.join(os.path.abspath(''), \"files/Fox.gltf\")],\n", " [os.path.join(os.path.abspath(''), \"files/face.obj\")],\n", " ],\n", ")\n", "\n", "if __name__ == \"__main__\":\n", " demo.launch()\n"]}], "metadata": {}, "nbformat": 4, "nbformat_minor": 5} +>>>>>>> main diff --git a/demo/model3D/run.py b/demo/model3D/run.py index 5a765cb19078..e26752f8d5dd 100644 --- a/demo/model3D/run.py +++ b/demo/model3D/run.py @@ -17,6 +17,7 @@ def load_mesh(mesh_file_name): [os.path.join(os.path.dirname(__file__), "files/Fox.gltf")], [os.path.join(os.path.dirname(__file__), "files/face.obj")], ], + cache_examples=True ) if __name__ == "__main__": diff --git a/demo/on_listener_basic/run.ipynb b/demo/on_listener_basic/run.ipynb index d3cc658c5bb7..8f78c318b40a 100644 --- a/demo/on_listener_basic/run.ipynb +++ b/demo/on_listener_basic/run.ipynb @@ -1 +1,5 @@ -{"cells": [{"cell_type": "markdown", "id": "302934307671667531413257853548643485645", "metadata": {}, "source": ["# Gradio Demo: on_listener_basic"]}, {"cell_type": "code", "execution_count": null, "id": "272996653310673477252411125948039410165", "metadata": {}, "outputs": [], "source": ["!pip install -q gradio "]}, {"cell_type": "code", "execution_count": null, "id": "288918539441861185822528903084949547379", "metadata": {}, "outputs": [], "source": ["import gradio as gr\n", "\n", "with gr.Blocks() as demo:\n", " name = gr.Textbox(label=\"Name\")\n", " output = gr.Textbox(label=\"Output Box\")\n", " greet_btn = gr.Button(\"Greet\")\n", "\n", " def greet(name):\n", " return \"Hello \" + name + \"!\"\n", "\n", " gr.on(\n", " triggers=[name.submit, greet_btn.click],\n", " fn=greet,\n", " inputs=name,\n", " outputs=output,\n", " )\n", "\n", "\n", "if __name__ == \"__main__\":\n", " demo.launch()\n"]}], "metadata": {}, "nbformat": 4, "nbformat_minor": 5} \ No newline at end of file +<<<<<<< HEAD +{"cells": [{"cell_type": "markdown", "id": 302934307671667531413257853548643485645, "metadata": {}, "source": ["# Gradio Demo: on_listener_basic"]}, {"cell_type": "code", "execution_count": null, "id": 272996653310673477252411125948039410165, "metadata": {}, "outputs": [], "source": ["!pip install -q gradio "]}, {"cell_type": "code", "execution_count": null, "id": 288918539441861185822528903084949547379, "metadata": {}, "outputs": [], "source": ["import gradio as gr\n", "\n", "with gr.Blocks() as demo:\n", " name = gr.Textbox(label=\"Name\")\n", " output = gr.Textbox(label=\"Output Box\")\n", " greet_btn = gr.Button(\"Greet\")\n", "\n", " def greet(name):\n", " return \"Hello \" + name + \"!\"\n", "\n", " gr.on(\n", " triggers=[name.submit, greet_btn.click],\n", " fn=greet,\n", " inputs=name,\n", " outputs=output,\n", " )\n", "\n", "\n", "if __name__ == \"__main__\":\n", " demo.launch()\n"]}], "metadata": {}, "nbformat": 4, "nbformat_minor": 5} +======= +{"cells": [{"cell_type": "markdown", "id": "302934307671667531413257853548643485645", "metadata": {}, "source": ["# Gradio Demo: on_listener_basic"]}, {"cell_type": "code", "execution_count": null, "id": "272996653310673477252411125948039410165", "metadata": {}, "outputs": [], "source": ["!pip install -q gradio "]}, {"cell_type": "code", "execution_count": null, "id": "288918539441861185822528903084949547379", "metadata": {}, "outputs": [], "source": ["import gradio as gr\n", "\n", "with gr.Blocks() as demo:\n", " name = gr.Textbox(label=\"Name\")\n", " output = gr.Textbox(label=\"Output Box\")\n", " greet_btn = gr.Button(\"Greet\")\n", "\n", " def greet(name):\n", " return \"Hello \" + name + \"!\"\n", "\n", " gr.on(\n", " triggers=[name.submit, greet_btn.click],\n", " fn=greet,\n", " inputs=name,\n", " outputs=output,\n", " )\n", "\n", "\n", "if __name__ == \"__main__\":\n", " demo.launch()\n"]}], "metadata": {}, "nbformat": 4, "nbformat_minor": 5} +>>>>>>> main diff --git a/demo/on_listener_decorator/run.ipynb b/demo/on_listener_decorator/run.ipynb index 1483324520b2..7091592bf529 100644 --- a/demo/on_listener_decorator/run.ipynb +++ b/demo/on_listener_decorator/run.ipynb @@ -1 +1,5 @@ -{"cells": [{"cell_type": "markdown", "id": "302934307671667531413257853548643485645", "metadata": {}, "source": ["# Gradio Demo: on_listener_decorator"]}, {"cell_type": "code", "execution_count": null, "id": "272996653310673477252411125948039410165", "metadata": {}, "outputs": [], "source": ["!pip install -q gradio "]}, {"cell_type": "code", "execution_count": null, "id": "288918539441861185822528903084949547379", "metadata": {}, "outputs": [], "source": ["import gradio as gr\n", "\n", "with gr.Blocks() as demo:\n", " name = gr.Textbox(label=\"Name\")\n", " output = gr.Textbox(label=\"Output Box\")\n", " greet_btn = gr.Button(\"Greet\")\n", "\n", " @gr.on(triggers=[name.submit, greet_btn.click], inputs=name, outputs=output)\n", " def greet(name):\n", " return \"Hello \" + name + \"!\"\n", "\n", "\n", "if __name__ == \"__main__\":\n", " demo.launch()\n"]}], "metadata": {}, "nbformat": 4, "nbformat_minor": 5} \ No newline at end of file +<<<<<<< HEAD +{"cells": [{"cell_type": "markdown", "id": 302934307671667531413257853548643485645, "metadata": {}, "source": ["# Gradio Demo: on_listener_decorator"]}, {"cell_type": "code", "execution_count": null, "id": 272996653310673477252411125948039410165, "metadata": {}, "outputs": [], "source": ["!pip install -q gradio "]}, {"cell_type": "code", "execution_count": null, "id": 288918539441861185822528903084949547379, "metadata": {}, "outputs": [], "source": ["import gradio as gr\n", "\n", "with gr.Blocks() as demo:\n", " name = gr.Textbox(label=\"Name\")\n", " output = gr.Textbox(label=\"Output Box\")\n", " greet_btn = gr.Button(\"Greet\")\n", "\n", " @gr.on(triggers=[name.submit, greet_btn.click], inputs=name, outputs=output)\n", " def greet(name):\n", " return \"Hello \" + name + \"!\"\n", "\n", "\n", "if __name__ == \"__main__\":\n", " demo.launch()\n"]}], "metadata": {}, "nbformat": 4, "nbformat_minor": 5} +======= +{"cells": [{"cell_type": "markdown", "id": "302934307671667531413257853548643485645", "metadata": {}, "source": ["# Gradio Demo: on_listener_decorator"]}, {"cell_type": "code", "execution_count": null, "id": "272996653310673477252411125948039410165", "metadata": {}, "outputs": [], "source": ["!pip install -q gradio "]}, {"cell_type": "code", "execution_count": null, "id": "288918539441861185822528903084949547379", "metadata": {}, "outputs": [], "source": ["import gradio as gr\n", "\n", "with gr.Blocks() as demo:\n", " name = gr.Textbox(label=\"Name\")\n", " output = gr.Textbox(label=\"Output Box\")\n", " greet_btn = gr.Button(\"Greet\")\n", "\n", " @gr.on(triggers=[name.submit, greet_btn.click], inputs=name, outputs=output)\n", " def greet(name):\n", " return \"Hello \" + name + \"!\"\n", "\n", "\n", "if __name__ == \"__main__\":\n", " demo.launch()\n"]}], "metadata": {}, "nbformat": 4, "nbformat_minor": 5} +>>>>>>> main diff --git a/demo/on_listener_live/run.ipynb b/demo/on_listener_live/run.ipynb index e6a97f9293e9..c119a21a61fd 100644 --- a/demo/on_listener_live/run.ipynb +++ b/demo/on_listener_live/run.ipynb @@ -1 +1,5 @@ -{"cells": [{"cell_type": "markdown", "id": "302934307671667531413257853548643485645", "metadata": {}, "source": ["# Gradio Demo: on_listener_live"]}, {"cell_type": "code", "execution_count": null, "id": "272996653310673477252411125948039410165", "metadata": {}, "outputs": [], "source": ["!pip install -q gradio "]}, {"cell_type": "code", "execution_count": null, "id": "288918539441861185822528903084949547379", "metadata": {}, "outputs": [], "source": ["import gradio as gr\n", "\n", "with gr.Blocks() as demo:\n", " with gr.Row():\n", " num1 = gr.Slider(1, 10)\n", " num2 = gr.Slider(1, 10)\n", " num3 = gr.Slider(1, 10)\n", " output = gr.Number(label=\"Sum\")\n", "\n", " @gr.on(inputs=[num1, num2, num3], outputs=output)\n", " def sum(a, b, c):\n", " return a + b + c\n", "\n", "\n", "if __name__ == \"__main__\":\n", " demo.launch()\n"]}], "metadata": {}, "nbformat": 4, "nbformat_minor": 5} \ No newline at end of file +<<<<<<< HEAD +{"cells": [{"cell_type": "markdown", "id": 302934307671667531413257853548643485645, "metadata": {}, "source": ["# Gradio Demo: on_listener_live"]}, {"cell_type": "code", "execution_count": null, "id": 272996653310673477252411125948039410165, "metadata": {}, "outputs": [], "source": ["!pip install -q gradio "]}, {"cell_type": "code", "execution_count": null, "id": 288918539441861185822528903084949547379, "metadata": {}, "outputs": [], "source": ["import gradio as gr\n", "\n", "with gr.Blocks() as demo:\n", " with gr.Row():\n", " num1 = gr.Slider(1, 10)\n", " num2 = gr.Slider(1, 10)\n", " num3 = gr.Slider(1, 10)\n", " output = gr.Number(label=\"Sum\")\n", "\n", " @gr.on(inputs=[num1, num2, num3], outputs=output)\n", " def sum(a, b, c):\n", " return a + b + c\n", "\n", "\n", "if __name__ == \"__main__\":\n", " demo.launch()\n"]}], "metadata": {}, "nbformat": 4, "nbformat_minor": 5} +======= +{"cells": [{"cell_type": "markdown", "id": "302934307671667531413257853548643485645", "metadata": {}, "source": ["# Gradio Demo: on_listener_live"]}, {"cell_type": "code", "execution_count": null, "id": "272996653310673477252411125948039410165", "metadata": {}, "outputs": [], "source": ["!pip install -q gradio "]}, {"cell_type": "code", "execution_count": null, "id": "288918539441861185822528903084949547379", "metadata": {}, "outputs": [], "source": ["import gradio as gr\n", "\n", "with gr.Blocks() as demo:\n", " with gr.Row():\n", " num1 = gr.Slider(1, 10)\n", " num2 = gr.Slider(1, 10)\n", " num3 = gr.Slider(1, 10)\n", " output = gr.Number(label=\"Sum\")\n", "\n", " @gr.on(inputs=[num1, num2, num3], outputs=output)\n", " def sum(a, b, c):\n", " return a + b + c\n", "\n", "\n", "if __name__ == \"__main__\":\n", " demo.launch()\n"]}], "metadata": {}, "nbformat": 4, "nbformat_minor": 5} +>>>>>>> main diff --git a/demo/stable-diffusion/run.ipynb b/demo/stable-diffusion/run.ipynb index 95d61e179903..a059ed9ddf3e 100644 --- a/demo/stable-diffusion/run.ipynb +++ b/demo/stable-diffusion/run.ipynb @@ -1 +1,5 @@ -{"cells": [{"cell_type": "markdown", "id": "302934307671667531413257853548643485645", "metadata": {}, "source": ["# Gradio Demo: stable-diffusion\n", "### Note: This is a simplified version of the code needed to create the Stable Diffusion demo. See full code here: https://hf.co/spaces/stabilityai/stable-diffusion/tree/main\n", " "]}, {"cell_type": "code", "execution_count": null, "id": "272996653310673477252411125948039410165", "metadata": {}, "outputs": [], "source": ["!pip install -q gradio diffusers transformers nvidia-ml-py3 ftfy torch"]}, {"cell_type": "code", "execution_count": null, "id": "288918539441861185822528903084949547379", "metadata": {}, "outputs": [], "source": ["import gradio as gr\n", "import torch\n", "from diffusers import StableDiffusionPipeline\n", "from PIL import Image\n", "import os\n", "\n", "auth_token = os.getenv(\"auth_token\")\n", "model_id = \"CompVis/stable-diffusion-v1-4\"\n", "device = \"cpu\"\n", "pipe = StableDiffusionPipeline.from_pretrained(\n", " model_id, use_auth_token=auth_token, revision=\"fp16\", torch_dtype=torch.float16\n", ")\n", "pipe = pipe.to(device)\n", "\n", "\n", "def infer(prompt, samples, steps, scale, seed):\n", " generator = torch.Generator(device=device).manual_seed(seed)\n", " images_list = pipe(\n", " [prompt] * samples,\n", " num_inference_steps=steps,\n", " guidance_scale=scale,\n", " generator=generator,\n", " )\n", " images = []\n", " safe_image = Image.open(r\"unsafe.png\")\n", " for i, image in enumerate(images_list[\"sample\"]):\n", " if images_list[\"nsfw_content_detected\"][i]:\n", " images.append(safe_image)\n", " else:\n", " images.append(image)\n", " return images\n", "\n", "\n", "block = gr.Blocks()\n", "\n", "with block:\n", " with gr.Group():\n", " with gr.Row():\n", " text = gr.Textbox(\n", " label=\"Enter your prompt\",\n", " max_lines=1,\n", " placeholder=\"Enter your prompt\",\n", " container=False,\n", " )\n", " btn = gr.Button(\"Generate image\")\n", " gallery = gr.Gallery(\n", " label=\"Generated images\",\n", " show_label=False,\n", " elem_id=\"gallery\",\n", " columns=[2],\n", " height=\"auto\",\n", " )\n", "\n", " advanced_button = gr.Button(\"Advanced options\", elem_id=\"advanced-btn\")\n", "\n", " with gr.Row(elem_id=\"advanced-options\"):\n", " samples = gr.Slider(label=\"Images\", minimum=1, maximum=4, value=4, step=1)\n", " steps = gr.Slider(label=\"Steps\", minimum=1, maximum=50, value=45, step=1)\n", " scale = gr.Slider(\n", " label=\"Guidance Scale\", minimum=0, maximum=50, value=7.5, step=0.1\n", " )\n", " seed = gr.Slider(\n", " label=\"Seed\",\n", " minimum=0,\n", " maximum=2147483647,\n", " step=1,\n", " randomize=True,\n", " )\n", " gr.on([text.submit, btn.click], infer, inputs=[text, samples, steps, scale, seed], outputs=gallery)\n", " advanced_button.click(\n", " None,\n", " [],\n", " text,\n", " )\n", "\n", "block.launch()\n"]}], "metadata": {}, "nbformat": 4, "nbformat_minor": 5} \ No newline at end of file +<<<<<<< HEAD +{"cells": [{"cell_type": "markdown", "id": 302934307671667531413257853548643485645, "metadata": {}, "source": ["# Gradio Demo: stable-diffusion\n", "### Note: This is a simplified version of the code needed to create the Stable Diffusion demo. See full code here: https://hf.co/spaces/stabilityai/stable-diffusion/tree/main\n", " "]}, {"cell_type": "code", "execution_count": null, "id": 272996653310673477252411125948039410165, "metadata": {}, "outputs": [], "source": ["!pip install -q gradio diffusers transformers nvidia-ml-py3 ftfy torch"]}, {"cell_type": "code", "execution_count": null, "id": 288918539441861185822528903084949547379, "metadata": {}, "outputs": [], "source": ["import gradio as gr\n", "import torch\n", "from diffusers import StableDiffusionPipeline\n", "from PIL import Image\n", "import os\n", "\n", "auth_token = os.getenv(\"auth_token\")\n", "model_id = \"CompVis/stable-diffusion-v1-4\"\n", "device = \"cpu\"\n", "pipe = StableDiffusionPipeline.from_pretrained(\n", " model_id, use_auth_token=auth_token, revision=\"fp16\", torch_dtype=torch.float16\n", ")\n", "pipe = pipe.to(device)\n", "\n", "\n", "def infer(prompt, samples, steps, scale, seed):\n", " generator = torch.Generator(device=device).manual_seed(seed)\n", " images_list = pipe(\n", " [prompt] * samples,\n", " num_inference_steps=steps,\n", " guidance_scale=scale,\n", " generator=generator,\n", " )\n", " images = []\n", " safe_image = Image.open(r\"unsafe.png\")\n", " for i, image in enumerate(images_list[\"sample\"]):\n", " if images_list[\"nsfw_content_detected\"][i]:\n", " images.append(safe_image)\n", " else:\n", " images.append(image)\n", " return images\n", "\n", "\n", "block = gr.Blocks()\n", "\n", "with block:\n", " with gr.Group():\n", " with gr.Row():\n", " text = gr.Textbox(\n", " label=\"Enter your prompt\",\n", " max_lines=1,\n", " placeholder=\"Enter your prompt\",\n", " container=False,\n", " )\n", " btn = gr.Button(\"Generate image\")\n", " gallery = gr.Gallery(\n", " label=\"Generated images\",\n", " show_label=False,\n", " elem_id=\"gallery\",\n", " columns=[2],\n", " height=\"auto\",\n", " )\n", "\n", " advanced_button = gr.Button(\"Advanced options\", elem_id=\"advanced-btn\")\n", "\n", " with gr.Row(elem_id=\"advanced-options\"):\n", " samples = gr.Slider(label=\"Images\", minimum=1, maximum=4, value=4, step=1)\n", " steps = gr.Slider(label=\"Steps\", minimum=1, maximum=50, value=45, step=1)\n", " scale = gr.Slider(\n", " label=\"Guidance Scale\", minimum=0, maximum=50, value=7.5, step=0.1\n", " )\n", " seed = gr.Slider(\n", " label=\"Seed\",\n", " minimum=0,\n", " maximum=2147483647,\n", " step=1,\n", " randomize=True,\n", " )\n", " gr.on([text.submit, btn.click], infer, inputs=[text, samples, steps, scale, seed], outputs=gallery)\n", " advanced_button.click(\n", " None,\n", " [],\n", " text,\n", " )\n", "\n", "block.launch()\n"]}], "metadata": {}, "nbformat": 4, "nbformat_minor": 5} +======= +{"cells": [{"cell_type": "markdown", "id": "302934307671667531413257853548643485645", "metadata": {}, "source": ["# Gradio Demo: stable-diffusion\n", "### Note: This is a simplified version of the code needed to create the Stable Diffusion demo. See full code here: https://hf.co/spaces/stabilityai/stable-diffusion/tree/main\n", " "]}, {"cell_type": "code", "execution_count": null, "id": "272996653310673477252411125948039410165", "metadata": {}, "outputs": [], "source": ["!pip install -q gradio diffusers transformers nvidia-ml-py3 ftfy torch"]}, {"cell_type": "code", "execution_count": null, "id": "288918539441861185822528903084949547379", "metadata": {}, "outputs": [], "source": ["import gradio as gr\n", "import torch\n", "from diffusers import StableDiffusionPipeline\n", "from PIL import Image\n", "import os\n", "\n", "auth_token = os.getenv(\"auth_token\")\n", "model_id = \"CompVis/stable-diffusion-v1-4\"\n", "device = \"cpu\"\n", "pipe = StableDiffusionPipeline.from_pretrained(\n", " model_id, use_auth_token=auth_token, revision=\"fp16\", torch_dtype=torch.float16\n", ")\n", "pipe = pipe.to(device)\n", "\n", "\n", "def infer(prompt, samples, steps, scale, seed):\n", " generator = torch.Generator(device=device).manual_seed(seed)\n", " images_list = pipe(\n", " [prompt] * samples,\n", " num_inference_steps=steps,\n", " guidance_scale=scale,\n", " generator=generator,\n", " )\n", " images = []\n", " safe_image = Image.open(r\"unsafe.png\")\n", " for i, image in enumerate(images_list[\"sample\"]):\n", " if images_list[\"nsfw_content_detected\"][i]:\n", " images.append(safe_image)\n", " else:\n", " images.append(image)\n", " return images\n", "\n", "\n", "block = gr.Blocks()\n", "\n", "with block:\n", " with gr.Group():\n", " with gr.Row():\n", " text = gr.Textbox(\n", " label=\"Enter your prompt\",\n", " max_lines=1,\n", " placeholder=\"Enter your prompt\",\n", " container=False,\n", " )\n", " btn = gr.Button(\"Generate image\")\n", " gallery = gr.Gallery(\n", " label=\"Generated images\",\n", " show_label=False,\n", " elem_id=\"gallery\",\n", " columns=[2],\n", " height=\"auto\",\n", " )\n", "\n", " advanced_button = gr.Button(\"Advanced options\", elem_id=\"advanced-btn\")\n", "\n", " with gr.Row(elem_id=\"advanced-options\"):\n", " samples = gr.Slider(label=\"Images\", minimum=1, maximum=4, value=4, step=1)\n", " steps = gr.Slider(label=\"Steps\", minimum=1, maximum=50, value=45, step=1)\n", " scale = gr.Slider(\n", " label=\"Guidance Scale\", minimum=0, maximum=50, value=7.5, step=0.1\n", " )\n", " seed = gr.Slider(\n", " label=\"Seed\",\n", " minimum=0,\n", " maximum=2147483647,\n", " step=1,\n", " randomize=True,\n", " )\n", " gr.on([text.submit, btn.click], infer, inputs=[text, samples, steps, scale, seed], outputs=gallery)\n", " advanced_button.click(\n", " None,\n", " [],\n", " text,\n", " )\n", "\n", "block.launch()\n"]}], "metadata": {}, "nbformat": 4, "nbformat_minor": 5} +>>>>>>> main diff --git a/demo/stt_or_tts/run.ipynb b/demo/stt_or_tts/run.ipynb index ae4ef31d6ae0..ad53035e0e6f 100644 --- a/demo/stt_or_tts/run.ipynb +++ b/demo/stt_or_tts/run.ipynb @@ -1 +1,5 @@ -{"cells": [{"cell_type": "markdown", "id": "302934307671667531413257853548643485645", "metadata": {}, "source": ["# Gradio Demo: stt_or_tts"]}, {"cell_type": "code", "execution_count": null, "id": "272996653310673477252411125948039410165", "metadata": {}, "outputs": [], "source": ["!pip install -q gradio "]}, {"cell_type": "code", "execution_count": null, "id": "288918539441861185822528903084949547379", "metadata": {}, "outputs": [], "source": ["import gradio as gr\n", "\n", "tts_examples = [\n", " \"I love learning machine learning\",\n", " \"How do you do?\",\n", "]\n", "\n", "tts_demo = gr.load(\n", " \"huggingface/facebook/fastspeech2-en-ljspeech\",\n", " title=None,\n", " examples=tts_examples,\n", " description=\"Give me something to say!\",\n", ")\n", "\n", "stt_demo = gr.load(\n", " \"huggingface/facebook/wav2vec2-base-960h\",\n", " title=None,\n", " inputs=\"mic\",\n", " description=\"Let me try to guess what you're saying!\",\n", ")\n", "\n", "demo = gr.TabbedInterface([tts_demo, stt_demo], [\"Text-to-speech\", \"Speech-to-text\"])\n", "\n", "if __name__ == \"__main__\":\n", " demo.launch()\n"]}], "metadata": {}, "nbformat": 4, "nbformat_minor": 5} \ No newline at end of file +<<<<<<< HEAD +{"cells": [{"cell_type": "markdown", "id": 302934307671667531413257853548643485645, "metadata": {}, "source": ["# Gradio Demo: stt_or_tts"]}, {"cell_type": "code", "execution_count": null, "id": 272996653310673477252411125948039410165, "metadata": {}, "outputs": [], "source": ["!pip install -q gradio "]}, {"cell_type": "code", "execution_count": null, "id": 288918539441861185822528903084949547379, "metadata": {}, "outputs": [], "source": ["import gradio as gr\n", "\n", "tts_examples = [\n", " \"I love learning machine learning\",\n", " \"How do you do?\",\n", "]\n", "\n", "tts_demo = gr.load(\n", " \"huggingface/facebook/fastspeech2-en-ljspeech\",\n", " title=None,\n", " examples=tts_examples,\n", " description=\"Give me something to say!\",\n", " cache_examples=False\n", ")\n", "\n", "stt_demo = gr.load(\n", " \"huggingface/facebook/wav2vec2-base-960h\",\n", " title=None,\n", " inputs=\"mic\",\n", " description=\"Let me try to guess what you're saying!\",\n", ")\n", "\n", "demo = gr.TabbedInterface([tts_demo, stt_demo], [\"Text-to-speech\", \"Speech-to-text\"])\n", "\n", "if __name__ == \"__main__\":\n", " demo.launch()\n"]}], "metadata": {}, "nbformat": 4, "nbformat_minor": 5} +======= +{"cells": [{"cell_type": "markdown", "id": "302934307671667531413257853548643485645", "metadata": {}, "source": ["# Gradio Demo: stt_or_tts"]}, {"cell_type": "code", "execution_count": null, "id": "272996653310673477252411125948039410165", "metadata": {}, "outputs": [], "source": ["!pip install -q gradio "]}, {"cell_type": "code", "execution_count": null, "id": "288918539441861185822528903084949547379", "metadata": {}, "outputs": [], "source": ["import gradio as gr\n", "\n", "tts_examples = [\n", " \"I love learning machine learning\",\n", " \"How do you do?\",\n", "]\n", "\n", "tts_demo = gr.load(\n", " \"huggingface/facebook/fastspeech2-en-ljspeech\",\n", " title=None,\n", " examples=tts_examples,\n", " description=\"Give me something to say!\",\n", ")\n", "\n", "stt_demo = gr.load(\n", " \"huggingface/facebook/wav2vec2-base-960h\",\n", " title=None,\n", " inputs=\"mic\",\n", " description=\"Let me try to guess what you're saying!\",\n", ")\n", "\n", "demo = gr.TabbedInterface([tts_demo, stt_demo], [\"Text-to-speech\", \"Speech-to-text\"])\n", "\n", "if __name__ == \"__main__\":\n", " demo.launch()\n"]}], "metadata": {}, "nbformat": 4, "nbformat_minor": 5} +>>>>>>> main diff --git a/demo/stt_or_tts/run.py b/demo/stt_or_tts/run.py index ed6a1adc32cf..98c97dd37611 100644 --- a/demo/stt_or_tts/run.py +++ b/demo/stt_or_tts/run.py @@ -10,6 +10,7 @@ title=None, examples=tts_examples, description="Give me something to say!", + cache_examples=False ) stt_demo = gr.load( diff --git a/demo/timeseries_component/run.ipynb b/demo/timeseries_component/run.ipynb deleted file mode 100644 index 5cff7ead96b5..000000000000 --- a/demo/timeseries_component/run.ipynb +++ /dev/null @@ -1 +0,0 @@ -{"cells": [{"cell_type": "markdown", "id": "302934307671667531413257853548643485645", "metadata": {}, "source": ["# Gradio Demo: timeseries_component"]}, {"cell_type": "code", "execution_count": null, "id": "272996653310673477252411125948039410165", "metadata": {}, "outputs": [], "source": ["!pip install -q gradio "]}, {"cell_type": "code", "execution_count": null, "id": "288918539441861185822528903084949547379", "metadata": {}, "outputs": [], "source": ["import gradio as gr \n", "\n", "with gr.Blocks() as demo:\n", " gr.Timeseries()\n", "\n", "demo.launch()"]}], "metadata": {}, "nbformat": 4, "nbformat_minor": 5} \ No newline at end of file diff --git a/demo/timeseries_component/run.py b/demo/timeseries_component/run.py deleted file mode 100644 index 0e65d8907fed..000000000000 --- a/demo/timeseries_component/run.py +++ /dev/null @@ -1,6 +0,0 @@ -import gradio as gr - -with gr.Blocks() as demo: - gr.Timeseries() - -demo.launch() \ No newline at end of file diff --git a/demo/video_component/run.ipynb b/demo/video_component/run.ipynb index 290e9a4d2121..4e4bccc3eaac 100644 --- a/demo/video_component/run.ipynb +++ b/demo/video_component/run.ipynb @@ -1 +1,5 @@ -{"cells": [{"cell_type": "markdown", "id": "302934307671667531413257853548643485645", "metadata": {}, "source": ["# Gradio Demo: video_component"]}, {"cell_type": "code", "execution_count": null, "id": "272996653310673477252411125948039410165", "metadata": {}, "outputs": [], "source": ["!pip install -q gradio "]}, {"cell_type": "code", "execution_count": null, "id": "288918539441861185822528903084949547379", "metadata": {}, "outputs": [], "source": ["# Downloading files from the demo repo\n", "import os\n", "os.mkdir('files')\n", "!wget -q -O files/a.mp4 https://github.com/gradio-app/gradio/raw/main/demo/video_component/files/a.mp4\n", "!wget -q -O files/b.mp4 https://github.com/gradio-app/gradio/raw/main/demo/video_component/files/b.mp4\n", "!wget -q -O files/world.mp4 https://github.com/gradio-app/gradio/raw/main/demo/video_component/files/world.mp4"]}, {"cell_type": "code", "execution_count": null, "id": "44380577570523278879349135829904343037", "metadata": {}, "outputs": [], "source": ["import gradio as gr\n", "import os\n", "\n", "\n", "a = os.path.join(os.path.abspath(''), \"files/world.mp4\") # Video\n", "b = os.path.join(os.path.abspath(''), \"files/a.mp4\") # Video\n", "c = os.path.join(os.path.abspath(''), \"files/b.mp4\") # Video\n", "\n", "\n", "demo = gr.Interface(\n", " fn=lambda x: x,\n", " inputs=gr.Video(type=\"file\"),\n", " outputs=gr.Video(),\n", " examples=[\n", " [a],\n", " [b],\n", " [c],\n", " ],\n", ")\n", "\n", "if __name__ == \"__main__\":\n", " demo.launch()\n"]}], "metadata": {}, "nbformat": 4, "nbformat_minor": 5} \ No newline at end of file +<<<<<<< HEAD +{"cells": [{"cell_type": "markdown", "id": 302934307671667531413257853548643485645, "metadata": {}, "source": ["# Gradio Demo: video_component"]}, {"cell_type": "code", "execution_count": null, "id": 272996653310673477252411125948039410165, "metadata": {}, "outputs": [], "source": ["!pip install -q gradio "]}, {"cell_type": "code", "execution_count": null, "id": 288918539441861185822528903084949547379, "metadata": {}, "outputs": [], "source": ["# Downloading files from the demo repo\n", "import os\n", "os.mkdir('files')\n", "!wget -q -O files/a.mp4 https://github.com/gradio-app/gradio/raw/main/demo/video_component/files/a.mp4\n", "!wget -q -O files/b.mp4 https://github.com/gradio-app/gradio/raw/main/demo/video_component/files/b.mp4\n", "!wget -q -O files/world.mp4 https://github.com/gradio-app/gradio/raw/main/demo/video_component/files/world.mp4"]}, {"cell_type": "code", "execution_count": null, "id": 44380577570523278879349135829904343037, "metadata": {}, "outputs": [], "source": ["import gradio as gr\n", "import os\n", "\n", "\n", "a = os.path.join(os.path.abspath(''), \"files/world.mp4\") # Video\n", "b = os.path.join(os.path.abspath(''), \"files/a.mp4\") # Video\n", "c = os.path.join(os.path.abspath(''), \"files/b.mp4\") # Video\n", "\n", "\n", "demo = gr.Interface(\n", " fn=lambda x: x,\n", " inputs=gr.Video(type=\"file\"),\n", " outputs=gr.Video(),\n", " examples=[\n", " [a],\n", " [b],\n", " [c],\n", " ],\n", " cache_examples=True\n", ")\n", "\n", "if __name__ == \"__main__\":\n", " demo.launch()\n"]}], "metadata": {}, "nbformat": 4, "nbformat_minor": 5} +======= +{"cells": [{"cell_type": "markdown", "id": "302934307671667531413257853548643485645", "metadata": {}, "source": ["# Gradio Demo: video_component"]}, {"cell_type": "code", "execution_count": null, "id": "272996653310673477252411125948039410165", "metadata": {}, "outputs": [], "source": ["!pip install -q gradio "]}, {"cell_type": "code", "execution_count": null, "id": "288918539441861185822528903084949547379", "metadata": {}, "outputs": [], "source": ["# Downloading files from the demo repo\n", "import os\n", "os.mkdir('files')\n", "!wget -q -O files/a.mp4 https://github.com/gradio-app/gradio/raw/main/demo/video_component/files/a.mp4\n", "!wget -q -O files/b.mp4 https://github.com/gradio-app/gradio/raw/main/demo/video_component/files/b.mp4\n", "!wget -q -O files/world.mp4 https://github.com/gradio-app/gradio/raw/main/demo/video_component/files/world.mp4"]}, {"cell_type": "code", "execution_count": null, "id": "44380577570523278879349135829904343037", "metadata": {}, "outputs": [], "source": ["import gradio as gr\n", "import os\n", "\n", "\n", "a = os.path.join(os.path.abspath(''), \"files/world.mp4\") # Video\n", "b = os.path.join(os.path.abspath(''), \"files/a.mp4\") # Video\n", "c = os.path.join(os.path.abspath(''), \"files/b.mp4\") # Video\n", "\n", "\n", "demo = gr.Interface(\n", " fn=lambda x: x,\n", " inputs=gr.Video(type=\"file\"),\n", " outputs=gr.Video(),\n", " examples=[\n", " [a],\n", " [b],\n", " [c],\n", " ],\n", ")\n", "\n", "if __name__ == \"__main__\":\n", " demo.launch()\n"]}], "metadata": {}, "nbformat": 4, "nbformat_minor": 5} +>>>>>>> main diff --git a/demo/video_component/run.py b/demo/video_component/run.py index 254a1fcfbb27..5b3971ebc75f 100644 --- a/demo/video_component/run.py +++ b/demo/video_component/run.py @@ -16,6 +16,7 @@ [b], [c], ], + cache_examples=True ) if __name__ == "__main__": diff --git a/gradio/CHANGELOG.md b/gradio/CHANGELOG.md index 04b46b565b24..78bc3a913fbf 100644 --- a/gradio/CHANGELOG.md +++ b/gradio/CHANGELOG.md @@ -113,6 +113,72 @@ For more information check the [`FileExplorer` documentation](https://gradio.app ### Fixes - [#5625](https://github.com/gradio-app/gradio/pull/5625) [`9ccc4794a`](https://github.com/gradio-app/gradio/commit/9ccc4794a72ce8319417119f6c370e7af3ffca6d) - Use ContextVar instead of threading.local(). Thanks [@cbensimon](https://github.com/cbensimon)! +- [#5636](https://github.com/gradio-app/gradio/pull/5636) [`fb5964fb8`](https://github.com/gradio-app/gradio/commit/fb5964fb88082e7b956853b543c468116811cab9) - Fix bug in example cache loading event. Thanks [@freddyaboulton](https://github.com/freddyaboulton)! +- [#5633](https://github.com/gradio-app/gradio/pull/5633) [`341402337`](https://github.com/gradio-app/gradio/commit/34140233794c29d4722020e13c2d045da642dfae) - Allow Gradio apps containing `gr.Radio()`, `gr.Checkboxgroup()`, or `gr.Dropdown()` to be loaded with `gr.load()`. Thanks [@abidlabs](https://github.com/abidlabs)! +- [#5593](https://github.com/gradio-app/gradio/pull/5593) [`88d43bd12`](https://github.com/gradio-app/gradio/commit/88d43bd124792d216da445adef932a2b02f5f416) - Fixes avatar image in chatbot being squashed. Thanks [@dawoodkhan82](https://github.com/dawoodkhan82)! + +## 3.45.0-beta.8 + +### Features + +- [#5649](https://github.com/gradio-app/gradio/pull/5649) [`d56b355c1`](https://github.com/gradio-app/gradio/commit/d56b355c12ccdeeb8406a3520fecc15ae69d9141) - Fix front-end imports + other misc fixes. Thanks [@freddyaboulton](https://github.com/freddyaboulton)! +- [#5651](https://github.com/gradio-app/gradio/pull/5651) [`0ab84bf80`](https://github.com/gradio-app/gradio/commit/0ab84bf80f66c866327473d08fe5bdc8d32f155a) - Add overwrite flag to create command. Thanks [@freddyaboulton](https://github.com/freddyaboulton)! + +## 3.45.0-beta.7 + +### Features + +- [#5648](https://github.com/gradio-app/gradio/pull/5648) [`c573e2339`](https://github.com/gradio-app/gradio/commit/c573e2339b86c85b378dc349de5e9223a3c3b04a) - Publish all components to npm. Thanks [@freddyaboulton](https://github.com/freddyaboulton)! +- [#5637](https://github.com/gradio-app/gradio/pull/5637) [`670cfb75b`](https://github.com/gradio-app/gradio/commit/670cfb75b7cfd5a25a22c5aa307cd29c8879889e) - Some minor v4 fixes. Thanks [@freddyaboulton](https://github.com/freddyaboulton)! + +## 3.45.0-beta.6 + +### Features + +- [#5630](https://github.com/gradio-app/gradio/pull/5630) [`0b4fd5b6d`](https://github.com/gradio-app/gradio/commit/0b4fd5b6db96fc95a155e5e935e17e1ab11d1161) - Fix esbuild. Thanks [@pngwn](https://github.com/pngwn)! + +## 3.45.0-beta.5 + +### Features + +- [#5624](https://github.com/gradio-app/gradio/pull/5624) [`14fc612d8`](https://github.com/gradio-app/gradio/commit/14fc612d84bf6b1408eccd3a40fab41f25477571) - Fix esbuild. Thanks [@pngwn](https://github.com/pngwn)! + +## 3.45.0-beta.4 + +### Features + +- [#5620](https://github.com/gradio-app/gradio/pull/5620) [`c4c25ecdf`](https://github.com/gradio-app/gradio/commit/c4c25ecdf8c2fab5e3c41b519564e3b6a9ebfce3) - fix build and broken imports. Thanks [@pngwn](https://github.com/pngwn)! + +## 3.45.0-beta.3 + +### Features + +- [#5618](https://github.com/gradio-app/gradio/pull/5618) [`327cc4a6c`](https://github.com/gradio-app/gradio/commit/327cc4a6c1a213238cecd21f2b6c9cedc64bde5b) - Add docstring to trigger release. Thanks [@freddyaboulton](https://github.com/freddyaboulton)! + +## 3.45.0-beta.2 + +### Features + +- [#5615](https://github.com/gradio-app/gradio/pull/5615) [`142880ba5`](https://github.com/gradio-app/gradio/commit/142880ba589126d98da3d6a38866828864cc6b81) - Publish js theme. Thanks [@freddyaboulton](https://github.com/freddyaboulton)! +- [#5613](https://github.com/gradio-app/gradio/pull/5613) [`d0b22b6cf`](https://github.com/gradio-app/gradio/commit/d0b22b6cf4345ce9954b166f8b4278f8d3e24472) - backend linting. Thanks [@freddyaboulton](https://github.com/freddyaboulton)! + +## 3.45.0-beta.1 + +### Features + +- [#5610](https://github.com/gradio-app/gradio/pull/5610) [`73f2e8e7e`](https://github.com/gradio-app/gradio/commit/73f2e8e7e426e80e397b5bf23b3a64b0dd6f4e09) - Fix js deps in cli and add gradio-preview artifacts to build. Thanks [@freddyaboulton](https://github.com/freddyaboulton)! + +## 3.45.0-beta.0 + +### Features + +- [#5507](https://github.com/gradio-app/gradio/pull/5507) [`1385dc688`](https://github.com/gradio-app/gradio/commit/1385dc6881f2d8ae7a41106ec21d33e2ef04d6a9) - Custom components. Thanks [@pngwn](https://github.com/pngwn)! +- [#5498](https://github.com/gradio-app/gradio/pull/5498) [`681f10c31`](https://github.com/gradio-app/gradio/commit/681f10c315a75cc8cd0473c9a0167961af7696db) - release first version. Thanks [@pngwn](https://github.com/pngwn)! +- [#5589](https://github.com/gradio-app/gradio/pull/5589) [`af1b2f9ba`](https://github.com/gradio-app/gradio/commit/af1b2f9bafbacf2804fcfe68af6bb4b921442aca) - image fixes. Thanks [@pngwn](https://github.com/pngwn)! +- [#5240](https://github.com/gradio-app/gradio/pull/5240) [`da05e59a5`](https://github.com/gradio-app/gradio/commit/da05e59a53bbad15e5755a47f46685da18e1031e) - Cleanup of .update and .get_config per component. Thanks [@aliabid94](https://github.com/aliabid94)!/n get_config is removed, the config used is simply any attribute that is in the Block that shares a name with one of the constructor paramaters./n update is not removed for backwards compatibility, but deprecated. Instead return the component itself. Created a updateable decorator that simply checks to see if we're in an update, and if so, skips the constructor and wraps the args and kwargs in an update dictionary. easy peasy. + +### Fixes + - [#5602](https://github.com/gradio-app/gradio/pull/5602) [`54d21d3f1`](https://github.com/gradio-app/gradio/commit/54d21d3f18f2ddd4e796d149a0b41461f49c711b) - Ensure `HighlightedText` with `merge_elements` loads without a value. Thanks [@hannahblair](https://github.com/hannahblair)! - [#5636](https://github.com/gradio-app/gradio/pull/5636) [`fb5964fb8`](https://github.com/gradio-app/gradio/commit/fb5964fb88082e7b956853b543c468116811cab9) - Fix bug in example cache loading event. Thanks [@freddyaboulton](https://github.com/freddyaboulton)! - [#5633](https://github.com/gradio-app/gradio/pull/5633) [`341402337`](https://github.com/gradio-app/gradio/commit/34140233794c29d4722020e13c2d045da642dfae) - Allow Gradio apps containing `gr.Radio()`, `gr.Checkboxgroup()`, or `gr.Dropdown()` to be loaded with `gr.load()`. Thanks [@abidlabs](https://github.com/abidlabs)! diff --git a/gradio/__init__.py b/gradio/__init__.py index e615c9578207..7bda540a39db 100644 --- a/gradio/__init__.py +++ b/gradio/__init__.py @@ -1,13 +1,13 @@ import json import gradio.components as components -import gradio.inputs as inputs -import gradio.outputs as outputs +import gradio.layouts as layouts import gradio.processing_utils import gradio.templates import gradio.themes as themes from gradio.blocks import Blocks from gradio.chat_interface import ChatInterface +from gradio.cli import deploy from gradio.components import ( HTML, JSON, @@ -36,7 +36,6 @@ HighlightedText, Highlightedtext, Image, - Interpretation, Json, Label, LinePlot, @@ -53,15 +52,13 @@ StatusTracker, Text, Textbox, - TimeSeries, - Timeseries, UploadButton, Variable, Video, component, ) -from gradio.deploy_space import deploy -from gradio.events import LikeData, SelectData, on +from gradio.data_classes import FileData +from gradio.events import EventData, LikeData, SelectData, on from gradio.exceptions import Error from gradio.external import load from gradio.flagging import ( @@ -72,7 +69,6 @@ SimpleCSVLogger, ) from gradio.helpers import ( - EventData, Info, Progress, Warning, diff --git a/gradio/blocks.py b/gradio/blocks.py index 682485d9ed4a..2759dd604179 100644 --- a/gradio/blocks.py +++ b/gradio/blocks.py @@ -1,6 +1,7 @@ from __future__ import annotations import copy +import hashlib import inspect import json import os @@ -11,9 +12,7 @@ import time import warnings import webbrowser -from abc import abstractmethod from collections import defaultdict -from functools import wraps from pathlib import Path from types import ModuleType from typing import TYPE_CHECKING, Any, AsyncIterator, Callable, Literal, Sequence, cast @@ -21,16 +20,15 @@ import anyio import requests from anyio import CapacityLimiter -from gradio_client import serializing from gradio_client import utils as client_utils from gradio_client.documentation import document, set_documentation_group -from packaging import version from gradio import ( analytics, components, external, networking, + processing_utils, queueing, routes, strings, @@ -39,14 +37,16 @@ wasm_utils, ) from gradio.context import Context +from gradio.data_classes import FileData from gradio.deprecation import check_deprecated_parameters, warn_deprecation +from gradio.events import EventData, EventListener, EventListenerMethod from gradio.exceptions import ( DuplicateBlockError, InvalidApiNameError, InvalidBlockError, InvalidComponentError, ) -from gradio.helpers import EventData, create_tracker, skip, special_args +from gradio.helpers import create_tracker, skip, special_args from gradio.state_holder import SessionState from gradio.themes import Default as DefaultTheme from gradio.themes import ThemeClass as Theme @@ -77,8 +77,7 @@ if TYPE_CHECKING: # Only import for type checking (is False at runtime). from fastapi.applications import FastAPI - from gradio.components import Component - from gradio.events import EventListenerMethod + from gradio.components.base import Component BUILT_IN_THEMES: dict[str, Theme] = { t.name: t @@ -92,42 +91,6 @@ } -def in_event_listener(): - from gradio.context import LocalContext - - return LocalContext.in_event_listener.get() - - -def updateable(fn): - @wraps(fn) - def wrapper(*args, **kwargs): - fn_args = inspect.getfullargspec(fn).args - self = args[0] - for i, arg in enumerate(args): - if i == 0 or i >= len(fn_args): # skip self, *args - continue - arg_name = fn_args[i] - kwargs[arg_name] = arg - self.constructor_args = kwargs - if in_event_listener(): - return None - else: - return fn(self, **kwargs) - - return wrapper - - -updated_cls_set = set() - - -class Updateable: - def __new__(cls, *args, **kwargs): - if cls not in updated_cls_set: - cls.__init__ = updateable(cls.__init__) - updated_cls_set.add(cls) - return super().__new__(cls) - - class Block: def __init__( self, @@ -159,6 +122,16 @@ def __init__( self.render() check_deprecated_parameters(self.__class__.__name__, kwargs=kwargs) + @property + def skip_api(self): + return False + + @property + def events( + self, + ) -> list[EventListener]: + return getattr(self, "EVENTS", []) + def render(self): """ Adds self into appropriate BlockContext @@ -172,7 +145,7 @@ def render(self): if Context.root_block is not None: Context.root_block.blocks[self._id] = self self.is_rendered = True - if isinstance(self, components.IOComponent): + if isinstance(self, components.Component): Context.root_block.temp_file_sets.append(self.temp_files) return self @@ -218,10 +191,13 @@ def get_config(self): if hasattr(self, parameter.name): value = getattr(self, parameter.name) config[parameter.name] = value + for e in self.events: + to_add = e.config_data() + if to_add: + config = {**config, **to_add} return {**config, "root_url": self.root_url, "name": self.get_block_name()} @staticmethod - @abstractmethod def update(**kwargs) -> dict: return {} @@ -241,6 +217,24 @@ def __init__( self.children: list[Block] = [] Block.__init__(self, visible=visible, render=render, **kwargs) + TEMPLATE_DIR = "./templates/" + FRONTEND_DIR = "../../frontend/" + + @property + def skip_api(self): + return True + + @classmethod + def get_component_class_id(cls) -> str: + module_name = cls.__module__ + module_path = sys.modules[module_name].__file__ + module_hash = hashlib.md5(f"{cls.__name__}_{module_path}".encode()).hexdigest() + return module_hash + + @property + def component_class_id(self): + return self.get_component_class_id() + def add_child(self, child: Block): self.children.append(child) @@ -333,7 +327,9 @@ def __repr__(self): return str(self) -def postprocess_update_dict(block: Block, update_dict: dict, postprocess: bool = True): +def postprocess_update_dict( + block: Component | BlockContext, update_dict: dict, postprocess: bool = True +): """ Converts a dictionary of updates into a format that can be sent to the frontend. E.g. {"__type__": "update", "value": "2", "interactive": False} @@ -354,7 +350,7 @@ def postprocess_update_dict(block: Block, update_dict: dict, postprocess: bool = attr_dict["__type__"] = "update" attr_dict.pop("value", None) if "value" in update_dict: - if not isinstance(block, components.IOComponent): + if not isinstance(block, components.Component): raise InvalidComponentError( f"Component {block.__class__} does not support value" ) @@ -392,147 +388,6 @@ def convert_component_dict_to_list( return predictions -def get_api_info(config: dict, serialize: bool = True): - """ - Gets the information needed to generate the API docs from a Blocks config. - Parameters: - config: a Blocks config dictionary - serialize: If True, returns the serialized version of the typed information. If False, returns the raw version. - """ - api_info = {"named_endpoints": {}, "unnamed_endpoints": {}} - mode = config.get("mode", None) - after_new_format = version.parse(config.get("version", "2.0")) > version.Version( - "3.28.3" - ) - - for d, dependency in enumerate(config["dependencies"]): - dependency_info = {"parameters": [], "returns": []} - skip_endpoint = False - - inputs = dependency["inputs"] - for i in inputs: - for component in config["components"]: - if component["id"] == i: - break - else: - skip_endpoint = True # if component not found, skip endpoint - break - type = component["type"] - if type in client_utils.SKIP_COMPONENTS: - continue - if ( - not component.get("serializer") - and type not in serializing.COMPONENT_MAPPING - ): - skip_endpoint = True # if component not serializable, skip endpoint - break - if type in client_utils.SKIP_COMPONENTS: - continue - label = component["props"].get("label", f"parameter_{i}") - # The config has the most specific API info (taking into account the parameters - # of the component), so we use that if it exists. Otherwise, we fallback to the - # Serializer's API info. - serializer = serializing.COMPONENT_MAPPING[type]() - if component.get("api_info") and after_new_format: - info = component["api_info"] - example = component["example_inputs"]["serialized"] - else: - assert isinstance(serializer, serializing.Serializable) - info = serializer.api_info() - example = serializer.example_inputs()["raw"] - python_info = info["info"] - if serialize and info["serialized_info"]: - python_info = serializer.serialized_info() - if ( - isinstance(serializer, serializing.FileSerializable) - and component["props"].get("file_count", "single") != "single" - ): - python_info = serializer._multiple_file_serialized_info() - - python_type = client_utils.json_schema_to_python_type(python_info) - serializer_name = serializing.COMPONENT_MAPPING[type].__name__ - dependency_info["parameters"].append( - { - "label": label, - "type": info["info"], - "python_type": { - "type": python_type, - "description": python_info.get("description", ""), - }, - "component": type.capitalize(), - "example_input": example, - "serializer": serializer_name, - } - ) - - outputs = dependency["outputs"] - for o in outputs: - for component in config["components"]: - if component["id"] == o: - break - else: - skip_endpoint = True # if component not found, skip endpoint - break - type = component["type"] - if type in client_utils.SKIP_COMPONENTS: - continue - if ( - not component.get("serializer") - and type not in serializing.COMPONENT_MAPPING - ): - skip_endpoint = True # if component not serializable, skip endpoint - break - label = component["props"].get("label", f"value_{o}") - serializer = serializing.COMPONENT_MAPPING[type]() - if component.get("api_info") and after_new_format: - info = component["api_info"] - example = component["example_inputs"]["serialized"] - else: - assert isinstance(serializer, serializing.Serializable) - info = serializer.api_info() - example = serializer.example_inputs()["raw"] - python_info = info["info"] - if serialize and info["serialized_info"]: - python_info = serializer.serialized_info() - if ( - isinstance(serializer, serializing.FileSerializable) - and component["props"].get("file_count", "single") != "single" - ): - python_info = serializer._multiple_file_serialized_info() - python_type = client_utils.json_schema_to_python_type(python_info) - serializer_name = serializing.COMPONENT_MAPPING[type].__name__ - dependency_info["returns"].append( - { - "label": label, - "type": info["info"], - "python_type": { - "type": python_type, - "description": python_info.get("description", ""), - }, - "component": type.capitalize(), - "serializer": serializer_name, - } - ) - - if not dependency["backend_fn"]: - skip_endpoint = True - - if skip_endpoint: - continue - if dependency["api_name"] is not None and dependency["api_name"] is not False: - api_info["named_endpoints"][f"/{dependency['api_name']}"] = dependency_info - elif ( - dependency["api_name"] is False - or mode == "interface" - or mode == "tabbed_interface" - ): - pass # Skip unnamed endpoints in interface mode - else: - api_info["unnamed_endpoints"][str(d)] = dependency_info - - return api_info - - @document("launch", "queue", "integrate", "load") class Blocks(BlockContext): """ @@ -630,7 +485,7 @@ def __init__( else: os.environ["HF_HUB_DISABLE_TELEMETRY"] = "True" super().__init__(render=False, **kwargs) - self.blocks: dict[int, Block] = {} + self.blocks: dict[int, Component | Block] = {} self.fns: list[BlockFunction] = [] self.dependencies = [] self.mode = mode @@ -679,9 +534,14 @@ def __init__( } analytics.initiated_analytics(data) + def get_component(self, id: int) -> Component: + comp = self.blocks[id] + assert isinstance(comp, components.Component), f"{comp}" + return comp + @property def _is_running_in_reload_thread(self): - from gradio.reload import reload_thread + from gradio.cli.commands.reload import reload_thread return getattr(reload_thread, "running_reload", False) @@ -810,7 +670,12 @@ def iterate_over_children(children_list): dependency.pop("status_tracker", None) dependency["preprocess"] = False dependency["postprocess"] = False - + targets = [ + EventListenerMethod( + t.__self__ if t.has_trigger else None, t.event_name + ) + for t in targets + ] dependency = blocks.set_event_trigger( targets=targets, fn=fn, **dependency )[0] @@ -869,7 +734,7 @@ def set_event_trigger( preprocess: bool = True, postprocess: bool = True, scroll_to_output: bool = False, - show_progress: str = "full", + show_progress: Literal["full", "minimal", "hidden"] | None = "full", api_name: str | None | Literal[False] = None, js: str | None = None, no_target: bool = False, @@ -909,7 +774,7 @@ def set_event_trigger( # Support for singular parameter _targets = [ ( - target.trigger._id if target.trigger and not no_target else None, + target.block._id if target.block and not no_target else None, target.event_name, ) for target in targets @@ -1124,8 +989,8 @@ def __call__(self, *inputs, fn_index: int = 0, api_name: str | None = None): if batch: outputs = [out[0] for out in outputs] - processed_outputs = self.deserialize_data(fn_index, outputs) - processed_outputs = utils.resolve_singleton(processed_outputs) + outputs = self.deserialize_data(fn_index, outputs) + processed_outputs = utils.resolve_singleton(outputs) return processed_outputs @@ -1220,6 +1085,9 @@ def serialize_data(self, fn_index: int, inputs: list[Any]) -> list[Any]: dependency = self.dependencies[fn_index] processed_input = [] + def format_file(s): + return FileData(name=s, is_file=True).model_dump() + for i, input_id in enumerate(dependency["inputs"]): try: block = self.blocks[input_id] @@ -1227,11 +1095,19 @@ def serialize_data(self, fn_index: int, inputs: list[Any]) -> list[Any]: raise InvalidBlockError( f"Input component with id {input_id} used in {dependency['trigger']}() event is not defined in this gr.Blocks context. You are allowed to nest gr.Blocks contexts, but there must be a gr.Blocks context that contains all components and events." ) from e - if not isinstance(block, components.IOComponent): + if not isinstance(block, components.Component): raise InvalidComponentError( f"{block.__class__} Component with id {input_id} not a valid input component." ) - serialized_input = block.serialize(inputs[i]) + api_info = block.api_info() + if client_utils.value_is_file(api_info): + serialized_input = client_utils.traverse( + inputs[i], + format_file, + lambda s: client_utils.is_filepath(s) or client_utils.is_url(s), + ) + else: + serialized_input = inputs[i] processed_input.append(serialized_input) return processed_input @@ -1247,15 +1123,13 @@ def deserialize_data(self, fn_index: int, outputs: list[Any]) -> list[Any]: raise InvalidBlockError( f"Output component with id {output_id} used in {dependency['trigger']}() event not found in this gr.Blocks context. You are allowed to nest gr.Blocks contexts, but there must be a gr.Blocks context that contains all components and events." ) from e - if not isinstance(block, components.IOComponent): + if not isinstance(block, components.Component): raise InvalidComponentError( f"{block.__class__} Component with id {output_id} not a valid output component." ) - deserialized = block.deserialize( - outputs[o], - save_dir=block.DEFAULT_TEMP_DIR, - root_url=block.root_url, - hf_token=Context.hf_token, + + deserialized = client_utils.traverse( + outputs[o], lambda s: s["name"], client_utils.is_file_obj ) predictions.append(deserialized) @@ -1326,7 +1200,10 @@ def preprocess_data( else: if input_id in state: block = state[input_id] - processed_input.append(block.preprocess(inputs[i])) + inputs_cached = processing_utils.move_files_to_cache( + inputs[i], block + ) + processed_input.append(block.preprocess(inputs_cached)) else: processed_input = inputs return processed_input @@ -1445,7 +1322,8 @@ def postprocess_data( f"{block.__class__} Component with id {output_id} not a valid output component." ) prediction_value = block.postprocess(prediction_value) - output.append(prediction_value) + outputs_cached = processing_utils.move_files_to_cache(prediction_value, block) # type: ignore + output.append(outputs_cached) return output @@ -1462,11 +1340,9 @@ def handle_streaming_outputs( self.pending_streams[session_hash][run] = {} stream_run = self.pending_streams[session_hash][run] - from gradio.events import StreamableOutput - for i, output_id in enumerate(self.dependencies[fn_index]["outputs"]): block = self.blocks[output_id] - if isinstance(block, StreamableOutput) and block.streaming: + if isinstance(block, components.StreamingOutput) and block.streaming: first_chunk = output_id not in stream_run binary_data, output_data = block.stream_output( data[i], f"{session_hash}/{run}/{output_id}", first_chunk @@ -1622,10 +1498,12 @@ def get_layout(block): "type": block.get_block_name(), "props": utils.delete_none(props), } - serializer = utils.get_serializer_name(block) - if serializer: - assert isinstance(block, serializing.Serializable) - block_config["serializer"] = serializer + block_config["skip_api"] = block.skip_api + block_config["component_class_id"] = getattr( + block, "component_class_id", None + ) + + if not block.skip_api: block_config["api_info"] = block.api_info() # type: ignore block_config["example_inputs"] = block.example_inputs() # type: ignore config["components"].append(block_config) @@ -1665,7 +1543,7 @@ def load( outputs: Component | list[Component] | None = None, api_name: str | None | Literal[False] = None, scroll_to_output: bool = False, - show_progress: str = "full", + show_progress: Literal["full", "hidden", "minimal"] | None = "full", queue=None, batch: bool = False, max_batch_size: int = 4, @@ -1750,7 +1628,7 @@ def get_time(): every=every, no_target=True, ) - return Dependency(dep, dep_index, fn) + return Dependency(None, dep, dep_index, fn) def clear(self): """Resets the layout of the Blocks object.""" @@ -2265,7 +2143,7 @@ def reverse(text): ): self.block_thread() - return TupleNoPrint((self.server_app, self.local_url, self.share_url)) + return TupleNoPrint((self.server_app, self.local_url, self.share_url)) # type: ignore def integrate( self, @@ -2371,12 +2249,11 @@ def attach_load_events(self): if Context.root_block: for component in Context.root_block.blocks.values(): if ( - isinstance(component, components.IOComponent) + isinstance(component, components.Component) and component.load_event_to_attach ): load_fn, every = component.load_event_to_attach # Use set_event_trigger to avoid ambiguity between load class/instance method - from gradio.events import EventListenerMethod dep = self.set_event_trigger( [EventListenerMethod(self, "load")], @@ -2406,3 +2283,96 @@ def queue_enabled_for_fn(self, fn_index: int): if self.dependencies[fn_index]["queue"] is None: return self.enable_queue return self.dependencies[fn_index]["queue"] + + def get_api_info(self): + """ + Gets the information needed to generate the API docs from a Blocks. + """ + config = self.config + api_info = {"named_endpoints": {}, "unnamed_endpoints": {}} + mode = config.get("mode", None) + + for d, dependency in enumerate(config["dependencies"]): + dependency_info = {"parameters": [], "returns": []} + skip_endpoint = False + + inputs = dependency["inputs"] + for i in inputs: + for component in config["components"]: + if component["id"] == i: + break + else: + skip_endpoint = True # if component not found, skip endpoint + break + type = component["type"] + if self.blocks[component["id"]].skip_api: + continue + label = component["props"].get("label", f"parameter_{i}") + # The config has the most specific API info (taking into account the parameters + # of the component), so we use that if it exists. Otherwise, we fallback to the + # Serializer's API info. + info = self.get_component(component["id"]).api_info() + example = self.get_component(component["id"]).example_inputs() + python_type = client_utils.json_schema_to_python_type(info) + dependency_info["parameters"].append( + { + "label": label, + "type": info, + "python_type": { + "type": python_type, + "description": info.get("description", ""), + }, + "component": type.capitalize(), + "example_input": example, + } + ) + + outputs = dependency["outputs"] + for o in outputs: + for component in config["components"]: + if component["id"] == o: + break + else: + skip_endpoint = True # if component not found, skip endpoint + break + type = component["type"] + if self.blocks[component["id"]].skip_api: + continue + label = component["props"].get("label", f"value_{o}") + info = self.get_component(component["id"]).api_info() + example = self.get_component(component["id"]).example_inputs() + python_type = client_utils.json_schema_to_python_type(info) + dependency_info["returns"].append( + { + "label": label, + "type": info, + "python_type": { + "type": python_type, + "description": info.get("description", ""), + }, + "component": type.capitalize(), + } + ) + + if not dependency["backend_fn"]: + skip_endpoint = True + + if skip_endpoint: + continue + if ( + dependency["api_name"] is not None + and dependency["api_name"] is not False + ): + api_info["named_endpoints"][ + f"/{dependency['api_name']}" + ] = dependency_info + elif ( + dependency["api_name"] is False + or mode == "interface" + or mode == "tabbed_interface" + ): + pass # Skip unnamed endpoints in interface mode + else: + api_info["unnamed_endpoints"][str(d)] = dependency_info + + return api_info diff --git a/gradio/chat_interface.py b/gradio/chat_interface.py index 740d7f50e5d1..f3a581c17732 100644 --- a/gradio/chat_interface.py +++ b/gradio/chat_interface.py @@ -16,13 +16,13 @@ from gradio.components import ( Button, Chatbot, - IOComponent, + Component, Markdown, State, Textbox, get_component_instance, ) -from gradio.events import Dependency, EventListenerMethod, on +from gradio.events import Dependency, on from gradio.helpers import create_examples as Examples # noqa: N812 from gradio.helpers import special_args from gradio.layouts import Accordion, Column, Group, Row @@ -59,7 +59,7 @@ def __init__( *, chatbot: Chatbot | None = None, textbox: Textbox | None = None, - additional_inputs: str | IOComponent | list[str | IOComponent] | None = None, + additional_inputs: str | Component | list[str | Component] | None = None, additional_inputs_accordion_name: str = "Additional Inputs", examples: list[str] | None = None, cache_examples: bool | None = None, @@ -115,7 +115,7 @@ def __init__( self.cache_examples = True else: self.cache_examples = cache_examples or False - self.buttons: list[Button] = [] + self.buttons: list[Button | None] = [] if additional_inputs: if not isinstance(additional_inputs, list): @@ -146,7 +146,9 @@ def __init__( if textbox: textbox.container = False textbox.show_label = False - self.textbox = textbox.render() + textbox_ = textbox.render() + assert isinstance(textbox_, Textbox) + self.textbox = textbox_ else: self.textbox = Textbox( container=False, @@ -186,7 +188,7 @@ def __init__( raise ValueError( f"The stop_btn parameter must be a gr.Button, string, or None, not {type(stop_btn)}" ) - self.buttons.extend([submit_btn, stop_btn]) + self.buttons.extend([submit_btn, stop_btn]) # type: ignore with Row(): for btn in [retry_btn, undo_btn, clear_btn]: @@ -199,7 +201,7 @@ def __init__( raise ValueError( f"All the _btn parameters must be a gr.Button, string, or None, not {type(btn)}" ) - self.buttons.append(btn) + self.buttons.append(btn) # type: ignore self.fake_api_btn = Button("Fake API", visible=False) self.fake_response_textbox = Textbox( @@ -327,7 +329,7 @@ def _setup_events(self) -> None: ) def _setup_stop_events( - self, event_triggers: list[EventListenerMethod], event_to_cancel: Dependency + self, event_triggers: list[Callable], event_to_cancel: Dependency ) -> None: if self.stop_btn and self.is_generator: if self.submit_btn: diff --git a/gradio/cli.py b/gradio/cli.py deleted file mode 100644 index b521bbf0a3cb..000000000000 --- a/gradio/cli.py +++ /dev/null @@ -1,21 +0,0 @@ -import sys - -from gradio_client.cli import deploy_discord # type: ignore - -import gradio.cli_env_info -import gradio.deploy_space -import gradio.reload - - -def cli(): - args = sys.argv[1:] - if len(args) == 0: - raise ValueError("No file specified.") - elif args[0] == "deploy": - gradio.deploy_space.deploy() - elif args[0] == "environment": - gradio.cli_env_info.print_environment_info() - elif args[0] == "deploy-discord": - deploy_discord.main() - else: - gradio.reload.main() diff --git a/gradio/cli/__init__.py b/gradio/cli/__init__.py new file mode 100644 index 000000000000..1fca2de36be2 --- /dev/null +++ b/gradio/cli/__init__.py @@ -0,0 +1,4 @@ +from .cli import cli, deploy +from .commands import custom_component + +__all__ = ["cli", "deploy", "custom_component"] diff --git a/gradio/cli/cli.py b/gradio/cli/cli.py new file mode 100644 index 000000000000..d20fd573c3cf --- /dev/null +++ b/gradio/cli/cli.py @@ -0,0 +1,31 @@ +import sys + +import typer +from gradio_client.cli import deploy_discord # type: ignore + +from .commands import custom_component, deploy, print_environment_info, reload + +app = typer.Typer() +app.command("environment", help="Print Gradio environment information.")( + print_environment_info +) +app.command( + "deploy", + help="Deploy a Gradio app to Spaces. Must be called within the directory you would like to deploy.", +)(deploy) +app.command("deploy-discord", help="Deploy a Gradio app to Discord.")( + deploy_discord.main +) + + +def cli(): + args = sys.argv[1:] + if len(args) == 0: + raise ValueError("No file specified.") + if args[0] in {"deploy", "environment", "deploy-discord"}: + app() + elif args[0] in {"cc", "component"}: + sys.argv = sys.argv[1:] + custom_component() + else: + typer.run(reload) diff --git a/gradio/cli/commands/__init__.py b/gradio/cli/commands/__init__.py new file mode 100644 index 000000000000..e4b20dbfc7bb --- /dev/null +++ b/gradio/cli/commands/__init__.py @@ -0,0 +1,6 @@ +from .cli_env_info import print_environment_info +from .components import app as custom_component +from .deploy_space import deploy +from .reload import main as reload + +__all__ = ["deploy", "reload", "print_environment_info", "custom_component"] diff --git a/gradio/cli_env_info.py b/gradio/cli/commands/cli_env_info.py similarity index 95% rename from gradio/cli_env_info.py rename to gradio/cli/commands/cli_env_info.py index 29df6e344144..5156f3a44940 100644 --- a/gradio/cli_env_info.py +++ b/gradio/cli/commands/cli_env_info.py @@ -4,8 +4,11 @@ import platform from importlib import metadata +from rich import print + def print_environment_info(): + """Print Gradio environment information.""" print("Gradio Environment Information:\n------------------------------") print("Operating System:", platform.system()) diff --git a/gradio/cli/commands/components/__init__.py b/gradio/cli/commands/components/__init__.py new file mode 100644 index 000000000000..34f275ed3c9d --- /dev/null +++ b/gradio/cli/commands/components/__init__.py @@ -0,0 +1,3 @@ +from .app import app + +__all__ = ["app"] diff --git a/gradio/cli/commands/components/_create_utils.py b/gradio/cli/commands/components/_create_utils.py new file mode 100644 index 000000000000..6039aaa29262 --- /dev/null +++ b/gradio/cli/commands/components/_create_utils.py @@ -0,0 +1,289 @@ +from __future__ import annotations + +import dataclasses +import inspect +import json +import re +import shutil +import textwrap +from pathlib import Path +from typing import Literal + +import gradio + + +def _in_test_dir(): + """Check if the current working directory ends with gradio/js/gradio-preview/test.""" + return Path.cwd().parts[-4:] == ("gradio", "js", "gradio-preview", "test") + + +default_demo_code = """ +example = {name}().example_inputs() + +with gr.Blocks() as demo: + {name}(value=example, interactive=True) + {name}(value=example, interactive=False) +""" + + +@dataclasses.dataclass +class ComponentFiles: + template: str + demo_code: str = default_demo_code + python_file_name: str = "" + js_dir: str = "" + + def __post_init__(self): + self.js_dir = self.js_dir or self.template.lower() + self.python_file_name = self.python_file_name or f"{self.template.lower()}.py" + + +OVERRIDES = { + "AnnotatedImage": ComponentFiles( + template="AnnotatedImage", python_file_name="annotated_image.py" + ), + "HighlightedText": ComponentFiles( + template="HighlightedText", python_file_name="highlighted_text.py" + ), + "BarPlot": ComponentFiles( + template="BarPlot", python_file_name="bar_plot.py", js_dir="plot" + ), + "ClearButton": ComponentFiles( + template="ClearButton", python_file_name="clear_button.py", js_dir="button" + ), + "ColorPicker": ComponentFiles( + template="ColorPicker", python_file_name="color_picker.py" + ), + "DuplicateButton": ComponentFiles( + template="DuplicateButton", + python_file_name="duplicate_button.py", + js_dir="button", + ), + "LinePlot": ComponentFiles( + template="LinePlot", python_file_name="line_plot.py", js_dir="plot" + ), + "LogoutButton": ComponentFiles( + template="LogoutButton", python_file_name="logout_button.py", js_dir="button" + ), + "LoginButton": ComponentFiles( + template="LoginButton", python_file_name="login_button.py", js_dir="button" + ), + "ScatterPlot": ComponentFiles( + template="ScatterPlot", python_file_name="scatter_plot.py", js_dir="plot" + ), + "UploadButton": ComponentFiles( + template="UploadButton", python_file_name="upload_button.py" + ), + "JSON": ComponentFiles(template="JSON", python_file_name="json_component.py"), + "Row": ComponentFiles( + template="Row", + demo_code=textwrap.dedent( + """ + with gr.Blocks() as demo: + with {name}(): + gr.Textbox(value="foo", interactive=True) + gr.Number(value=10, interactive=True) + """ + ), + ), + "Column": ComponentFiles( + template="Column", + demo_code=textwrap.dedent( + """ + with gr.Blocks() as demo: + with {name}(): + gr.Textbox(value="foo", interactive=True) + gr.Number(value=10, interactive=True) + """ + ), + ), + "Tabs": ComponentFiles( + template="Tabs", + demo_code=textwrap.dedent( + """ + with gr.Blocks() as demo: + with {name}(): + with gr.Tab("Tab 1"): + gr.Textbox(value="foo", interactive=True) + with gr.Tab("Tab 2"): + gr.Number(value=10, interactive=True) + """ + ), + ), + "Group": ComponentFiles( + template="Group", + demo_code=textwrap.dedent( + """ + with gr.Blocks() as demo: + with {name}(): + gr.Textbox(value="foo", interactive=True) + gr.Number(value=10, interactive=True) + """ + ), + ), + "Accordion": ComponentFiles( + template="Accordion", + demo_code=textwrap.dedent( + """ + with gr.Blocks() as demo: + with {name}(label="Accordion"): + gr.Textbox(value="foo", interactive=True) + gr.Number(value=10, interactive=True) + """ + ), + ), +} + + +def _get_component_code(template: str | None) -> ComponentFiles: + template = template or "Fallback" + if template in OVERRIDES: + return OVERRIDES[template] + else: + return ComponentFiles( + python_file_name=f"{template.lower()}.py", + js_dir=template.lower(), + template=template, + ) + + +def _get_js_dependency_version(name: str, local_js_dir: Path) -> str: + package_json = json.loads( + Path(local_js_dir / name.split("/")[1] / "package.json").read_text() + ) + return package_json["version"] + + +def _modify_js_deps( + package_json: dict, + key: Literal["dependencies", "devDependencies"], + gradio_dir: Path, +): + for dep in package_json.get(key, []): + # if curent working directory is the gradio repo, use the local version of the dependency' + if not _in_test_dir() and dep.startswith("@gradio/"): + package_json[key][dep] = _get_js_dependency_version( + dep, gradio_dir / "_frontend_code" + ) + return package_json + + +def delete_contents(directory: str | Path) -> None: + """Delete all contents of a directory, but not the directory itself.""" + path = Path(directory) + for child in path.glob("*"): + if child.is_file(): + child.unlink() + elif child.is_dir(): + delete_contents(child) + child.rmdir() + + +def _create_frontend(name: str, component: ComponentFiles, directory: Path): + frontend = directory / "frontend" + frontend.mkdir(exist_ok=True) + + p = Path(inspect.getfile(gradio)).parent + + def ignore(s, names): + ignored = [] + for n in names: + if ( + n.startswith("CHANGELOG") + or n.startswith("README.md") + or ".test." in n + or ".stories." in n + or ".spec." in n + ): + ignored.append(n) + return ignored + + shutil.copytree( + str(p / "_frontend_code" / component.js_dir), + frontend, + dirs_exist_ok=True, + ignore=ignore, + ) + source_package_json = json.loads(Path(frontend / "package.json").read_text()) + source_package_json["name"] = name.lower() + source_package_json = _modify_js_deps(source_package_json, "dependencies", p) + source_package_json = _modify_js_deps(source_package_json, "devDependencies", p) + (frontend / "package.json").write_text(json.dumps(source_package_json, indent=2)) + + +def _replace_old_class_name(old_class_name: str, new_class_name: str, content: str): + pattern = rf"(?<=\b)(?>", package_name)) + + demo_dir = directory / "demo" + demo_dir.mkdir(exist_ok=True, parents=True) + + (demo_dir / "app.py").write_text( + f""" +import gradio as gr +from {package_name} import {name} + +{component.demo_code.format(name=name)} + +demo.launch() +""" + ) + (demo_dir / "__init__.py").touch() + + init = backend / "__init__.py" + init.write_text( + f""" +from .{name.lower()} import {name} + +__all__ = ['{name}'] +""" + ) + + p = Path(inspect.getfile(gradio)).parent + python_file = backend / f"{name.lower()}.py" + + shutil.copy( + str(p / module / component.python_file_name), + str(python_file), + ) + + source_pyi_file = p / module / component.python_file_name.replace(".py", ".pyi") + pyi_file = backend / f"{name.lower()}.pyi" + if source_pyi_file.exists(): + shutil.copy(str(source_pyi_file), str(pyi_file)) + + content = python_file.read_text() + python_file.write_text(_replace_old_class_name(component.template, name, content)) + if pyi_file.exists(): + pyi_content = pyi_file.read_text() + pyi_file.write_text( + _replace_old_class_name(component.template, name, pyi_content) + ) diff --git a/gradio/cli/commands/components/app.py b/gradio/cli/commands/components/app.py new file mode 100644 index 000000000000..7c2c391ebe5d --- /dev/null +++ b/gradio/cli/commands/components/app.py @@ -0,0 +1,14 @@ +from typer import Typer + +from .build import _build +from .create import _create +from .dev import _dev + +app = Typer(help="Create and publish a new Gradio component") + +app.command("create", help="Create a new component.")(_create) +app.command( + "build", + help="Build the component for distribution. Must be called from the component directory.", +)(_build) +app.command("dev", help="Launch the custom component demo in development mode.")(_dev) diff --git a/gradio/cli/commands/components/build.py b/gradio/cli/commands/components/build.py new file mode 100644 index 000000000000..87487e011660 --- /dev/null +++ b/gradio/cli/commands/components/build.py @@ -0,0 +1,69 @@ +import shutil +import subprocess +import sys +from pathlib import Path + +import typer +from typing_extensions import Annotated + +import gradio +from gradio.cli.commands.display import LivePanelDisplay + +gradio_template_path = Path(gradio.__file__).parent / "templates" / "frontend" +gradio_node_path = Path(gradio.__file__).parent / "node" / "dev" / "files" / "index.js" + + +def _build( + path: Annotated[ + Path, typer.Argument(help="The directory of the custom component.") + ] = Path("."), + build_frontend: Annotated[ + bool, typer.Option(help="Whether to build the frontend as well.") + ] = True, +): + name = Path(path).resolve() + if not (name / "pyproject.toml").exists(): + raise ValueError(f"Cannot find pyproject.toml file in {name}") + + with LivePanelDisplay() as live: + live.update( + f":package: Building package in [orange3]{str(name.name)}[/]", add_sleep=0.2 + ) + if build_frontend: + live.update(":art: Building frontend") + component_directory = path.resolve() + + node = shutil.which("node") + if not node: + raise ValueError("node must be installed in order to run dev mode.") + + node_cmds = [ + node, + gradio_node_path, + "--component-directory", + component_directory, + "--root", + gradio_template_path, + "--mode", + "build", + ] + + pipe = subprocess.run(node_cmds, capture_output=True, text=True) + if pipe.returncode != 0: + live.update(":red_square: Build failed!") + live.update(pipe.stderr) + return + else: + live.update(":white_check_mark: Build succeeded!") + + cmds = [sys.executable, "-m", "build", str(name)] + live.update(f":construction_worker: Building... [grey37]({' '.join(cmds)})[/]") + pipe = subprocess.run(cmds, capture_output=True, text=True) + if pipe.returncode != 0: + live.update(":red_square: Build failed!") + live.update(pipe.stderr) + else: + live.update(":white_check_mark: Build succeeded!") + live.update( + f":ferris_wheel: Wheel located in [orange3]{str(name / 'dist')}[/]" + ) diff --git a/gradio/cli/commands/components/create.py b/gradio/cli/commands/components/create.py new file mode 100644 index 000000000000..88a1e0fb94ae --- /dev/null +++ b/gradio/cli/commands/components/create.py @@ -0,0 +1,127 @@ +import shutil +import subprocess +from pathlib import Path +from typing import Optional + +import typer +from rich.markup import escape +from typing_extensions import Annotated + +from gradio.cli.commands.display import LivePanelDisplay +from gradio.utils import set_directory + +from . import _create_utils + + +def _create( + name: Annotated[ + str, + typer.Argument( + help="Name of the component. Preferably in camel case, i.e. MyTextBox." + ), + ], + directory: Annotated[ + Optional[Path], + typer.Option( + help="Directory to create the component in. Default is None. If None, will be created inHello
" + + def preprocess(self, x: Any) -> Any: + return x + + def postprocess(self, y): + return y + @staticmethod def update( value: Any | Literal[_Keywords.NO_VALUE] | None = _Keywords.NO_VALUE, @@ -77,3 +86,6 @@ def update( "__type__": "update", } return updated_config + + def api_info(self) -> dict[str, Any]: + return {"type": "string"} diff --git a/gradio/components/image.py b/gradio/components/image.py index b5fd6a19cd02..de3c997bd708 100644 --- a/gradio/components/image.py +++ b/gradio/components/image.py @@ -11,39 +11,19 @@ import PIL.ImageOps from gradio_client import utils as client_utils from gradio_client.documentation import document, set_documentation_group -from gradio_client.serializing import ImgSerializable from PIL import Image as _Image # using _ to minimize namespace pollution from gradio import processing_utils, utils -from gradio.components.base import IOComponent, _Keywords -from gradio.deprecation import warn_style_method_deprecation -from gradio.events import ( - Changeable, - Clearable, - Editable, - EventListenerMethod, - Selectable, - Streamable, - Uploadable, -) -from gradio.interpretation import TokenInterpretable +from gradio.components.base import Component, StreamingInput, _Keywords +from gradio.data_classes import FileData +from gradio.events import Events set_documentation_group("component") _Image.init() # fixes https://github.com/gradio-app/gradio/issues/2843 @document() -class Image( - Editable, - Clearable, - Changeable, - Streamable, - Selectable, - Uploadable, - IOComponent, - ImgSerializable, - TokenInterpretable, -): +class Image(StreamingInput, Component): """ Creates an image component that can be used to upload/draw images (as an input) or display images (as an output). Preprocessing: passes the uploaded image as a {numpy.array}, {PIL.Image} or {str} filepath depending on `type` -- unless `tool` is `sketch` AND source is one of `upload` or `webcam`. In these cases, a {dict} with keys `image` and `mask` is passed, and the format of the corresponding values depends on `type`. @@ -53,6 +33,16 @@ class Image( Guides: image-classification-in-pytorch, image-classification-in-tensorflow, image-classification-with-vision-transformers, building-a-pictionary_app, create-your-own-friends-with-a-gan """ + EVENTS = [ + Events.edit, + Events.clear, + Events.change, + Events.stream, + Events.select, + Events.upload, + ] + data_model = FileData + def __init__( self, value: str | _Image.Image | np.ndarray | None = None, @@ -144,19 +134,12 @@ def __init__( self.show_download_button = show_download_button if streaming and source != "webcam": raise ValueError("Image streaming only available if source is 'webcam'.") - self.select: EventListenerMethod - """ - Event listener for when the user clicks on a pixel within the image. - Uses event data gradio.SelectData to carry `index` to refer to the [x, y] coordinates of the clicked pixel. - See EventData documentation on how to use this event data. - """ self.show_share_button = ( (utils.get_space() is not None) if show_share_button is None else show_share_button ) - IOComponent.__init__( - self, + super().__init__( label=label, every=every, show_label=show_label, @@ -170,7 +153,6 @@ def __init__( value=value, **kwargs, ) - TokenInterpretable.__init__(self) @staticmethod def update( @@ -224,10 +206,9 @@ def _format_image( elif self.type == "numpy": return np.array(im) elif self.type == "filepath": - path = self.pil_to_temp_file( - im, dir=self.DEFAULT_TEMP_DIR, format=fmt or "png" + path = processing_utils.save_pil_to_cache( + im, cache_dir=self.GRADIO_CACHE, format=fmt or "png" # type: ignore ) - self.temp_files.add(path) return path else: raise ValueError( @@ -253,8 +234,10 @@ def preprocess( assert isinstance(x, dict) x, mask = x["image"], x["mask"] - assert isinstance(x, str) - im = processing_utils.decode_base64_to_image(x) + if isinstance(x, str): + im = processing_utils.decode_base64_to_image(x) + else: + im = _Image.open(x["name"]) with warnings.catch_warnings(): warnings.simplefilter("ignore") im = im.convert(self.image_mode) @@ -284,7 +267,7 @@ def preprocess( def postprocess( self, y: np.ndarray | _Image.Image | str | Path | None - ) -> str | None: + ) -> FileData | None: """ Parameters: y: image as a numpy array, PIL Image, string/Path filepath, or string URL @@ -294,125 +277,19 @@ def postprocess( if y is None: return None if isinstance(y, np.ndarray): - return processing_utils.encode_array_to_base64(y) + path = processing_utils.save_img_array_to_cache( + y, cache_dir=self.GRADIO_CACHE + ) elif isinstance(y, _Image.Image): - return processing_utils.encode_pil_to_base64(y) + path = processing_utils.save_pil_to_cache(y, cache_dir=self.GRADIO_CACHE) elif isinstance(y, (str, Path)): - return client_utils.encode_url_or_file_to_base64(y) + path = y if isinstance(y, str) else y.name else: raise ValueError("Cannot process this value as an Image") - - def set_interpret_parameters(self, segments: int = 16): - """ - Calculates interpretation score of image subsections by splitting the image into subsections, then using a "leave one out" method to calculate the score of each subsection by whiting out the subsection and measuring the delta of the output value. - Parameters: - segments: Number of interpretation segments to split image into. - """ - self.interpretation_segments = segments - return self - - def _segment_by_slic(self, x): - """ - Helper method that segments an image into superpixels using slic. - Parameters: - x: base64 representation of an image - """ - x = processing_utils.decode_base64_to_image(x) - if self.shape is not None: - x = processing_utils.resize_and_crop(x, self.shape) - resized_and_cropped_image = np.array(x) - try: - from skimage.segmentation import slic - except (ImportError, ModuleNotFoundError) as err: - raise ValueError( - "Error: running this interpretation for images requires scikit-image, please install it first." - ) from err - try: - segments_slic = slic( - resized_and_cropped_image, - self.interpretation_segments, - compactness=10, - sigma=1, - start_label=1, - ) - except TypeError: # For skimage 0.16 and older - segments_slic = slic( - resized_and_cropped_image, - self.interpretation_segments, - compactness=10, - sigma=1, - ) - return segments_slic, resized_and_cropped_image - - def tokenize(self, x): - """ - Segments image into tokens, masks, and leave-one-out-tokens - Parameters: - x: base64 representation of an image - Returns: - tokens: list of tokens, used by the get_masked_input() method - leave_one_out_tokens: list of left-out tokens, used by the get_interpretation_neighbors() method - masks: list of masks, used by the get_interpretation_neighbors() method - """ - segments_slic, resized_and_cropped_image = self._segment_by_slic(x) - tokens, masks, leave_one_out_tokens = [], [], [] - replace_color = np.mean(resized_and_cropped_image, axis=(0, 1)) - for segment_value in np.unique(segments_slic): - mask = segments_slic == segment_value - image_screen = np.copy(resized_and_cropped_image) - image_screen[segments_slic == segment_value] = replace_color - leave_one_out_tokens.append( - processing_utils.encode_array_to_base64(image_screen) - ) - token = np.copy(resized_and_cropped_image) - token[segments_slic != segment_value] = 0 - tokens.append(token) - masks.append(mask) - return tokens, leave_one_out_tokens, masks - - def get_masked_inputs(self, tokens, binary_mask_matrix): - masked_inputs = [] - for binary_mask_vector in binary_mask_matrix: - masked_input = np.zeros_like(tokens[0], dtype=int) - for token, b in zip(tokens, binary_mask_vector): - masked_input = masked_input + token * int(b) - masked_inputs.append(processing_utils.encode_array_to_base64(masked_input)) - return masked_inputs - - def get_interpretation_scores( - self, x, neighbors, scores, masks, tokens=None, **kwargs - ) -> list[list[float]]: - """ - Returns: - A 2D array representing the interpretation score of each pixel of the image. - """ - x = processing_utils.decode_base64_to_image(x) - if self.shape is not None: - x = processing_utils.resize_and_crop(x, self.shape) - x = np.array(x) - output_scores = np.zeros((x.shape[0], x.shape[1])) - - for score, mask in zip(scores, masks): - output_scores += score * mask - - max_val, min_val = np.max(output_scores), np.min(output_scores) - if max_val > 0: - output_scores = (output_scores - min_val) / (max_val - min_val) - return output_scores.tolist() - - def style(self, *, height: int | None = None, width: int | None = None, **kwargs): - """ - This method is deprecated. Please set these arguments in the constructor instead. - """ - warn_style_method_deprecation() - if height is not None: - self.height = height - if width is not None: - self.width = width - return self + return FileData(name=path, data=None, is_file=True) def check_streamable(self): - if self.source != "webcam": + if self.source != "webcam" and self.streaming: raise ValueError("Image streaming only available if source is 'webcam'.") def as_example(self, input_data: str | Path | None) -> str: @@ -423,3 +300,6 @@ def as_example(self, input_data: str | Path | None) -> str: if self.root_url or client_utils.is_http_url_like(input_data): return input_data return str(utils.abspath(input_data)) + + def example_inputs(self) -> Any: + return "https://raw.githubusercontent.com/gradio-app/gradio/main/test/test_files/bus.png" diff --git a/gradio/components/interpretation.py b/gradio/components/interpretation.py deleted file mode 100644 index b261f4f637d2..000000000000 --- a/gradio/components/interpretation.py +++ /dev/null @@ -1,55 +0,0 @@ -"""gr.Interpretation() component""" - -from __future__ import annotations - -from typing import Any, Literal - -from gradio_client.documentation import document, set_documentation_group -from gradio_client.serializing import SimpleSerializable - -from gradio.components.base import Component, _Keywords - -set_documentation_group("component") - - -@document() -class Interpretation(Component, SimpleSerializable): - """ - Used to create an interpretation widget for a component. - Preprocessing: this component does *not* accept input. - Postprocessing: expects a {dict} with keys "original" and "interpretation". - - Guides: custom-interpretations-with-blocks - """ - - def __init__( - self, - component: Component, - *, - visible: bool = True, - elem_id: str | None = None, - elem_classes: list[str] | str | None = None, - **kwargs, - ): - """ - Parameters: - component: Which component to show in the interpretation widget. - visible: Whether or not the interpretation is visible. - elem_id: An optional string that is assigned as the id of this component in the HTML DOM. Can be used for targeting CSS styles. - elem_classes: An optional list of strings that are assigned as the classes of this component in the HTML DOM. Can be used for targeting CSS styles. - """ - Component.__init__( - self, visible=visible, elem_id=elem_id, elem_classes=elem_classes, **kwargs - ) - self.component = component - - @staticmethod - def update( - value: Any | Literal[_Keywords.NO_VALUE] | None = _Keywords.NO_VALUE, - visible: bool | None = None, - ): - return { - "visible": visible, - "value": value, - "__type__": "update", - } diff --git a/gradio/components/json_component.py b/gradio/components/json_component.py index 46bef37ba671..02a75e2bcdec 100644 --- a/gradio/components/json_component.py +++ b/gradio/components/json_component.py @@ -4,22 +4,20 @@ import json import warnings +from pathlib import Path from typing import Any, Callable, Literal from gradio_client.documentation import document, set_documentation_group -from gradio_client.serializing import JSONSerializable -from gradio.components.base import IOComponent, _Keywords +from gradio.components.base import Component, _Keywords from gradio.deprecation import warn_style_method_deprecation -from gradio.events import ( - Changeable, -) +from gradio.events import Events set_documentation_group("component") @document() -class JSON(Changeable, IOComponent, JSONSerializable): +class JSON(Component): """ Used to display arbitrary JSON output prettily. Preprocessing: this component does *not* accept input. @@ -28,6 +26,8 @@ class JSON(Changeable, IOComponent, JSONSerializable): Demos: zip_to_json, blocks_xray """ + EVENTS = [Events.change] + def __init__( self, value: str | dict | list | Callable | None = None, @@ -56,8 +56,7 @@ def __init__( elem_id: An optional string that is assigned as the id of this component in the HTML DOM. Can be used for targeting CSS styles. elem_classes: An optional list of strings that are assigned as the classes of this component in the HTML DOM. Can be used for targeting CSS styles. """ - IOComponent.__init__( - self, + super().__init__( label=label, every=every, show_label=show_label, @@ -110,6 +109,18 @@ def postprocess(self, y: dict | list | str | None) -> dict | list | None: else: return y + def preprocess(self, x: Any) -> Any: + return x + + def example_inputs(self) -> Any: + return {"foo": "bar"} + + def flag(self, x: Any, flag_dir: str | Path = "") -> str: + return json.dumps(x) + + def read_from_flag(self, x: Any, flag_dir: str | Path | None = None): + return json.loads(x) + def style(self, *, container: bool | None = None, **kwargs): """ This method is deprecated. Please set these arguments in the constructor instead. @@ -118,3 +129,6 @@ def style(self, *, container: bool | None = None, **kwargs): if container is not None: self.container = container return self + + def api_info(self) -> dict[str, Any]: + return {"type": {}, "description": "any valid json"} diff --git a/gradio/components/label.py b/gradio/components/label.py index f6e965b0a3f8..0d755e5e569d 100644 --- a/gradio/components/label.py +++ b/gradio/components/label.py @@ -2,29 +2,34 @@ from __future__ import annotations +import json import operator import warnings from pathlib import Path -from typing import Callable, Literal +from typing import Any, Callable, List, Literal, Optional, Union from gradio_client.documentation import document, set_documentation_group -from gradio_client.serializing import ( - JSONSerializable, -) -from gradio.components.base import IOComponent, _Keywords +from gradio.components.base import Component, _Keywords +from gradio.data_classes import GradioModel from gradio.deprecation import warn_style_method_deprecation -from gradio.events import ( - Changeable, - EventListenerMethod, - Selectable, -) +from gradio.events import Events set_documentation_group("component") +class LabelConfidence(GradioModel): + label: Optional[Union[str, int, float]] = None + confidence: Optional[float] = None + + +class LabelData(GradioModel): + label: Union[str, int, float] + confidences: Optional[List[LabelConfidence]] = None + + @document() -class Label(Changeable, Selectable, IOComponent, JSONSerializable): +class Label(Component): """ Displays a classification label, along with confidence scores of top categories, if provided. Preprocessing: this component does *not* accept input. @@ -35,6 +40,8 @@ class Label(Changeable, Selectable, IOComponent, JSONSerializable): """ CONFIDENCES_KEY = "confidences" + data_model = LabelData + EVENTS = [Events.change, Events.select] def __init__( self, @@ -70,14 +77,7 @@ def __init__( """ self.num_top_classes = num_top_classes self.color = color - self.select: EventListenerMethod - """ - Event listener for when the user selects a category from Label. - Uses event data gradio.SelectData to carry `value` referring to name of selected category, and `index` to refer to index. - See EventData documentation on how to use this event data. - """ - IOComponent.__init__( - self, + super().__init__( label=label, every=every, show_label=show_label, @@ -91,7 +91,9 @@ def __init__( **kwargs, ) - def postprocess(self, y: dict[str, float] | str | float | None) -> dict | None: + def postprocess( + self, y: dict[str, float] | str | float | None + ) -> LabelData | dict | None: """ Parameters: y: a dictionary mapping labels to confidence value, or just a string/numerical label by itself @@ -101,9 +103,9 @@ def postprocess(self, y: dict[str, float] | str | float | None) -> dict | None: if y is None or y == {}: return {} if isinstance(y, str) and y.endswith(".json") and Path(y).exists(): - return self.serialize(y) + return LabelData(**json.loads(Path(y).read_text())) if isinstance(y, (str, float, int)): - return {"label": str(y)} + return LabelData(label=str(y)) if isinstance(y, dict): if "confidences" in y and isinstance(y["confidences"], dict): y = y["confidences"] @@ -111,12 +113,15 @@ def postprocess(self, y: dict[str, float] | str | float | None) -> dict | None: sorted_pred = sorted(y.items(), key=operator.itemgetter(1), reverse=True) if self.num_top_classes is not None: sorted_pred = sorted_pred[: self.num_top_classes] - return { - "label": sorted_pred[0][0], - "confidences": [ - {"label": pred[0], "confidence": pred[1]} for pred in sorted_pred - ], - } + return LabelData( + **{ + "label": sorted_pred[0][0], + "confidences": [ + {"label": pred[0], "confidence": pred[1]} + for pred in sorted_pred + ], + } + ) raise ValueError( "The `Label` output interface expects one of: a string label, or an int label, a " "float label, or a dictionary whose keys are labels and values are confidences. " @@ -175,3 +180,15 @@ def style( if container is not None: self.container = container return self + + def preprocess(self, x: Any) -> Any: + return x + + def example_inputs(self) -> Any: + return { + "label": "Cat", + "confidences": [ + {"label": "cat", "confidence": 0.9}, + {"label": "dog", "confidence": 0.1}, + ], + } diff --git a/gradio/components/line_plot.py b/gradio/components/line_plot.py index 7feb215679ce..59b523354918 100644 --- a/gradio/components/line_plot.py +++ b/gradio/components/line_plot.py @@ -3,14 +3,14 @@ from __future__ import annotations import warnings -from typing import Callable, Literal +from typing import Any, Callable, Literal import altair as alt import pandas as pd from gradio_client.documentation import document, set_documentation_group from gradio.components.base import _Keywords -from gradio.components.plot import AltairPlot, Plot +from gradio.components.plot import AltairPlot, AltairPlotData, Plot set_documentation_group("component") @@ -26,6 +26,8 @@ class LinePlot(Plot): Demos: line_plot, live_dashboard """ + data_model = AltairPlotData + def __init__( self, value: pd.DataFrame | Callable | None = None, @@ -423,7 +425,9 @@ def create_plot( return chart - def postprocess(self, y: pd.DataFrame | dict | None) -> dict[str, str] | None: + def postprocess( + self, y: pd.DataFrame | dict | None + ) -> AltairPlotData | dict | None: # if None or update if y is None or isinstance(y, dict): return y @@ -453,4 +457,12 @@ def postprocess(self, y: pd.DataFrame | dict | None) -> dict[str, str] | None: width=self.width, ) - return {"type": "altair", "plot": chart.to_json(), "chart": "line"} + return AltairPlotData( + **{"type": "altair", "plot": chart.to_json(), "chart": "line"} + ) + + def example_inputs(self) -> Any: + return None + + def preprocess(self, x: Any) -> Any: + return x diff --git a/gradio/components/markdown.py b/gradio/components/markdown.py index fa58269a4ff5..3ebcaa67404f 100644 --- a/gradio/components/markdown.py +++ b/gradio/components/markdown.py @@ -7,18 +7,15 @@ from typing import Any, Callable, Literal from gradio_client.documentation import document, set_documentation_group -from gradio_client.serializing import StringSerializable -from gradio.components.base import IOComponent, _Keywords -from gradio.events import ( - Changeable, -) +from gradio.components.base import Component, _Keywords +from gradio.events import Events set_documentation_group("component") @document() -class Markdown(IOComponent, Changeable, StringSerializable): +class Markdown(Component): """ Used to render arbitrary Markdown output. Can also render latex enclosed by dollar signs. Preprocessing: this component does *not* accept input. @@ -28,6 +25,8 @@ class Markdown(IOComponent, Changeable, StringSerializable): Guides: key-features """ + EVENTS = [Events.change] + def __init__( self, value: str | Callable = "", @@ -53,14 +52,11 @@ def __init__( line_breaks: If True, will enable Github-flavored Markdown line breaks in chatbot messages. If False (default), single new lines will be ignored. """ self.rtl = rtl - if latex_delimiters is None: - latex_delimiters = [{"left": "$", "right": "$", "display": False}] self.latex_delimiters = latex_delimiters self.sanitize_html = sanitize_html self.line_breaks = line_breaks - IOComponent.__init__( - self, + super().__init__( visible=visible, elem_id=elem_id, elem_classes=elem_classes, @@ -106,3 +102,12 @@ def update( def as_example(self, input_data: str | None) -> str: postprocessed = self.postprocess(input_data) return postprocessed if postprocessed else "" + + def preprocess(self, x: Any) -> Any: + return x + + def example_inputs(self) -> Any: + return "# Hello!" + + def api_info(self) -> dict[str, Any]: + return {"type": "string"} diff --git a/gradio/components/model3d.py b/gradio/components/model3d.py index d11bef86b2c1..af2a80f06206 100644 --- a/gradio/components/model3d.py +++ b/gradio/components/model3d.py @@ -6,25 +6,17 @@ from pathlib import Path from typing import Any, Callable, Literal -from gradio_client import media_data from gradio_client.documentation import document, set_documentation_group -from gradio_client.serializing import FileSerializable -from gradio.components.base import IOComponent, _Keywords -from gradio.events import ( - Changeable, - Clearable, - Editable, - Uploadable, -) +from gradio.components.base import Component, _Keywords +from gradio.data_classes import FileData +from gradio.events import Events set_documentation_group("component") @document() -class Model3D( - Changeable, Uploadable, Editable, Clearable, IOComponent, FileSerializable -): +class Model3D(Component): """ Component allows users to upload or view 3D Model files (.obj, .glb, or .gltf). Preprocessing: This component passes the uploaded file as a {str}filepath. @@ -34,6 +26,10 @@ class Model3D( Guides: how-to-use-3D-model-component """ + EVENTS = [Events.change, Events.upload, Events.edit, Events.clear] + + data_model = FileData + def __init__( self, value: str | Callable | None = None, @@ -80,9 +76,7 @@ def __init__( self.camera_position = camera_position self.height = height self.zoom_speed = zoom_speed - - IOComponent.__init__( - self, + super().__init__( label=label, every=every, show_label=show_label, @@ -96,12 +90,6 @@ def __init__( **kwargs, ) - def example_inputs(self) -> dict[str, Any]: - return { - "raw": {"is_file": False, "data": media_data.BASE64_MODEL3D}, - "serialized": "https://github.com/gradio-app/gradio/raw/main/test/test_files/Box.gltf", - } - @staticmethod def update( value: Any | Literal[_Keywords.NO_VALUE] | None = _Keywords.NO_VALUE, @@ -147,19 +135,9 @@ def preprocess(self, x: dict[str, str] | None) -> str | None: """ if x is None: return x - file_name, file_data, is_file = ( - x["name"], - x["data"], - x.get("is_file", False), - ) - if is_file: - temp_file_path = self.make_temp_copy_if_needed(file_name) - else: - temp_file_path = self.base64_to_temp_file_if_needed(file_data, file_name) - - return temp_file_path + return x["name"] - def postprocess(self, y: str | Path | None) -> dict[str, str] | None: + def postprocess(self, y: str | Path | None) -> FileData | None: """ Parameters: y: path to the model @@ -168,12 +146,11 @@ def postprocess(self, y: str | Path | None) -> dict[str, str] | None: """ if y is None: return y - data = { - "name": self.make_temp_copy_if_needed(y), - "data": None, - "is_file": True, - } - return data + return FileData(name=str(y), is_file=True) def as_example(self, input_data: str | None) -> str: return Path(input_data).name if input_data else "" + + def example_inputs(self): + # TODO: Use permanent link + return "https://raw.githubusercontent.com/gradio-app/gradio/main/demo/model3D/files/Fox.gltf" diff --git a/gradio/components/number.py b/gradio/components/number.py index 6f6d0149ac50..85ad9a3aece4 100644 --- a/gradio/components/number.py +++ b/gradio/components/number.py @@ -2,38 +2,20 @@ from __future__ import annotations -import math import warnings -from typing import Callable, Literal +from typing import Any, Callable, Literal -import numpy as np from gradio_client.documentation import document, set_documentation_group -from gradio_client.serializing import NumberSerializable - -from gradio.components.base import FormComponent, IOComponent, _Keywords -from gradio.events import ( - Changeable, - Focusable, - Inputable, - Submittable, -) + +from gradio.components.base import FormComponent, _Keywords +from gradio.events import Events from gradio.exceptions import Error -from gradio.interpretation import NeighborInterpretable set_documentation_group("component") @document() -class Number( - FormComponent, - Changeable, - Inputable, - Submittable, - Focusable, - IOComponent, - NumberSerializable, - NeighborInterpretable, -): +class Number(FormComponent): """ Creates a numeric field for user to enter numbers as input or display numeric output. Preprocessing: passes field value as a {float} or {int} into the function, depending on `precision`. @@ -43,6 +25,8 @@ class Number( Demos: tax_calculator, titanic_survival, blocks_simple_squares """ + EVENTS = [Events.change, Events.input, Events.submit, Events.focus] + def __init__( self, value: float | Callable | None = None, @@ -88,8 +72,7 @@ def __init__( self.maximum = maximum self.step = step - IOComponent.__init__( - self, + super().__init__( label=label, info=info, every=every, @@ -104,7 +87,6 @@ def __init__( value=value, **kwargs, ) - NeighborInterpretable.__init__(self) @staticmethod def _round_to_precision(num: float | int, precision: int | None) -> float | int: @@ -188,51 +170,8 @@ def postprocess(self, y: float | None) -> float | None: return None return self._round_to_precision(y, self.precision) - def set_interpret_parameters( - self, steps: int = 3, delta: float = 1, delta_type: str = "percent" - ): - """ - Calculates interpretation scores of numeric values close to the input number. - Parameters: - steps: Number of nearby values to measure in each direction (above and below the input number). - delta: Size of step in each direction between nearby values. - delta_type: "percent" if delta step between nearby values should be a calculated as a percent, or "absolute" if delta should be a constant step change. - """ - self.interpretation_steps = steps - self.interpretation_delta = delta - self.interpretation_delta_type = delta_type - return self - - def get_interpretation_neighbors(self, x: float | int) -> tuple[list[float], dict]: - x = self._round_to_precision(x, self.precision) - if self.interpretation_delta_type == "percent": - delta = 1.0 * self.interpretation_delta * x / 100 - elif self.interpretation_delta_type == "absolute": - delta = self.interpretation_delta - else: - delta = self.interpretation_delta - if self.precision == 0 and math.floor(delta) != delta: - raise ValueError( - f"Delta value {delta} is not an integer and precision=0. Cannot generate valid set of neighbors. " - "If delta_type='percent', pick a value of delta such that x * delta is an integer. " - "If delta_type='absolute', pick a value of delta that is an integer." - ) - # run_interpretation will preprocess the neighbors so no need to convert to int here - negatives = ( - np.array(x) + np.arange(-self.interpretation_steps, 0) * delta - ).tolist() - positives = ( - np.array(x) + np.arange(1, self.interpretation_steps + 1) * delta - ).tolist() - return negatives + positives, {} - - def get_interpretation_scores( - self, x: float, neighbors: list[float], scores: list[float | None], **kwargs - ) -> list[tuple[float, float | None]]: - """ - Returns: - Each tuple set represents a numeric value near the input and its corresponding interpretation score. - """ - interpretation = list(zip(neighbors, scores)) - interpretation.insert(int(len(interpretation) / 2), (x, None)) - return interpretation + def api_info(self) -> dict[str, str]: + return {"type": "number"} + + def example_inputs(self) -> Any: + return 3 diff --git a/gradio/components/plot.py b/gradio/components/plot.py index 763f871c9d7b..03f37777efbe 100644 --- a/gradio/components/plot.py +++ b/gradio/components/plot.py @@ -10,18 +10,28 @@ import altair as alt import pandas as pd from gradio_client.documentation import document, set_documentation_group -from gradio_client.serializing import JSONSerializable from gradio import processing_utils -from gradio.components.base import IOComponent, _Keywords +from gradio.components.base import Component, _Keywords +from gradio.data_classes import GradioModel from gradio.deprecation import warn_style_method_deprecation -from gradio.events import Changeable, Clearable +from gradio.events import Events set_documentation_group("component") +class PlotData(GradioModel): + type: Literal["altair", "bokeh", "plotly", "matplotlib"] + plot: str + + +class AltairPlotData(PlotData): + chart: Literal["bar", "line", "scatter"] + type: Literal["altair"] = "altair" + + @document() -class Plot(Changeable, Clearable, IOComponent, JSONSerializable): +class Plot(Component): """ Used to display various kinds of plots (matplotlib, plotly, or bokeh are supported) Preprocessing: this component does *not* accept input. @@ -31,6 +41,9 @@ class Plot(Changeable, Clearable, IOComponent, JSONSerializable): Guides: plot-component-for-maps """ + data_model = PlotData + EVENTS = [Events.change, Events.clear] + def __init__( self, value: Callable | None | pd.DataFrame = None, @@ -59,8 +72,7 @@ def __init__( elem_id: An optional string that is assigned as the id of this component in the HTML DOM. Can be used for targeting CSS styles. elem_classes: An optional list of strings that are assigned as the classes of this component in the HTML DOM. Can be used for targeting CSS styles. """ - IOComponent.__init__( - self, + super().__init__( label=label, every=every, show_label=show_label, @@ -111,7 +123,13 @@ def update( } return updated_config - def postprocess(self, y) -> dict[str, str] | None: + def preprocess(self, x: Any) -> Any: + return x + + def example_inputs(self) -> Any: + return None + + def postprocess(self, y) -> PlotData | None: """ Parameters: y: plot data @@ -134,7 +152,7 @@ def postprocess(self, y) -> dict[str, str] | None: is_altair = "altair" in y.__module__ dtype = "altair" if is_altair else "plotly" out_y = y.to_json() - return {"type": dtype, "plot": out_y} + return PlotData(**{"type": dtype, "plot": out_y}) def style(self, container: bool | None = None): """ diff --git a/gradio/components/radio.py b/gradio/components/radio.py index 2e1d1aad80b9..8fe38483a52a 100644 --- a/gradio/components/radio.py +++ b/gradio/components/radio.py @@ -6,26 +6,15 @@ from typing import Any, Callable, Literal from gradio_client.documentation import document, set_documentation_group -from gradio_client.serializing import StringSerializable -from gradio.components.base import FormComponent, IOComponent, _Keywords -from gradio.deprecation import warn_deprecation, warn_style_method_deprecation -from gradio.events import Changeable, EventListenerMethod, Inputable, Selectable -from gradio.interpretation import NeighborInterpretable +from gradio.components.base import FormComponent, _Keywords +from gradio.events import Events set_documentation_group("component") @document() -class Radio( - FormComponent, - Selectable, - Changeable, - Inputable, - IOComponent, - StringSerializable, - NeighborInterpretable, -): +class Radio(FormComponent): """ Creates a set of (string or numeric type) radio buttons of which only one can be selected. Preprocessing: passes the value of the selected radio button as a {str} or {int} or {float} or its index as an {int} into the function, depending on `type`. @@ -35,6 +24,8 @@ class Radio( Demos: sentence_builder, titanic_survival, blocks_essay """ + EVENTS = [Events.select, Events.change, Events.input] + def __init__( self, choices: list[str | int | float | tuple[str, str | int | float]] | None = None, @@ -84,14 +75,7 @@ def __init__( f"Invalid value for parameter `type`: {type}. Please choose from one of: {valid_types}" ) self.type = type - self.select: EventListenerMethod - """ - Event listener for when the user selects Radio option. - Uses event data gradio.SelectData to carry `value` referring to label of selected option, and `index` to refer to index. - See EventData documentation on how to use this event data. - """ - IOComponent.__init__( - self, + super().__init__( label=label, info=info, every=every, @@ -106,13 +90,9 @@ def __init__( value=value, **kwargs, ) - NeighborInterpretable.__init__(self) - def example_inputs(self) -> dict[str, Any]: - return { - "raw": self.choices[0][1] if self.choices else None, - "serialized": self.choices[0][1] if self.choices else None, - } + def example_inputs(self) -> Any: + return self.choices[0][1] if self.choices else None @staticmethod def update( @@ -173,38 +153,15 @@ def preprocess(self, x: str | int | float | None) -> str | int | float | None: f"Unknown type: {self.type}. Please choose from: 'value', 'index'." ) - def get_interpretation_neighbors(self, x): - choices = [value for _, value in self.choices] - choices.remove(x) - return choices, {} - - def get_interpretation_scores( - self, x, neighbors, scores: list[float | None], **kwargs - ) -> list: - """ - Returns: - Each value represents the interpretation score corresponding to each choice. - """ - choices = [value for _, value in self.choices] - scores.insert(choices.index(x), None) - return scores + def postprocess(self, y): + return y - def style( - self, - *, - item_container: bool | None = None, - container: bool | None = None, - **kwargs, - ): - """ - This method is deprecated. Please set these arguments in the constructor instead. - """ - warn_style_method_deprecation() - if item_container is not None: - warn_deprecation("The `item_container` parameter is deprecated.") - if container is not None: - self.container = container - return self + def api_info(self) -> dict[str, Any]: + return { + "enum": [c[1] for c in self.choices], + "title": "Radio", + "type": "string", + } def as_example(self, input_data): return next((c[0] for c in self.choices if c[1] == input_data), None) diff --git a/gradio/components/scatter_plot.py b/gradio/components/scatter_plot.py index 2369570eb87e..d5c57f96fa8a 100644 --- a/gradio/components/scatter_plot.py +++ b/gradio/components/scatter_plot.py @@ -3,7 +3,7 @@ from __future__ import annotations import warnings -from typing import Callable, Literal +from typing import Any, Callable, Literal import altair as alt import pandas as pd @@ -11,7 +11,7 @@ from pandas.api.types import is_numeric_dtype from gradio.components.base import _Keywords -from gradio.components.plot import AltairPlot, Plot +from gradio.components.plot import AltairPlot, AltairPlotData, Plot set_documentation_group("component") @@ -28,6 +28,8 @@ class ScatterPlot(Plot): Guides: creating-a-dashboard-from-bigquery-data """ + data_model = AltairPlotData + def __init__( self, value: pd.DataFrame | Callable | None = None, @@ -463,7 +465,9 @@ def create_plot( return chart - def postprocess(self, y: pd.DataFrame | dict | None) -> dict[str, str] | None: + def postprocess( + self, y: pd.DataFrame | dict | None + ) -> AltairPlotData | dict | None: # if None or update if y is None or isinstance(y, dict): return y @@ -495,4 +499,12 @@ def postprocess(self, y: pd.DataFrame | dict | None) -> dict[str, str] | None: y_lim=self.y_lim, ) - return {"type": "altair", "plot": chart.to_json(), "chart": "scatter"} + return AltairPlotData( + **{"type": "altair", "plot": chart.to_json(), "chart": "scatter"} + ) + + def example_inputs(self) -> Any: + return None + + def preprocess(self, x: Any) -> Any: + return x diff --git a/gradio/components/slider.py b/gradio/components/slider.py index 514fec178b6a..7c1162259993 100644 --- a/gradio/components/slider.py +++ b/gradio/components/slider.py @@ -7,28 +7,16 @@ import warnings from typing import Any, Callable, Literal -import numpy as np from gradio_client.documentation import document, set_documentation_group -from gradio_client.serializing import NumberSerializable -from gradio.components.base import FormComponent, IOComponent, _Keywords -from gradio.deprecation import warn_style_method_deprecation -from gradio.events import Changeable, Inputable, Releaseable -from gradio.interpretation import NeighborInterpretable +from gradio.components.base import FormComponent, _Keywords +from gradio.events import Events set_documentation_group("component") @document() -class Slider( - FormComponent, - Changeable, - Inputable, - Releaseable, - IOComponent, - NumberSerializable, - NeighborInterpretable, -): +class Slider(FormComponent): """ Creates a slider that ranges from `minimum` to `maximum` with a step size of `step`. Preprocessing: passes slider value as a {float} into the function. @@ -39,6 +27,8 @@ class Slider( Guides: create-your-own-friends-with-a-gan """ + EVENTS = [Events.change, Events.input, Events.release] + def __init__( self, minimum: float = 0, @@ -89,8 +79,7 @@ def __init__( self.step = step if randomize: value = self.get_random_value - IOComponent.__init__( - self, + super().__init__( label=label, info=info, every=every, @@ -105,22 +94,15 @@ def __init__( value=value, **kwargs, ) - NeighborInterpretable.__init__(self) - def api_info(self) -> dict[str, dict | bool]: + def api_info(self) -> dict[str, Any]: return { - "info": { - "type": "number", - "description": f"numeric value between {self.minimum} and {self.maximum}", - }, - "serialized_info": False, + "type": "number", + "description": f"numeric value between {self.minimum} and {self.maximum}", } - def example_inputs(self) -> dict[str, Any]: - return { - "raw": self.minimum, - "serialized": self.minimum, - } + def example_inputs(self) -> Any: + return self.minimum def get_random_value(self): n_steps = int((self.maximum - self.minimum) / self.step) @@ -176,30 +158,5 @@ def postprocess(self, y: float | None) -> float | None: """ return self.minimum if y is None else y - def set_interpret_parameters(self, steps: int = 8) -> Slider: - """ - Calculates interpretation scores of numeric values ranging between the minimum and maximum values of the slider. - Parameters: - steps: Number of neighboring values to measure between the minimum and maximum values of the slider range. - """ - self.interpretation_steps = steps - return self - - def get_interpretation_neighbors(self, x) -> tuple[object, dict]: - return ( - np.linspace(self.minimum, self.maximum, self.interpretation_steps).tolist(), - {}, - ) - - def style( - self, - *, - container: bool | None = None, - ): - """ - This method is deprecated. Please set these arguments in the constructor instead. - """ - warn_style_method_deprecation() - if container is not None: - self.container = container - return self + def preprocess(self, x: Any) -> Any: + return x diff --git a/gradio/components/state.py b/gradio/components/state.py index c027875b090f..a20689adab9f 100644 --- a/gradio/components/state.py +++ b/gradio/components/state.py @@ -6,15 +6,15 @@ from typing import Any from gradio_client.documentation import document, set_documentation_group -from gradio_client.serializing import SimpleSerializable -from gradio.components.base import IOComponent +from gradio.components.base import Component set_documentation_group("component") @document() -class State(IOComponent, SimpleSerializable): +class State(Component): + EVENTS = [] """ Special hidden component that stores session state across runs of the demo by the same user. The value of the State variable is cleared when the user refreshes the page. @@ -43,7 +43,23 @@ def __init__( raise TypeError( f"The initial value of `gr.State` must be able to be deepcopied. The initial value of type {type(value)} cannot be deepcopied." ) from err - IOComponent.__init__(self, value=self.value, **kwargs) + super().__init__(value=self.value, **kwargs) + + def preprocess(self, x: Any) -> Any: + return x + + def postprocess(self, y): + return y + + def api_info(self) -> dict[str, Any]: + return {"type": {}, "description": "any valid json"} + + def example_inputs(self) -> Any: + return None + + @property + def skip_api(self): + return True class Variable(State): diff --git a/gradio/components/status_tracker.py b/gradio/components/status_tracker.py index a9abec2969d9..b5a9d35f9d4d 100644 --- a/gradio/components/status_tracker.py +++ b/gradio/components/status_tracker.py @@ -1,11 +1,11 @@ """gr.StatusTracker() component.""" -from gradio_client.serializing import SimpleSerializable - from gradio.components.base import Component from gradio.deprecation import warn_deprecation -class StatusTracker(Component, SimpleSerializable): +class StatusTracker(Component): + EVENTS = [] + def __init__( self, **kwargs, diff --git a/gradio/components/textbox.py b/gradio/components/textbox.py index 7b8bed6e19a4..9617ef7faa15 100644 --- a/gradio/components/textbox.py +++ b/gradio/components/textbox.py @@ -3,43 +3,21 @@ from __future__ import annotations import warnings -from typing import Callable, Literal +from typing import Any, Callable, Literal -import numpy as np from gradio_client.documentation import document, set_documentation_group -from gradio_client.serializing import StringSerializable from gradio.components.base import ( FormComponent, - IOComponent, _Keywords, ) -from gradio.deprecation import warn_style_method_deprecation -from gradio.events import ( - Changeable, - EventListenerMethod, - Focusable, - Inputable, - Selectable, - Submittable, -) -from gradio.interpretation import TokenInterpretable +from gradio.events import Events set_documentation_group("component") @document() -class Textbox( - FormComponent, - Changeable, - Inputable, - Selectable, - Submittable, - Focusable, - IOComponent, - StringSerializable, - TokenInterpretable, -): +class Textbox(FormComponent): """ Creates a textarea for user to enter string input or display string output. Preprocessing: passes textarea value as a {str} into the function. @@ -50,6 +28,15 @@ class Textbox( Guides: creating-a-chatbot, real-time-speech-recognition """ + EVENTS = [ + Events.change, + Events.input, + Events.select, + Events.submit, + Events.focus, + Events.blur, + ] + def __init__( self, value: str | Callable | None = "", @@ -111,15 +98,8 @@ def __init__( self.placeholder = placeholder self.show_copy_button = show_copy_button self.autofocus = autofocus - self.select: EventListenerMethod self.autoscroll = autoscroll - """ - Event listener for when the user selects text in the Textbox. - Uses event data gradio.SelectData to carry `value` referring to selected substring, and `index` tuple referring to selected range endpoints. - See EventData documentation on how to use this event data. - """ - IOComponent.__init__( - self, + super().__init__( label=label, info=info, every=every, @@ -134,7 +114,6 @@ def __init__( value=value, **kwargs, ) - TokenInterpretable.__init__(self) self.type = type self.rtl = rtl self.text_align = text_align @@ -205,74 +184,8 @@ def postprocess(self, y: str | None) -> str | None: """ return None if y is None else str(y) - def set_interpret_parameters( - self, separator: str = " ", replacement: str | None = None - ): - """ - Calculates interpretation score of characters in input by splitting input into tokens, then using a "leave one out" method to calculate the score of each token by removing each token and measuring the delta of the output value. - Parameters: - separator: Separator to use to split input into tokens. - replacement: In the "leave one out" step, the text that the token should be replaced with. If None, the token is removed altogether. - """ - self.interpretation_separator = separator - self.interpretation_replacement = replacement - return self - - def tokenize(self, x: str) -> tuple[list[str], list[str], None]: - """ - Tokenizes an input string by dividing into "words" delimited by self.interpretation_separator - """ - tokens = x.split(self.interpretation_separator) - leave_one_out_strings = [] - for index in range(len(tokens)): - leave_one_out_set = list(tokens) - if self.interpretation_replacement is None: - leave_one_out_set.pop(index) - else: - leave_one_out_set[index] = self.interpretation_replacement - leave_one_out_strings.append( - self.interpretation_separator.join(leave_one_out_set) - ) - return tokens, leave_one_out_strings, None + def api_info(self) -> dict[str, Any]: + return {"type": "string"} - def get_masked_inputs( - self, tokens: list[str], binary_mask_matrix: list[list[int]] - ) -> list[str]: - """ - Constructs partially-masked sentences for SHAP interpretation - """ - masked_inputs = [] - for binary_mask_vector in binary_mask_matrix: - masked_input = np.array(tokens)[np.array(binary_mask_vector, dtype=bool)] - masked_inputs.append(self.interpretation_separator.join(masked_input)) - return masked_inputs - - def get_interpretation_scores( - self, x, neighbors, scores: list[float], tokens: list[str], masks=None, **kwargs - ) -> list[tuple[str, float]]: - """ - Returns: - Each tuple set represents a set of characters and their corresponding interpretation score. - """ - result = [] - for token, score in zip(tokens, scores): - result.append((token, score)) - result.append((self.interpretation_separator, 0)) - return result - - def style( - self, - *, - show_copy_button: bool | None = None, - container: bool | None = None, - **kwargs, - ): - """ - This method is deprecated. Please set these arguments in the constructor instead. - """ - warn_style_method_deprecation() - if show_copy_button is not None: - self.show_copy_button = show_copy_button - if container is not None: - self.container = container - return self + def example_inputs(self) -> Any: + return "Hello!!" diff --git a/gradio/components/timeseries.py b/gradio/components/timeseries.py deleted file mode 100644 index 7cdd82ecb092..000000000000 --- a/gradio/components/timeseries.py +++ /dev/null @@ -1,152 +0,0 @@ -"""gr.Timeseries() component.""" - -from __future__ import annotations - -import warnings -from pathlib import Path -from typing import Any, Callable, Literal - -import pandas as pd -from gradio_client.documentation import document, set_documentation_group -from gradio_client.serializing import JSONSerializable - -from gradio.components.base import IOComponent, _Keywords -from gradio.events import Changeable - -set_documentation_group("component") - - -@document() -class Timeseries(Changeable, IOComponent, JSONSerializable): - """ - Creates a component that can be used to upload/preview timeseries csv files or display a dataframe consisting of a time series graphically. - Preprocessing: passes the uploaded timeseries data as a {pandas.DataFrame} into the function - Postprocessing: expects a {pandas.DataFrame} or {str} path to a csv to be returned, which is then displayed as a timeseries graph - Examples-format: a {str} filepath of csv data with time series data. - Demos: fraud_detector - """ - - def __init__( - self, - value: str | Callable | None = None, - *, - x: str | None = None, - y: str | list[str] | None = None, - colors: list[str] | None = None, - label: str | None = None, - every: float | None = None, - show_label: bool | None = None, - container: bool = True, - scale: int | None = None, - min_width: int = 160, - interactive: bool | None = None, - visible: bool = True, - elem_id: str | None = None, - elem_classes: list[str] | str | None = None, - **kwargs, - ): - """ - Parameters: - value: File path for the timeseries csv file. If callable, the function will be called whenever the app loads to set the initial value of the component. - x: Column name of x (time) series. None if csv has no headers, in which case first column is x series. - y: Column name of y series, or list of column names if multiple series. None if csv has no headers, in which case every column after first is a y series. - label: component name in interface. - every: If `value` is a callable, run the function 'every' number of seconds while the client connection is open. Has no effect otherwise. Queue must be enabled. The event can be accessed (e.g. to cancel it) via this component's .load_event attribute. - colors: an ordered list of colors to use for each line plot - show_label: if True, will display label. - container: If True, will place the component in a container - providing some extra padding around the border. - scale: relative width compared to adjacent Components in a Row. For example, if Component A has scale=2, and Component B has scale=1, A will be twice as wide as B. Should be an integer. - min_width: minimum pixel width, will wrap if not sufficient screen space to satisfy this value. If a certain scale value results in this Component being narrower than min_width, the min_width parameter will be respected first. - interactive: if True, will allow users to upload a timeseries csv; if False, can only be used to display timeseries data. If not provided, this is inferred based on whether the component is used as an input or output. - visible: If False, component will be hidden. - elem_id: An optional string that is assigned as the id of this component in the HTML DOM. Can be used for targeting CSS styles. - elem_classes: An optional list of strings that are assigned as the classes of this component in the HTML DOM. Can be used for targeting CSS styles. - """ - self.x = x - if isinstance(y, str): - y = [y] - self.y = y - self.colors = colors - IOComponent.__init__( - self, - label=label, - every=every, - show_label=show_label, - container=container, - scale=scale, - min_width=min_width, - interactive=interactive, - visible=visible, - elem_id=elem_id, - elem_classes=elem_classes, - value=value, - **kwargs, - ) - - @staticmethod - def update( - value: Any | Literal[_Keywords.NO_VALUE] | None = _Keywords.NO_VALUE, - colors: list[str] | None = None, - label: str | None = None, - show_label: bool | None = None, - container: bool | None = None, - scale: int | None = None, - min_width: int | None = None, - interactive: bool | None = None, - visible: bool | None = None, - ): - warnings.warn( - "Using the update method is deprecated. Simply return a new object instead, e.g. `return gr.Timeseries(...)` instead of `return gr.Timeseries.update(...)`." - ) - return { - "colors": colors, - "label": label, - "show_label": show_label, - "container": container, - "scale": scale, - "min_width": min_width, - "interactive": interactive, - "visible": visible, - "value": value, - "__type__": "update", - } - - def preprocess(self, x: dict | None) -> pd.DataFrame | None: - """ - Parameters: - x: Dict with keys 'data': 2D array of str, numeric, or bool data, 'headers': list of strings for header names, 'range': optional two element list designating start of end of subrange. - Returns: - Dataframe of timeseries data - """ - if x is None: - return x - elif x.get("is_file"): - dataframe = pd.read_csv(x["name"]) - else: - dataframe = pd.DataFrame(data=x["data"], columns=x["headers"]) - if x.get("range") is not None: - dataframe = dataframe.loc[dataframe[self.x or 0] >= x["range"][0]] - dataframe = dataframe.loc[dataframe[self.x or 0] <= x["range"][1]] - return dataframe - - def postprocess(self, y: str | pd.DataFrame | None) -> dict | None: - """ - Parameters: - y: csv or dataframe with timeseries data - Returns: - JSON object with key 'headers' for list of header names, 'data' for 2D array of string or numeric data - """ - if y is None: - return None - if isinstance(y, str): - dataframe = pd.read_csv(y) - return { - "headers": dataframe.columns.values.tolist(), - "data": dataframe.values.tolist(), - } - if isinstance(y, pd.DataFrame): - return {"headers": y.columns.values.tolist(), "data": y.values.tolist()} - raise ValueError("Cannot process value as Timeseries data") - - def as_example(self, input_data: str | None) -> str: - return Path(input_data).name if input_data else "" diff --git a/gradio/components/upload_button.py b/gradio/components/upload_button.py index 268c6bfc0e91..27eb6a78474e 100644 --- a/gradio/components/upload_button.py +++ b/gradio/components/upload_button.py @@ -4,22 +4,25 @@ import tempfile import warnings -from typing import Any, Callable, Literal +from typing import Any, Callable, List, Literal -from gradio_client import utils as client_utils from gradio_client.documentation import document, set_documentation_group -from gradio_client.serializing import FileSerializable -from gradio import utils -from gradio.components.base import IOComponent, _Keywords +from gradio.components.base import Component, _Keywords +from gradio.components.file import File +from gradio.data_classes import FileData, GradioRootModel from gradio.deprecation import warn_deprecation, warn_style_method_deprecation -from gradio.events import Clickable, Uploadable +from gradio.events import Events set_documentation_group("component") +class ListFiles(GradioRootModel): + root: List[FileData] + + @document() -class UploadButton(Clickable, Uploadable, IOComponent, FileSerializable): +class UploadButton(Component): """ Used to create an upload button, when clicked allows a user to upload files that satisfy the specified file type or generic files (if file_type not set). Preprocessing: passes the uploaded file as a {file-object} or {List[file-object]} depending on `file_count` (or a {bytes}/{List[bytes]} depending on `type`) @@ -28,6 +31,8 @@ class UploadButton(Clickable, Uploadable, IOComponent, FileSerializable): Demos: upload_button """ + EVENTS = [Events.click, Events.upload] + def __init__( self, label: str = "Upload a File", @@ -76,8 +81,7 @@ def __init__( self.file_types = file_types self.label = label self.variant = variant - IOComponent.__init__( - self, + super().__init__( label=label, visible=visible, elem_id=elem_id, @@ -89,6 +93,20 @@ def __init__( **kwargs, ) + def api_info(self) -> dict[str, list[str]]: + if self.file_count == "single": + return FileData.model_json_schema() + else: + return ListFiles.model_json_schema() + + def example_inputs(self) -> Any: + if self.file_count == "single": + return "https://github.com/gradio-app/gradio/raw/main/test/test_files/sample_file.pdf" + else: + return [ + "https://github.com/gradio-app/gradio/raw/main/test/test_files/sample_file.pdf" + ] + @staticmethod def update( value: str @@ -135,48 +153,30 @@ def preprocess( if x is None: return None - def process_single_file(f) -> bytes | tempfile._TemporaryFileWrapper: - file_name, data, is_file = ( - f["name"], - f["data"], - f.get("is_file", False), - ) - if self.type == "file": - if is_file: - path = self.make_temp_copy_if_needed(file_name) - else: - data, _ = client_utils.decode_base64_to_binary(data) - path = self.file_bytes_to_file(data, file_name=file_name) - path = str(utils.abspath(path)) - self.temp_files.add(path) - file = tempfile.NamedTemporaryFile( - delete=False, dir=self.DEFAULT_TEMP_DIR - ) - file.name = path - file.orig_name = file_name # type: ignore - return file - elif self.type == "bytes": - if is_file: - with open(file_name, "rb") as file_data: - return file_data.read() - return client_utils.decode_base64_to_binary(data)[0] - else: - raise ValueError( - "Unknown type: " - + str(self.type) - + ". Please choose from: 'file', 'bytes'." - ) - if self.file_count == "single": if isinstance(x, list): - return process_single_file(x[0]) + return File._process_single_file( + x[0], type=self.type, cache_dir=self.GRADIO_CACHE # type: ignore + ) else: - return process_single_file(x) + return File._process_single_file( + x, type=self.type, cache_dir=self.GRADIO_CACHE # type: ignore + ) else: if isinstance(x, list): - return [process_single_file(f) for f in x] + return [ + File._process_single_file( + f, type=self.type, cache_dir=self.GRADIO_CACHE # type: ignore + ) + for f in x + ] else: - return process_single_file(x) + return File._process_single_file( + x, type=self.type, cache_dir=self.GRADIO_CACHE # type: ignore + ) + + def postprocess(self, y): + return super().postprocess(y) def style( self, @@ -198,3 +198,7 @@ def style( if size is not None: self.size = size return self + + @property + def skip_api(self): + return False diff --git a/gradio/components/video.py b/gradio/components/video.py index 5b1d3e5a7473..cc5ee825e2a5 100644 --- a/gradio/components/video.py +++ b/gradio/components/video.py @@ -5,17 +5,16 @@ import tempfile import warnings from pathlib import Path -from typing import Callable, Literal +from typing import Any, Callable, Literal, Optional from gradio_client import utils as client_utils -from gradio_client.data_classes import FileData from gradio_client.documentation import document, set_documentation_group -from gradio_client.serializing import VideoSerializable from gradio import processing_utils, utils, wasm_utils -from gradio.components.base import IOComponent, _Keywords +from gradio.components.base import Component, _Keywords +from gradio.data_classes import FileData, GradioModel from gradio.deprecation import warn_style_method_deprecation -from gradio.events import Changeable, Clearable, Playable, Recordable, Uploadable +from gradio.events import Events if not wasm_utils.IS_WASM: # TODO: Support ffmpeg on Wasm @@ -24,16 +23,13 @@ set_documentation_group("component") +class VideoData(GradioModel): + video: FileData + subtitles: Optional[FileData] = None + + @document() -class Video( - Changeable, - Clearable, - Playable, - Recordable, - Uploadable, - IOComponent, - VideoSerializable, -): +class Video(Component): """ Creates a video component that can be used to upload/record videos (as an input) or display videos (as an output). For the video to be playable in the browser it must have a compatible container and codec combination. Allowed @@ -46,6 +42,19 @@ class Video( Demos: video_identity, video_subtitle """ + data_model = VideoData + input_data_model = FileData + EVENTS = [ + Events.change, + Events.clear, + Events.start_recording, + Events.stop_recording, + Events.stop, + Events.play, + Events.pause, + Events.end, + ] + def __init__( self, value: str @@ -115,8 +124,7 @@ def __init__( if show_share_button is None else show_share_button ) - IOComponent.__init__( - self, + super().__init__( label=label, every=every, show_label=show_label, @@ -170,9 +178,7 @@ def update( "__type__": "update", } - def preprocess( - self, x: tuple[FileData, FileData | None] | FileData | None - ) -> str | None: + def preprocess(self, x: dict | VideoData) -> str | None: """ Parameters: x: A tuple of (video file data, subtitle file data) or just video file data. @@ -181,30 +187,9 @@ def preprocess( """ if x is None: return None - elif isinstance(x, dict): - video = x - else: - video = x[0] - - file_name, file_data, is_file = ( - video.get("name"), - video["data"], - video.get("is_file", False), - ) - - if is_file: - if file_name is None: - raise ValueError("Received file data without a file name.") - if client_utils.is_http_url_like(file_name): - fn = self.download_temp_copy_if_needed - else: - fn = self.make_temp_copy_if_needed - file_name = Path(fn(file_name)) - else: - if file_data is None: - raise ValueError("Received empty file data.") - file_name = Path(self.base64_to_temp_file_if_needed(file_data, file_name)) - + data: VideoData = VideoData(**x) if isinstance(x, dict) else x + assert data.video.name + file_name = Path(data.video.name) uploaded_format = file_name.suffix.replace(".", "") needs_formatting = self.format is not None and uploaded_format != self.format flip = self.source == "webcam" and self.mirror_webcam @@ -248,7 +233,7 @@ def preprocess( def postprocess( self, y: str | Path | tuple[str | Path, str | Path | None] | None - ) -> tuple[FileData | None, FileData | None] | None: + ) -> VideoData | None: """ Processes a video to ensure that it is in the correct format before returning it to the front end. Parameters: @@ -289,8 +274,8 @@ def postprocess( ) else: raise Exception(f"Cannot process type as video: {type(y)}") - - return processed_files + assert processed_files[0] + return VideoData(video=processed_files[0], subtitles=processed_files[1]) def _format_video(self, video: str | Path | None) -> FileData | None: """ @@ -317,11 +302,13 @@ def _format_video(self, video: str | Path | None) -> FileData | None: # For cases where the video is a URL and does not need to be converted to another format, we can just return the URL if is_url and not (conversion_needed): - return {"name": video, "data": None, "is_file": True} + return FileData(name=video, is_file=True) # For cases where the video needs to be converted to another format if is_url: - video = self.download_temp_copy_if_needed(video) + video = processing_utils.save_url_to_cache( + video, cache_dir=self.GRADIO_CACHE + ) if ( processing_utils.ffmpeg_installed() and not processing_utils.video_is_playable(video) @@ -347,14 +334,7 @@ def _format_video(self, video: str | Path | None) -> FileData | None: ff.run() video = output_file_name - video = self.make_temp_copy_if_needed(video) - - return { - "name": video, - "data": None, - "is_file": True, - "orig_name": Path(video).name, - } + return FileData(name=video, data=None, is_file=True, orig_name=Path(video).name) def _format_subtitle(self, subtitle: str | Path | None) -> FileData | None: """ @@ -394,14 +374,14 @@ def srt_to_vtt(srt_file_path, vtt_file_path): # HTML5 only support vtt format if Path(subtitle).suffix == ".srt": temp_file = tempfile.NamedTemporaryFile( - delete=False, suffix=".vtt", dir=self.DEFAULT_TEMP_DIR + delete=False, suffix=".vtt", dir=self.GRADIO_CACHE ) srt_to_vtt(subtitle, temp_file.name) subtitle = temp_file.name subtitle_data = client_utils.encode_url_or_file_to_base64(subtitle) - return {"name": None, "data": subtitle_data, "is_file": False} + return FileData(name=None, data=subtitle_data, is_file=False) def style(self, *, height: int | None = None, width: int | None = None, **kwargs): """ @@ -413,3 +393,6 @@ def style(self, *, height: int | None = None, width: int | None = None, **kwargs if width is not None: self.width = width return self + + def example_inputs(self) -> Any: + return "https://github.com/gradio-app/gradio/raw/main/demo/video_component/files/world.mp4" diff --git a/gradio/data_classes.py b/gradio/data_classes.py index 514bed2accca..33a342e67828 100644 --- a/gradio/data_classes.py +++ b/gradio/data_classes.py @@ -1,9 +1,16 @@ """Pydantic data models and other dataclasses. This is the only file that uses Optional[] typing syntax instead of | None syntax to work with pydantic""" +from __future__ import annotations + +import pathlib +import secrets +import shutil +from abc import ABC, abstractmethod from enum import Enum, auto -from typing import Any, Dict, List, Optional, Union +from typing import Any, List, Optional, Union -from pydantic import BaseModel +from gradio_client.utils import traverse +from pydantic import BaseModel, RootModel, ValidationError from typing_extensions import Literal @@ -17,7 +24,7 @@ class PredictBody(BaseModel): bool ] = False # Whether the data is a batch of samples (i.e. called from the queue if batch=True) or a single sample (i.e. called from the UI) request: Optional[ - Union[Dict, List[Dict]] + Union[dict, List[dict]] ] = None # dictionary of request headers, query parameters, url, etc. (used to to pass in request for queuing) @@ -67,3 +74,90 @@ class LogMessage(BaseModel): msg: str = "log" log: str level: Literal["info", "warning"] + + +class GradioBaseModel(ABC): + def copy_to_dir(self, dir: str | pathlib.Path) -> GradioDataModel: + assert isinstance(self, (BaseModel, RootModel)) + if isinstance(dir, str): + dir = pathlib.Path(dir) + + # TODO: Making sure path is unique should be done in caller + def unique_copy(obj: dict): + data = FileData(**obj) + return data._copy_to_dir( + str(pathlib.Path(dir / secrets.token_hex(10))) + ).model_dump() + + return self.__class__.from_json( + x=traverse( + self.model_dump(), + unique_copy, + FileData.is_file_data, + ) + ) + + @classmethod + @abstractmethod + def from_json(cls, x) -> GradioDataModel: + pass + + +class GradioModel(GradioBaseModel, BaseModel): + @classmethod + def from_json(cls, x) -> GradioModel: + return cls(**x) + + +class GradioRootModel(GradioBaseModel, RootModel): + @classmethod + def from_json(cls, x) -> GradioRootModel: + return cls(root=x) + + +GradioDataModel = Union[GradioModel, GradioRootModel] + + +class FileData(GradioModel): + name: Optional[str] = None + data: Optional[str] = None # base64 encoded data + size: Optional[int] = None # size in bytes + is_file: Optional[bool] = None + orig_name: Optional[str] = None # original filename + mime_type: Optional[str] = None + + @property + def is_none(self): + return all( + f is None + for f in [ + self.name, + self.data, + self.size, + self.is_file, + self.orig_name, + self.mime_type, + ] + ) + + @classmethod + def from_path(cls, path: str) -> FileData: + return cls(name=path, is_file=True) + + def _copy_to_dir(self, dir: str) -> FileData: + pathlib.Path(dir).mkdir(exist_ok=True) + new_obj = dict(self) + if self.is_file: + assert self.name + new_name = shutil.copy(self.name, dir) + new_obj["name"] = new_name + return self.__class__(**new_obj) + + @classmethod + def is_file_data(cls, obj: Any): + if isinstance(obj, dict): + try: + return not FileData(**obj).is_none + except (TypeError, ValidationError): + return False + return False diff --git a/gradio/events.py b/gradio/events.py index 2fb5fdcf56d4..48a84d88cec6 100644 --- a/gradio/events.py +++ b/gradio/events.py @@ -3,22 +3,20 @@ from __future__ import annotations -from functools import wraps +import dataclasses +import string +from functools import partial, wraps from typing import TYPE_CHECKING, Any, Callable, Literal, Sequence -from gradio_client.documentation import document, set_documentation_group +from gradio_client.documentation import document + +if TYPE_CHECKING: + from gradio.blocks import Block, Component -from gradio.blocks import Block from gradio.context import Context from gradio.deprecation import warn_deprecation -from gradio.helpers import EventData from gradio.utils import get_cancel_function -if TYPE_CHECKING: # Only import for type checking (is False at runtime). - from gradio.components import Component - -set_documentation_group("events") - def set_cancel_events( triggers: Sequence[EventListenerMethod], @@ -41,35 +39,35 @@ def set_cancel_events( outputs=None, queue=False, preprocess=False, + api_name=False, cancels=fn_indices_to_cancel, ) -class EventListener(Block): - def __init__(self: Any): - for event_listener_class in EventListener.__subclasses__(): - if isinstance(self, event_listener_class): - event_listener_class.__init__(self) - - class Dependency(dict): - def __init__(self, key_vals, dep_index, fn): + def __init__(self, trigger, key_vals, dep_index, fn): super().__init__(key_vals) self.fn = fn - self.then = EventListenerMethod( - None, - "then", - trigger_after=dep_index, - trigger_only_on_success=False, + self.then = partial( + EventListener( + "then", + trigger_after=dep_index, + trigger_only_on_success=False, + has_trigger=False, + ).listener, + trigger, ) """ Triggered after directly preceding event is completed, regardless of success or failure. """ - self.success = EventListenerMethod( - None, - "success", - trigger_after=dep_index, - trigger_only_on_success=True, + self.success = partial( + EventListener( + "success", + trigger_after=dep_index, + trigger_only_on_success=True, + has_trigger=False, + ).listener, + trigger, ) """ Triggered after directly preceding event is completed, if it was successful. @@ -79,138 +77,242 @@ def __call__(self, *args, **kwargs): return self.fn(*args, **kwargs) -class EventListenerMethod: +@document() +class EventData: """ - Triggered on an event deployment. + When a subclass of EventData is added as a type hint to an argument of an event listener method, this object will be passed as that argument. + It contains information about the event that triggered the listener, such the target object, and other data related to the specific event that are attributes of the subclass. + + Example: + table = gr.Dataframe([[1, 2, 3], [4, 5, 6]]) + gallery = gr.Gallery([("cat.jpg", "Cat"), ("dog.jpg", "Dog")]) + textbox = gr.Textbox("Hello World!") + + statement = gr.Textbox() + + def on_select(evt: gr.SelectData): # SelectData is a subclass of EventData + return f"You selected {evt.value} at {evt.index} from {evt.target}" + + table.select(on_select, None, statement) + gallery.select(on_select, None, statement) + textbox.select(on_select, None, statement) + Demos: gallery_selections, tictactoe """ + def __init__(self, target: Block | None, _data: Any): + """ + Parameters: + target: The target object that triggered the event. Can be used to distinguish if multiple components are bound to the same listener. + """ + self.target = target + self._data = _data + + +class SelectData(EventData): + def __init__(self, target: Block | None, data: Any): + super().__init__(target, data) + self.index: int | tuple[int, int] = data["index"] + """ + The index of the selected item. Is a tuple if the component is two dimensional or selection is a range. + """ + self.value: Any = data["value"] + """ + The value of the selected item. + """ + self.selected: bool = data.get("selected", True) + """ + True if the item was selected, False if deselected. + """ + + +@dataclasses.dataclass +class EventListenerMethod: + block: Block | None + event_name: str + + +class EventListener(str): + def __new__(cls, event_name, *args, **kwargs): + return super().__new__(cls, event_name) + def __init__( self, - trigger: Block | None, event_name: str, - show_progress: Literal["full", "minimal", "hidden"] = "full", + has_trigger: bool = True, + config_data: Callable[..., dict[str, Any]] = lambda: {}, + show_progress: Literal["full", "minimal", "hidden"] | None = None, callback: Callable | None = None, trigger_after: int | None = None, trigger_only_on_success: bool = False, ): - self.trigger = trigger + super().__init__() + self.has_trigger = has_trigger + self.config_data = config_data self.event_name = event_name self.show_progress = show_progress - self.callback = callback self.trigger_after = trigger_after self.trigger_only_on_success = trigger_only_on_success + self.callback = callback + self.listener = self._setup( + event_name, + has_trigger, + show_progress, + callback, + trigger_after, + trigger_only_on_success, + ) - def __call__( - self, - fn: Callable | None | Literal["decorator"] = "decorator", - inputs: Component | Sequence[Component] | set[Component] | None = None, - outputs: Component | Sequence[Component] | None = None, - api_name: str | None | Literal[False] = None, - status_tracker: None = None, - scroll_to_output: bool = False, - show_progress: Literal["full", "minimal", "hidden"] | None = None, - queue: bool | None = None, - batch: bool = False, - max_batch_size: int = 4, - preprocess: bool = True, - postprocess: bool = True, - cancels: dict[str, Any] | list[dict[str, Any]] | None = None, - every: float | None = None, - _js: str | None = None, - ) -> Dependency: - """ - Parameters: - fn: the function to call when this event is triggered. Often a machine learning model's prediction function. Each parameter of the function corresponds to one input component, and the function should return a single value or a tuple of values, with each element in the tuple corresponding to one output component. - inputs: List of gradio.components to use as inputs. If the function takes no inputs, this should be an empty list. - outputs: List of gradio.components to use as outputs. If the function returns no outputs, this should be an empty list. - api_name: Defines how the endpoint appears in the API docs. Can be a string, None, or False. If False, the endpoint will not be exposed in the api docs. If set to None, the endpoint will be exposed in the api docs as an unnamed endpoint, although this behavior will be changed in Gradio 4.0. If set to a string, the endpoint will be exposed in the api docs with the given name. - status_tracker: Deprecated and has no effect. - scroll_to_output: If True, will scroll to output component on completion - show_progress: If True, will show progress animation while pending - queue: If True, will place the request on the queue, if the queue has been enabled. If False, will not put this event on the queue, even if the queue has been enabled. If None, will use the queue setting of the gradio app. - batch: If True, then the function should process a batch of inputs, meaning that it should accept a list of input values for each parameter. The lists should be of equal length (and be up to length `max_batch_size`). The function is then *required* to return a tuple of lists (even if there is only 1 output component), with each list in the tuple corresponding to one output component. - max_batch_size: Maximum number of inputs to batch together if this is called from the queue (only relevant if batch=True) - preprocess: If False, will not run preprocessing of component data before running 'fn' (e.g. leaving it as a base64 string if this method is called with the `Image` component). - postprocess: If False, will not run postprocessing of component data before returning 'fn' output to the browser. - cancels: A list of other events to cancel when this listener is triggered. For example, setting cancels=[click_event] will cancel the click_event, where click_event is the return value of another components .click method. Functions that have not yet run (or generators that are iterating) will be cancelled, but functions that are currently running will be allowed to finish. - every: Run this event 'every' number of seconds while the client connection is open. Interpreted in seconds. Queue must be enabled. - """ - if fn == "decorator": - - def wrapper(func): - self.__call__( - func, - inputs, - outputs, - api_name, - status_tracker, - scroll_to_output, - show_progress, - queue, - batch, - max_batch_size, - preprocess, - postprocess, - cancels, - every, - _js, + @staticmethod + def _setup( + _event_name: str, + _has_trigger: bool, + _show_progress: Literal["full", "minimal", "hidden"] | None, + _callback: Callable | None, + _trigger_after: int | None, + _trigger_only_on_success: bool, + ): + def event_trigger( + block: Block | None, + fn: Callable | None, + inputs: Component | list[Component] | set[Component] | None = None, + outputs: Component | list[Component] | None = None, + api_name: str | None | Literal[False] = None, + status_tracker: None = None, + scroll_to_output: bool = False, + show_progress: Literal["full", "minimal", "hidden"] = "full", + queue: bool | None = None, + batch: bool = False, + max_batch_size: int = 4, + preprocess: bool = True, + postprocess: bool = True, + cancels: dict[str, Any] | list[dict[str, Any]] | None = None, + every: float | None = None, + _js: str | None = None, + ) -> Dependency: + """ + Parameters: + fn: the function to call when this event is triggered. Often a machine learning model's prediction function. Each parameter of the function corresponds to one input component, and the function should return a single value or a tuple of values, with each element in the tuple corresponding to one output component. + inputs: List of gradio.components to use as inputs. If the function takes no inputs, this should be an empty list. + outputs: List of gradio.components to use as outputs. If the function returns no outputs, this should be an empty list. + api_name: Defines how the endpoint appears in the API docs. Can be a string, None, or False. If False, the endpoint will not be exposed in the api docs. If set to None, the endpoint will be given the name of the python function fn. If no fn is passed in, it will be given the name 'unnamed'. If set to a string, the endpoint will be exposed in the api docs with the given name. + status_tracker: Deprecated and has no effect. + scroll_to_output: If True, will scroll to output component on completion + show_progress: If True, will show progress animation while pending + queue: If True, will place the request on the queue, if the queue has been enabled. If False, will not put this event on the queue, even if the queue has been enabled. If None, will use the queue setting of the gradio app. + batch: If True, then the function should process a batch of inputs, meaning that it should accept a list of input values for each parameter. The lists should be of equal length (and be up to length `max_batch_size`). The function is then *required* to return a tuple of lists (even if there is only 1 output component), with each list in the tuple corresponding to one output component. + max_batch_size: Maximum number of inputs to batch together if this is called from the queue (only relevant if batch=True) + preprocess: If False, will not run preprocessing of component data before running 'fn' (e.g. leaving it as a base64 string if this method is called with the `Image` component). + postprocess: If False, will not run postprocessing of component data before returning 'fn' output to the browser. + cancels: A list of other events to cancel when this listener is triggered. For example, setting cancels=[click_event] will cancel the click_event, where click_event is the return value of another components .click method. Functions that have not yet run (or generators that are iterating) will be cancelled, but functions that are currently running will be allowed to finish. + every: Run this event 'every' number of seconds while the client connection is open. Interpreted in seconds. Queue must be enabled. + """ + + if fn == "decorator": + + def wrapper(func): + event_trigger( + block, + func, + inputs, + outputs, + api_name, + status_tracker, + scroll_to_output, + show_progress, + queue, + batch, + max_batch_size, + preprocess, + postprocess, + cancels, + every, + _js, + ) + + @wraps(func) + def inner(*args, **kwargs): + return func(*args, **kwargs) + + return inner + + return Dependency(None, {}, None, wrapper) + + if status_tracker: + warn_deprecation( + "The 'status_tracker' parameter has been deprecated and has no effect." + ) + if _event_name == "stop": + warn_deprecation( + "The `stop` event on Video and Audio has been deprecated and will be remove in a future version. Use `ended` instead." + ) + if block and "stream" in block.events: + block.check_streamable() # type: ignore + if isinstance(show_progress, bool): + show_progress = "full" if show_progress else "hidden" + + if api_name is None: + if fn is not None: + if not hasattr(fn, "__name__"): + if hasattr(fn, "__class__") and hasattr( + fn.__class__, "__name__" + ): + name = fn.__class__.__name__ + else: + name = "unnamed" + else: + name = fn.__name__ + api_name = "".join( + [ + s + for s in name + if s not in set(string.punctuation) - {"-", "_"} + ] + ) + else: + # Don't document _js only events + api_name = False + + if Context.root_block is None: + raise AttributeError( + "Cannot call {self.event_name} outside of a gradio.Blocks context." ) - @wraps(func) - def inner(*args, **kwargs): - return func(*args, **kwargs) - - return inner - - return Dependency({}, None, wrapper) - - if status_tracker: - warn_deprecation( - "The 'status_tracker' parameter has been deprecated and has no effect." + dep, dep_index = Context.root_block.set_event_trigger( + [EventListenerMethod(block if _has_trigger else None, _event_name)], + fn, + inputs, + outputs, + preprocess=preprocess, + postprocess=postprocess, + scroll_to_output=scroll_to_output, + show_progress=show_progress + if show_progress is not None + else _show_progress, + api_name=api_name, + js=_js, + queue=queue, + batch=batch, + max_batch_size=max_batch_size, + every=every, + trigger_after=_trigger_after, + trigger_only_on_success=_trigger_only_on_success, ) - if self.event_name == "stop": - warn_deprecation( - "The `stop` event on Video and Audio has been deprecated and will be remove in a future version. Use `ended` instead." + set_cancel_events( + [EventListenerMethod(block if _has_trigger else None, _event_name)], + cancels, ) + if _callback: + _callback(block) + return Dependency(block, dep, dep_index, fn) - if isinstance(self, Streamable): - self.check_streamable() - if isinstance(show_progress, bool): - show_progress = "full" if show_progress else "hidden" - - if Context.root_block is None: - raise AttributeError( - "Cannot call {self.event_name} outside of a gradio.Blocks context." - ) - - dep, dep_index = Context.root_block.set_event_trigger( - [self], - fn, - inputs, - outputs, - preprocess=preprocess, - postprocess=postprocess, - scroll_to_output=scroll_to_output, - show_progress=show_progress - if show_progress is not None - else self.show_progress, - api_name=api_name, - js=_js, - queue=queue, - batch=batch, - max_batch_size=max_batch_size, - every=every, - trigger_after=self.trigger_after, - trigger_only_on_success=self.trigger_only_on_success, - ) - set_cancel_events([self], cancels) - if self.callback: - self.callback() - return Dependency(dep, dep_index, fn) + event_trigger.event_name = _event_name + event_trigger.has_trigger = _has_trigger + return event_trigger +# TODO: Fix type def on( - triggers: Sequence[EventListenerMethod] | EventListenerMethod | None = None, + triggers: Sequence[Any] | Any | None = None, fn: Callable | None | Literal["decorator"] = "decorator", inputs: Component | list[Component] | set[Component] | None = None, outputs: Component | list[Component] | None = None, @@ -246,7 +348,7 @@ def on( """ from gradio.components.base import Component - if isinstance(triggers, EventListenerMethod): + if isinstance(triggers, EventListener): triggers = [triggers] if isinstance(inputs, Component): inputs = [inputs] @@ -278,13 +380,14 @@ def inner(*args, **kwargs): return inner - return Dependency({}, None, wrapper) + return Dependency(None, {}, None, wrapper) if Context.root_block is None: raise Exception("Cannot call on() outside of a gradio.Blocks context.") if triggers is None: - triggers = [input.change for input in inputs] if inputs is not None else [] - + triggers = [EventListenerMethod(input, "change") for input in inputs] if inputs is not None else [] # type: ignore + else: + triggers = [EventListenerMethod(t.__self__ if t.has_trigger else None, t.event_name) for t in triggers] # type: ignore dep, dep_index = Context.root_block.set_event_trigger( triggers, fn, @@ -302,216 +405,42 @@ def inner(*args, **kwargs): every=every, ) set_cancel_events(triggers, cancels) - return Dependency(dep, dep_index, fn) - - -@document("*change", inherit=True) -class Changeable(EventListener): - def __init__(self): - self.change = EventListenerMethod(self, "change") - """ - This listener is triggered when the component's value changes either because of user input (e.g. a user types in a textbox) OR because of a function update (e.g. an image receives a value from the output of an event trigger). - See `.input()` for a listener that is only triggered by user input. - """ - - -@document("*input", inherit=True) -class Inputable(EventListener): - def __init__(self): - self.input = EventListenerMethod(self, "input") - """ - This listener is triggered when the user changes the value of the component. - """ - - -@document("*click", inherit=True) -class Clickable(EventListener): - def __init__(self): - self.click = EventListenerMethod(self, "click") - """ - This listener is triggered when the component (e.g. a button) is clicked. - """ - - -@document("*submit", inherit=True) -class Submittable(EventListener): - def __init__(self): - self.submit = EventListenerMethod(self, "submit") - """ - This listener is triggered when the user presses the Enter key while the component (e.g. a textbox) is focused. - """ - - -@document("*edit", inherit=True) -class Editable(EventListener): - def __init__(self): - self.edit = EventListenerMethod(self, "edit") - """ - This listener is triggered when the user edits the component (e.g. image) using the - built-in editor. - """ - - -@document("*clear", inherit=True) -class Clearable(EventListener): - def __init__(self): - self.clear = EventListenerMethod(self, "clear") - """ - This listener is triggered when the user clears the component (e.g. image or audio) - using the X button for the component. - """ - - -@document("*play", "*pause", "*stop", "*end", inherit=True) -class Playable(EventListener): - def __init__(self): - self.play = EventListenerMethod(self, "play") - """ - This listener is triggered when the user plays the component (e.g. audio or video). - """ - - self.pause = EventListenerMethod(self, "pause") - """ - This listener is triggered when the media stops playing for any reason (e.g. audio or video). - """ - - self.stop = EventListenerMethod(self, "stop") - """ - This listener is triggered when the user reaches the end of the media track (e.g. audio or video). - """ - - self.end = EventListenerMethod(self, "end") - """ - This listener is triggered when the user reaches the end of the media track (e.g. audio or video). - """ - - -@document("*stream", inherit=True) -class Streamable(EventListener): - def __init__(self): - self.streaming: bool - self.stream = EventListenerMethod( - self, - "stream", - show_progress="hidden", - callback=lambda: setattr(self, "streaming", True), - ) - """ - This listener is triggered when the user streams the component (e.g. a live webcam - component). - """ - - def check_streamable(self): - pass - - -class StreamableOutput(EventListener): - def __init__(self): - self.streaming: bool - - def stream_output(self, y, output_id: str, first_chunk: bool) -> tuple[bytes, Any]: - raise NotImplementedError - - -@document("*start_recording", "*stop_recording", inherit=True) -class Recordable(EventListener): - def __init__(self): - self.start_recording = EventListenerMethod(self, "start_recording") - """ - This listener is triggered when the user starts recording with the component (e.g. audio or video). - """ - - self.stop_recording = EventListenerMethod(self, "stop_recording") - """ - This listener is triggered when the user stops recording with the component (e.g. audio or video). - """ - - -@document("*focus", "*blur", inherit=True) -class Focusable(EventListener): - def __init__(self): - self.focus = EventListenerMethod(self, "focus") - """ - This listener is triggered when the component is focused (e.g. when the user clicks inside a textbox). - """ - - self.blur = EventListenerMethod(self, "blur") - """ - This listener is triggered when the component's is unfocused/blurred (e.g. when the user clicks outside of a textbox). - """ - - -@document("*upload", inherit=True) -class Uploadable(EventListener): - def __init__(self): - self.upload = EventListenerMethod(self, "upload") - """ - This listener is triggered when the user uploads a file into the component (e.g. when the user uploads a video into a video component). - """ - - -@document("*release", inherit=True) -class Releaseable(EventListener): - def __init__(self): - self.release = EventListenerMethod(self, "release") - """ - This listener is triggered when the user releases the mouse on this component (e.g. when the user releases the slider). - """ - - -@document("*select", inherit=True) -class Selectable(EventListener): - def __init__(self): - self.selectable: bool = False - self.select = EventListenerMethod( - self, "select", callback=lambda: setattr(self, "selectable", True) - ) - """ - This listener is triggered when the user selects from within the Component. - This event has EventData of type gradio.SelectData that carries information, accessible through SelectData.index and SelectData.value. - See EventData documentation on how to use this event data. - """ - - def get_config(self): - config = super().get_config() - config["selectable"] = self.selectable - return config - - -class SelectData(EventData): - def __init__(self, target: Block | None, data: Any): - super().__init__(target, data) - self.index: int | tuple[int, int] = data["index"] - """ - The index of the selected item. Is a tuple if the component is two dimensional or selection is a range. - """ - self.value: Any = data["value"] - """ - The value of the selected item. - """ - self.selected: bool = data.get("selected", True) - """ - True if the item was selected, False if deselected. - """ - - -@document("*like", inherit=True) -class Likeable(EventListener): - def __init__(self): - self.likeable: bool = False - self.like = EventListenerMethod( - self, "like", callback=lambda: setattr(self, "likeable", True) - ) - """ - This listener is triggered when the user likes/dislikes from within the Component. - This event has EventData of type gradio.LikeData that carries information, accessible through LikeData.index and LikeData.value. - See EventData documentation on how to use this event data. - """ - - def get_config(self): - config = super().get_config() - config["likeable"] = self.likeable - return config + return Dependency(None, dep, dep_index, fn) + + +class Events: + change = "change" + input = "input" + click = "click" + submit = "submit" + edit = "edit" + clear = "clear" + play = "play" + pause = "pause" + stop = "stop" + end = "end" + start_recording = "start_recording" + stop_recording = "stop_recording" + focus = "focus" + blur = "blur" + upload = "upload" + release = "release" + select = EventListener( + "select", + config_data=lambda: {"selectable": False}, + callback=lambda block: setattr(block, "selectable", True), + ) + stream = EventListener( + "stream", + show_progress="hidden", + config_data=lambda: {"streamable": False}, + callback=lambda block: setattr(block, "streaming", True), + ) + like = EventListener( + "like", + config_data=lambda: {"likeable": False}, + callback=lambda block: setattr(block, "likeable", True), + ) class LikeData(EventData): diff --git a/gradio/exceptions.py b/gradio/exceptions.py index b8ed0989ae06..9667e2c9faed 100644 --- a/gradio/exceptions.py +++ b/gradio/exceptions.py @@ -81,3 +81,7 @@ def __init__(self, message: str = "Error raised."): def __str__(self): return repr(self.message) + + +class ComponentDefinitionError(NotImplementedError): + pass diff --git a/gradio/flagging.py b/gradio/flagging.py index a226fb8d50e4..5d2644f06d87 100644 --- a/gradio/flagging.py +++ b/gradio/flagging.py @@ -21,7 +21,7 @@ from gradio.deprecation import warn_deprecation if TYPE_CHECKING: - from gradio.components import IOComponent + from gradio.components import Component set_documentation_group("flagging") @@ -32,7 +32,7 @@ class FlaggingCallback(ABC): """ @abstractmethod - def setup(self, components: list[IOComponent], flagging_dir: str): + def setup(self, components: list[Component], flagging_dir: str): """ This method should be overridden and ensure that everything is set up correctly for flag(). This method gets called once at the beginning of the Interface.launch() method. @@ -80,7 +80,7 @@ def image_classifier(inp): def __init__(self): pass - def setup(self, components: list[IOComponent], flagging_dir: str | Path): + def setup(self, components: list[Component], flagging_dir: str | Path): self.components = components self.flagging_dir = flagging_dir os.makedirs(flagging_dir, exist_ok=True) @@ -99,11 +99,11 @@ def flag( save_dir = Path( flagging_dir ) / client_utils.strip_invalid_filename_characters(component.label or "") + save_dir.mkdir(exist_ok=True) csv_data.append( - component.deserialize( + component.flag( sample, save_dir, - None, ) ) @@ -135,7 +135,7 @@ def __init__(self): def setup( self, - components: list[IOComponent], + components: list[Component], flagging_dir: str | Path, ): self.components = components @@ -167,11 +167,12 @@ def flag( ) / client_utils.strip_invalid_filename_characters( getattr(component, "label", None) or f"component {idx}" ) + save_dir.mkdir(exist_ok=True) if utils.is_update(sample): csv_data.append(str(sample)) else: csv_data.append( - component.deserialize(sample, save_dir=save_dir) + component.flag(sample, flag_dir=save_dir) if sample is not None else "" ) @@ -234,7 +235,7 @@ def __init__( self.info_filename = info_filename self.separate_dirs = separate_dirs - def setup(self, components: list[IOComponent], flagging_dir: str): + def setup(self, components: list[Component], flagging_dir: str): """ Params: flagging_dir (str): local directory where the dataset is cloned, @@ -425,7 +426,8 @@ def _deserialize_components( # Get deserialized object (will save sample to disk if applicable -file, audio, image,...-) label = component.label or "" save_dir = data_dir / client_utils.strip_invalid_filename_characters(label) - deserialized = component.deserialize(sample, save_dir, None) + save_dir.mkdir(exist_ok=True, parents=True) + deserialized = component.flag(sample, save_dir) # Add deserialized object to row features[label] = {"dtype": "string", "_type": "Value"} diff --git a/gradio/helpers.py b/gradio/helpers.py index 794e0a98c998..893a789260f7 100644 --- a/gradio/helpers.py +++ b/gradio/helpers.py @@ -25,12 +25,13 @@ from gradio import components, oauth, processing_utils, routes, utils, wasm_utils from gradio.context import Context, LocalContext +from gradio.data_classes import GradioModel, GradioRootModel +from gradio.events import EventData from gradio.exceptions import Error from gradio.flagging import CSVLogger if TYPE_CHECKING: # Only import for type checking (to avoid circular imports). - from gradio.blocks import Block - from gradio.components import IOComponent + from gradio.components import Component CACHED_FOLDER = "gradio_cached_examples" LOG_FILE = "log.csv" @@ -40,8 +41,8 @@ def create_examples( examples: list[Any] | list[list[Any]] | str, - inputs: IOComponent | list[IOComponent], - outputs: IOComponent | list[IOComponent] | None = None, + inputs: Component | list[Component], + outputs: Component | list[Component] | None = None, fn: Callable | None = None, cache_examples: bool = False, examples_per_page: int = 10, @@ -91,8 +92,8 @@ class Examples: def __init__( self, examples: list[Any] | list[list[Any]] | str, - inputs: IOComponent | list[IOComponent], - outputs: IOComponent | list[IOComponent] | None = None, + inputs: Component | list[Component], + outputs: Component | list[Component] | None = None, fn: Callable | None = None, cache_examples: bool = False, examples_per_page: int = 10, @@ -206,13 +207,19 @@ def __init__( self.batch = batch with utils.set_directory(working_directory): - self.processed_examples = [ - [ - component.postprocess(sample) - for component, sample in zip(inputs, example) - ] - for example in examples - ] + self.processed_examples = [] + for example in examples: + sub = [] + for component, sample in zip(inputs, example): + prediction_value = component.postprocess(sample) + if isinstance(prediction_value, (GradioRootModel, GradioModel)): + prediction_value = prediction_value.model_dump() + prediction_value = processing_utils.move_files_to_cache( + prediction_value, component + ) + sub.append(prediction_value) + self.processed_examples.append(sub) + self.non_none_processed_examples = [ [ex for (ex, keep) in zip(example, input_has_examples) if keep] for example in self.processed_examples @@ -410,23 +417,21 @@ def load_from_cache(self, example_id: int) -> list[Any]: output.append(value_as_dict) except (ValueError, TypeError, SyntaxError, AssertionError): output.append( - component.serialize( - value_to_use, self.cached_folder, allow_links=True + component.read_from_flag( + value_to_use, + self.cached_folder, ) ) return output def merge_generated_values_into_output( - components: list[IOComponent], generated_values: list, output: list + components: list[Component], generated_values: list, output: list ): - from gradio.events import StreamableOutput + from gradio.components.base import StreamingOutput for output_index, output_component in enumerate(components): - if ( - isinstance(output_component, StreamableOutput) - and output_component.streaming - ): + if isinstance(output_component, StreamingOutput) and output_component.streaming: binary_chunks = [] for i, chunk in enumerate(generated_values): if len(components) > 1: @@ -1059,37 +1064,6 @@ def _animate(_): return output_mp4.name -@document() -class EventData: - """ - When a subclass of EventData is added as a type hint to an argument of an event listener method, this object will be passed as that argument. - It contains information about the event that triggered the listener, such the target object, and other data related to the specific event that are attributes of the subclass. - - Example: - table = gr.Dataframe([[1, 2, 3], [4, 5, 6]]) - gallery = gr.Gallery([("cat.jpg", "Cat"), ("dog.jpg", "Dog")]) - textbox = gr.Textbox("Hello World!") - - statement = gr.Textbox() - - def on_select(evt: gr.SelectData): # SelectData is a subclass of EventData - return f"You selected {evt.value} at {evt.index} from {evt.target}" - - table.select(on_select, None, statement) - gallery.select(on_select, None, statement) - textbox.select(on_select, None, statement) - Demos: gallery_selections, tictactoe - """ - - def __init__(self, target: Block | None, _data: Any): - """ - Parameters: - target: The target object that triggered the event. Can be used to distinguish if multiple components are bound to the same listener. - """ - self.target = target - self._data = _data - - def log_message(message: str, level: Literal["info", "warning"] = "info"): from gradio.context import LocalContext diff --git a/gradio/inputs.py b/gradio/inputs.py deleted file mode 100644 index 9345530649a0..000000000000 --- a/gradio/inputs.py +++ /dev/null @@ -1,451 +0,0 @@ -# type: ignore -""" -This module defines various classes that can serve as the `input` to an interface. Each class must inherit from -`InputComponent`, and each class must define a path to its template. All of the subclasses of `InputComponent` are -automatically added to a registry, which allows them to be easily referenced in other parts of the code. -""" - -from __future__ import annotations - -from typing import Any, Optional - -from gradio import components -from gradio.deprecation import warn_deprecation - - -def warn_inputs_deprecation(): - warn_deprecation( - "Usage of gradio.inputs is deprecated, and will not be supported in the future, please import your component from gradio.components", - ) - - -class Textbox(components.Textbox): - def __init__( - self, - lines: int = 1, - placeholder: Optional[str] = None, - default: str = "", - numeric: Optional[bool] = False, - type: Optional[str] = "text", - label: Optional[str] = None, - optional: bool = False, - ): - warn_inputs_deprecation() - super().__init__( - value=default, - lines=lines, - placeholder=placeholder, - label=label, - numeric=numeric, - type=type, - optional=optional, - ) - - -class Number(components.Number): - """ - Component creates a field for user to enter numeric input. Provides a number as an argument to the wrapped function. - Input type: float - """ - - def __init__( - self, - default: Optional[float] = None, - label: Optional[str] = None, - optional: bool = False, - ): - """ - Parameters: - default (float): default value. - label (str): component name in interface. - optional (bool): If True, the interface can be submitted with no value for this component. - """ - warn_inputs_deprecation() - super().__init__(value=default, label=label, optional=optional) - - -class Slider(components.Slider): - """ - Component creates a slider that ranges from `minimum` to `maximum`. Provides number as an argument to the wrapped function. - Input type: float - """ - - def __init__( - self, - minimum: float = 0, - maximum: float = 100, - step: Optional[float] = None, - default: Optional[float] = None, - label: Optional[str] = None, - optional: bool = False, - ): - """ - Parameters: - minimum (float): minimum value for slider. - maximum (float): maximum value for slider. - step (float): increment between slider values. - default (float): default value. - label (str): component name in interface. - optional (bool): this parameter is ignored. - """ - warn_inputs_deprecation() - - super().__init__( - value=default, - minimum=minimum, - maximum=maximum, - step=step, - label=label, - optional=optional, - ) - - -class Checkbox(components.Checkbox): - """ - Component creates a checkbox that can be set to `True` or `False`. Provides a boolean as an argument to the wrapped function. - Input type: bool - """ - - def __init__( - self, - default: bool = False, - label: Optional[str] = None, - optional: bool = False, - ): - """ - Parameters: - label (str): component name in interface. - default (bool): if True, checked by default. - optional (bool): this parameter is ignored. - """ - warn_inputs_deprecation() - super().__init__(value=default, label=label, optional=optional) - - -class CheckboxGroup(components.CheckboxGroup): - """ - Component creates a set of checkboxes of which a subset can be selected. Provides a list of strings representing the selected choices as an argument to the wrapped function. - Input type: Union[List[str], List[int]] - """ - - def __init__( - self, - choices: list[str], - default: list[str] | None = None, - type: str = "value", - label: Optional[str] = None, - optional: bool = False, - ): - """ - Parameters: - choices (List[str]): list of options to select from. - default (List[str]): default selected list of options. - type (str): Type of value to be returned by component. "value" returns the list of strings of the choices selected, "index" returns the list of indices of the choices selected. - label (str): component name in interface. - optional (bool): this parameter is ignored. - """ - if default is None: - default = [] - warn_inputs_deprecation() - super().__init__( - value=default, - choices=choices, - type=type, - label=label, - optional=optional, - ) - - -class Radio(components.Radio): - """ - Component creates a set of radio buttons of which only one can be selected. Provides string representing selected choice as an argument to the wrapped function. - Input type: Union[str, int] - """ - - def __init__( - self, - choices: list[str], - type: str = "value", - default: Optional[str] = None, - label: Optional[str] = None, - optional: bool = False, - ): - """ - Parameters: - choices (List[str]): list of options to select from. - type (str): Type of value to be returned by component. "value" returns the string of the choice selected, "index" returns the index of the choice selected. - default (str): the button selected by default. If None, no button is selected by default. - label (str): component name in interface. - optional (bool): this parameter is ignored. - """ - warn_inputs_deprecation() - super().__init__( - choices=choices, - type=type, - value=default, - label=label, - optional=optional, - ) - - -class Dropdown(components.Dropdown): - """ - Component creates a dropdown of which only one can be selected. Provides string representing selected choice as an argument to the wrapped function. - Input type: Union[str, int] - """ - - def __init__( - self, - choices: list[str], - type: str = "value", - default: Optional[str] = None, - label: Optional[str] = None, - optional: bool = False, - ): - """ - Parameters: - choices (List[str]): list of options to select from. - type (str): Type of value to be returned by component. "value" returns the string of the choice selected, "index" returns the index of the choice selected. - default (str): default value selected in dropdown. If None, no value is selected by default. - label (str): component name in interface. - optional (bool): this parameter is ignored. - """ - warn_inputs_deprecation() - super().__init__( - choices=choices, - type=type, - value=default, - label=label, - optional=optional, - ) - - -class Image(components.Image): - """ - Component creates an image upload box with editing capabilities. - Input type: Union[numpy.array, PIL.Image, file-object] - """ - - def __init__( - self, - shape: tuple[int, int] = None, - image_mode: str = "RGB", - invert_colors: bool = False, - source: str = "upload", - tool: str = "editor", - type: str = "numpy", - label: str = None, - optional: bool = False, - ): - """ - Parameters: - shape (Tuple[int, int]): (width, height) shape to crop and resize image to; if None, matches input image size. - image_mode (str): How to process the uploaded image. Accepts any of the PIL image modes, e.g. "RGB" for color images, "RGBA" to include the transparency mask, "L" for black-and-white images. - invert_colors (bool): whether to invert the image as a preprocessing step. - source (str): Source of image. "upload" creates a box where user can drop an image file, "webcam" allows user to take snapshot from their webcam, "canvas" defaults to a white image that can be edited and drawn upon with tools. - tool (str): Tools used for editing. "editor" allows a full screen editor, "select" provides a cropping and zoom tool. - type (str): Type of value to be returned by component. "numpy" returns a numpy array with shape (height, width, 3) and values from 0 to 255, "pil" returns a PIL image object, "file" returns a temporary file object whose path can be retrieved by file_obj.name, "filepath" returns the path directly. - label (str): component name in interface. - optional (bool): If True, the interface can be submitted with no uploaded image, in which case the input value is None. - """ - warn_inputs_deprecation() - super().__init__( - shape=shape, - image_mode=image_mode, - invert_colors=invert_colors, - source=source, - tool=tool, - type=type, - label=label, - optional=optional, - ) - - -class Video(components.Video): - """ - Component creates a video file upload that is converted to a file path. - - Input type: filepath - """ - - def __init__( - self, - type: Optional[str] = None, - source: str = "upload", - label: Optional[str] = None, - optional: bool = False, - ): - """ - Parameters: - type (str): Type of video format to be returned by component, such as 'avi' or 'mp4'. If set to None, video will keep uploaded format. - source (str): Source of video. "upload" creates a box where user can drop an video file, "webcam" allows user to record a video from their webcam. - label (str): component name in interface. - optional (bool): If True, the interface can be submitted with no uploaded video, in which case the input value is None. - """ - warn_inputs_deprecation() - super().__init__(format=type, source=source, label=label, optional=optional) - - -class Audio(components.Audio): - """ - Component accepts audio input files. - Input type: Union[Tuple[int, numpy.array], file-object, numpy.array] - """ - - def __init__( - self, - source: str = "upload", - type: str = "numpy", - label: str = None, - optional: bool = False, - ): - """ - Parameters: - source (str): Source of audio. "upload" creates a box where user can drop an audio file, "microphone" creates a microphone input. - type (str): Type of value to be returned by component. "numpy" returns a 2-set tuple with an integer sample_rate and the data numpy.array of shape (samples, 2), "file" returns a temporary file object whose path can be retrieved by file_obj.name, "filepath" returns the path directly. - label (str): component name in interface. - optional (bool): If True, the interface can be submitted with no uploaded audio, in which case the input value is None. - """ - warn_inputs_deprecation() - super().__init__(source=source, type=type, label=label, optional=optional) - - -class File(components.File): - """ - Component accepts generic file uploads. - Input type: Union[file-object, bytes, List[Union[file-object, bytes]]] - """ - - def __init__( - self, - file_count: str = "single", - type: str = "file", - label: Optional[str] = None, - keep_filename: bool = True, - optional: bool = False, - ): - """ - Parameters: - file_count (str): if single, allows user to upload one file. If "multiple", user uploads multiple files. If "directory", user uploads all files in selected directory. Return type will be list for each file in case of "multiple" or "directory". - type (str): Type of value to be returned by component. "file" returns a temporary file object whose path can be retrieved by file_obj.name, "binary" returns an bytes object. - label (str): component name in interface. - keep_filename (bool): DEPRECATED. Original filename always kept. - optional (bool): If True, the interface can be submitted with no uploaded image, in which case the input value is None. - """ - warn_inputs_deprecation() - super().__init__( - file_count=file_count, - type=type, - label=label, - keep_filename=keep_filename, - optional=optional, - ) - - -class Dataframe(components.Dataframe): - """ - Component accepts 2D input through a spreadsheet interface. - Input type: Union[pandas.DataFrame, numpy.array, List[Union[str, float]], List[List[Union[str, float]]]] - """ - - def __init__( - self, - headers: Optional[list[str]] = None, - row_count: int = 3, - col_count: Optional[int] = 3, - datatype: str | list[str] = "str", - col_width: int | list[int] = None, - default: Optional[list[list[Any]]] = None, - type: str = "pandas", - label: Optional[str] = None, - optional: bool = False, - ): - """ - Parameters: - headers (List[str]): Header names to dataframe. If None, no headers are shown. - row_count (int): Limit number of rows for input. - col_count (int): Limit number of columns for input. If equal to 1, return data will be one-dimensional. Ignored if `headers` is provided. - datatype (Union[str, List[str]]): Datatype of values in sheet. Can be provided per column as a list of strings, or for the entire sheet as a single string. Valid datatypes are "str", "number", "bool", and "date". - col_width (Union[int, List[int]]): Width of columns in pixels. Can be provided as single value or list of values per column. - default (List[List[Any]]): Default value - type (str): Type of value to be returned by component. "pandas" for pandas dataframe, "numpy" for numpy array, or "array" for a Python array. - label (str): component name in interface. - optional (bool): this parameter is ignored. - """ - warn_inputs_deprecation() - super().__init__( - value=default, - headers=headers, - row_count=row_count, - col_count=col_count, - datatype=datatype, - col_width=col_width, - type=type, - label=label, - optional=optional, - ) - - -class Timeseries(components.Timeseries): - """ - Component accepts pandas.DataFrame uploaded as a timeseries csv file. - Input type: pandas.DataFrame - """ - - def __init__( - self, - x: Optional[str] = None, - y: str | list[str] = None, - label: Optional[str] = None, - optional: bool = False, - ): - """ - Parameters: - x (str): Column name of x (time) series. None if csv has no headers, in which case first column is x series. - y (Union[str, List[str]]): Column name of y series, or list of column names if multiple series. None if csv has no headers, in which case every column after first is a y series. - label (str): component name in interface. - optional (bool): If True, the interface can be submitted with no uploaded csv file, in which case the input value is None. - """ - warn_inputs_deprecation() - super().__init__(x=x, y=y, label=label, optional=optional) - - -class State(components.State): - """ - Special hidden component that stores state across runs of the interface. - Input type: Any - """ - - def __init__( - self, - label: str = None, - default: Any = None, - ): - """ - Parameters: - label (str): component name in interface (not used). - default (Any): the initial value of the state. - optional (bool): this parameter is ignored. - """ - warn_inputs_deprecation() - super().__init__(value=default, label=label) - - -class Image3D(components.Model3D): - """ - Used for 3D image model output. - Input type: File object of type (.obj, glb, or .gltf) - """ - - def __init__( - self, - label: Optional[str] = None, - optional: bool = False, - ): - """ - Parameters: - label (str): component name in interface. - optional (bool): If True, the interface can be submitted with no uploaded image, in which case the input value is None. - """ - warn_inputs_deprecation() - super().__init__(label=label, optional=optional) diff --git a/gradio/interface.py b/gradio/interface.py index c4534e35a197..1681b75d5620 100644 --- a/gradio/interface.py +++ b/gradio/interface.py @@ -13,21 +13,20 @@ from gradio_client.documentation import document, set_documentation_group -from gradio import Examples, external, interpretation, utils +from gradio import Examples, external, utils from gradio.blocks import Blocks from gradio.components import ( Button, ClearButton, + Component, DuplicateButton, - Interpretation, - IOComponent, Markdown, State, get_component_instance, ) from gradio.data_classes import InterfaceTypes from gradio.deprecation import warn_deprecation -from gradio.events import Changeable, Streamable, Submittable, on +from gradio.events import Events, on from gradio.exceptions import RenderError from gradio.flagging import CSVLogger, FlaggingCallback, FlagMethod from gradio.layouts import Column, Row, Tab, Tabs @@ -39,8 +38,6 @@ if TYPE_CHECKING: # Only import for type checking (is False at runtime). from transformers.pipelines.base import Pipeline - from gradio.events import EventListenerMethod - @document("launch", "load", "from_pipeline", "integrate", "queue") class Interface(Blocks): @@ -125,14 +122,12 @@ def from_pipeline(cls, pipeline: Pipeline, **kwargs) -> Interface: def __init__( self, fn: Callable, - inputs: str | IOComponent | list[str | IOComponent] | None, - outputs: str | IOComponent | list[str | IOComponent] | None, + inputs: str | Component | list[str | Component] | None, + outputs: str | Component | list[str | Component] | None, examples: list[Any] | list[list[Any]] | str | None = None, cache_examples: bool | None = None, examples_per_page: int = 10, live: bool = False, - interpretation: Callable | str | None = None, - num_shap: float = 2.0, title: str | None = None, description: str | None = None, article: str | None = None, @@ -142,7 +137,7 @@ def __init__( allow_flagging: str | None = None, flagging_options: list[str] | list[tuple[str, str]] | None = None, flagging_dir: str = "flagged", - flagging_callback: FlaggingCallback = CSVLogger(), + flagging_callback: FlaggingCallback | None = None, analytics_enabled: bool | None = None, batch: bool = False, max_batch_size: int = 4, @@ -160,8 +155,6 @@ def __init__( cache_examples: If True, caches examples in the server for fast runtime in examples. If `fn` is a generator function, then the last yielded value will be used as the output. The default option in HuggingFace Spaces is True. The default option elsewhere is False. examples_per_page: If examples are provided, how many to display per page. live: whether the interface should automatically rerun if any of the inputs change. - interpretation: function that provides interpretation explaining prediction output. Pass "default" to use simple built-in interpreter, "shap" to use a built-in shapley-based interpreter, or your own custom interpretation function. For more information on the different interpretation methods, see the Advanced Interface Features guide. - num_shap: a multiplier that determines how many examples are computed for shap-based interpretation. Increasing this value will increase shap runtime, but improve results. Only applies if interpretation is "shap". title: a title for the interface; if provided, appears above the input and output components in large font. Also used as the tab title when opened in a browser window. description: a description for the interface; if provided, appears above the input and output components and beneath the title in regular font. Accepts Markdown and HTML content. article: an expanded article explaining the interface; if provided, appears below the input and output components in regular font. Accepts Markdown and HTML content. @@ -205,8 +198,8 @@ def __init__( inputs = [] self.interface_type = InterfaceTypes.OUTPUT_ONLY - assert isinstance(inputs, (str, list, IOComponent)) - assert isinstance(outputs, (str, list, IOComponent)) + assert isinstance(inputs, (str, list, Component)) + assert isinstance(outputs, (str, list, Component)) if not isinstance(inputs, list): inputs = [inputs] @@ -258,7 +251,7 @@ def __init__( ] for component in self.input_components + self.output_components: - if not (isinstance(component, IOComponent)): + if not (isinstance(component, Component)): raise ValueError( f"{component} is not a valid input/output component for Interface." ) @@ -275,23 +268,11 @@ def __init__( InterfaceTypes.OUTPUT_ONLY, ]: for o in self.output_components: - assert isinstance(o, IOComponent) + assert isinstance(o, Component) if o.interactive is None: # Unless explicitly otherwise specified, force output components to # be non-interactive o.interactive = False - if ( - interpretation is None - or isinstance(interpretation, list) - or callable(interpretation) - ): - self.interpretation = interpretation - elif isinstance(interpretation, str): - self.interpretation = [ - interpretation.lower() for _ in self.input_components - ] - else: - raise ValueError("Invalid value for parameter: interpretation") self.api_mode = _api_mode self.fn = fn @@ -309,7 +290,6 @@ def __init__( self.thumbnail = thumbnail self.examples = examples - self.num_shap = num_shap self.examples_per_page = examples_per_page self.simple_server = None @@ -359,8 +339,11 @@ def __init__( "flagging_options must be a list of strings or list of (string, string) tuples." ) + if not flagging_callback: + flagging_callback = CSVLogger() self.flagging_callback = flagging_callback self.flagging_dir = flagging_dir + self.batch = batch self.max_batch_size = max_batch_size self.allow_duplication = allow_duplication @@ -380,11 +363,11 @@ def __init__( if utils.is_special_typed_parameter(param_name, param_types): param_names.remove(param_name) for component, param_name in zip(self.input_components, param_names): - assert isinstance(component, IOComponent) + assert isinstance(component, Component) if component.label is None: component.label = param_name for i, component in enumerate(self.output_components): - assert isinstance(component, IOComponent) + assert isinstance(component, Component) if component.label is None: if len(self.output_components) == 1: component.label = "output" @@ -415,7 +398,6 @@ def __init__( None, None, ) - interpretation_btn, interpretation_set = None, None input_component_column, interpret_component_column = None, None with Row(equal_height=False): @@ -430,8 +412,6 @@ def __init__( stop_btn, flag_btns, input_component_column, - interpret_component_column, - interpretation_set, ) = self.render_input_column() if self.interface_type in [ InterfaceTypes.STANDARD, @@ -443,7 +423,6 @@ def __init__( duplicate_btn, stop_btn_2_out, flag_btns_out, - interpretation_btn, ) = self.render_output_column(submit_btn) submit_btn = submit_btn or submit_btn_out clear_btn = clear_btn or clear_btn_2_out @@ -459,12 +438,6 @@ def __init__( ) if duplicate_btn is not None: duplicate_btn.activate() - self.attach_interpretation_events( - interpretation_btn, - interpretation_set, - input_component_column, - interpret_component_column, - ) self.attach_flagging_events(flag_btns, clear_btn) self.render_examples() @@ -491,23 +464,14 @@ def render_input_column( Button | None, list[Button] | None, Column, - Column | None, - list[Interpretation] | None, ]: submit_btn, clear_btn, stop_btn, flag_btns = None, None, None, None - interpret_component_column, interpretation_set = None, None with Column(variant="panel"): input_component_column = Column() with input_component_column: for component in self.input_components: component.render() - if self.interpretation: - interpret_component_column = Column(visible=False) - interpretation_set = [] - with interpret_component_column: - for component in self.input_components: - interpretation_set.append(Interpretation(component)) with Row(): if self.interface_type in [ InterfaceTypes.STANDARD, @@ -543,8 +507,6 @@ def render_input_column( stop_btn, flag_btns, input_component_column, - interpret_component_column, - interpretation_set, ) def render_output_column( @@ -553,14 +515,12 @@ def render_output_column( ) -> tuple[ Button | None, ClearButton | None, - DuplicateButton, + DuplicateButton | None, Button | None, list | None, - Button | None, ]: submit_btn = submit_btn_in - interpretation_btn, clear_btn, duplicate_btn, flag_btns, stop_btn = ( - None, + clear_btn, duplicate_btn, flag_btns, stop_btn = ( None, None, None, @@ -592,9 +552,6 @@ def render_output_column( raise RenderError("Submit button not rendered") flag_btns = [submit_btn] - if self.interpretation: - interpretation_btn = Button("Interpret") - if self.allow_duplication: duplicate_btn = DuplicateButton(scale=1, size="lg", _activate=False) @@ -604,7 +561,6 @@ def render_output_column( duplicate_btn, stop_btn, flag_btns, - interpretation_btn, ) def render_article(self): @@ -630,12 +586,12 @@ def attach_submit_events(self, submit_btn: Button | None, stop_btn: Button | Non max_batch_size=self.max_batch_size, ) else: - events: list[EventListenerMethod] = [] + events: list[Callable] = [] for component in self.input_components: - if isinstance(component, Streamable) and component.streaming: - events.append(component.stream) - elif isinstance(component, Changeable): - events.append(component.change) + if component.has_event("stream") and component.streaming: # type: ignore + events.append(component.stream) # type: ignore + elif component.has_event("change"): + events.append(component.change) # type: ignore on( events, self.fn, @@ -652,9 +608,9 @@ def attach_submit_events(self, submit_btn: Button | None, stop_btn: Button | Non extra_output = [] triggers = [submit_btn.click] + [ - component.submit + component.submit # type: ignore for component in self.input_components - if isinstance(component, Submittable) + if component.has_event(Events.submit) ] if stop_btn: @@ -697,6 +653,7 @@ def cleanup(): outputs=[submit_btn, stop_btn], cancels=predict_event, queue=False, + api_name=False, ) else: on( @@ -723,8 +680,7 @@ def attach_clear_events( None, [], ( - ([input_component_column] if input_component_column else []) - + ([interpret_component_column] if self.interpretation else []) + [input_component_column] if input_component_column else [] ), # type: ignore _js=f"""() => {json.dumps( ( @@ -737,26 +693,10 @@ def attach_clear_events( ] else [] ) - + ([{'variant': None, 'visible': False, '__type__': 'update'}] if self.interpretation else []) )} """, ) - def attach_interpretation_events( - self, - interpretation_btn: Button | None, - interpretation_set: list[Interpretation] | None, - input_component_column: Column | None, - interpret_component_column: Column | None, - ): - if interpretation_btn: - interpretation_btn.click( - self.interpret_func, - inputs=self.input_components + self.output_components, - outputs=(interpretation_set or []) + [input_component_column, interpret_component_column], # type: ignore - preprocess=False, - ) - def attach_flagging_events( self, flag_btns: list[Button] | None, clear_btn: ClearButton ): @@ -797,6 +737,7 @@ def attach_flagging_events( None, flag_btn, queue=False, + api_name=False, ) flag_btn.click( flag_method, @@ -804,12 +745,10 @@ def attach_flagging_events( outputs=flag_btn, preprocess=False, queue=False, + api_name=False, ) clear_btn.click( - flag_method.reset, - None, - flag_btn, - queue=False, + flag_method.reset, None, flag_btn, queue=False, api_name=False ) def render_examples(self): @@ -845,20 +784,6 @@ def __repr__(self): repr += f"\n|-{component}" return repr - async def interpret_func(self, *args): - return await self.interpret(list(args)) + [ - Column(visible=False), - Column(visible=True), - ] - - async def interpret(self, raw_input: list[Any]) -> list[Any]: - return [ - {"original": raw_value, "interpretation": interpretation} - for interpretation, raw_value in zip( - (await interpretation.run_interpret(self, raw_input))[0], raw_input - ) - ] - def test_launch(self) -> None: """ Deprecated. diff --git a/gradio/interpretation.py b/gradio/interpretation.py deleted file mode 100644 index 3731a9d38153..000000000000 --- a/gradio/interpretation.py +++ /dev/null @@ -1,329 +0,0 @@ -"""Contains classes and methods related to interpretation for components in Gradio.""" - -from __future__ import annotations - -import copy -import math -from abc import ABC, abstractmethod -from typing import TYPE_CHECKING, Any - -import numpy as np -from gradio_client import utils as client_utils - -from gradio import components - -if TYPE_CHECKING: # Only import for type checking (is False at runtime). - from gradio import Interface - - -class Interpretable(ABC): # noqa: B024 - def __init__(self) -> None: - self.set_interpret_parameters() - - def set_interpret_parameters(self): # noqa: B027 - """ - Set any parameters for interpretation. Properties can be set here to be - used in get_interpretation_neighbors and get_interpretation_scores. - """ - pass - - def get_interpretation_scores( - self, x: Any, neighbors: list[Any] | None, scores: list[float], **kwargs - ) -> list: - """ - Arrange the output values from the neighbors into interpretation scores for the interface to render. - Parameters: - x: Input to interface - neighbors: Neighboring values to input x used for interpretation. - scores: Output value corresponding to each neighbor in neighbors - Returns: - Arrangement of interpretation scores for interfaces to render. - """ - return scores - - -class TokenInterpretable(Interpretable, ABC): - @abstractmethod - def tokenize(self, x: Any) -> tuple[list, list, None]: - """ - Interprets an input data point x by splitting it into a list of tokens (e.g - a string into words or an image into super-pixels). - """ - return [], [], None - - @abstractmethod - def get_masked_inputs(self, tokens: list, binary_mask_matrix: list[list]) -> list: - return [] - - -class NeighborInterpretable(Interpretable, ABC): - @abstractmethod - def get_interpretation_neighbors(self, x: Any) -> tuple[list, dict]: - """ - Generates values similar to input to be used to interpret the significance of the input in the final output. - Parameters: - x: Input to interface - Returns: (neighbor_values, interpret_kwargs, interpret_by_removal) - neighbor_values: Neighboring values to input x to compute for interpretation - interpret_kwargs: Keyword arguments to be passed to get_interpretation_scores - """ - return [], {} - - -async def run_interpret(interface: Interface, raw_input: list): - """ - Runs the interpretation command for the machine learning model. Handles both the "default" out-of-the-box - interpretation for a certain set of UI component types, as well as the custom interpretation case. - Parameters: - raw_input: a list of raw inputs to apply the interpretation(s) on. - """ - if isinstance(interface.interpretation, list): # Either "default" or "shap" - processed_input = [ - input_component.preprocess(raw_input[i]) - for i, input_component in enumerate(interface.input_components) - ] - original_output = await interface.call_function(0, processed_input) - original_output = original_output["prediction"] - - if len(interface.output_components) == 1: - original_output = [original_output] - - scores, alternative_outputs = [], [] - - for i, (x, interp) in enumerate(zip(raw_input, interface.interpretation)): - if interp == "default": - input_component = interface.input_components[i] - neighbor_raw_input = list(raw_input) - if isinstance(input_component, TokenInterpretable): - tokens, neighbor_values, masks = input_component.tokenize(x) - interface_scores = [] - alternative_output = [] - for neighbor_input in neighbor_values: - neighbor_raw_input[i] = neighbor_input - processed_neighbor_input = [ - input_component.preprocess(neighbor_raw_input[i]) - for i, input_component in enumerate( - interface.input_components - ) - ] - - neighbor_output = await interface.call_function( - 0, processed_neighbor_input - ) - neighbor_output = neighbor_output["prediction"] - if len(interface.output_components) == 1: - neighbor_output = [neighbor_output] - processed_neighbor_output = [ - output_component.postprocess(neighbor_output[i]) - for i, output_component in enumerate( - interface.output_components - ) - ] - - alternative_output.append(processed_neighbor_output) - interface_scores.append( - quantify_difference_in_label( - interface, original_output, neighbor_output - ) - ) - alternative_outputs.append(alternative_output) - scores.append( - input_component.get_interpretation_scores( - raw_input[i], - neighbor_values, - interface_scores, - masks=masks, - tokens=tokens, - ) - ) - elif isinstance(input_component, NeighborInterpretable): - ( - neighbor_values, - interpret_kwargs, - ) = input_component.get_interpretation_neighbors( - x - ) # type: ignore - interface_scores = [] - alternative_output = [] - for neighbor_input in neighbor_values: - neighbor_raw_input[i] = neighbor_input - processed_neighbor_input = [ - input_component.preprocess(neighbor_raw_input[i]) - for i, input_component in enumerate( - interface.input_components - ) - ] - neighbor_output = await interface.call_function( - 0, processed_neighbor_input - ) - neighbor_output = neighbor_output["prediction"] - if len(interface.output_components) == 1: - neighbor_output = [neighbor_output] - processed_neighbor_output = [ - output_component.postprocess(neighbor_output[i]) - for i, output_component in enumerate( - interface.output_components - ) - ] - - alternative_output.append(processed_neighbor_output) - interface_scores.append( - quantify_difference_in_label( - interface, original_output, neighbor_output - ) - ) - alternative_outputs.append(alternative_output) - interface_scores = [-score for score in interface_scores] - scores.append( - input_component.get_interpretation_scores( - raw_input[i], - neighbor_values, - interface_scores, - **interpret_kwargs, - ) - ) - else: - raise ValueError( - f"Component {input_component} does not support interpretation" - ) - elif interp == "shap" or interp == "shapley": - try: - import shap # type: ignore - except (ImportError, ModuleNotFoundError) as err: - raise ValueError( - "The package `shap` is required for this interpretation method. Try: `pip install shap`" - ) from err - input_component = interface.input_components[i] - if not isinstance(input_component, TokenInterpretable): - raise ValueError( - f"Input component {input_component} does not support `shap` interpretation" - ) - - tokens, _, masks = input_component.tokenize(x) - - # construct a masked version of the input - def get_masked_prediction(binary_mask): - assert isinstance(input_component, TokenInterpretable) - masked_xs = input_component.get_masked_inputs(tokens, binary_mask) - preds = [] - for masked_x in masked_xs: - processed_masked_input = copy.deepcopy(processed_input) - processed_masked_input[i] = input_component.preprocess(masked_x) - new_output = client_utils.synchronize_async( - interface.call_function, 0, processed_masked_input - ) - new_output = new_output["prediction"] - if len(interface.output_components) == 1: - new_output = [new_output] - pred = get_regression_or_classification_value( - interface, original_output, new_output - ) - preds.append(pred) - return np.array(preds) - - num_total_segments = len(tokens) - explainer = shap.KernelExplainer( - get_masked_prediction, np.zeros((1, num_total_segments)) - ) - shap_values = explainer.shap_values( - np.ones((1, num_total_segments)), - nsamples=int(interface.num_shap * num_total_segments), - silent=True, - ) - if shap_values is None: - raise ValueError("SHAP values could not be calculated") - scores.append( - input_component.get_interpretation_scores( - raw_input[i], - None, - shap_values[0].tolist(), - masks=masks, - tokens=tokens, - ) - ) - alternative_outputs.append([]) - elif interp is None: - scores.append(None) - alternative_outputs.append([]) - else: - raise ValueError(f"Unknown interpretation method: {interp}") - return scores, alternative_outputs - elif interface.interpretation: # custom interpretation function - processed_input = [ - input_component.preprocess(raw_input[i]) - for i, input_component in enumerate(interface.input_components) - ] - interpreter = interface.interpretation - interpretation = interpreter(*processed_input) - if len(raw_input) == 1: - interpretation = [interpretation] - return interpretation, [] - else: - raise ValueError("No interpretation method specified.") - - -def diff(original: Any, perturbed: Any) -> int | float: - try: # try computing numerical difference - score = float(original) - float(perturbed) - except ValueError: # otherwise, look at strict difference in label - score = int(original != perturbed) - return score - - -def quantify_difference_in_label( - interface: Interface, original_output: list, perturbed_output: list -) -> int | float: - output_component = interface.output_components[0] - post_original_output = output_component.postprocess(original_output[0]) - post_perturbed_output = output_component.postprocess(perturbed_output[0]) - - if isinstance(output_component, components.Label): - original_label = post_original_output["label"] - perturbed_label = post_perturbed_output["label"] - - # Handle different return types of Label interface - if "confidences" in post_original_output: - original_confidence = original_output[0][original_label] - perturbed_confidence = perturbed_output[0][original_label] - score = original_confidence - perturbed_confidence - else: - score = diff(original_label, perturbed_label) - return score - - elif isinstance(output_component, components.Number): - score = diff(post_original_output, post_perturbed_output) - return score - - else: - raise ValueError( - f"This interpretation method doesn't support the Output component: {output_component}" - ) - - -def get_regression_or_classification_value( - interface: Interface, original_output: list, perturbed_output: list -) -> int | float: - """Used to combine regression/classification for Shap interpretation method.""" - output_component = interface.output_components[0] - post_original_output = output_component.postprocess(original_output[0]) - post_perturbed_output = output_component.postprocess(perturbed_output[0]) - - if isinstance(output_component, components.Label): - original_label = post_original_output["label"] - perturbed_label = post_perturbed_output["label"] - - # Handle different return types of Label interface - if "confidences" in post_original_output: - if math.isnan(perturbed_output[0][original_label]): - return 0 - return perturbed_output[0][original_label] - else: - score = diff( - perturbed_label, original_label - ) # Intentionally inverted order of arguments. - return score - - else: - raise ValueError( - f"This interpretation method doesn't support the Output component: {output_component}" - ) diff --git a/gradio/layouts.py b/gradio/layouts.py deleted file mode 100644 index f4d4374aca36..000000000000 --- a/gradio/layouts.py +++ /dev/null @@ -1,373 +0,0 @@ -from __future__ import annotations - -import warnings -from typing import TYPE_CHECKING, Literal - -from gradio_client.documentation import document, set_documentation_group - -from gradio.blocks import BlockContext, Updateable -from gradio.deprecation import warn_deprecation, warn_style_method_deprecation -from gradio.events import Changeable, Selectable - -if TYPE_CHECKING: - from gradio.blocks import Block - -set_documentation_group("layout") - - -@document() -class Row(Updateable, BlockContext): - """ - Row is a layout element within Blocks that renders all children horizontally. - Example: - with gr.Blocks() as demo: - with gr.Row(): - gr.Image("lion.jpg", scale=2) - gr.Image("tiger.jpg", scale=1) - demo.launch() - Guides: controlling-layout - """ - - def __init__( - self, - *, - variant: Literal["default", "panel", "compact"] = "default", - visible: bool = True, - elem_id: str | None = None, - elem_classes: list[str] | str | None = None, - equal_height: bool = True, - **kwargs, - ): - """ - Parameters: - variant: row type, 'default' (no background), 'panel' (gray background color and rounded corners), or 'compact' (rounded corners and no internal gap). - visible: If False, row will be hidden. - elem_id: An optional string that is assigned as the id of this component in the HTML DOM. Can be used for targeting CSS styles. - elem_classes: An optional string or list of strings that are assigned as the class of this component in the HTML DOM. Can be used for targeting CSS styles. - equal_height: If True, makes every child element have equal height - """ - self.variant = variant - self.equal_height = equal_height - if variant == "compact": - self.allow_expected_parents = False - BlockContext.__init__( - self, visible=visible, elem_id=elem_id, elem_classes=elem_classes, **kwargs - ) - - @staticmethod - def update( - visible: bool | None = None, - ): - return { - "visible": visible, - "__type__": "update", - } - - def style( - self, - *, - equal_height: bool | None = None, - **kwargs, - ): - """ - Styles the Row. - Parameters: - equal_height: If True, makes every child element have equal height - """ - warn_style_method_deprecation() - if equal_height is not None: - self.equal_height = equal_height - return self - - -@document() -class Column(Updateable, BlockContext): - """ - Column is a layout element within Blocks that renders all children vertically. The widths of columns can be set through the `scale` and `min_width` parameters. - If a certain scale results in a column narrower than min_width, the min_width parameter will win. - Example: - with gr.Blocks() as demo: - with gr.Row(): - with gr.Column(scale=1): - text1 = gr.Textbox() - text2 = gr.Textbox() - with gr.Column(scale=4): - btn1 = gr.Button("Button 1") - btn2 = gr.Button("Button 2") - Guides: controlling-layout - """ - - def __init__( - self, - *, - scale: int = 1, - min_width: int = 320, - variant: Literal["default", "panel", "compact"] = "default", - visible: bool = True, - elem_id: str | None = None, - elem_classes: list[str] | str | None = None, - **kwargs, - ): - """ - Parameters: - scale: relative width compared to adjacent Columns. For example, if Column A has scale=2, and Column B has scale=1, A will be twice as wide as B. - min_width: minimum pixel width of Column, will wrap if not sufficient screen space to satisfy this value. If a certain scale value results in a column narrower than min_width, the min_width parameter will be respected first. - variant: column type, 'default' (no background), 'panel' (gray background color and rounded corners), or 'compact' (rounded corners and no internal gap). - visible: If False, column will be hidden. - elem_id: An optional string that is assigned as the id of this component in the HTML DOM. Can be used for targeting CSS styles. - elem_classes: An optional string or list of strings that are assigned as the class of this component in the HTML DOM. Can be used for targeting CSS styles. - """ - if scale != round(scale): - warn_deprecation( - f"'scale' value should be an integer. Using {scale} will cause issues." - ) - - self.scale = scale - self.min_width = min_width - self.variant = variant - if variant == "compact": - self.allow_expected_parents = False - BlockContext.__init__( - self, visible=visible, elem_id=elem_id, elem_classes=elem_classes, **kwargs - ) - - @staticmethod - def update( - variant: str | None = None, - visible: bool | None = None, - ): - return { - "variant": variant, - "visible": visible, - "__type__": "update", - } - - -class Tabs(Updateable, BlockContext, Changeable, Selectable): - """ - Tabs is a layout element within Blocks that can contain multiple "Tab" Components. - """ - - def __init__( - self, - *, - selected: int | str | None = None, - visible: bool = True, - elem_id: str | None = None, - elem_classes: list[str] | str | None = None, - **kwargs, - ): - """ - Parameters: - selected: The currently selected tab. Must correspond to an id passed to the one of the child TabItems. Defaults to the first TabItem. - visible: If False, Tabs will be hidden. - elem_id: An optional string that is assigned as the id of this component in the HTML DOM. Can be used for targeting CSS styles. - elem_classes: An optional string or list of strings that are assigned as the class of this component in the HTML DOM. Can be used for targeting CSS styles. - """ - BlockContext.__init__( - self, visible=visible, elem_id=elem_id, elem_classes=elem_classes, **kwargs - ) - Changeable.__init__(self) - Selectable.__init__(self) - self.selected = selected - - @staticmethod - def update( - selected: int | str | None = None, - ): - return { - "selected": selected, - "__type__": "update", - } - - -@document() -class Tab(Updateable, BlockContext, Selectable): - """ - Tab (or its alias TabItem) is a layout element. Components defined within the Tab will be visible when this tab is selected tab. - Example: - with gr.Blocks() as demo: - with gr.Tab("Lion"): - gr.Image("lion.jpg") - gr.Button("New Lion") - with gr.Tab("Tiger"): - gr.Image("tiger.jpg") - gr.Button("New Tiger") - Guides: controlling-layout - """ - - def __init__( - self, - label: str, - *, - id: int | str | None = None, - elem_id: str | None = None, - elem_classes: list[str] | str | None = None, - **kwargs, - ): - """ - Parameters: - label: The visual label for the tab - id: An optional identifier for the tab, required if you wish to control the selected tab from a predict function. - elem_id: An optional string that is assigned as the id of the