import gradio as gr import requests import os from dotenv import load_dotenv import tempfile # Load environment variables load_dotenv() def get_sample_cv(): """ Return the sample CV markdown content for reference """ try: with open('Sample.md', 'r', encoding='utf-8') as f: return f.read() except FileNotFoundError: return "Sample.md file not found in the current directory." except Exception as e: return f"Error reading Sample.md: {str(e)}" def get_cv_formatting_instructions(): """ Return detailed CV formatting instructions from external markdown file """ try: with open('Instructions.md', 'r', encoding='utf-8') as f: return f.read() except FileNotFoundError: return "Instructions.md file not found in the current directory." except Exception as e: return f"Error reading Instructions.md: {str(e)}" def convert_markdown_to_pdf(markdown_text): """ Convert markdown text to PDF and HTML using the external API endpoints Args: markdown_text (str): The markdown text to convert Returns: tuple: (pdf_path, html_content, status_message) """ if not markdown_text.strip(): return None, "", "Please enter some markdown text." # Get bearer token from environment bearer_token = os.getenv('BEARER_TOKEN') if not bearer_token or bearer_token == 'your_bearer_token_here': return None, "", "❌ Bearer token not configured. Please set BEARER_TOKEN in .env file." try: headers = { 'Authorization': f'Bearer {bearer_token}', 'Content-Type': 'text/markdown' } # Get base URL from environment base_url = os.getenv('API_BASE_URL', 'https://nirav-madhani-resume-server.hf.space') # Get PDF directly from API pdf_url = f"{base_url}/convert/pdf" print(f"📡 Making request to {pdf_url}") pdf_response = requests.post(pdf_url, data=markdown_text, headers=headers, timeout=30) if pdf_response.status_code != 200: return None, "", f"❌ PDF API request failed with status {pdf_response.status_code}: {pdf_response.text}" # Save PDF to temporary file with tempfile.NamedTemporaryFile(delete=False, suffix='.pdf', mode='w+b') as temp_pdf: temp_pdf.write(pdf_response.content) pdf_path = temp_pdf.name # Get HTML for preview html_url = f"{base_url}/convert/html" print(f"📡 Making request to {html_url}") html_response = requests.post(html_url, data=markdown_text, headers=headers, timeout=30) if html_response.status_code != 200: # PDF worked but HTML failed - still return PDF return pdf_path, "", f"✅ PDF generated successfully! (HTML preview failed: {html_response.status_code})" html_content = html_response.text return pdf_path, html_content, "✅ PDF and HTML generated successfully via API!" except requests.exceptions.RequestException as e: return None, "", f"❌ Network error: {str(e)}" except Exception as e: return None, "", f"❌ Error generating PDF: {str(e)}" def process_conversion(markdown_text): """ Process the markdown conversion and return results for Gradio interface Args: markdown_text (str): The markdown text to convert Returns: tuple: (pdf_file_path, html_content, status_message) """ pdf_path, html_content, message = convert_markdown_to_pdf(markdown_text) return pdf_path, html_content, message # MCP Tool Functions (callable by AI assistants) def mcp_get_sample_cv(): """MCP tool: Get sample CV markdown Returns: str: The sample CV markdown content """ return get_sample_cv() def mcp_get_cv_instructions(): """MCP tool: Get CV formatting instructions Returns: str: The CV formatting instructions """ return get_cv_formatting_instructions() def mcp_convert_cv(markdown_text: str): """MCP tool: Convert CV markdown to PDF Args: markdown_text (str): The markdown text to convert to PDF Returns: str: The conversion result message """ pdf_path, html_content, message = process_conversion(markdown_text) return f"Conversion result: {message}" # Create Gradio interface with gr.Blocks(title="CV Markdown to PDF Converter", theme=gr.themes.Soft()) as demo: gr.Markdown("# 📄 CV Markdown to PDF Converter") gr.Markdown("Convert your CV markdown to professional PDF format. Use the Instructions & Sample tab to learn the proper formatting.") with gr.Tabs(): with gr.TabItem("🚀 Convert CV"): with gr.Row(): with gr.Column(scale=1): gr.Markdown("## Input") markdown_input = gr.Textbox( label="CV Markdown Text", placeholder="Enter your CV markdown here... (see Instructions & Sample tab for formatting guide)", lines=20, max_lines=30 ) with gr.Column(scale=1): gr.Markdown("## Output") with gr.Tabs(): with gr.TabItem("📄 PDF Download"): pdf_output = gr.File( label="Generated PDF", file_types=[".pdf"] ) with gr.TabItem("🌐 HTML Preview"): html_output = gr.HTML( label="HTML Preview", value="HTML preview will appear here after conversion..." ) status_message = gr.Textbox( label="Status", interactive=False, lines=2 ) with gr.Row(): convert_btn = gr.Button("🚀 Convert to PDF", variant="primary", size="lg") # Event handler convert_btn.click( fn=process_conversion, inputs=[markdown_input], outputs=[pdf_output, html_output, status_message] ) with gr.TabItem("📋 Instructions & Sample"): with gr.Tabs(): with gr.TabItem("📖 Formatting Instructions"): gr.Markdown(get_cv_formatting_instructions()) with gr.TabItem("📄 Sample CV"): gr.Markdown("## Sample CV Markdown") gr.Markdown("Below is a complete sample CV showing all the formatting patterns:") sample_cv_display = gr.Code( value=get_sample_cv(), language="markdown", label="Sample CV Markdown Code", lines=30, max_lines=50 ) copy_sample_btn = gr.Button("📋 Copy Sample to Converter", variant="secondary") # Copy sample to main input copy_sample_btn.click( fn=get_sample_cv, outputs=[markdown_input] ) # Example CV templates with gr.Row(): gr.Examples( examples=[ [get_sample_cv()], ["""--- name: John Doe header: - text: | Full Stack Developer - text: (555) 987-6543 newLine: true - text: john.doe@email.com link: mailto:john.doe@email.com --- ## Experience [L2]Tech Startup Inc.[/L2] [L2R]San Francisco, CA[/L2R] [L3]Full Stack Developer[/L3] [L3R]Jan 2022 - Present[/L3R] - Designed and implemented scalable web applications serving 10K+ users - Reduced page load times by 40% through optimization techniques - Led migration from monolith to microservices architecture ## Education [L2]University of California[/L2] GPA 3.8 [L2R]Berkeley, CA[/L2R] [L3]B.S. in Computer Science[/L3] [L3R]2018 - 2022[/L3R] ## Skills **Programming:** Python, JavaScript, TypeScript, Java
**Frameworks:** React, Node.js, Django, Spring Boot
**Databases:** PostgreSQL, MongoDB, Redis """], ], inputs=[markdown_input], label="📝 CV Templates" ) # Register MCP tools gr.api(mcp_get_sample_cv) gr.api(mcp_get_cv_instructions) gr.api(mcp_convert_cv) # Launch the app with MCP enabled if __name__ == "__main__": demo.launch( mcp_server=True )