Spaces:
Sleeping
Sleeping
| """ | |
| Hugging Face Gradio Interface for RFP Analyzer | |
| """ | |
| import gradio as gr | |
| import json | |
| import os | |
| from rfp_analyzer import analyze_rfp, load_rubric, AnalyzerConfig | |
| # Load rubric once at startup | |
| rubric = load_rubric("rubric.yaml") | |
| def analyze_rfp_gradio(pdf_file, target_states, partner_known=False): | |
| """ | |
| Gradio interface function for RFP analysis | |
| """ | |
| if pdf_file is None: | |
| return "Please upload a PDF file", "", "" | |
| try: | |
| # Read PDF bytes | |
| with open(pdf_file.name, 'rb') as f: | |
| pdf_bytes = f.read() | |
| # Prepare metadata | |
| meta = { | |
| "target_states": target_states.split(",") if target_states else [], | |
| "partner_known": partner_known | |
| } | |
| # Configure analyzer for HuggingFace Spaces deployment | |
| # Try multiple environment variable names for HF token | |
| hf_token = ( | |
| os.environ.get("HF_TOKEN") or | |
| os.environ.get("HF_API_TOKEN") or | |
| os.environ.get("HUGGING_FACE_HUB_TOKEN") or | |
| "" | |
| ) | |
| config = AnalyzerConfig( | |
| use_hf_api=True, | |
| hf_model="meta-llama/llama-2-7b-hf", # Using your linked model | |
| enable_ai_summaries=True, | |
| hf_token=hf_token, | |
| temperature=0.1 | |
| ) | |
| # Debug: Show token status | |
| if hf_token: | |
| print(f"β HF_TOKEN configured: {hf_token[:10]}...{hf_token[-4:]}") | |
| else: | |
| print("β οΈ HF_TOKEN not found - AI features will be disabled") | |
| print(" Set HF_TOKEN in Space secrets: https://huggingface.co/spaces/Varun10000/qwertyuiop/settings") | |
| # Analyze RFP | |
| result = analyze_rfp(pdf_bytes, rubric, config, meta) | |
| # Format results for display | |
| status = f"## Decision: {result['status']}\n\n" | |
| status += f"**Score:** {result.get('score', 0):.2%}\n\n" | |
| # AI Insights | |
| ai_insights = "## π AI-Extracted RFP Requirements\n\n" | |
| if result.get('ai_insights'): | |
| insights = result['ai_insights'] | |
| # Scope | |
| if insights.get('scope'): | |
| scope = insights['scope'] | |
| ai_insights += f"### π΅ Scope Summary & Deliverables\n\n" | |
| ai_insights += f"{scope.get('scope_summary_and_work', 'N/A')}\n\n" | |
| ai_insights += f"**Type of Work:** {scope.get('type_of_work', 'N/A')}\n\n" | |
| ai_insights += f"π {scope.get('reference', '')}\n\n" | |
| ai_insights += "---\n\n" | |
| # Certifications | |
| if insights.get('certifications'): | |
| certs = insights['certifications'] | |
| ai_insights += f"### π’ Certifications Required\n\n" | |
| if certs.get('detailed_text'): | |
| ai_insights += f"{certs['detailed_text']}\n\n" | |
| ai_insights += "**Business Certifications:**\n" | |
| ai_insights += f"- SBE: {'β ' if certs.get('sbe_required') else 'β¬'}\n" | |
| ai_insights += f"- MWBE: {'β ' if certs.get('mwbe_required') else 'β¬'}\n" | |
| ai_insights += f"- MBE: {'β ' if certs.get('mbe_required') else 'β¬'}\n" | |
| ai_insights += f"- WBE: {'β ' if certs.get('wbe_required') else 'β¬'}\n\n" | |
| ai_insights += f"π {certs.get('reference', '')}\n\n" | |
| ai_insights += "---\n\n" | |
| # Eligibility | |
| if insights.get('eligibility_requirements'): | |
| elig = insights['eligibility_requirements'] | |
| ai_insights += f"### π‘ Eligibility & Requirements\n\n" | |
| ai_insights += f"{elig.get('requirements_summary', 'N/A')}\n\n" | |
| if elig.get('years_experience'): | |
| ai_insights += f"**Years of Experience Required:** {elig['years_experience']}+ years\n\n" | |
| if elig.get('past_experience_required'): | |
| ai_insights += f"**Past Experience:**\n{elig['past_experience_required']}\n\n" | |
| ai_insights += f"π {elig.get('reference', '')}\n\n" | |
| # Detailed Analysis | |
| details = "## Detailed Analysis\n\n" | |
| details += f"**Analysis Time:** {result.get('analysis_time', 'N/A')}\n\n" | |
| details += f"**Method:** {result.get('method', 'N/A')}\n\n" | |
| if result.get('reasons'): | |
| details += "### Reasons:\n" | |
| for reason in result['reasons']: | |
| details += f"- {reason}\n" | |
| details += "\n" | |
| # Strategic Notes | |
| if result.get('strategic_notes'): | |
| details += "### Strategic Notes:\n\n" | |
| for note in result['strategic_notes']: | |
| details += f"{note}\n\n" | |
| # Full JSON for advanced users | |
| full_json = json.dumps(result, indent=2) | |
| return status, ai_insights, details, full_json | |
| except Exception as e: | |
| error_msg = f"## Error\n\nFailed to analyze RFP: {str(e)}" | |
| return error_msg, "", "", str(e) | |
| # Create Gradio interface | |
| with gr.Blocks(title="RFP Go/No-Go Analyzer", theme=gr.themes.Soft()) as demo: | |
| gr.Markdown(""" | |
| # π RFP Go/No-Go Decision Analyzer | |
| Upload an RFP PDF to get instant AI-powered analysis with: | |
| - β Go/No-Go recommendation | |
| - π Comprehensive scope, certification, and eligibility extraction | |
| - π― Strategic insights and compliance checks | |
| - β‘ Fast pattern-based extraction (<1 second) | |
| **Powered by:** Llama3 AI + Pattern Matching | |
| """) | |
| with gr.Row(): | |
| with gr.Column(scale=1): | |
| pdf_input = gr.File( | |
| label="Upload RFP PDF", | |
| file_types=[".pdf"], | |
| type="filepath" | |
| ) | |
| target_states = gr.Textbox( | |
| label="Target States (comma-separated)", | |
| placeholder="Virginia, Maryland, DC", | |
| value="" | |
| ) | |
| partner_known = gr.Checkbox( | |
| label="Partner Already Known?", | |
| value=False | |
| ) | |
| analyze_btn = gr.Button("π Analyze RFP", variant="primary", size="lg") | |
| with gr.Column(scale=2): | |
| status_output = gr.Markdown(label="Decision") | |
| with gr.Row(): | |
| with gr.Column(): | |
| ai_insights_output = gr.Markdown(label="AI Insights") | |
| with gr.Column(): | |
| details_output = gr.Markdown(label="Detailed Analysis") | |
| with gr.Accordion("π Full JSON Response", open=False): | |
| json_output = gr.Code(label="Complete Analysis Data", language="json") | |
| # Connect button to function | |
| analyze_btn.click( | |
| fn=analyze_rfp_gradio, | |
| inputs=[pdf_input, target_states, partner_known], | |
| outputs=[status_output, ai_insights_output, details_output, json_output] | |
| ) | |
| gr.Markdown(""" | |
| --- | |
| ### π Features | |
| - **Ultra-Fast Analysis:** Pattern-based extraction in <1 second | |
| - **Page Citations:** Exact page numbers for all extracted data | |
| - **Comprehensive Extraction:** Scope, Certifications, Eligibility, Past Experience | |
| - **Go/No-Go Decision:** AI-powered recommendation with criteria scoring | |
| - **Strategic Notes:** Actionable insights for proposal strategy | |
| ### π§ Technical Details | |
| - **Text Extraction:** 99% accuracy with PyMuPDF | |
| - **Pattern Matching:** Advanced regex for instant field detection | |
| - **AI Model:** Llama3 (optional for enhanced summaries) | |
| - **Processing Time:** 0.1-0.5 seconds per RFP | |
| """) | |
| # Launch app | |
| if __name__ == "__main__": | |
| demo.launch( | |
| server_name="0.0.0.0", | |
| server_port=7860, | |
| share=False | |
| ) | |