Introducing Gradio Clients
WatchIntroducing Gradio Clients
WatchIn 4.15, we added a new gradio cc docs
command to the Gradio CLI to generate rich documentation for your custom component. This command will generate documentation for users automatically, but to get the most out of it, you need to do a few things.
The documentation will be generated when running gradio cc build
. You can pass the --no-generate-docs
argument to turn off this behaviour.
There is also a standalone docs
command that allows for greater customisation. If you are running this command manually it should be run after the version
in your pyproject.toml
has been bumped but before building the component.
All arguments are optional.
gradio cc docs
path # The directory of the custom component.
--demo-dir # Path to the demo directory.
--demo-name # Name of the demo file
--space-url # URL of the Hugging Face Space to link to
--generate-space # create a documentation space.
--no-generate-space # do not create a documentation space
--readme-path # Path to the README.md file.
--generate-readme # create a REAMDE.md file
--no-generate-readme # do not create a README.md file
--suppress-demo-check # suppress validation checks and warnings
The gradio cc docs
command will generate an interactive Gradio app and a static README file with various features. You can see an example here:
The README.md and space both have the following features:
Additionally, the Gradio includes:
The documentation generator uses existing standards to extract the necessary information, namely Type Hints and Docstrings. There are no Gradio-specific APIs for documentation, so following best practices will generally yield the best results.
If you already use type hints and docstrings in your component source code, you don't need to do much to benefit from this feature, but there are some details that you should be aware of.
To get the best documentation experience, you need to use Python 3.10
or greater when generating documentation. This is because some introspection features used to generate the documentation were only added in 3.10
.
Python type hints are used extensively to provide helpful information for users.
If you need to become more familiar with type hints in Python, they are a simple way to express what Python types are expected for arguments and return values of functions and methods. They provide a helpful in-editor experience, aid in maintenance, and integrate with various other tools. These types can be simple primitives, like list
str
bool
; they could be more compound types like list[str]
, str | None
or tuple[str, float | int]
; or they can be more complex types using utility classed like TypedDict
.
You do not need to add type hints to every part of your code. For the documentation to work correctly, you will need to add type hints to the following component methods:
__init__
parameters should be typed.postprocess
parameters and return value should be typed.preprocess
parameters and return value should be typed.If you are using gradio cc create
, these types should already exist, but you may need to tweak them based on any changes you make.
__init__
Here, you only need to type the parameters. If you have cloned a template with gradio
cc create`, these should already be in place. You will only need to add new hints for anything you have added or changed:
def __init__(
self,
value: str | None = None,
*,
sources: Literal["upload", "microphone"] = "upload,
every: Timer | float | None = None,
...
):
...
preprocess
and postprocess
The preprocess
and postprocess
methods determine the value passed to the user function and the value that needs to be returned.
Even if the design of your component is primarily as an input or an output, it is worth adding type hints to both the input parameters and the return values because Gradio has no way of limiting how components can be used.
In this case, we specifically care about:
preprocess
.postprocess
.def preprocess(
self, payload: FileData | None # input is optional
) -> tuple[int, str] | str | None:
# user function input is the preprocess return ▲
# user function output is the postprocess input ▼
def postprocess(
self, value: tuple[int, str] | None
) -> FileData | bytes | None: # return is optional
...
Docstrings are also used extensively to extract more meaningful, human-readable descriptions of certain parts of the API.
If you need to become more familiar with docstrings in Python, they are a way to annotate parts of your code with human-readable decisions and explanations. They offer a rich in-editor experience like type hints, but unlike type hints, they don't have any specific syntax requirements. They are simple strings and can take almost any form. The only requirement is where they appear. Docstrings should be "a string literal that occurs as the first statement in a module, function, class, or method definition".
While docstrings don't have any syntax requirements, we need a particular structure for documentation purposes.
As with type hint, the specific information we care about is as follows:
__init__
parameter docstrings.preprocess
return docstrings.postprocess
input parameter docstrings.Everything else is optional.
Docstrings should always take this format to be picked up by the documentation generator:
"""
A description of the class.
This can span multiple lines and can _contain_ *markdown*.
"""
Markdown in these descriptions will not be converted into formatted text.
"""
Parameters:
param_one: A description for this parameter.
param_two: A description for this parameter.
Returns:
A description for this return value.
"""
In custom components, events are expressed as a list stored on the events
field of the component class. While we do not need types for events, we do need a human-readable description so users can understand the behaviour of the event.
To facilitate this, we must create the event in a specific way.
There are two ways to add events to a custom component.
Gradio comes with a variety of built-in events that may be enough for your component. If you are using built-in events, you do not need to do anything as they already have descriptions we can extract:
from gradio.events import Events
class ParamViewer(Component):
...
EVENTS = [
Events.change,
Events.upload,
]
You can define a custom event if the built-in events are unsuitable for your use case. This is a straightforward process, but you must create the event in this way for docstrings to work correctly:
from gradio.events import Events, EventListener
class ParamViewer(Component):
...
EVENTS = [
Events.change,
EventListener(
"bingbong",
doc="This listener is triggered when the user does a bingbong."
)
]
The demo/app.py
, often used for developing the component, generates the live demo and code snippet. The only strict rule here is that the demo.launch()
command must be contained with a __name__ == "__main__"
conditional as below:
if __name__ == "__main__":
demo.launch()
The documentation generator will scan for such a clause and error if absent. If you are not launching the demo inside the demo/app.py
, then you can pass --suppress-demo-check
to turn off this check.
Although there are no additional rules, there are some best practices you should bear in mind to get the best experience from the documentation generator.
These are only guidelines, and every situation is unique, but they are sound principles to remember.
Compact demos look better and make it easier for users to understand what the demo does. Try to remove as many extraneous UI elements as possible to focus the users' attention on the core use case.
Sometimes, it might make sense to have a demo/app.py
just for the docs and an additional, more complex app for your testing purposes. You can also create other spaces, showcasing more complex examples and linking to them from the main class docstring or the pyproject.toml
description.
The 'getting started' snippet utilises the demo code, which should be as short as possible to keep users engaged and avoid confusion.
It isn't the job of the sample snippet to demonstrate the whole API; this snippet should be the shortest path to success for a new user. It should be easy to type or copy-paste and easy to understand. Explanatory comments should be brief and to the point.
As mentioned above, users should be able to copy-paste a snippet and have a fully working app. Try to avoid third-party library dependencies to facilitate this.
You should carefully consider any examples; avoiding examples that require additional files or that make assumptions about the environment is generally a good idea.
demo
directory is self-containedOnly the demo
directory will be uploaded to Hugging Face spaces in certain instances, as the component will be installed via PyPi if possible. It is essential that this directory is self-contained and any files needed for the correct running of the demo are present.
The documentation generator will generate a few buttons, providing helpful information and links to users. They are obtained automatically in some cases, but some need to be explicitly included in the pyproject.yaml
.
pyproject.toml
's project.urls.repository
.pyproject.toml
's project.urls.space
.An example pyproject.toml
urls section might look like this:
[project.urls]
repository = "https://github.com/user/repo-name"
space = "https://huggingface.co/spaces/user/space-name"