PRSHNTKUMR commited on
Commit
f67b4aa
·
verified ·
1 Parent(s): 7dd218b

Create app.py

Browse files
Files changed (1) hide show
  1. app.py +234 -0
app.py ADDED
@@ -0,0 +1,234 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ import gradio as gr
2
+ import requests
3
+ import base64
4
+ import re
5
+ import json
6
+ from PIL import Image
7
+ import io
8
+ import tempfile
9
+ import os
10
+
11
+ def get_molecular_structure(compound_name):
12
+ """
13
+ Get molecular structure image for a chemical compound
14
+ Returns: dict with image URL, metadata, and status
15
+ """
16
+ try:
17
+ # Clean compound name
18
+ clean_compound = re.sub(r'[^a-zA-Z0-9\s-]', '', compound_name.strip())
19
+ if not clean_compound:
20
+ return {
21
+ "success": False,
22
+ "error": "Invalid compound name",
23
+ "image_url": None
24
+ }
25
+
26
+ print(f"Processing compound: {clean_compound}")
27
+
28
+ # Step 1: Get InChIKey from NIH Resolver
29
+ inchikey_url = f"https://cactus.nci.nih.gov/chemical/structure/{clean_compound}/stdinchikey"
30
+
31
+ try:
32
+ response = requests.get(inchikey_url, timeout=10)
33
+ if response.status_code == 200 and response.text.strip():
34
+ inchikey = response.text.strip()
35
+ # Remove InChIKey= prefix if present
36
+ inchikey = inchikey.replace('InChIKey=', '')
37
+ print(f"Found InChIKey: {inchikey}")
38
+ else:
39
+ raise Exception("InChIKey not found")
40
+ except Exception as e:
41
+ print(f"InChIKey lookup failed: {e}")
42
+ # Try direct NIH image as fallback
43
+ return get_direct_nih_image(clean_compound)
44
+
45
+ # Step 2: Get CID from PubChem
46
+ cid_url = f"https://pubchem.ncbi.nlm.nih.gov/rest/pug/compound/inchikey/{inchikey}/cids/JSON"
47
+
48
+ try:
49
+ response = requests.get(cid_url, timeout=10)
50
+ if response.status_code == 200:
51
+ cid_data = response.json()
52
+ if 'IdentifierList' in cid_data and 'CID' in cid_data['IdentifierList']:
53
+ cid = cid_data['IdentifierList']['CID'][0]
54
+ print(f"Found CID: {cid}")
55
+ else:
56
+ raise Exception("CID not found in response")
57
+ else:
58
+ raise Exception(f"CID request failed: {response.status_code}")
59
+ except Exception as e:
60
+ print(f"CID lookup failed: {e}")
61
+ return get_direct_nih_image(clean_compound)
62
+
63
+ # Step 3: Get image from PubChem
64
+ image_url = f"https://pubchem.ncbi.nlm.nih.gov/rest/pug/compound/cid/{cid}/PNG"
65
+
66
+ try:
67
+ response = requests.get(image_url, timeout=15)
68
+ if response.status_code == 200 and len(response.content) > 1000:
69
+ # Save image temporarily and return public URL
70
+ return save_and_return_image(response.content, {
71
+ "compound": compound_name,
72
+ "cid": cid,
73
+ "inchikey": inchikey,
74
+ "source": "PubChem"
75
+ })
76
+ else:
77
+ raise Exception("Invalid image data")
78
+ except Exception as e:
79
+ print(f"PubChem image failed: {e}")
80
+ return get_direct_nih_image(clean_compound)
81
+
82
+ except Exception as e:
83
+ return {
84
+ "success": False,
85
+ "error": str(e),
86
+ "image_url": None,
87
+ "compound": compound_name
88
+ }
89
+
90
+ def get_direct_nih_image(compound_name):
91
+ """Fallback to direct NIH image"""
92
+ try:
93
+ nih_url = f"https://cactus.nci.nih.gov/chemical/structure/{compound_name}/image"
94
+ response = requests.get(nih_url, timeout=15)
95
+
96
+ if response.status_code == 200 and len(response.content) > 1000:
97
+ return save_and_return_image(response.content, {
98
+ "compound": compound_name,
99
+ "source": "NIH Direct"
100
+ })
101
+ else:
102
+ return {
103
+ "success": False,
104
+ "error": "No molecular structure found",
105
+ "image_url": None,
106
+ "compound": compound_name
107
+ }
108
+ except Exception as e:
109
+ return {
110
+ "success": False,
111
+ "error": f"NIH fallback failed: {str(e)}",
112
+ "image_url": None,
113
+ "compound": compound_name
114
+ }
115
+
116
+ def save_and_return_image(image_data, metadata):
117
+ """Save image and return file path for Gradio"""
118
+ try:
119
+ # Create PIL Image
120
+ image = Image.open(io.BytesIO(image_data))
121
+
122
+ # Save to temporary file
123
+ temp_file = tempfile.NamedTemporaryFile(delete=False, suffix='.png')
124
+ image.save(temp_file.name, 'PNG')
125
+
126
+ return {
127
+ "success": True,
128
+ "image_path": temp_file.name, # For Gradio display
129
+ "image_url": f"data:image/png;base64,{base64.b64encode(image_data).decode()}", # For API
130
+ "metadata": metadata,
131
+ "compound": metadata.get("compound", ""),
132
+ "size": len(image_data)
133
+ }
134
+ except Exception as e:
135
+ return {
136
+ "success": False,
137
+ "error": f"Image processing failed: {str(e)}",
138
+ "image_url": None
139
+ }
140
+
141
+ def molecular_structure_interface(compound_name):
142
+ """Gradio interface function"""
143
+ if not compound_name or not compound_name.strip():
144
+ return None, "Please enter a compound name"
145
+
146
+ result = get_molecular_structure(compound_name.strip())
147
+
148
+ if result["success"]:
149
+ info = f"""
150
+ **Compound:** {result['compound']}
151
+ **Source:** {result['metadata']['source']}
152
+ **Image Size:** {result['size']} bytes
153
+ """
154
+ if 'cid' in result['metadata']:
155
+ info += f"**PubChem CID:** {result['metadata']['cid']}\n"
156
+ if 'inchikey' in result['metadata']:
157
+ info += f"**InChIKey:** {result['metadata']['inchikey']}\n"
158
+
159
+ return result["image_path"], info
160
+ else:
161
+ return None, f"❌ Error: {result['error']}"
162
+
163
+ def api_endpoint(compound_name):
164
+ """API endpoint that returns JSON"""
165
+ result = get_molecular_structure(compound_name)
166
+ return result
167
+
168
+ # Create Gradio interface
169
+ with gr.Blocks(title="Molecular Structure Generator") as demo:
170
+ gr.Markdown("# 🧪 Molecular Structure Generator")
171
+ gr.Markdown("Generate molecular structure images for chemical compounds using PubChem and NIH databases.")
172
+
173
+ with gr.Row():
174
+ with gr.Column():
175
+ compound_input = gr.Textbox(
176
+ label="Chemical Compound Name",
177
+ placeholder="Enter compound name (e.g., 'aspirin', 'caffeine', 'Rochelle salt')",
178
+ value="Rochelle salt"
179
+ )
180
+ generate_btn = gr.Button("Generate Structure", variant="primary")
181
+
182
+ with gr.Column():
183
+ image_output = gr.Image(label="Molecular Structure", type="filepath")
184
+ info_output = gr.Markdown(label="Information")
185
+
186
+ generate_btn.click(
187
+ molecular_structure_interface,
188
+ inputs=[compound_input],
189
+ outputs=[image_output, info_output]
190
+ )
191
+
192
+ # Examples
193
+ gr.Examples(
194
+ examples=[
195
+ ["Rochelle salt"],
196
+ ["aspirin"],
197
+ ["caffeine"],
198
+ ["benzene"],
199
+ ["glucose"],
200
+ ["ethanol"]
201
+ ],
202
+ inputs=[compound_input]
203
+ )
204
+
205
+ # API section
206
+ gr.Markdown("## 🔗 API Usage")
207
+ gr.Markdown("""
208
+ **Endpoint:** `POST /api/molecular-structure`
209
+
210
+ **Example Request:**
211
+ ```bash
212
+ curl -X POST "https://your-space.hf.space/api/molecular-structure" \
213
+ -H "Content-Type: application/json" \
214
+ -d '{"compound_name": "aspirin"}'
215
+ ```
216
+
217
+ **Example Response:**
218
+ ```json
219
+ {
220
+ "success": true,
221
+ "image_url": "data:image/png;base64,iVBORw0KGgoAAAA...",
222
+ "metadata": {
223
+ "compound": "aspirin",
224
+ "cid": 2244,
225
+ "inchikey": "BSYNRYMUTXBXSQ-UHFFFAOYSA-N",
226
+ "source": "PubChem"
227
+ },
228
+ "size": 3456
229
+ }
230
+ ```
231
+ """)
232
+
233
+ if __name__ == "__main__":
234
+ demo.launch(server_name="0.0.0.0", server_port=7860)