From eac5778c5eed2c1ef21ecf2ac8987e8bdae4584f Mon Sep 17 00:00:00 2001 From: Jun Chen Date: Fri, 19 May 2023 21:07:33 +0800 Subject: [PATCH 1/5] Enable offline usage for gradio --- README_OFFLINE.md | 11 ++ gradio/version.txt | 2 +- js/app/index.html | 7 - js/app/package.json | 3 +- js/app/src/iframeResizer.contentWindow.min.js | 10 ++ pnpm-lock.yaml | 166 ++---------------- pyproject.toml | 8 +- scripts/build_frontend.sh | 2 +- 8 files changed, 44 insertions(+), 165 deletions(-) create mode 100644 README_OFFLINE.md create mode 100644 js/app/src/iframeResizer.contentWindow.min.js diff --git a/README_OFFLINE.md b/README_OFFLINE.md new file mode 100644 index 00000000000..5708e75b27a --- /dev/null +++ b/README_OFFLINE.md @@ -0,0 +1,11 @@ +# Gradio Offline + +Use gradio without internet connection. This repo tracks [the official repo](https://github.com/gradio-app/gradio) until it supports offline mode. + +## Install + +```shell +pip install gradio-offline +``` + +Usage is the same as using `gradio`. diff --git a/gradio/version.txt b/gradio/version.txt index d9351e5882a..2eb94cb4085 100644 --- a/gradio/version.txt +++ b/gradio/version.txt @@ -1 +1 @@ -3.31.0 +3.31.0.2 diff --git a/js/app/index.html b/js/app/index.html index e74d43728d0..dfb837673da 100644 --- a/js/app/index.html +++ b/js/app/index.html @@ -40,13 +40,6 @@ %gradio_config% - - - =0.8.0'} + dev: false + /ignore@5.2.4: resolution: {integrity: sha512-MAb38BcSbH0eHNBxn7ql2NH/kX33OkB3lZ1BNdh7ENeRChHTYsTvWrMubiIAMNS2llXEEgZ1MUOBtXChP3kaFQ==} engines: {node: '>= 4'} @@ -4699,7 +4707,6 @@ packages: resolution: {integrity: sha512-fmsZYa9lpn69Ad5eDn7FMcnnSR+8R34W9qJEijxYhTbfOWzr22n1QxCMzXLK+ODyW2973V3Fux959iQoUxzUIA==} engines: {node: ^10 || ^12 || ^13.7 || ^14 || >=15.0.1} hasBin: true - dev: false /nanoid@3.3.4: resolution: {integrity: sha512-MqBkQh/OHTS2egovRtLk45wEyNXwF+cokD+1YPf9u5VfJiRdAiRwB2froX5Co9Rh20xs4siNPm8naNotSD6RBw==} @@ -5257,7 +5264,6 @@ packages: nanoid: 3.2.0 picocolors: 1.0.0 source-map-js: 1.0.2 - dev: false /preferred-pm@3.0.3: resolution: {integrity: sha512-+wZgbxNES/KlJs9q40F/1sfOd/j7f1O9JaHcW5Dsn3aUUOZg3L2bjpVUcKV2jvtElYfoTuQiNeMfQJ4kwUAhCQ==} @@ -6051,34 +6057,6 @@ packages: - sass - stylus - sugarss - dev: false - - /svelte-check@3.1.4(svelte@3.57.0): - resolution: {integrity: sha512-25Lb46ZS4IK/XpBMe4IBMrtYf23V8alqBX+szXoccb7uM0D2Wqq5rMRzYBONZnFVuU1bQG3R50lyIT5eRewv2g==} - hasBin: true - peerDependencies: - svelte: ^3.55.0 - dependencies: - '@jridgewell/trace-mapping': 0.3.17 - chokidar: 3.5.3 - fast-glob: 3.2.11 - import-fresh: 3.3.0 - picocolors: 1.0.0 - sade: 1.8.1 - svelte: 3.57.0 - svelte-preprocess: 5.0.3(svelte@3.57.0)(typescript@4.9.5) - typescript: 4.9.5 - transitivePeerDependencies: - - '@babel/core' - - coffeescript - - less - - postcss - - postcss-load-config - - pug - - sass - - stylus - - sugarss - dev: true /svelte-hmr@0.14.11(svelte@3.49.0): resolution: {integrity: sha512-R9CVfX6DXxW1Kn45Jtmx+yUe+sPhrbYSUp7TkzbW0jI5fVPn6lsNG9NEs5dFg5qRhFNAoVdRw5qQDLALNKhwbQ==} @@ -6323,54 +6301,6 @@ packages: strip-indent: 3.0.0 svelte: 3.57.0 typescript: 4.9.5 - dev: false - - /svelte-preprocess@5.0.3(svelte@3.57.0)(typescript@4.9.5): - resolution: {integrity: sha512-GrHF1rusdJVbOZOwgPWtpqmaexkydznKzy5qIC2FabgpFyKN57bjMUUUqPRfbBXK5igiEWn1uO/DXsa2vJ5VHA==} - engines: {node: '>= 14.10.0'} - requiresBuild: true - peerDependencies: - '@babel/core': ^7.10.2 - coffeescript: ^2.5.1 - less: ^3.11.3 || ^4.0.0 - postcss: ^7 || ^8 - postcss-load-config: ^2.1.0 || ^3.0.0 || ^4.0.0 - pug: ^3.0.0 - sass: ^1.26.8 - stylus: ^0.55.0 - sugarss: ^2.0.0 || ^3.0.0 || ^4.0.0 - svelte: ^3.23.0 - typescript: '>=3.9.5 || ^4.0.0 || ^5.0.0' - peerDependenciesMeta: - '@babel/core': - optional: true - coffeescript: - optional: true - less: - optional: true - postcss: - optional: true - postcss-load-config: - optional: true - pug: - optional: true - sass: - optional: true - stylus: - optional: true - sugarss: - optional: true - typescript: - optional: true - dependencies: - '@types/pug': 2.0.6 - detect-indent: 6.1.0 - magic-string: 0.27.0 - sorcery: 0.11.0 - strip-indent: 3.0.0 - svelte: 3.57.0 - typescript: 4.9.5 - dev: true /svelte-range-slider-pips@2.0.2: resolution: {integrity: sha512-VTWHOdwDyWbndGZnI0PQJY9DO7hgQlNubtCcCL6Wlypv5dU4vEsc4A1sX9TWMuvebEe4332SgsQQHzOdZ+guhQ==} @@ -7159,39 +7089,6 @@ packages: fsevents: 2.3.2 dev: true - /vite@4.2.1: - resolution: {integrity: sha512-7MKhqdy0ISo4wnvwtqZkjke6XN4taqQ2TBaTccLIpOKv7Vp2h4Y+NpmWCnGDeSvvn45KxvWgGyb0MkHvY1vgbg==} - engines: {node: ^14.18.0 || >=16.0.0} - hasBin: true - peerDependencies: - '@types/node': '>= 14' - less: '*' - sass: '*' - stylus: '*' - sugarss: '*' - terser: ^5.4.0 - peerDependenciesMeta: - '@types/node': - optional: true - less: - optional: true - sass: - optional: true - stylus: - optional: true - sugarss: - optional: true - terser: - optional: true - dependencies: - esbuild: 0.17.14 - postcss: 8.4.21 - resolve: 1.22.1 - rollup: 3.20.2 - optionalDependencies: - fsevents: 2.3.2 - dev: false - /vite@4.2.1(@types/node@17.0.14): resolution: {integrity: sha512-7MKhqdy0ISo4wnvwtqZkjke6XN4taqQ2TBaTccLIpOKv7Vp2h4Y+NpmWCnGDeSvvn45KxvWgGyb0MkHvY1vgbg==} engines: {node: ^14.18.0 || >=16.0.0} @@ -7226,38 +7123,6 @@ packages: fsevents: 2.3.2 dev: false - /vite@4.3.5: - resolution: {integrity: sha512-0gEnL9wiRFxgz40o/i/eTBwm+NEbpUeTWhzKrZDSdKm6nplj+z4lKz8ANDgildxHm47Vg8EUia0aicKbawUVVA==} - engines: {node: ^14.18.0 || >=16.0.0} - hasBin: true - peerDependencies: - '@types/node': '>= 14' - less: '*' - sass: '*' - stylus: '*' - sugarss: '*' - terser: ^5.4.0 - peerDependenciesMeta: - '@types/node': - optional: true - less: - optional: true - sass: - optional: true - stylus: - optional: true - sugarss: - optional: true - terser: - optional: true - dependencies: - esbuild: 0.17.14 - postcss: 8.4.23 - rollup: 3.21.6 - optionalDependencies: - fsevents: 2.3.2 - dev: true - /vite@4.3.5(@types/node@17.0.14): resolution: {integrity: sha512-0gEnL9wiRFxgz40o/i/eTBwm+NEbpUeTWhzKrZDSdKm6nplj+z4lKz8ANDgildxHm47Vg8EUia0aicKbawUVVA==} engines: {node: ^14.18.0 || >=16.0.0} @@ -7289,7 +7154,6 @@ packages: rollup: 3.21.6 optionalDependencies: fsevents: 2.3.2 - dev: false /vitefu@0.2.4(vite@4.3.5): resolution: {integrity: sha512-fanAXjSaf9xXtOOeno8wZXIhgia+CZury481LsDaV++lSvcU2R9Ch2bPh3PYFyoHW+w9LqAeYRISVQjUIew14g==} @@ -7299,7 +7163,7 @@ packages: vite: optional: true dependencies: - vite: 4.3.5 + vite: 4.3.5(@types/node@17.0.14) dev: true /vitest@0.29.8(happy-dom@2.49.0)(playwright@1.27.1): diff --git a/pyproject.toml b/pyproject.toml index da10bde849c..ee7694b6ce7 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -3,7 +3,7 @@ requires = ["hatchling", "hatch-requirements-txt", "hatch-fancy-pypi-readme>=22. build-backend = "hatchling.build" [project] -name = "gradio" +name = "gradio-offline" dynamic = ["version", "dependencies", "readme"] description = "Python library for easily interacting with trained machine learning models" license = "Apache-2.0" @@ -24,7 +24,7 @@ gradio = "gradio.reload:main" upload_theme = "gradio.themes.upload_theme:main" [project.urls] -Homepage = "https://github.com/gradio-app/gradio" +Homepage = "https://github.com/junchen1992/gradio-offline" [tool.hatch.version] path = "gradio/version.txt" @@ -36,7 +36,7 @@ filename = "requirements.txt" [tool.hatch.metadata.hooks.fancy-pypi-readme] content-type = "text/markdown" fragments = [ - { path = "README.md" }, + { path = "README_OFFLINE.md" }, ] [[tool.hatch.metadata.hooks.fancy-pypi-readme.substitutions]] @@ -57,7 +57,7 @@ artifacts = [ include = [ "/gradio", "/test", - "/README.md", + "/README_OFFLINE.md", "/requirements.txt", ] diff --git a/scripts/build_frontend.sh b/scripts/build_frontend.sh index 5ff83d2a32a..e3688d26463 100644 --- a/scripts/build_frontend.sh +++ b/scripts/build_frontend.sh @@ -6,5 +6,5 @@ source scripts/helpers.sh pnpm_required echo "Building the frontend..." -pnpm i --frozen-lockfile +pnpm i --no-frozen-lockfile pnpm build From a8a1a5afe9df253769ed3da65d1fdf828ede2116 Mon Sep 17 00:00:00 2001 From: Jun Chen Date: Fri, 19 May 2023 21:37:12 +0800 Subject: [PATCH 2/5] Fix: pack version.txt into whl file --- pyproject.toml | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/pyproject.toml b/pyproject.toml index ee7694b6ce7..f26c9f7944c 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -52,7 +52,6 @@ artifacts = [ "/gradio/templates", ] - [tool.hatch.build.targets.sdist] include = [ "/gradio", @@ -61,6 +60,11 @@ include = [ "/requirements.txt", ] +[tool.hatch.build.targets.wheel] +include = [ + "/gradio", +] + [tool.ruff] target-version = "py37" extend-select = [ From 585235582967c0f1c83095c737e8bdf9c5890dd7 Mon Sep 17 00:00:00 2001 From: Jun Chen Date: Fri, 19 May 2023 22:06:29 +0800 Subject: [PATCH 3/5] Fix: change default theme and disable Google Analytics --- README_OFFLINE.md | 2 ++ gradio/analytics.py | 2 +- gradio/themes/default.py | 4 ++-- gradio/version.txt | 2 +- upload_artifacts.sh | 7 +++++++ 5 files changed, 13 insertions(+), 4 deletions(-) create mode 100644 upload_artifacts.sh diff --git a/README_OFFLINE.md b/README_OFFLINE.md index 5708e75b27a..e2c5614e5b7 100644 --- a/README_OFFLINE.md +++ b/README_OFFLINE.md @@ -9,3 +9,5 @@ pip install gradio-offline ``` Usage is the same as using `gradio`. + +:warning: This repo is designed to make minimal changes to enable the offline usage of gradio. diff --git a/gradio/analytics.py b/gradio/analytics.py index c1c1a908bbb..35de8f27e8a 100644 --- a/gradio/analytics.py +++ b/gradio/analytics.py @@ -23,7 +23,7 @@ def analytics_enabled() -> bool: """ Returns: True if analytics are enabled, False otherwise. """ - return os.getenv("GRADIO_ANALYTICS_ENABLED", "True") == "True" + return os.getenv("GRADIO_ANALYTICS_ENABLED", "False") == "True" def _do_analytics_request(url: str, data: dict[str, Any]) -> None: diff --git a/gradio/themes/default.py b/gradio/themes/default.py index c58299eb645..52167735ea4 100644 --- a/gradio/themes/default.py +++ b/gradio/themes/default.py @@ -19,7 +19,7 @@ def __init__( font: fonts.Font | str | Iterable[fonts.Font | str] = ( - fonts.GoogleFont("Source Sans Pro"), + # fonts.GoogleFont("Source Sans Pro"), "ui-sans-serif", "system-ui", "sans-serif", @@ -27,7 +27,7 @@ def __init__( font_mono: fonts.Font | str | Iterable[fonts.Font | str] = ( - fonts.GoogleFont("IBM Plex Mono"), + # fonts.GoogleFont("IBM Plex Mono"), "ui-monospace", "Consolas", "monospace", diff --git a/gradio/version.txt b/gradio/version.txt index 2eb94cb4085..6b2bc8393b5 100644 --- a/gradio/version.txt +++ b/gradio/version.txt @@ -1 +1 @@ -3.31.0.2 +3.31.0.4 diff --git a/upload_artifacts.sh b/upload_artifacts.sh new file mode 100644 index 00000000000..c88a20c6d25 --- /dev/null +++ b/upload_artifacts.sh @@ -0,0 +1,7 @@ +#!/bin/bash + +rm -rf dist/ + +python3 -m build + +twine upload dist/* \ No newline at end of file From 778198668f6cba3a4746407e2a4ae64d66be61a1 Mon Sep 17 00:00:00 2001 From: Jun Chen Date: Fri, 19 May 2023 22:13:31 +0800 Subject: [PATCH 4/5] Update README --- README.md | 290 ++------------------------------------------ README_ORINGINAL.md | 289 +++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 296 insertions(+), 283 deletions(-) create mode 100644 README_ORINGINAL.md diff --git a/README.md b/README.md index fab1a00a0e0..e2c5614e5b7 100644 --- a/README.md +++ b/README.md @@ -1,289 +1,13 @@ - +# Gradio Offline -
+Use gradio without internet connection. This repo tracks [the official repo](https://github.com/gradio-app/gradio) until it supports offline mode. - [gradio](https://gradio.app)
- Build & share delightful machine learning apps easily +## Install - [![gradio-backend](https://github.com/gradio-app/gradio/actions/workflows/backend.yml/badge.svg)](https://github.com/gradio-app/gradio/actions/workflows/backend.yml) - [![gradio-ui](https://github.com/gradio-app/gradio/actions/workflows/ui.yml/badge.svg)](https://github.com/gradio-app/gradio/actions/workflows/ui.yml) - [![PyPI](https://img.shields.io/pypi/v/gradio)](https://pypi.org/project/gradio/) - [![PyPI downloads](https://img.shields.io/pypi/dm/gradio)](https://pypi.org/project/gradio/) - ![Python version](https://img.shields.io/badge/python-3.7+-important) - [![Twitter follow](https://img.shields.io/twitter/follow/gradio?style=social&label=follow)](https://twitter.com/gradio) - - [Website](https://gradio.app) - | [Documentation](https://gradio.app/docs/) - | [Guides](https://gradio.app/guides/) - | [Getting Started](https://gradio.app/getting_started/) - | [Examples](demo/) - | [δΈ­ζ–‡](readme_files/zh-cn#readme) -
- -# Gradio: Build Machine Learning Web Apps β€” in Python - -Gradio is an open-source Python library that is used to build machine learning and data science demos and web applications. - -With Gradio, you can quickly create a beautiful user interface around your machine learning models or data science workflow and let people "try it out" by dragging-and-dropping in their own images, -pasting text, recording their own voice, and interacting with your demo, all through the browser. - -![Interface montage](readme_files/header-image.jpg) - -Gradio is useful for: - -- **Demoing** your machine learning models for clients/collaborators/users/students. - -- **Deploying** your models quickly with automatic shareable links and getting feedback on model performance. - -- **Debugging** your model interactively during development using built-in manipulation and interpretation tools. - -## Quickstart - -**Prerequisite**: Gradio requires Python 3.7 or higher, that's all! - -### What Does Gradio Do? - -One of the *best ways to share* your machine learning model, API, or data science workflow with others is to create an **interactive app** that allows your users or colleagues to try out the demo in their browsers. - -Gradio allows you to **build demos and share them, all in Python.** And usually in just a few lines of code! So let's get started. - -### Hello, World - -To get Gradio running with a simple "Hello, World" example, follow these three steps: - -1\. Install Gradio using pip: - -```bash -pip install gradio -``` - -2\. Run the code below as a Python script or in a Jupyter Notebook (or [Google Colab](https://colab.research.google.com/drive/18ODkJvyxHutTN0P5APWyGFO_xwNcgHDZ?usp=sharing)): - -```python -import gradio as gr - -def greet(name): - return "Hello " + name + "!" - -demo = gr.Interface(fn=greet, inputs="text", outputs="text") - -demo.launch() -``` - - -3\. The demo below will appear automatically within the Jupyter Notebook, or pop in a browser on [http://localhost:7860](http://localhost:7860) if running from a script: - -![`hello_world` demo](demo/hello_world/screenshot.gif) - -When developing locally, if you want to run the code as a Python script, you can use the Gradio CLI to launch the application **in reload mode**, which will provide seamless and fast development. Learn more about reloading in the [Auto-Reloading Guide](https://gradio.app/developing-faster-with-reload-mode/). - -```bash -gradio app.py -``` - -Note: you can also do `python app.py`, but it won't provide the automatic reload mechanism. - -### The `Interface` Class - -You'll notice that in order to make the demo, we created a `gradio.Interface`. This `Interface` class can wrap any Python function with a user interface. In the example above, we saw a simple text-based function, but the function could be anything from music generator to a tax calculator to the prediction function of a pretrained machine learning model. - -The core `Interface` class is initialized with three required parameters: - -- `fn`: the function to wrap a UI around -- `inputs`: which component(s) to use for the input (e.g. `"text"`, `"image"` or `"audio"`) -- `outputs`: which component(s) to use for the output (e.g. `"text"`, `"image"` or `"label"`) - -Let's take a closer look at these components used to provide input and output. - -### Components Attributes - -We saw some simple `Textbox` components in the previous examples, but what if you want to change how the UI components look or behave? - -Let's say you want to customize the input text field β€” for example, you wanted it to be larger and have a text placeholder. If we use the actual class for `Textbox` instead of using the string shortcut, you have access to much more customizability through component attributes. - -```python -import gradio as gr - -def greet(name): - return "Hello " + name + "!" - -demo = gr.Interface( - fn=greet, - inputs=gr.Textbox(lines=2, placeholder="Name Here..."), - outputs="text", -) -demo.launch() +```shell +pip install gradio-offline ``` -![`hello_world_2` demo](demo/hello_world_2/screenshot.gif) - -### Multiple Input and Output Components - -Suppose you had a more complex function, with multiple inputs and outputs. In the example below, we define a function that takes a string, boolean, and number, and returns a string and number. Take a look how you pass a list of input and output components. - -```python -import gradio as gr - -def greet(name, is_morning, temperature): - salutation = "Good morning" if is_morning else "Good evening" - greeting = f"{salutation} {name}. It is {temperature} degrees today" - celsius = (temperature - 32) * 5 / 9 - return greeting, round(celsius, 2) - -demo = gr.Interface( - fn=greet, - inputs=["text", "checkbox", gr.Slider(0, 100)], - outputs=["text", "number"], -) -demo.launch() -``` - -![`hello_world_3` demo](demo/hello_world_3/screenshot.gif) - -You simply wrap the components in a list. Each component in the `inputs` list corresponds to one of the parameters of the function, in order. Each component in the `outputs` list corresponds to one of the values returned by the function, again in order. - -### An Image Example - -Gradio supports many types of components, such as `Image`, `DataFrame`, `Video`, or `Label`. Let's try an image-to-image function to get a feel for these! +Usage is the same as using `gradio`. -```python -import numpy as np -import gradio as gr - -def sepia(input_img): - sepia_filter = np.array([ - [0.393, 0.769, 0.189], - [0.349, 0.686, 0.168], - [0.272, 0.534, 0.131] - ]) - sepia_img = input_img.dot(sepia_filter.T) - sepia_img /= sepia_img.max() - return sepia_img - -demo = gr.Interface(sepia, gr.Image(shape=(200, 200)), "image") -demo.launch() -``` - -![`sepia_filter` demo](demo/sepia_filter/screenshot.gif) - -When using the `Image` component as input, your function will receive a NumPy array with the shape `(height, width, 3)`, where the last dimension represents the RGB values. We'll return an image as well in the form of a NumPy array. - -You can also set the datatype used by the component with the `type=` keyword argument. For example, if you wanted your function to take a file path to an image instead of a NumPy array, the input `Image` component could be written as: - -```python -gr.Image(type="filepath", shape=...) -``` - -Also note that our input `Image` component comes with an edit button πŸ–‰, which allows for cropping and zooming into images. Manipulating images in this way can help reveal biases or hidden flaws in a machine learning model! - -You can read more about the many components and how to use them in the [Gradio docs](https://gradio.app/docs). - -### Blocks: More Flexibility and Control - -Gradio offers two classes to build apps: - -1\. **Interface**, that provides a high-level abstraction for creating demos that we've been discussing so far. - -2\. **Blocks**, a low-level API for designing web apps with more flexible layouts and data flows. Blocks allows you to do things like feature multiple data flows and demos, control where components appear on the page, handle complex data flows (e.g. outputs can serve as inputs to other functions), and update properties/visibility of components based on user interaction β€” still all in Python. If this customizability is what you need, try `Blocks` instead! - -### Hello, Blocks - -Let's take a look at a simple example. Note how the API here differs from `Interface`. - -```python -import gradio as gr - -def greet(name): - return "Hello " + name + "!" - -with gr.Blocks() as demo: - name = gr.Textbox(label="Name") - output = gr.Textbox(label="Output Box") - greet_btn = gr.Button("Greet") - greet_btn.click(fn=greet, inputs=name, outputs=output) - -demo.launch() -``` - -![`hello_blocks` demo](demo/hello_blocks/screenshot.gif) - -Things to note: - -- `Blocks` are made with a `with` clause, and any component created inside this clause is automatically added to the app. -- Components appear vertically in the app in the order they are created. (Later we will cover customizing layouts!) -- A `Button` was created, and then a `click` event-listener was added to this button. The API for this should look familiar! Like an `Interface`, the `click` method takes a Python function, input components, and output components. - -### More Complexity - -Here's an app to give you a taste of what's possible with `Blocks`: - -```python -import numpy as np -import gradio as gr - - -def flip_text(x): - return x[::-1] - - -def flip_image(x): - return np.fliplr(x) - - -with gr.Blocks() as demo: - gr.Markdown("Flip text or image files using this demo.") - with gr.Tab("Flip Text"): - text_input = gr.Textbox() - text_output = gr.Textbox() - text_button = gr.Button("Flip") - with gr.Tab("Flip Image"): - with gr.Row(): - image_input = gr.Image() - image_output = gr.Image() - image_button = gr.Button("Flip") - - with gr.Accordion("Open for More!"): - gr.Markdown("Look at me...") - - text_button.click(flip_text, inputs=text_input, outputs=text_output) - image_button.click(flip_image, inputs=image_input, outputs=image_output) - -demo.launch() -``` - -![`blocks_flipper` demo](demo/blocks_flipper/screenshot.gif) - -A lot more going on here! We'll cover how to create complex `Blocks` apps like this in the [building with blocks](https://gradio.app/building_with_blocks) section for you. - -Congrats, you're now familiar with the basics of Gradio! πŸ₯³ Go to our [next guide](https://gradio.app/key_features) to learn more about the key features of Gradio. - - -## Open Source Stack - -Gradio is built with many wonderful open-source libraries, please support them as well! - -[huggingface](https://huggingface.co) -[python](https://www.python.org) -[fastapi](https://fastapi.tiangolo.com) -[encode](https://www.encode.io) -[svelte](https://svelte.dev) -[vite](https://vitejs.dev) -[pnpm](https://pnpm.io) -[tailwind](https://tailwindcss.com) - -## License - -Gradio is licensed under the Apache License 2.0 found in the [LICENSE](LICENSE) file in the root directory of this repository. - -## Citation - -Also check out the paper *[Gradio: Hassle-Free Sharing and Testing of ML Models in the Wild](https://arxiv.org/abs/1906.02569), ICML HILL 2019*, and please cite it if you use Gradio in your work. - -``` -@article{abid2019gradio, - title = {Gradio: Hassle-Free Sharing and Testing of ML Models in the Wild}, - author = {Abid, Abubakar and Abdalla, Ali and Abid, Ali and Khan, Dawood and Alfozan, Abdulrahman and Zou, James}, - journal = {arXiv preprint arXiv:1906.02569}, - year = {2019}, -} -``` +:warning: This repo is designed to make minimal changes to enable the offline usage of gradio. diff --git a/README_ORINGINAL.md b/README_ORINGINAL.md new file mode 100644 index 00000000000..fab1a00a0e0 --- /dev/null +++ b/README_ORINGINAL.md @@ -0,0 +1,289 @@ + + +
+ + [gradio](https://gradio.app)
+ Build & share delightful machine learning apps easily + + [![gradio-backend](https://github.com/gradio-app/gradio/actions/workflows/backend.yml/badge.svg)](https://github.com/gradio-app/gradio/actions/workflows/backend.yml) + [![gradio-ui](https://github.com/gradio-app/gradio/actions/workflows/ui.yml/badge.svg)](https://github.com/gradio-app/gradio/actions/workflows/ui.yml) + [![PyPI](https://img.shields.io/pypi/v/gradio)](https://pypi.org/project/gradio/) + [![PyPI downloads](https://img.shields.io/pypi/dm/gradio)](https://pypi.org/project/gradio/) + ![Python version](https://img.shields.io/badge/python-3.7+-important) + [![Twitter follow](https://img.shields.io/twitter/follow/gradio?style=social&label=follow)](https://twitter.com/gradio) + + [Website](https://gradio.app) + | [Documentation](https://gradio.app/docs/) + | [Guides](https://gradio.app/guides/) + | [Getting Started](https://gradio.app/getting_started/) + | [Examples](demo/) + | [δΈ­ζ–‡](readme_files/zh-cn#readme) +
+ +# Gradio: Build Machine Learning Web Apps β€” in Python + +Gradio is an open-source Python library that is used to build machine learning and data science demos and web applications. + +With Gradio, you can quickly create a beautiful user interface around your machine learning models or data science workflow and let people "try it out" by dragging-and-dropping in their own images, +pasting text, recording their own voice, and interacting with your demo, all through the browser. + +![Interface montage](readme_files/header-image.jpg) + +Gradio is useful for: + +- **Demoing** your machine learning models for clients/collaborators/users/students. + +- **Deploying** your models quickly with automatic shareable links and getting feedback on model performance. + +- **Debugging** your model interactively during development using built-in manipulation and interpretation tools. + +## Quickstart + +**Prerequisite**: Gradio requires Python 3.7 or higher, that's all! + +### What Does Gradio Do? + +One of the *best ways to share* your machine learning model, API, or data science workflow with others is to create an **interactive app** that allows your users or colleagues to try out the demo in their browsers. + +Gradio allows you to **build demos and share them, all in Python.** And usually in just a few lines of code! So let's get started. + +### Hello, World + +To get Gradio running with a simple "Hello, World" example, follow these three steps: + +1\. Install Gradio using pip: + +```bash +pip install gradio +``` + +2\. Run the code below as a Python script or in a Jupyter Notebook (or [Google Colab](https://colab.research.google.com/drive/18ODkJvyxHutTN0P5APWyGFO_xwNcgHDZ?usp=sharing)): + +```python +import gradio as gr + +def greet(name): + return "Hello " + name + "!" + +demo = gr.Interface(fn=greet, inputs="text", outputs="text") + +demo.launch() +``` + + +3\. The demo below will appear automatically within the Jupyter Notebook, or pop in a browser on [http://localhost:7860](http://localhost:7860) if running from a script: + +![`hello_world` demo](demo/hello_world/screenshot.gif) + +When developing locally, if you want to run the code as a Python script, you can use the Gradio CLI to launch the application **in reload mode**, which will provide seamless and fast development. Learn more about reloading in the [Auto-Reloading Guide](https://gradio.app/developing-faster-with-reload-mode/). + +```bash +gradio app.py +``` + +Note: you can also do `python app.py`, but it won't provide the automatic reload mechanism. + +### The `Interface` Class + +You'll notice that in order to make the demo, we created a `gradio.Interface`. This `Interface` class can wrap any Python function with a user interface. In the example above, we saw a simple text-based function, but the function could be anything from music generator to a tax calculator to the prediction function of a pretrained machine learning model. + +The core `Interface` class is initialized with three required parameters: + +- `fn`: the function to wrap a UI around +- `inputs`: which component(s) to use for the input (e.g. `"text"`, `"image"` or `"audio"`) +- `outputs`: which component(s) to use for the output (e.g. `"text"`, `"image"` or `"label"`) + +Let's take a closer look at these components used to provide input and output. + +### Components Attributes + +We saw some simple `Textbox` components in the previous examples, but what if you want to change how the UI components look or behave? + +Let's say you want to customize the input text field β€” for example, you wanted it to be larger and have a text placeholder. If we use the actual class for `Textbox` instead of using the string shortcut, you have access to much more customizability through component attributes. + +```python +import gradio as gr + +def greet(name): + return "Hello " + name + "!" + +demo = gr.Interface( + fn=greet, + inputs=gr.Textbox(lines=2, placeholder="Name Here..."), + outputs="text", +) +demo.launch() +``` + +![`hello_world_2` demo](demo/hello_world_2/screenshot.gif) + +### Multiple Input and Output Components + +Suppose you had a more complex function, with multiple inputs and outputs. In the example below, we define a function that takes a string, boolean, and number, and returns a string and number. Take a look how you pass a list of input and output components. + +```python +import gradio as gr + +def greet(name, is_morning, temperature): + salutation = "Good morning" if is_morning else "Good evening" + greeting = f"{salutation} {name}. It is {temperature} degrees today" + celsius = (temperature - 32) * 5 / 9 + return greeting, round(celsius, 2) + +demo = gr.Interface( + fn=greet, + inputs=["text", "checkbox", gr.Slider(0, 100)], + outputs=["text", "number"], +) +demo.launch() +``` + +![`hello_world_3` demo](demo/hello_world_3/screenshot.gif) + +You simply wrap the components in a list. Each component in the `inputs` list corresponds to one of the parameters of the function, in order. Each component in the `outputs` list corresponds to one of the values returned by the function, again in order. + +### An Image Example + +Gradio supports many types of components, such as `Image`, `DataFrame`, `Video`, or `Label`. Let's try an image-to-image function to get a feel for these! + +```python +import numpy as np +import gradio as gr + +def sepia(input_img): + sepia_filter = np.array([ + [0.393, 0.769, 0.189], + [0.349, 0.686, 0.168], + [0.272, 0.534, 0.131] + ]) + sepia_img = input_img.dot(sepia_filter.T) + sepia_img /= sepia_img.max() + return sepia_img + +demo = gr.Interface(sepia, gr.Image(shape=(200, 200)), "image") +demo.launch() +``` + +![`sepia_filter` demo](demo/sepia_filter/screenshot.gif) + +When using the `Image` component as input, your function will receive a NumPy array with the shape `(height, width, 3)`, where the last dimension represents the RGB values. We'll return an image as well in the form of a NumPy array. + +You can also set the datatype used by the component with the `type=` keyword argument. For example, if you wanted your function to take a file path to an image instead of a NumPy array, the input `Image` component could be written as: + +```python +gr.Image(type="filepath", shape=...) +``` + +Also note that our input `Image` component comes with an edit button πŸ–‰, which allows for cropping and zooming into images. Manipulating images in this way can help reveal biases or hidden flaws in a machine learning model! + +You can read more about the many components and how to use them in the [Gradio docs](https://gradio.app/docs). + +### Blocks: More Flexibility and Control + +Gradio offers two classes to build apps: + +1\. **Interface**, that provides a high-level abstraction for creating demos that we've been discussing so far. + +2\. **Blocks**, a low-level API for designing web apps with more flexible layouts and data flows. Blocks allows you to do things like feature multiple data flows and demos, control where components appear on the page, handle complex data flows (e.g. outputs can serve as inputs to other functions), and update properties/visibility of components based on user interaction β€” still all in Python. If this customizability is what you need, try `Blocks` instead! + +### Hello, Blocks + +Let's take a look at a simple example. Note how the API here differs from `Interface`. + +```python +import gradio as gr + +def greet(name): + return "Hello " + name + "!" + +with gr.Blocks() as demo: + name = gr.Textbox(label="Name") + output = gr.Textbox(label="Output Box") + greet_btn = gr.Button("Greet") + greet_btn.click(fn=greet, inputs=name, outputs=output) + +demo.launch() +``` + +![`hello_blocks` demo](demo/hello_blocks/screenshot.gif) + +Things to note: + +- `Blocks` are made with a `with` clause, and any component created inside this clause is automatically added to the app. +- Components appear vertically in the app in the order they are created. (Later we will cover customizing layouts!) +- A `Button` was created, and then a `click` event-listener was added to this button. The API for this should look familiar! Like an `Interface`, the `click` method takes a Python function, input components, and output components. + +### More Complexity + +Here's an app to give you a taste of what's possible with `Blocks`: + +```python +import numpy as np +import gradio as gr + + +def flip_text(x): + return x[::-1] + + +def flip_image(x): + return np.fliplr(x) + + +with gr.Blocks() as demo: + gr.Markdown("Flip text or image files using this demo.") + with gr.Tab("Flip Text"): + text_input = gr.Textbox() + text_output = gr.Textbox() + text_button = gr.Button("Flip") + with gr.Tab("Flip Image"): + with gr.Row(): + image_input = gr.Image() + image_output = gr.Image() + image_button = gr.Button("Flip") + + with gr.Accordion("Open for More!"): + gr.Markdown("Look at me...") + + text_button.click(flip_text, inputs=text_input, outputs=text_output) + image_button.click(flip_image, inputs=image_input, outputs=image_output) + +demo.launch() +``` + +![`blocks_flipper` demo](demo/blocks_flipper/screenshot.gif) + +A lot more going on here! We'll cover how to create complex `Blocks` apps like this in the [building with blocks](https://gradio.app/building_with_blocks) section for you. + +Congrats, you're now familiar with the basics of Gradio! πŸ₯³ Go to our [next guide](https://gradio.app/key_features) to learn more about the key features of Gradio. + + +## Open Source Stack + +Gradio is built with many wonderful open-source libraries, please support them as well! + +[huggingface](https://huggingface.co) +[python](https://www.python.org) +[fastapi](https://fastapi.tiangolo.com) +[encode](https://www.encode.io) +[svelte](https://svelte.dev) +[vite](https://vitejs.dev) +[pnpm](https://pnpm.io) +[tailwind](https://tailwindcss.com) + +## License + +Gradio is licensed under the Apache License 2.0 found in the [LICENSE](LICENSE) file in the root directory of this repository. + +## Citation + +Also check out the paper *[Gradio: Hassle-Free Sharing and Testing of ML Models in the Wild](https://arxiv.org/abs/1906.02569), ICML HILL 2019*, and please cite it if you use Gradio in your work. + +``` +@article{abid2019gradio, + title = {Gradio: Hassle-Free Sharing and Testing of ML Models in the Wild}, + author = {Abid, Abubakar and Abdalla, Ali and Abid, Ali and Khan, Dawood and Alfozan, Abdulrahman and Zou, James}, + journal = {arXiv preprint arXiv:1906.02569}, + year = {2019}, +} +``` From a0e69e1bfd971560ef1ef5c46d73d5563ef37b6f Mon Sep 17 00:00:00 2001 From: Jun Chen Date: Wed, 14 Jun 2023 08:49:14 +0800 Subject: [PATCH 5/5] Update README.md --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index e2c5614e5b7..735aecf3d64 100644 --- a/README.md +++ b/README.md @@ -10,4 +10,4 @@ pip install gradio-offline Usage is the same as using `gradio`. -:warning: This repo is designed to make minimal changes to enable the offline usage of gradio. +:warning: This repo is designed to make minimal changes to enable the offline usage of gradio. **It is still under development.**