Skip to content

Commit 1b01838

Browse files
committed
Fix HuggingFace runtime error with standalone VCF parser
1 parent 12dac1e commit 1b01838

2 files changed

Lines changed: 444 additions & 49 deletions

File tree

app_hf.py

Lines changed: 187 additions & 49 deletions
Original file line numberDiff line numberDiff line change
@@ -2,24 +2,56 @@
22
# -*- coding: utf-8 -*-
33
"""
44
Dirghayu - HuggingFace Spaces Deployment
5-
Simplified Gradio app for genomic analysis
5+
Standalone version with built-in VCF parser
66
"""
77

88
import gradio as gr
99
import pandas as pd
1010
from pathlib import Path
11-
import sys
1211

13-
# Add src to path
14-
sys.path.insert(0, str(Path(__file__).parent / "src"))
1512

16-
try:
17-
from data import parse_vcf_file
18-
except ImportError:
19-
print("Installing dependencies...")
20-
import subprocess
21-
subprocess.check_call([sys.executable, "-m", "pip", "install", "pandas"])
22-
from data import parse_vcf_file
13+
def parse_vcf_file(vcf_path):
14+
"""Parse VCF file and return DataFrame"""
15+
variants = []
16+
17+
try:
18+
with open(vcf_path, 'r') as f:
19+
for line in f:
20+
# Skip header lines
21+
if line.startswith('#'):
22+
continue
23+
24+
parts = line.strip().split('\t')
25+
if len(parts) < 5:
26+
continue
27+
28+
# Extract basic info
29+
chrom = parts[0].replace('chr', '')
30+
pos = parts[1]
31+
rsid = parts[2] if parts[2] != '.' else None
32+
ref = parts[3]
33+
alt = parts[4]
34+
35+
# Extract genotype if available
36+
genotype = '0/1' # default
37+
if len(parts) > 9:
38+
gt_field = parts[9].split(':')[0]
39+
genotype = gt_field
40+
41+
variants.append({
42+
'chrom': chrom,
43+
'pos': int(pos),
44+
'rsid': rsid,
45+
'ref': ref,
46+
'alt': alt,
47+
'genotype': genotype
48+
})
49+
50+
return pd.DataFrame(variants)
51+
52+
except Exception as e:
53+
print(f"Error parsing VCF: {e}")
54+
return pd.DataFrame()
2355

2456

2557
def analyze_vcf(vcf_file):
@@ -33,86 +65,192 @@ def analyze_vcf(vcf_file):
3365
variants_df = parse_vcf_file(vcf_path)
3466

3567
if len(variants_df) == 0:
36-
return "<h3>❌ No variants found</h3>"
68+
return "<h3>❌ No variants found in VCF file</h3><p>Please ensure your VCF file is properly formatted.</p>"
3769

3870
# Key variants database
3971
key_variants = {
40-
'rs1801133': {'gene': 'MTHFR', 'name': 'C677T', 'risk': 'HIGH', 'emoji': '🧬'},
41-
'rs429358': {'gene': 'APOE', 'name': 'ε4', 'risk': 'MODERATE', 'emoji': '🧠'},
42-
'rs1801131': {'gene': 'MTHFR', 'name': 'A1298C', 'risk': 'MODERATE', 'emoji': '🧬'},
43-
'rs1333049': {'gene': 'CDKN2B-AS1', 'name': '9p21.3', 'risk': 'HIGH', 'emoji': '❤️'},
44-
'rs713598': {'gene': 'TAS2R38', 'name': 'PTC', 'risk': 'LOW', 'emoji': '👅'},
72+
'rs1801133': {
73+
'gene': 'MTHFR',
74+
'name': 'C677T',
75+
'risk': 'HIGH',
76+
'emoji': '🧬',
77+
'description': 'Folate metabolism - Higher homocysteine levels',
78+
'recommendation': 'Consider methylfolate supplementation (800 mcg/day)'
79+
},
80+
'rs429358': {
81+
'gene': 'APOE',
82+
'name': 'ε4 allele',
83+
'risk': 'MODERATE',
84+
'emoji': '🧠',
85+
'description': "Increased Alzheimer's disease risk (3-4x)",
86+
'recommendation': 'Focus on cardiovascular health, Mediterranean diet'
87+
},
88+
'rs1801131': {
89+
'gene': 'MTHFR',
90+
'name': 'A1298C',
91+
'risk': 'MODERATE',
92+
'emoji': '🧬',
93+
'description': 'Folate metabolism - Combined with C677T increases risk',
94+
'recommendation': 'Monitor homocysteine levels, B-vitamin supplementation'
95+
},
96+
'rs1333049': {
97+
'gene': 'CDKN2B-AS1',
98+
'name': '9p21.3 locus',
99+
'risk': 'HIGH',
100+
'emoji': '❤️',
101+
'description': 'Coronary artery disease risk marker',
102+
'recommendation': 'Regular cardiovascular screening, healthy lifestyle'
103+
},
104+
'rs713598': {
105+
'gene': 'TAS2R38',
106+
'name': 'PTC taster',
107+
'risk': 'LOW',
108+
'emoji': '👅',
109+
'description': 'Bitter taste perception - affects vegetable preferences',
110+
'recommendation': 'Ensure varied vegetable intake'
111+
},
45112
}
46113

47114
# Generate report
48115
html = f"""
49-
<div style="font-family: 'Segoe UI', sans-serif;">
116+
<div style="font-family: 'Segoe UI', Tahoma, sans-serif; max-width: 900px; margin: 0 auto;">
50117
<div style="background: linear-gradient(135deg, #FF6B35, #F7931E); padding: 30px; border-radius: 15px; color: white; text-align: center; margin-bottom: 20px;">
51-
<h1 style="margin: 0;">🧬 Dirghayu Analysis</h1>
52-
<p>India-First Longevity Genomics</p>
118+
<h1 style="margin: 0; font-size: 2.5em;">🧬 Dirghayu Analysis</h1>
119+
<p style="font-size: 1.2em; margin: 10px 0 0 0;">India-First Longevity Genomics</p>
53120
</div>
54121
55-
<div style="background: white; padding: 20px; border-radius: 10px; margin-bottom: 20px; border: 1px solid #ddd;">
56-
<h2>📊 Summary</h2>
57-
<p><strong>{len(variants_df)}</strong> variants analyzed</p>
58-
</div>
122+
<div style="background: white; padding: 25px; border-radius: 10px; margin-bottom: 20px; border: 1px solid #ddd; box-shadow: 0 2px 8px rgba(0,0,0,0.1);">
123+
<h2 style="color: #FF6B35; margin-top: 0;">📊 Analysis Summary</h2>
124+
<p style="font-size: 1.1em;"><strong>{len(variants_df)}</strong> variants analyzed from your VCF file</p>
59125
"""
60126

61127
# Find key variants
62-
found = False
128+
found_variants = []
63129
for _, var in variants_df.iterrows():
64130
rsid = var['rsid']
65131
if rsid in key_variants:
66-
found = True
67-
info = key_variants[rsid]
132+
found_variants.append((rsid, var, key_variants[rsid]))
133+
134+
if found_variants:
135+
html += f"<p style='font-size: 1.1em;'><strong>{len(found_variants)}</strong> clinically significant variants found</p>"
136+
html += "</div>"
137+
138+
html += "<h2 style='color: #FF6B35;'>🎯 Clinically Significant Variants</h2>"
139+
140+
for rsid, var, info in found_variants:
68141
color = {'HIGH': '#e74c3c', 'MODERATE': '#f39c12', 'LOW': '#27ae60'}[info['risk']]
69142

70143
html += f"""
71-
<div style="background: white; border-left: 5px solid {color}; padding: 20px; margin: 15px 0; border-radius: 8px; box-shadow: 0 2px 8px rgba(0,0,0,0.1);">
72-
<h3 style="color: {color}; margin: 0;">
144+
<div style="background: white; border-left: 5px solid {color}; padding: 25px; margin: 20px 0; border-radius: 8px; box-shadow: 0 2px 8px rgba(0,0,0,0.1);">
145+
<h3 style="color: {color}; margin: 0 0 10px 0; font-size: 1.5em;">
73146
{info['emoji']} {rsid} - {info['name']}
74147
</h3>
75-
<p><strong>Gene:</strong> {info['gene']} | <strong>Genotype:</strong> {var['genotype']} | <strong>Risk:</strong> {info['risk']}</p>
76-
<p><strong>Position:</strong> chr{var['chrom']}:{var['pos']}</p>
148+
<div style="background: #f8f9fa; padding: 15px; border-radius: 5px; margin: 10px 0;">
149+
<p style="margin: 5px 0;"><strong>Gene:</strong> {info['gene']}</p>
150+
<p style="margin: 5px 0;"><strong>Genotype:</strong> <code style="background: #e9ecef; padding: 2px 6px; border-radius: 3px;">{var['genotype']}</code></p>
151+
<p style="margin: 5px 0;"><strong>Position:</strong> chr{var['chrom']}:{var['pos']}</p>
152+
<p style="margin: 5px 0;"><strong>Risk Level:</strong> <span style="color: {color}; font-weight: bold;">{info['risk']}</span></p>
153+
</div>
154+
<p style="margin: 15px 0;"><strong>Impact:</strong> {info['description']}</p>
155+
<div style="background: #e8f5e9; padding: 15px; border-left: 3px solid #4caf50; border-radius: 5px; margin-top: 15px;">
156+
<p style="margin: 0;"><strong>💡 Recommendation:</strong> {info['recommendation']}</p>
157+
</div>
77158
</div>
78159
"""
160+
else:
161+
html += "<p style='color: #666; font-size: 1.1em;'>No clinically significant variants found in our current database.</p>"
162+
html += "</div>"
163+
html += """
164+
<div style="background: #e3f2fd; padding: 20px; border-radius: 8px; border-left: 4px solid #2196f3; margin: 20px 0;">
165+
<p style="margin: 0;"><strong>ℹ️ Note:</strong> This is common and doesn't indicate any issues. Our database focuses on high-impact variants relevant to Indian population health.</p>
166+
</div>
167+
"""
79168

80-
if not found:
81-
html += "<p>No clinically significant variants found in database.</p>"
169+
# Disclaimer
170+
html += """
171+
<div style="background: #fff3cd; padding: 20px; border-radius: 8px; border-left: 4px solid #ffc107; margin: 30px 0;">
172+
<h3 style="margin: 0 0 10px 0; color: #856404;">⚠️ Important Disclaimer</h3>
173+
<p style="margin: 5px 0; color: #856404;"><strong>This report is for research and educational purposes only.</strong></p>
174+
<ul style="color: #856404; margin: 10px 0;">
175+
<li>NOT for clinical diagnosis or treatment decisions</li>
176+
<li>Consult a healthcare provider before acting on genetic results</li>
177+
<li>Genetic risk ≠ disease certainty</li>
178+
<li>Lifestyle and environment are critical factors</li>
179+
</ul>
180+
</div>
181+
</div>
182+
"""
82183

83-
html += "</div>"
84184
return html
85185

86186
except Exception as e:
87-
return f"<h3>❌ Error: {str(e)}</h3>"
187+
return f"""
188+
<div style="background: #f8d7da; padding: 20px; border-radius: 8px; border-left: 4px solid #dc3545;">
189+
<h3 style="color: #721c24; margin: 0 0 10px 0;">❌ Error Processing VCF File</h3>
190+
<p style="color: #721c24; margin: 0;"><strong>Error:</strong> {str(e)}</p>
191+
<p style="color: #721c24; margin: 10px 0 0 0;">Please ensure your file is a valid VCF format.</p>
192+
</div>
193+
"""
88194

89195

90196
# Create Gradio interface
91-
with gr.Blocks(title="Dirghayu - Genomic Analysis") as app:
197+
with gr.Blocks(
198+
title="Dirghayu - India-First Genomic Analysis",
199+
theme=gr.themes.Soft(primary_hue="orange")
200+
) as app:
201+
92202
gr.HTML("""
93-
<div style="text-align: center; padding: 20px; background: linear-gradient(135deg, #FF6B35, #F7931E); border-radius: 10px; color: white;">
94-
<h1>🧬 Dirghayu</h1>
95-
<p>India-First Longevity Genomics Platform</p>
203+
<div style="text-align: center; padding: 30px; background: linear-gradient(135deg, #FF6B35, #F7931E); border-radius: 15px; color: white; margin-bottom: 20px;">
204+
<h1 style="margin: 0; font-size: 3em;">🧬 Dirghayu</h1>
205+
<p style="font-size: 1.3em; margin: 10px 0 0 0;">India-First Longevity Genomics Platform</p>
206+
<p style="font-size: 1em; margin: 5px 0 0 0; opacity: 0.9;">Upload your VCF file for personalized genetic insights</p>
96207
</div>
97208
""")
98209

99210
with gr.Row():
100-
vcf_input = gr.File(label="Upload VCF File", file_types=[".vcf"])
101-
analyze_btn = gr.Button("🔍 Analyze", variant="primary")
211+
with gr.Column(scale=2):
212+
vcf_input = gr.File(
213+
label="📤 Upload VCF File",
214+
file_types=[".vcf"],
215+
type="filepath"
216+
)
217+
with gr.Column(scale=1):
218+
analyze_btn = gr.Button(
219+
"🔍 Analyze Genome",
220+
variant="primary",
221+
size="lg"
222+
)
102223

103-
output = gr.HTML(label="Results")
224+
output = gr.HTML(label="Analysis Results")
104225

105226
analyze_btn.click(fn=analyze_vcf, inputs=vcf_input, outputs=output)
106227

107228
gr.Markdown("""
108-
### About
109-
- 🇮🇳 India-focused genomic analysis
110-
- ⚡ Fast VCF parsing
111-
- 🎯 Actionable health insights
229+
### 🌟 About Dirghayu
230+
231+
- 🇮🇳 **India-focused** genomic analysis with population-specific insights
232+
- ⚡ **Fast VCF parsing** - results in seconds
233+
- 🎯 **Actionable health insights** based on latest research
234+
- 🔒 **Privacy-first** - your data is processed in memory and never stored
235+
236+
### 🧬 What We Analyze
237+
238+
- **Folate metabolism** (MTHFR variants) - critical for Indian populations
239+
- **Alzheimer's risk** (APOE genotypes)
240+
- **Cardiovascular disease** risk markers
241+
- **Nutrient metabolism** and deficiencies
242+
- **Taste perception** and dietary preferences
243+
244+
### 📖 How to Use
245+
246+
1. Upload your VCF file (from 23andMe, AncestryDNA, or whole genome sequencing)
247+
2. Click "Analyze Genome"
248+
3. Review your personalized genetic insights
249+
4. Consult with a healthcare provider for clinical decisions
250+
251+
---
112252
113-
### Privacy
114-
- All analysis runs on this server
115-
- Your data is not stored
253+
**Version:** 0.1.0 | **Source Code:** [GitHub](https://github.com/VedantMadane/dirghayu)
116254
""")
117255

118256
if __name__ == "__main__":

0 commit comments

Comments
 (0)