Simon Dürr commited on
Commit
139b37b
1 Parent(s): 86ebb4c

add app.py

Browse files
Files changed (2) hide show
  1. README.md +7 -3
  2. app.py +102 -0
README.md CHANGED
@@ -1,6 +1,6 @@
1
  ---
2
- title: Gradio 2dmoleculeeditor
3
- emoji: 😻
4
  colorFrom: green
5
  colorTo: red
6
  sdk: gradio
@@ -10,4 +10,8 @@ pinned: false
10
  license: mit
11
  ---
12
 
13
- Check out the configuration reference at https://huggingface.co/docs/hub/spaces-config-reference
 
 
 
 
 
1
  ---
2
+ title: Gradio 2D Molecule Editor (SMILES)
3
+ emoji: ⚛️
4
  colorFrom: green
5
  colorTo: red
6
  sdk: gradio
 
10
  license: mit
11
  ---
12
 
13
+ This repo contains a sample on how to use the Ketcher Molecule Editor with gradio.
14
+
15
+ To adapt simply add your ML model in the run function.
16
+
17
+ Ketcher is licensed under Apache2.0 License https://github.com/epam/ketcher
app.py ADDED
@@ -0,0 +1,102 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ import gradio as gr
2
+
3
+ viewer_html = """
4
+ <div id="loading" style="display:flex;justify-content:center;align-items:center">
5
+ <p style="padding:0.2rem 1rem 0 0;color:#c1c1c1; font-size:1rem">loading SMILES editor</p>
6
+ <svg version="1.1" id="L4" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0px" y="0px"
7
+ viewBox="0 0 100 100" enable-background="new 0 0 0 0" xml:space="preserve" width="5rem">
8
+ <circle fill="#FF7C00" stroke="none" cx="6" cy="50" r="6">
9
+ <animate
10
+ attributeName="opacity"
11
+ dur="1s"
12
+ values="0;1;0"
13
+ repeatCount="indefinite"
14
+ begin="0.1"/>
15
+ </circle>
16
+ <circle fill="#FF7C00" stroke="none" cx="26" cy="50" r="6">
17
+ <animate
18
+ attributeName="opacity"
19
+ dur="1s"
20
+ values="0;1;0"
21
+ repeatCount="indefinite"
22
+ begin="0.2"/>
23
+ </circle>
24
+ <circle fill="#FF7C00" stroke="none" cx="46" cy="50" r="6">
25
+ <animate
26
+ attributeName="opacity"
27
+ dur="1s"
28
+ values="0;1;0"
29
+ repeatCount="indefinite"
30
+ begin="0.3"/>
31
+ </circle>
32
+ </svg>
33
+ </div>
34
+ <div id="root"></div>
35
+ """
36
+
37
+
38
+ load_js = """
39
+ async () => {
40
+ var loadingDiv = document.getElementById('loading');
41
+ loadingDiv.style.display = 'flex';
42
+
43
+ //load css
44
+ let url = "https://huggingface.co/datasets/simonduerr/ketcher-2.7.2/raw/main/static/css/main.6a646761.css"
45
+ fetch(url)
46
+ .then(res => res.text())
47
+ .then(text => {
48
+ const style = document.createElement('style');
49
+ style.textContent = text
50
+ document.head.appendChild(style);
51
+
52
+ });
53
+ //load ketcher
54
+ url = "https://huggingface.co/datasets/simonduerr/ketcher-2.7.2/resolve/main/static/js/main.5445f351.js"
55
+ fetch(url)
56
+ .then(res => res.text())
57
+ .then(text => {
58
+ const script = document.createElement('script');
59
+ //script.type = "module"
60
+ script.src = URL.createObjectURL(new Blob([text], { type: 'application/javascript' }));
61
+ document.head.appendChild(script);
62
+ loadingDiv.style.display = 'none';
63
+ });
64
+
65
+
66
+ }
67
+ """
68
+
69
+ # add your logic here, hidden_state contains the SMILES string returned from Editor
70
+ def run(hidden_state):
71
+ return f"{hidden_state}"
72
+
73
+ get_js = """
74
+ async () => {
75
+ return ketcher.getSmiles().then(function(smiFile){return smiFile})
76
+ }
77
+ """
78
+
79
+
80
+
81
+ with gr.Blocks() as blocks:
82
+ gr.Markdown("""
83
+ # Gradio Molecule entry with Ketcher
84
+ """)
85
+ html = gr.HTML(viewer_html)
86
+ #do not change this part
87
+ hidden_state = gr.Textbox(visible=False)
88
+ # we need a hidden textbox that can be used to first trigger the JS callback
89
+ # and then onchange of the textbox, we can run the python function
90
+ out = gr.Textbox("", label="SMILES")
91
+ btn = gr.Button("Get SMILES")
92
+ # trigger JS callback and written to hidden textbox
93
+ btn.click(fn=None,
94
+ inputs=[],
95
+ outputs=[hidden_state],
96
+ _js=get_js)
97
+ # run python function on change of hidden textbox, add your logic to run function
98
+ hidden_state.change(fn=run, inputs=[hidden_state], outputs=[out])
99
+ # load JS on load of the page
100
+ blocks.load(None, None, None, _js=load_js)
101
+
102
+ blocks.launch()