import os import sys import json from jinja2 import Template import requests import markdown2 import re from gradio.inputs import InputComponent from gradio.outputs import OutputComponent from gradio.interface import Interface import inspect import shutil GRADIO_DIR = "../../" GRADIO_GUIDES_DIR = os.path.join(GRADIO_DIR, "guides") GRADIO_DEMO_DIR = os.path.join(GRADIO_DIR, "demo") guide_names = [] # used for dropdown in navbar for guide in sorted(os.listdir(GRADIO_GUIDES_DIR)): if "template" in guide: continue guide_name = guide[:-3] pretty_guide_name = " ".join([word.capitalize().replace("Ml", "ML") for word in guide_name.split("_")]) guide_names.append((guide_name, pretty_guide_name)) def render_index(): os.makedirs("generated", exist_ok=True) with open("src/tweets.json", encoding='utf-8') as tweets_file: tweets = json.load(tweets_file) star_count = "{:,}".format(requests.get("https://api.github.com/repos/gradio-app/gradio" ).json()["stargazers_count"]) with open("src/index_template.html", encoding='utf-8') as template_file: template = Template(template_file.read()) output_html = template.render(tweets=tweets, star_count=star_count, guide_names=guide_names) with open(os.path.join("generated", "index.html"), "w", encoding='utf-8') as generated_template: generated_template.write(output_html) def render_guides(): guides = [] for guide in os.listdir(GRADIO_GUIDES_DIR): if "template" in guide: continue with open(os.path.join(GRADIO_GUIDES_DIR, guide), encoding='utf-8') as guide_file: guide_text = guide_file.read() code_tags = re.findall(r'\{\{ code\["([^\s]*)"\] \}\}', guide_text) demo_names = re.findall(r'\{\{ demos\["([^\s]*)"\] \}\}', guide_text) code, demos = {}, {} guide_text = guide_text.replace( "website/src/assets", "/assets").replace( "```python\n", "
").replace(
"```bash\n", "").replace(
"```directory\n", "").replace(
"```csv\n", "").replace(
"```", "
")
for code_src in code_tags:
with open(os.path.join(GRADIO_DEMO_DIR, code_src, "run.py")) as code_file:
python_code = code_file.read().replace(
'if __name__ == "__main__":\n iface.launch()', "iface.launch()")
code[code_src] = "" + \
python_code + "
"
for demo_name in demo_names:
demos[demo_name] = ""
guide_template = Template(guide_text)
guide_output = guide_template.render(code=code, demos=demos)
output_html = markdown2.markdown(guide_output)
output_html = output_html.replace("([A-Za-z0-9 ]*)<\/h3>', output_html):
output_html = output_html.replace(
f"{match}
", f"{match}
")
os.makedirs("generated", exist_ok=True)
guide = guide[:-3]
os.makedirs(os.path.join(
"generated", guide), exist_ok=True)
with open("src/guides_template.html", encoding='utf-8') as general_template_file:
general_template = Template(general_template_file.read())
with open(os.path.join("generated", guide, "index.html"), "w", encoding='utf-8') as generated_template:
output_html = general_template.render(template_html=output_html, demo_names=demo_names, guide_names=guide_names)
generated_template.write(output_html)
def render_docs():
if os.path.exists("generated/colab_links.json"):
with open("generated/colab_links.json") as demo_links_file:
demo_links = json.load(demo_links_file)
else: # docs will be missing demo links
demo_links = {}
SCREENSHOT_FOLDER = "dist/assets/demo_screenshots"
os.makedirs(SCREENSHOT_FOLDER, exist_ok=True)
def get_function_documentation(func):
doc_str = inspect.getdoc(func)
func_doc, params_doc, return_doc = [], [], []
documented_params = {"self"}
mode = "pre"
for line in doc_str.split("\n"):
if line.startswith("Parameters:"):
mode = "in"
continue
if line.startswith("Returns:"):
mode = "out"
continue
if "DEPRECATED" in line:
continue
if mode == "pre":
func_doc.append(line)
elif mode == "in":
space_index = line.index(" ")
colon_index = line.index(":")
name = line[:space_index]
documented_params.add(name)
params_doc.append(
(name, line[space_index+2:colon_index-1], line[colon_index+2:]))
elif mode == "out":
colon_index = line.index(":")
return_doc.append((line[1:colon_index-1], line[colon_index+2:]))
params = inspect.getfullargspec(func)
param_set = []
for i in range(len(params.args)):
neg_index = -1 - i
if params.args[neg_index] not in documented_params:
continue
if params.defaults and i < len(params.defaults):
default = params.defaults[neg_index]
if type(default) == str:
default = '"' + default + '"'
else:
default = str(default)
param_set.insert(0, (params.args[neg_index], default))
else:
param_set.insert(0, (params.args[neg_index],))
return "\n".join(func_doc), param_set, params_doc, return_doc
def get_class_documentation(cls):
inp = {}
inp["name"] = cls.__name__
doc = inspect.getdoc(cls)
doc_lines = doc.split("\n")
inp["doc"] = "\n".join(doc_lines[:-2])
inp["type"] = doc_lines[-2].split("type: ")[-1]
inp["demos"] = doc_lines[-1][7:].split(", ")
_, inp["params"], inp["params_doc"], _ = get_function_documentation(cls.__init__)
inp["shortcuts"] = list(cls.get_shortcut_implementations().items())
if "interpret" in cls.__dict__:
inp["interpret"], inp["interpret_params"], inp["interpret_params_doc"], _ = get_function_documentation(
cls.interpret)
_, _, _, inp["interpret_returns_doc"] = get_function_documentation(
cls.get_interpretation_scores)
return inp
inputs = [get_class_documentation(cls) for cls in InputComponent.__subclasses__()]
outputs = [get_class_documentation(cls) for cls in OutputComponent.__subclasses__()]
interface_params = get_function_documentation(Interface.__init__)
interface = {
"doc": inspect.getdoc(Interface),
"params": interface_params[1],
"params_doc": interface_params[2],
}
launch_params = get_function_documentation(Interface.launch)
launch = {
"params": launch_params[1],
"params_doc": launch_params[2],
}
load_params = get_function_documentation(Interface.load)
load = {
"params": load_params[1],
"params_doc": load_params[2],
"return_doc": load_params[3],
}
docs = {
"input": inputs,
"output": outputs,
"interface": interface,
"launch": launch,
"load": load,
}
os.makedirs("generated", exist_ok=True)
with open("src/docs_template.html") as template_file:
template = Template(template_file.read())
output_html = template.render(docs=docs, demo_links=demo_links, guide_names=guide_names)
os.makedirs(os.path.join("generated", "docs"), exist_ok=True)
with open(os.path.join("generated", "docs", "index.html"), "w") as generated_template:
generated_template.write(output_html)
if __name__ == "__main__":
render_index()
render_guides()
render_docs()