import gradio as gr viewer_html = """

loading SMILES editor

""" load_js = """ async () => { var loadingDiv = document.getElementById('loading'); loadingDiv.style.display = 'flex'; //load css let url = "https://huggingface.co/datasets/simonduerr/ketcher-2.7.2/raw/main/static/css/main.6a646761.css" fetch(url) .then(res => res.text()) .then(text => { const style = document.createElement('style'); style.textContent = text document.head.appendChild(style); }); //load ketcher url = "https://huggingface.co/datasets/simonduerr/ketcher-2.7.2/resolve/main/static/js/main.5445f351.js" fetch(url) .then(res => res.text()) .then(text => { const script = document.createElement('script'); //script.type = "module" script.src = URL.createObjectURL(new Blob([text], { type: 'application/javascript' })); document.head.appendChild(script); loadingDiv.style.display = 'none'; }); } """ # add your logic here, hidden_state contains the SMILES string returned from Editor def run(hidden_state): return f"{hidden_state}" get_js = """ async () => { return ketcher.getSmiles().then(function(smiFile){return smiFile}) } """ with gr.Blocks() as blocks: gr.Markdown(""" # Gradio Molecule entry with Ketcher """) html = gr.HTML(viewer_html) #do not change this part hidden_state = gr.Textbox(visible=False) # we need a hidden textbox that can be used to first trigger the JS callback # and then onchange of the textbox, we can run the python function out = gr.Textbox("", label="SMILES") btn = gr.Button("Get SMILES") # trigger JS callback and written to hidden textbox btn.click(fn=None, inputs=[], outputs=[hidden_state], _js=get_js) # run python function on change of hidden textbox, add your logic to run function hidden_state.change(fn=run, inputs=[hidden_state], outputs=[out]) # load JS on load of the page blocks.load(None, None, None, _js=load_js) blocks.launch()