Nanny7 commited on
Commit
b7a9482
·
0 Parent(s):

Add SMILES to Name conversion tab

Browse files
Files changed (5) hide show
  1. README.md +38 -0
  2. __pycache__/app.cpython-311.pyc +0 -0
  3. app.py +200 -0
  4. force_rebuild.txt +1 -0
  5. requirements.txt +5 -0
README.md ADDED
@@ -0,0 +1,38 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ ---
2
+ title: RDKit API
3
+ emoji: 🔬
4
+ colorFrom: blue
5
+ colorTo: green
6
+ sdk: gradio
7
+ sdk_version: "4.44.1"
8
+ app_file: app.py
9
+ pinned: false
10
+ ---
11
+
12
+ # RDKit API
13
+
14
+ This is a Hugging Face Space providing API access to various RDKit cheminformatics functions.
15
+
16
+ ## Endpoints
17
+
18
+ - `POST /api/name_to_smiles` : Convert chemical name to SMILES
19
+ - `POST /api/name_to_3d_molecule` : Generate 3D molecule visualization
20
+ - `POST /api/smiles_to_mol` : Convert SMILES to canonical SMILES
21
+ - `POST /api/molecular_weight` : Calculate molecular weight
22
+ - `POST /api/logp` : Calculate logP (partition coefficient)
23
+ - `POST /api/tpsa` : Calculate topological polar surface area
24
+ - `POST /api/tpsa` : Calculate TPSA (topological polar surface area)
25
+ - `POST /api/mol_image` : Generate 2D molecule image (returns PIL Image)
26
+
27
+ ## Usage
28
+
29
+ To deploy on Hugging Face Spaces, upload this repository.
30
+
31
+ For local testing, run:
32
+
33
+ ```bash
34
+ pip install -r requirements.txt
35
+ python app.py
36
+ ```
37
+
38
+ The API endpoints can be accessed programmatically using the Gradio client or HTTP requests.
__pycache__/app.cpython-311.pyc ADDED
Binary file (3.98 kB). View file
 
app.py ADDED
@@ -0,0 +1,200 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ import gradio as gr
2
+ from rdkit import Chem
3
+ from rdkit.Chem import Descriptors, Draw, AllChem
4
+ import cirpy
5
+
6
+
7
+ # RDKit API with multiple endpoints
8
+
9
+
10
+ def _mol_from_smiles(smiles: str):
11
+ mol = Chem.MolFromSmiles(smiles)
12
+ if mol is None:
13
+ raise gr.Error("Invalid SMILES string.")
14
+ return mol
15
+
16
+
17
+ def smiles_to_canonical(smiles: str) -> str:
18
+ mol = _mol_from_smiles(smiles)
19
+ return Chem.MolToSmiles(mol)
20
+
21
+
22
+ def molecular_weight(smiles: str) -> float:
23
+ mol = _mol_from_smiles(smiles)
24
+ return float(Descriptors.MolWt(mol))
25
+
26
+
27
+ def logp(smiles: str) -> float:
28
+ mol = _mol_from_smiles(smiles)
29
+ return float(Descriptors.MolLogP(mol))
30
+
31
+
32
+ def tpsa(smiles: str) -> float:
33
+ mol = _mol_from_smiles(smiles)
34
+ return float(Descriptors.TPSA(mol))
35
+
36
+
37
+ def mol_image(smiles: str):
38
+ mol = _mol_from_smiles(smiles)
39
+ return Draw.MolToImage(mol)
40
+
41
+
42
+ def name_to_smiles(name: str) -> str:
43
+ """Convert chemical name to SMILES using Chemical Identifier Resolver (CIR)"""
44
+ try:
45
+ smiles = cirpy.resolve(name, 'smiles')
46
+ if smiles is None:
47
+ raise gr.Error(f"Could not find SMILES for chemical name: {name}")
48
+ return smiles
49
+ except Exception as e:
50
+ raise gr.Error(f"Error converting name to SMILES: {str(e)}")
51
+
52
+
53
+ def smiles_to_name(smiles: str) -> str:
54
+ """Convert SMILES string to chemical name using Chemical Identifier Resolver (CIR)"""
55
+ try:
56
+ # First validate the SMILES
57
+ mol = _mol_from_smiles(smiles)
58
+
59
+ # Try to resolve SMILES to a chemical name
60
+ name = cirpy.resolve(smiles, 'name')
61
+ if name is None:
62
+ # If no name found, return the canonical SMILES
63
+ return Chem.MolToSmiles(mol)
64
+ return name
65
+ except Exception as e:
66
+ raise gr.Error(f"Error converting SMILES to name: {str(e)}")
67
+
68
+
69
+ def name_to_3d_molecule(name: str) -> str:
70
+ """Convert chemical name to 3D molecule visualization"""
71
+ try:
72
+ # Convert name to SMILES
73
+ smiles = cirpy.resolve(name, 'smiles')
74
+ if smiles is None:
75
+ raise gr.Error(f"Could not find SMILES for chemical name: {name}")
76
+
77
+ # Create molecule from SMILES
78
+ mol = Chem.MolFromSmiles(smiles)
79
+ if mol is None:
80
+ raise gr.Error(f"Could not create molecule from SMILES: {smiles}")
81
+
82
+ # Add hydrogens for better 3D structure
83
+ mol = Chem.AddHs(mol)
84
+
85
+ # Generate 3D coordinates
86
+ success = AllChem.EmbedMolecule(mol, AllChem.ETKDG())
87
+ if success == -1:
88
+ raise gr.Error(f"Could not generate 3D coordinates for: {name}")
89
+
90
+ # Optimize geometry
91
+ AllChem.MMFFOptimizeMolecule(mol)
92
+
93
+ # Convert to SDF format (contains 3D coordinates)
94
+ sdf_string = Chem.SDWriter.GetText(mol)
95
+
96
+ # Create HTML with embedded 3D viewer using 3Dmol.js
97
+ html_content = f"""
98
+ <!DOCTYPE html>
99
+ <html>
100
+ <head>
101
+ <script src="https://3dmol.csb.pitt.edu/build/3Dmol-min.js"></script>
102
+ </head>
103
+ <body>
104
+ <div id="container" style="width: 400px; height: 400px; position: relative;"></div>
105
+ <script>
106
+ let viewer = $3Dmol.createViewer($("#container"));
107
+ let sdf = `{sdf_string}`;
108
+ viewer.addModel(sdf, "sdf");
109
+ viewer.setStyle({{'stick': {{}}}});
110
+ viewer.zoomTo();
111
+ viewer.render();
112
+ </script>
113
+ </body>
114
+ </html>
115
+ """
116
+
117
+ return html_content
118
+
119
+ except Exception as e:
120
+ raise gr.Error(f"Error creating 3D molecule: {str(e)}")
121
+
122
+
123
+ smiles_interface = gr.Interface(
124
+ fn=smiles_to_canonical,
125
+ inputs=gr.Textbox(label="SMILES"),
126
+ outputs=gr.Textbox(label="Canonical SMILES"),
127
+ api_name="smiles_to_mol",
128
+ description="Convert an input SMILES string to its canonical form.",
129
+ )
130
+
131
+ smiles_to_name_interface = gr.Interface(
132
+ fn=smiles_to_name,
133
+ inputs=gr.Textbox(label="SMILES", placeholder="e.g., CC(=O)Oc1ccccc1C(=O)O"),
134
+ outputs=gr.Textbox(label="Chemical Name"),
135
+ api_name="smiles_to_name",
136
+ description="Convert a SMILES string to a chemical name.",
137
+ examples=[["CC(=O)Oc1ccccc1C(=O)O"], ["CN1C=NC2=C1C(=O)N(C(=O)N2C)C"], ["c1ccccc1"]],
138
+ )
139
+
140
+ name_interface = gr.Interface(
141
+ fn=name_to_smiles,
142
+ inputs=gr.Textbox(label="Chemical Name", placeholder="e.g., aspirin, caffeine, benzene"),
143
+ outputs=gr.Textbox(label="SMILES"),
144
+ api_name="name_to_smiles",
145
+ description="Convert a chemical name to SMILES notation.",
146
+ examples=[["aspirin"], ["caffeine"], ["benzene"], ["ethanol"]],
147
+ )
148
+
149
+ mw_interface = gr.Interface(
150
+ fn=molecular_weight,
151
+ inputs=gr.Textbox(label="SMILES"),
152
+ outputs=gr.Number(label="Molecular Weight (g/mol)"),
153
+ api_name="molecular_weight",
154
+ description="Compute the molecular weight from a SMILES string.",
155
+ )
156
+
157
+ logp_interface = gr.Interface(
158
+ fn=logp,
159
+ inputs=gr.Textbox(label="SMILES"),
160
+ outputs=gr.Number(label="logP"),
161
+ api_name="logp",
162
+ description="Calculate the octanol/water partition coefficient (logP).",
163
+ )
164
+
165
+ tpsa_interface = gr.Interface(
166
+ fn=tpsa,
167
+ inputs=gr.Textbox(label="SMILES"),
168
+ outputs=gr.Number(label="TPSA"),
169
+ api_name="tpsa",
170
+ description="Calculate the topological polar surface area (TPSA).",
171
+ )
172
+
173
+ molecule_3d_interface = gr.Interface(
174
+ fn=name_to_3d_molecule,
175
+ inputs=gr.Textbox(label="Chemical Name", placeholder="e.g., benzene, aspirin, caffeine"),
176
+ outputs=gr.HTML(label="3D Molecule Viewer"),
177
+ api_name="name_to_3d_molecule",
178
+ description="Convert a chemical name to an interactive 3D molecule visualization.",
179
+ examples=[["benzene"], ["aspirin"], ["caffeine"], ["ethanol"]],
180
+ )
181
+
182
+
183
+ demo = gr.TabbedInterface(
184
+ [name_interface, molecule_3d_interface, smiles_interface, smiles_to_name_interface, mw_interface, logp_interface, tpsa_interface],
185
+ [
186
+ "Name to SMILES",
187
+ "3D Molecule Viewer",
188
+ "SMILES to Canonical",
189
+ "SMILES to Name",
190
+ "Molecular Weight",
191
+ "LogP",
192
+ "TPSA",
193
+ ],
194
+ title="RDKit API",
195
+ css=".gradio-container {max-width: 800px; margin: auto;}",
196
+ )
197
+
198
+
199
+ if __name__ == "__main__":
200
+ demo.queue().launch(server_name="0.0.0.0", server_port=7860)
force_rebuild.txt ADDED
@@ -0,0 +1 @@
 
 
1
+ # Force rebuild
requirements.txt ADDED
@@ -0,0 +1,5 @@
 
 
 
 
 
 
1
+ # RDKit dependencies
2
+ rdkit
3
+ gradio==4.44.1
4
+ huggingface_hub==0.19.4
5
+ cirpy