Add requirements support to gradio.
Browse files- app.py +39 -20
- templates.py +45 -12
- templates/gradio-lite/gradio-lite-snippet-template.html +3 -0
- templates/gradio-lite/gradio-lite-template.html +3 -0
app.py
CHANGED
@@ -86,11 +86,11 @@ def transcribe(audio: str) -> (str, str):
|
|
86 |
return result["text"], None
|
87 |
|
88 |
|
89 |
-
def link_copy_notify(
|
90 |
gr.Info("Share link copied!")
|
91 |
|
92 |
|
93 |
-
def copy_notify(code):
|
94 |
gr.Info("App code snippet copied!")
|
95 |
|
96 |
|
@@ -98,6 +98,15 @@ def add_hotkeys() -> str:
|
|
98 |
return Path("hotkeys.js").read_text()
|
99 |
|
100 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
101 |
with gr.Blocks() as demo:
|
102 |
gr.Markdown("<h1 id=\"TEST\" align=\"center\"><a href=\"?\">KiteWind</a> πͺπ</h1>")
|
103 |
gr.Markdown(
|
@@ -112,19 +121,24 @@ with gr.Blocks() as demo:
|
|
112 |
with gr.Row():
|
113 |
with gr.Column():
|
114 |
with gr.Group():
|
115 |
-
in_audio = gr.Audio(label="Record a voice request (click or press ctrl + ` to start/stop)",
|
|
|
116 |
in_prompt = gr.Textbox(label="Or type a text request and press Enter",
|
117 |
placeholder="Need an idea? Try one of these:\n- Add a button to reverse the name\n- Change the greeting to Spanish\n- Put the reversed name output into a separate textbox")
|
118 |
out_text = gr.TextArea(label="π€ Chat Assistant Response")
|
119 |
clear = gr.ClearButton([in_prompt, in_audio, out_text])
|
120 |
with gr.Column():
|
121 |
-
|
122 |
-
|
|
|
|
|
123 |
update_btn = gr.Button("Update App (Ctrl + Space)", variant="primary", elem_classes=["update-btn"])
|
124 |
-
|
|
|
|
|
125 |
'_js': update_iframe_js(DemoType.GRADIO)}
|
126 |
-
gen_text_params = {'fn': generate_text, 'inputs': [
|
127 |
-
'outputs': [out_text,
|
128 |
transcribe_params = {'fn': transcribe, 'inputs': [in_audio], 'outputs': [in_prompt, in_audio]}
|
129 |
update_btn.click(**code_update_params)
|
130 |
in_prompt.submit(**gen_text_params).then(**code_update_params)
|
@@ -133,11 +147,11 @@ with gr.Blocks() as demo:
|
|
133 |
with gr.Column():
|
134 |
gr.Markdown("## 3. Export your app to share!")
|
135 |
share_link_btn = gr.Button("π Copy share link to clipboard")
|
136 |
-
share_link_btn.click(link_copy_notify,
|
137 |
copy_snippet_btn = gr.Button("βοΈ Copy app snippet to paste into another page")
|
138 |
-
copy_snippet_btn.click(copy_notify,
|
139 |
download_btn = gr.Button("π Download app as a standalone file")
|
140 |
-
download_btn.click(None,
|
141 |
with gr.Row():
|
142 |
with gr.Column():
|
143 |
gr.Markdown("## Current limitations")
|
@@ -153,19 +167,22 @@ with gr.Blocks() as demo:
|
|
153 |
with gr.Row():
|
154 |
with gr.Column():
|
155 |
with gr.Group():
|
156 |
-
in_audio = gr.Audio(label="Record a voice request (click or press ctrl + ` to start/stop)",
|
|
|
157 |
in_prompt = gr.Textbox(label="Or type a text request and press Enter",
|
158 |
-
placeholder="Need an idea? Try one of these:\n- Add a button to reverse the name\n- Change the greeting to Spanish\n-
|
159 |
out_text = gr.TextArea(label="π€ Chat Assistant Response")
|
160 |
clear_btn = gr.ClearButton([in_prompt, in_audio, out_text])
|
161 |
with gr.Column():
|
162 |
-
|
163 |
-
|
|
|
|
|
164 |
update_btn = gr.Button("Update App (Ctrl + Space)", variant="primary", elem_classes=["update-btn"])
|
165 |
-
code_update_params = {'fn': None, 'inputs':
|
166 |
'_js': update_iframe_js(DemoType.STREAMLIT)}
|
167 |
-
gen_text_params = {'fn': generate_text, 'inputs': [
|
168 |
-
'outputs': [out_text,
|
169 |
transcribe_params = {'fn': transcribe, 'inputs': [in_audio], 'outputs': [in_prompt, in_audio]}
|
170 |
update_btn.click(**code_update_params)
|
171 |
in_prompt.submit(**gen_text_params).then(**code_update_params)
|
@@ -174,9 +191,9 @@ with gr.Blocks() as demo:
|
|
174 |
with gr.Column():
|
175 |
gr.Markdown("## 3. Export your app to share!")
|
176 |
copy_snippet_btn = gr.Button("βοΈ Copy app snippet into paste in another page")
|
177 |
-
copy_snippet_btn.click(copy_notify,
|
178 |
download_btn = gr.Button("π Download app as a standalone file")
|
179 |
-
download_btn.click(None,
|
180 |
with gr.Row():
|
181 |
with gr.Column():
|
182 |
gr.Markdown("## Current limitations")
|
@@ -188,6 +205,8 @@ with gr.Blocks() as demo:
|
|
188 |
stlite_tab.select(lambda: "stlite", None, selectedTab).then(None, None, None, _js=load_js(DemoType.STREAMLIT))
|
189 |
demo.load(None, None, None, _js=load_js(DemoType.GRADIO))
|
190 |
demo.load(None, None, None, _js=add_hotkeys())
|
|
|
|
|
191 |
demo.css = "footer {visibility: hidden}"
|
192 |
|
193 |
if __name__ == "__main__":
|
|
|
86 |
return result["text"], None
|
87 |
|
88 |
|
89 |
+
def link_copy_notify():
|
90 |
gr.Info("Share link copied!")
|
91 |
|
92 |
|
93 |
+
def copy_notify(code: str, requirements: str):
|
94 |
gr.Info("App code snippet copied!")
|
95 |
|
96 |
|
|
|
98 |
return Path("hotkeys.js").read_text()
|
99 |
|
100 |
|
101 |
+
def apply_query_params(code: str, request: gr.Request) -> (str, str):
|
102 |
+
params = dict(request.query_params)
|
103 |
+
return params.get('code') or code, params.get('requirements') or ''
|
104 |
+
|
105 |
+
|
106 |
+
def update_state(requirements: [str], error: str):
|
107 |
+
return '\n'.join(sorted(requirements)), error
|
108 |
+
|
109 |
+
|
110 |
with gr.Blocks() as demo:
|
111 |
gr.Markdown("<h1 id=\"TEST\" align=\"center\"><a href=\"?\">KiteWind</a> πͺπ</h1>")
|
112 |
gr.Markdown(
|
|
|
121 |
with gr.Row():
|
122 |
with gr.Column():
|
123 |
with gr.Group():
|
124 |
+
in_audio = gr.Audio(label="Record a voice request (click or press ctrl + ` to start/stop)",
|
125 |
+
source='microphone', type='filepath', elem_classes=["record-btn"])
|
126 |
in_prompt = gr.Textbox(label="Or type a text request and press Enter",
|
127 |
placeholder="Need an idea? Try one of these:\n- Add a button to reverse the name\n- Change the greeting to Spanish\n- Put the reversed name output into a separate textbox")
|
128 |
out_text = gr.TextArea(label="π€ Chat Assistant Response")
|
129 |
clear = gr.ClearButton([in_prompt, in_audio, out_text])
|
130 |
with gr.Column():
|
131 |
+
gradio_code_area = gr.Code(
|
132 |
+
label="App Code - You can also edit directly and then click Update App or ctrl + space",
|
133 |
+
language='python', value=starting_app_code(DemoType.GRADIO))
|
134 |
+
gradio_requirements_area = gr.Code(label="App Requirements (additional modules pip installed for pyodide)")
|
135 |
update_btn = gr.Button("Update App (Ctrl + Space)", variant="primary", elem_classes=["update-btn"])
|
136 |
+
last_error = gr.State()
|
137 |
+
code_update_params = {'fn': update_state, 'inputs': [gradio_code_area, gradio_requirements_area],
|
138 |
+
'outputs': [gradio_requirements_area, last_error],
|
139 |
'_js': update_iframe_js(DemoType.GRADIO)}
|
140 |
+
gen_text_params = {'fn': generate_text, 'inputs': [gradio_code_area, in_prompt],
|
141 |
+
'outputs': [out_text, gradio_code_area]}
|
142 |
transcribe_params = {'fn': transcribe, 'inputs': [in_audio], 'outputs': [in_prompt, in_audio]}
|
143 |
update_btn.click(**code_update_params)
|
144 |
in_prompt.submit(**gen_text_params).then(**code_update_params)
|
|
|
147 |
with gr.Column():
|
148 |
gr.Markdown("## 3. Export your app to share!")
|
149 |
share_link_btn = gr.Button("π Copy share link to clipboard")
|
150 |
+
share_link_btn.click(link_copy_notify, None, None, _js=copy_share_link_js(DemoType.GRADIO))
|
151 |
copy_snippet_btn = gr.Button("βοΈ Copy app snippet to paste into another page")
|
152 |
+
copy_snippet_btn.click(copy_notify, [gradio_code_area, gradio_requirements_area], None, _js=copy_snippet_js(DemoType.GRADIO))
|
153 |
download_btn = gr.Button("π Download app as a standalone file")
|
154 |
+
download_btn.click(None, [gradio_code_area, gradio_requirements_area], None, _js=download_code_js(DemoType.GRADIO))
|
155 |
with gr.Row():
|
156 |
with gr.Column():
|
157 |
gr.Markdown("## Current limitations")
|
|
|
167 |
with gr.Row():
|
168 |
with gr.Column():
|
169 |
with gr.Group():
|
170 |
+
in_audio = gr.Audio(label="Record a voice request (click or press ctrl + ` to start/stop)",
|
171 |
+
source='microphone', type='filepath', elem_classes=["record-btn"])
|
172 |
in_prompt = gr.Textbox(label="Or type a text request and press Enter",
|
173 |
+
placeholder="Need an idea? Try one of these:\n- Add a button to reverse the name\n- Change the greeting to Spanish\n- Change the theme to soft")
|
174 |
out_text = gr.TextArea(label="π€ Chat Assistant Response")
|
175 |
clear_btn = gr.ClearButton([in_prompt, in_audio, out_text])
|
176 |
with gr.Column():
|
177 |
+
stlite_code_area = gr.Code(
|
178 |
+
label="App Code - You can also edit directly and then click Update App or ctrl + space",
|
179 |
+
language='python', value=starting_app_code(DemoType.STREAMLIT))
|
180 |
+
requirements_area = gr.Code(label="App Requirements (additional modules pip installed for pyodide)")
|
181 |
update_btn = gr.Button("Update App (Ctrl + Space)", variant="primary", elem_classes=["update-btn"])
|
182 |
+
code_update_params = {'fn': None, 'inputs': [stlite_code_area, requirements_area], 'outputs': None,
|
183 |
'_js': update_iframe_js(DemoType.STREAMLIT)}
|
184 |
+
gen_text_params = {'fn': generate_text, 'inputs': [stlite_code_area, in_prompt],
|
185 |
+
'outputs': [out_text, stlite_code_area]}
|
186 |
transcribe_params = {'fn': transcribe, 'inputs': [in_audio], 'outputs': [in_prompt, in_audio]}
|
187 |
update_btn.click(**code_update_params)
|
188 |
in_prompt.submit(**gen_text_params).then(**code_update_params)
|
|
|
191 |
with gr.Column():
|
192 |
gr.Markdown("## 3. Export your app to share!")
|
193 |
copy_snippet_btn = gr.Button("βοΈ Copy app snippet into paste in another page")
|
194 |
+
copy_snippet_btn.click(copy_notify, [stlite_code_area, requirements_area], None, _js=copy_snippet_js(DemoType.STREAMLIT))
|
195 |
download_btn = gr.Button("π Download app as a standalone file")
|
196 |
+
download_btn.click(None, stlite_code_area, None, _js=download_code_js(DemoType.STREAMLIT))
|
197 |
with gr.Row():
|
198 |
with gr.Column():
|
199 |
gr.Markdown("## Current limitations")
|
|
|
205 |
stlite_tab.select(lambda: "stlite", None, selectedTab).then(None, None, None, _js=load_js(DemoType.STREAMLIT))
|
206 |
demo.load(None, None, None, _js=load_js(DemoType.GRADIO))
|
207 |
demo.load(None, None, None, _js=add_hotkeys())
|
208 |
+
# TODO: select stlite tab and populate that code based on query param type
|
209 |
+
demo.load(apply_query_params, gradio_code_area, [gradio_code_area, gradio_requirements_area])
|
210 |
demo.css = "footer {visibility: hidden}"
|
211 |
|
212 |
if __name__ == "__main__":
|
templates.py
CHANGED
@@ -49,6 +49,7 @@ def load_js(demo_type: DemoType) -> str:
|
|
49 |
const queryParams = parseQueryString(queryString);
|
50 |
// Access individual parameters
|
51 |
const codeValue = queryParams.code;
|
|
|
52 |
|
53 |
const htmlString = '<iframe id="gradio-iframe" width="100%" height="512px" src="about:blank"></iframe>';
|
54 |
const parser = new DOMParser();
|
@@ -59,8 +60,9 @@ def load_js(demo_type: DemoType) -> str:
|
|
59 |
|
60 |
let template = `{gradio_lite_html_template.replace('STARTING_CODE', starting_app_code(demo_type))}`;
|
61 |
if (codeValue) {{
|
62 |
-
template = `{gradio_lite_html_template}`.replace('STARTING_CODE', codeValue);
|
63 |
}}
|
|
|
64 |
const frame = document.getElementById('gradio-iframe');
|
65 |
frame.contentWindow.document.open('text/html', 'replace');
|
66 |
frame.contentWindow.document.write(template);
|
@@ -91,7 +93,11 @@ def load_js(demo_type: DemoType) -> str:
|
|
91 |
|
92 |
def update_iframe_js(demo_type: DemoType) -> str:
|
93 |
if demo_type == DemoType.GRADIO:
|
94 |
-
return f"""async (code, requirements) => {{
|
|
|
|
|
|
|
|
|
95 |
async function update() {{
|
96 |
// Remove existing stylesheet so it will be reloaded;
|
97 |
// see https://github.com/gradio-app/gradio/blob/200237d73c169f39514465efc163db756969d3ac/js/app/src/lite/css.ts#L41
|
@@ -101,28 +107,55 @@ def update_iframe_js(demo_type: DemoType) -> str:
|
|
101 |
const appController = demoFrameWindow.window.appController;
|
102 |
const newCode = code + ` # Update tag ${{Math.random()}}`;
|
103 |
try {{
|
|
|
104 |
await appController.run_code(newCode);
|
105 |
}}
|
106 |
-
catch (e) {{
|
107 |
// Replace old style if code error prevented new style from loading.
|
108 |
const newStyle = demoFrameWindow.document.querySelector("head style");
|
109 |
if (!newStyle) {{
|
110 |
demoFrameWindow.document.head.appendChild(oldStyle);
|
111 |
}}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
112 |
// Hide app so the error traceback is visible.
|
113 |
// First div in main is the error traceback, second is the app.
|
114 |
const appBody = demoFrameWindow.document.querySelectorAll("div.main > div")[1];
|
115 |
appBody.style.visibility = "hidden";
|
116 |
-
|
|
|
|
|
|
|
117 |
}}
|
118 |
}};
|
119 |
await update();
|
120 |
|
|
|
121 |
// Update URL query params to include the current demo code state
|
122 |
const currentUrl = new URL(window.location.href);
|
|
|
123 |
currentUrl.searchParams.set('code', code);
|
124 |
// Replace the current URL with the updated one
|
125 |
history.replaceState({{}}, '', currentUrl.href);
|
|
|
|
|
126 |
}}"""
|
127 |
elif demo_type == DemoType.STREAMLIT:
|
128 |
return f"""async (code, requirements) => {{
|
@@ -139,7 +172,7 @@ def update_iframe_js(demo_type: DemoType) -> str:
|
|
139 |
|
140 |
def copy_share_link_js(demo_type: DemoType) -> str:
|
141 |
if demo_type == DemoType.GRADIO:
|
142 |
-
return f"""async (
|
143 |
const shareLink = document.URL;
|
144 |
await navigator.clipboard.writeText(shareLink);
|
145 |
}}"""
|
@@ -148,14 +181,14 @@ def copy_share_link_js(demo_type: DemoType) -> str:
|
|
148 |
|
149 |
def copy_snippet_js(demo_type: DemoType) -> str:
|
150 |
if demo_type == DemoType.GRADIO:
|
151 |
-
return f"""async (code) => {{
|
152 |
-
const escapedCode = code.replace('`', String.fromCharCode(92) + '`');
|
153 |
const template = `{gradio_lite_snippet_template}`;
|
154 |
// Step 1: Generate the HTML content
|
155 |
-
const completedTemplate = template.replace('STARTING_CODE', code);
|
156 |
-
|
157 |
const snippet = completedTemplate;
|
158 |
await navigator.clipboard.writeText(snippet);
|
|
|
159 |
}}"""
|
160 |
elif demo_type == DemoType.STREAMLIT:
|
161 |
return f"""async (code) => {{
|
@@ -172,10 +205,10 @@ def copy_snippet_js(demo_type: DemoType) -> str:
|
|
172 |
|
173 |
def download_code_js(demo_type: DemoType) -> str:
|
174 |
if demo_type == demo_type.GRADIO:
|
175 |
-
return f"""(code) => {{
|
176 |
-
const escapedCode = code.replace('`', String.fromCharCode(92) + '`');
|
177 |
// Step 1: Generate the HTML content
|
178 |
-
const completedTemplate = `{gradio_lite_html_template}`.replace('STARTING_CODE', escapedCode);
|
179 |
|
180 |
// Step 2: Create a Blob from the HTML content
|
181 |
const blob = new Blob([completedTemplate], {{ type: "text/html" }});
|
|
|
49 |
const queryParams = parseQueryString(queryString);
|
50 |
// Access individual parameters
|
51 |
const codeValue = queryParams.code;
|
52 |
+
const requirementsValue = queryParams.requirements;
|
53 |
|
54 |
const htmlString = '<iframe id="gradio-iframe" width="100%" height="512px" src="about:blank"></iframe>';
|
55 |
const parser = new DOMParser();
|
|
|
60 |
|
61 |
let template = `{gradio_lite_html_template.replace('STARTING_CODE', starting_app_code(demo_type))}`;
|
62 |
if (codeValue) {{
|
63 |
+
template = `{gradio_lite_html_template}`.replace('STARTING_CODE', codeValue.replace(String.fromCharCode(92), String.fromCharCode(92) + String.fromCharCode(92)).replace('`', String.fromCharCode(92) + '`'));
|
64 |
}}
|
65 |
+
template = template.replace('STARTING_REQUIREMENTS', requirementsValue || '');
|
66 |
const frame = document.getElementById('gradio-iframe');
|
67 |
frame.contentWindow.document.open('text/html', 'replace');
|
68 |
frame.contentWindow.document.write(template);
|
|
|
93 |
|
94 |
def update_iframe_js(demo_type: DemoType) -> str:
|
95 |
if demo_type == DemoType.GRADIO:
|
96 |
+
return f"""async (code, requirements) => {{
|
97 |
+
const formattedRequirements = requirements.split('\\n').filter(x => x && !x.startsWith('#')).map(x => x.trim());
|
98 |
+
let errorResult = null;
|
99 |
+
const attemptedRequirements = new Set();
|
100 |
+
const installedRequirements = [];
|
101 |
async function update() {{
|
102 |
// Remove existing stylesheet so it will be reloaded;
|
103 |
// see https://github.com/gradio-app/gradio/blob/200237d73c169f39514465efc163db756969d3ac/js/app/src/lite/css.ts#L41
|
|
|
107 |
const appController = demoFrameWindow.window.appController;
|
108 |
const newCode = code + ` # Update tag ${{Math.random()}}`;
|
109 |
try {{
|
110 |
+
await appController.install(formattedRequirements);
|
111 |
await appController.run_code(newCode);
|
112 |
}}
|
113 |
+
catch (e) {{
|
114 |
// Replace old style if code error prevented new style from loading.
|
115 |
const newStyle = demoFrameWindow.document.querySelector("head style");
|
116 |
if (!newStyle) {{
|
117 |
demoFrameWindow.document.head.appendChild(oldStyle);
|
118 |
}}
|
119 |
+
|
120 |
+
// If the error is caused by a missing module try once to install it and update again.
|
121 |
+
if (e.toString().includes('ModuleNotFoundError')) {{
|
122 |
+
try {{
|
123 |
+
const guessedModuleName = e.toString().split("'")[1].replaceAll('_', '-');
|
124 |
+
if (attemptedRequirements.has(guessedModuleName)) {{
|
125 |
+
throw Error(`Could not install pyodide module ${{guessedModuleName}}`);
|
126 |
+
}}
|
127 |
+
console.log(`Attempting to install missing pyodide module "${{guessedModuleName}}"`);
|
128 |
+
attemptedRequirements.add(guessedModuleName);
|
129 |
+
await appController.install([guessedModuleName]);
|
130 |
+
installedRequirements.push(guessedModuleName);
|
131 |
+
return await update();
|
132 |
+
}}
|
133 |
+
catch (err) {{
|
134 |
+
console.log(err);
|
135 |
+
}}
|
136 |
+
}}
|
137 |
+
|
138 |
// Hide app so the error traceback is visible.
|
139 |
// First div in main is the error traceback, second is the app.
|
140 |
const appBody = demoFrameWindow.document.querySelectorAll("div.main > div")[1];
|
141 |
appBody.style.visibility = "hidden";
|
142 |
+
errorResult = e.toString();
|
143 |
+
const allRequirements = formattedRequirements.concat(installedRequirements);
|
144 |
+
console.log(allRequirements, errorResult);
|
145 |
+
return [allRequirements, errorResult];
|
146 |
}}
|
147 |
}};
|
148 |
await update();
|
149 |
|
150 |
+
const allRequirements = formattedRequirements.concat(installedRequirements);
|
151 |
// Update URL query params to include the current demo code state
|
152 |
const currentUrl = new URL(window.location.href);
|
153 |
+
currentUrl.searchParams.set('requirements', allRequirements.join('\\n'));
|
154 |
currentUrl.searchParams.set('code', code);
|
155 |
// Replace the current URL with the updated one
|
156 |
history.replaceState({{}}, '', currentUrl.href);
|
157 |
+
|
158 |
+
return [allRequirements, errorResult];
|
159 |
}}"""
|
160 |
elif demo_type == DemoType.STREAMLIT:
|
161 |
return f"""async (code, requirements) => {{
|
|
|
172 |
|
173 |
def copy_share_link_js(demo_type: DemoType) -> str:
|
174 |
if demo_type == DemoType.GRADIO:
|
175 |
+
return f"""async () => {{
|
176 |
const shareLink = document.URL;
|
177 |
await navigator.clipboard.writeText(shareLink);
|
178 |
}}"""
|
|
|
181 |
|
182 |
def copy_snippet_js(demo_type: DemoType) -> str:
|
183 |
if demo_type == DemoType.GRADIO:
|
184 |
+
return f"""async (code, requirements) => {{
|
185 |
+
const escapedCode = code.replace(String.fromCharCode(92), String.fromCharCode(92) + String.fromCharCode(92)).replace('`', String.fromCharCode(92) + '`');
|
186 |
const template = `{gradio_lite_snippet_template}`;
|
187 |
// Step 1: Generate the HTML content
|
188 |
+
const completedTemplate = template.replace('STARTING_CODE', code).replace('STARTING_REQUIREMENTS', requirements);
|
|
|
189 |
const snippet = completedTemplate;
|
190 |
await navigator.clipboard.writeText(snippet);
|
191 |
+
return [code, requirements];
|
192 |
}}"""
|
193 |
elif demo_type == DemoType.STREAMLIT:
|
194 |
return f"""async (code) => {{
|
|
|
205 |
|
206 |
def download_code_js(demo_type: DemoType) -> str:
|
207 |
if demo_type == demo_type.GRADIO:
|
208 |
+
return f"""(code, requirements) => {{
|
209 |
+
const escapedCode = code.replace(String.fromCharCode(92), String.fromCharCode(92) + String.fromCharCode(92)).replace('`', String.fromCharCode(92) + '`');
|
210 |
// Step 1: Generate the HTML content
|
211 |
+
const completedTemplate = `{gradio_lite_html_template}`.replace('STARTING_CODE', escapedCode).replace('STARTING_REQUIREMENTS', requirements);
|
212 |
|
213 |
// Step 2: Create a Blob from the HTML content
|
214 |
const blob = new Blob([completedTemplate], {{ type: "text/html" }});
|
templates/gradio-lite/gradio-lite-snippet-template.html
CHANGED
@@ -7,6 +7,7 @@
|
|
7 |
<link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/@gradio/lite/dist/lite.css" />
|
8 |
<script type="module">
|
9 |
const code = \\\`STARTING_CODE\\\`;
|
|
|
10 |
const appController = createGradioApp({
|
11 |
target: document.getElementById("gradio-app"),
|
12 |
code: code,
|
@@ -21,6 +22,8 @@
|
|
21 |
appMode: true
|
22 |
});
|
23 |
window.appController = appController;
|
|
|
|
|
24 |
<\\\/script>\`
|
25 |
const frame = document.getElementById('demo-iframe');
|
26 |
frame.contentWindow.document.open();
|
|
|
7 |
<link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/@gradio/lite/dist/lite.css" />
|
8 |
<script type="module">
|
9 |
const code = \\\`STARTING_CODE\\\`;
|
10 |
+
const requirements = \\\`STARTING_REQUIREMENTS\\\`.split('\\\\n').filter(x => x && !x.startsWith('#')).map(x => x.trim());
|
11 |
const appController = createGradioApp({
|
12 |
target: document.getElementById("gradio-app"),
|
13 |
code: code,
|
|
|
22 |
appMode: true
|
23 |
});
|
24 |
window.appController = appController;
|
25 |
+
await appController.install(requirements);
|
26 |
+
await appController.run_code(code);
|
27 |
<\\\/script>\`
|
28 |
const frame = document.getElementById('demo-iframe');
|
29 |
frame.contentWindow.document.open();
|
templates/gradio-lite/gradio-lite-template.html
CHANGED
@@ -9,6 +9,7 @@
|
|
9 |
<div id="gradio-app"></div>
|
10 |
<script type="module">
|
11 |
const code = \`STARTING_CODE\`;
|
|
|
12 |
// Mount options defined here: https://github.com/gradio-app/gradio/blob/1d986217f6f4fc1829e528d2afe365635788204f/js/lite/index.html#L27
|
13 |
const appController = createGradioApp({
|
14 |
target: document.getElementById("gradio-app"),
|
@@ -26,6 +27,8 @@
|
|
26 |
// Returned controller functions defined here:
|
27 |
// https://github.com/gradio-app/gradio/blob/1d986217f6f4fc1829e528d2afe365635788204f/js/app/src/lite/index.ts#L165
|
28 |
window.appController = appController;
|
|
|
|
|
29 |
</script>
|
30 |
</body>
|
31 |
</html>
|
|
|
9 |
<div id="gradio-app"></div>
|
10 |
<script type="module">
|
11 |
const code = \`STARTING_CODE\`;
|
12 |
+
const requirements = \`STARTING_REQUIREMENTS\`.split('\\n').filter(x => x && !x.startsWith('#')).map(x => x.trim());
|
13 |
// Mount options defined here: https://github.com/gradio-app/gradio/blob/1d986217f6f4fc1829e528d2afe365635788204f/js/lite/index.html#L27
|
14 |
const appController = createGradioApp({
|
15 |
target: document.getElementById("gradio-app"),
|
|
|
27 |
// Returned controller functions defined here:
|
28 |
// https://github.com/gradio-app/gradio/blob/1d986217f6f4fc1829e528d2afe365635788204f/js/app/src/lite/index.ts#L165
|
29 |
window.appController = appController;
|
30 |
+
await appController.install(requirements);
|
31 |
+
await appController.run_code(code);
|
32 |
</script>
|
33 |
</body>
|
34 |
</html>
|