Spaces:
Sleeping
Sleeping
| """ | |
| Core conversion logic for transforming Python code to Gradio apps | |
| """ | |
| import re | |
| import traceback | |
| from typing import Dict, Any | |
| from langchain_groq import ChatGroq | |
| from langchain_core.prompts import ChatPromptTemplate | |
| from langchain_core.output_parsers import StrOutputParser | |
| def convert_code(input_code: str, groq_api_key: str, model_name: str = "llama-3.3-70b-versatile") -> Dict[str, str]: | |
| """ | |
| Converts input Python/IPYNB code into a Gradio app structure. | |
| """ | |
| # Validate API key | |
| if not groq_api_key: | |
| raise ValueError("Groq API Key is required for conversion.") | |
| if not groq_api_key.startswith('gsk_'): | |
| raise ValueError("Invalid Groq API Key. It should start with 'gsk_'") | |
| try: | |
| # Initialize Groq client | |
| chat = ChatGroq( | |
| temperature=0.1, | |
| model_name=model_name, | |
| api_key=groq_api_key, | |
| max_retries=2, | |
| timeout=30 | |
| ) | |
| except Exception as e: | |
| raise ValueError(f"Failed to initialize Groq client: {str(e)}") | |
| # System prompt for conversion - UPDATED with Gradio 6.2.0 | |
| system_prompt = """You are an expert Python developer specializing in Gradio and Hugging Face Spaces. | |
| Your task is to convert the provided Python code into a deployable Gradio web application. | |
| Return your response in this exact format: | |
| ===APP_PY=== | |
| [Complete app.py code here - NO markdown backticks or ```python] | |
| ===APP_PY_END=== | |
| ===REQUIREMENTS_TXT=== | |
| [Requirements.txt content here, one dependency per line - NO markdown backticks] | |
| ===REQUIREMENTS_TXT_END=== | |
| ===README_MD=== | |
| [README.md content here with proper YAML frontmatter] | |
| ===README_MD_END=== | |
| CRITICAL RULES: | |
| 1. app.py MUST be valid Python code ONLY | |
| 2. requirements.txt MUST be plain text | |
| 3. README.md MUST have YAML frontmatter at the top | |
| 4. Include all necessary imports in app.py | |
| 5. Always include: if __name__ == "__main__": demo.launch() | |
| 6. requirements.txt must include: gradio>=6.2.0 # CHANGED FROM 4.0.0 TO 6.2.0 | |
| YAML frontmatter template: | |
| --- | |
| title: Generated Gradio App | |
| emoji: 🚀 | |
| colorFrom: blue | |
| colorTo: purple | |
| sdk: gradio | |
| sdk_version: "6.2.0" # CHANGED FROM 4.0.0 TO 6.2.0 | |
| app_file: app.py | |
| pinned: false | |
| --- | |
| Do NOT include markdown code blocks (```) in any output. | |
| """ | |
| human_template = """Convert this Python code to a complete Gradio app. | |
| Code to convert: | |
| ```python | |
| {code} | |
| ```""" | |
| # Create the chain | |
| prompt = ChatPromptTemplate.from_messages([ | |
| ("system", system_prompt), | |
| ("human", human_template) | |
| ]) | |
| chain = prompt | chat | StrOutputParser() | |
| try: | |
| # Invoke the chain | |
| response = chain.invoke({"code": input_code[:50000]}) | |
| # Parse the response | |
| result = parse_llm_response(response) | |
| # Clean and validate outputs | |
| result = clean_all_outputs(result) | |
| result = post_process_conversion(result, input_code) | |
| return result | |
| except Exception as e: | |
| print(f"Conversion error: {e}") | |
| print(f"Traceback: {traceback.format_exc()}") | |
| return create_basic_template(input_code) | |
| def parse_llm_response(response: str) -> Dict[str, str]: | |
| """Parse the LLM response into structured components""" | |
| result = { | |
| "app_py": "", | |
| "requirements_txt": "", | |
| "readme_md": "" | |
| } | |
| patterns = [ | |
| (r'===APP_PY===(.*?)===APP_PY_END===', "app_py"), | |
| (r'===REQUIREMENTS_TXT===(.*?)===REQUIREMENTS_TXT_END===', "requirements_txt"), | |
| (r'===README_MD===(.*?)===README_MD_END===', "readme_md") | |
| ] | |
| for pattern, key in patterns: | |
| match = re.search(pattern, response, re.DOTALL) | |
| if match: | |
| result[key] = match.group(1).strip() | |
| return result | |
| def clean_all_outputs(result: Dict[str, str]) -> Dict[str, str]: | |
| """Clean markdown backticks from all outputs""" | |
| for key in ["app_py", "requirements_txt", "readme_md"]: | |
| if key in result and result[key]: | |
| content = result[key] | |
| # Remove markdown code blocks | |
| content = re.sub(r'^```(python|py)?\s*', '', content, flags=re.IGNORECASE) | |
| content = re.sub(r'\s*```$', '', content) | |
| content = re.sub(r'```(python|py)?\s*(.*?)\s*```', r'\2', content, flags=re.DOTALL | re.IGNORECASE) | |
| # Remove any remaining stray backticks | |
| content = content.replace('```', '') | |
| # Strip whitespace | |
| content = content.strip() | |
| result[key] = content | |
| return result | |
| def post_process_conversion(result: Dict[str, str], original_code: str) -> Dict[str, str]: | |
| """Post-process and validate the conversion result""" | |
| # Ensure app.py is valid Python | |
| if not result.get("app_py"): | |
| result["app_py"] = create_basic_app_template(original_code) | |
| # Ensure requirements.txt is clean | |
| result["requirements_txt"] = clean_requirements(result.get("requirements_txt", "")) | |
| # Ensure README has proper format | |
| result["readme_md"] = clean_readme(result.get("readme_md", "")) | |
| return result | |
| def clean_requirements(req_text: str) -> str: | |
| """Clean and format requirements.txt content""" | |
| if not req_text: | |
| return "gradio>=6.2.0\nlangchain-groq>=0.1.0\nhuggingface-hub>=0.20.0" # UPDATED | |
| # Remove any markdown | |
| req_text = re.sub(r'```.*?\n', '', req_text, flags=re.DOTALL) | |
| req_text = req_text.replace('```', '') | |
| lines = [] | |
| for line in req_text.strip().split('\n'): | |
| line = line.strip() | |
| if line and not line.startswith('#') and not line.startswith('==='): | |
| line = re.sub(r'[\[\]"\']', '', line) | |
| if line: | |
| lines.append(line) | |
| # Ensure essential packages are included - UPDATED VERSION | |
| essential_packages = ["gradio>=6.2.0", "langchain-groq>=0.1.0", "huggingface-hub>=0.20.0"] # UPDATED | |
| for package in essential_packages: | |
| if not any(package.split('>=')[0] in line.lower() for line in lines): | |
| lines.insert(0, package) | |
| # Remove duplicates and sort | |
| return "\n".join(sorted(set(lines))) | |
| def clean_readme(readme_text: str) -> str: | |
| """Clean README.md to ensure proper format""" | |
| if not readme_text: | |
| return create_default_readme() | |
| # Remove markdown code blocks | |
| readme_text = re.sub(r'```.*?\n', '', readme_text, flags=re.DOTALL) | |
| readme_text = readme_text.replace('```', '') | |
| # Check for proper YAML frontmatter | |
| if not re.search(r'^---\s*$', readme_text.strip(), re.MULTILINE): | |
| return create_default_readme() | |
| # Update sdk_version in frontmatter if it's 4.0.0 | |
| readme_text = re.sub( | |
| r'sdk_version:\s*["\']4\.0\.0["\']', | |
| 'sdk_version: "6.2.0"', | |
| readme_text | |
| ) | |
| # Update gradio version in requirements if mentioned | |
| readme_text = re.sub( | |
| r'gradio>=4\.0\.0', | |
| 'gradio>=6.2.0', | |
| readme_text | |
| ) | |
| return readme_text.strip() | |
| def create_default_readme() -> str: | |
| """Create a default README with proper YAML frontmatter""" | |
| return """--- | |
| title: Generated Gradio App | |
| emoji: 🚀 | |
| colorFrom: blue | |
| colorTo: purple | |
| sdk: gradio | |
| sdk_version: "6.2.0" # UPDATED | |
| app_file: app.py | |
| pinned: false | |
| --- | |
| # Generated Gradio Application | |
| This application was automatically generated using the Hugging Face Space Creator. | |
| ## Features | |
| - User-friendly interface built with Gradio 6.2.0 | |
| - Ready for deployment on Hugging Face Spaces | |
| - Includes all necessary dependencies | |
| ## How to Use | |
| 1. Launch the application | |
| 2. Enter your inputs in the provided fields | |
| 3. Click submit to see results | |
| ## Deployment | |
| To deploy this application on Hugging Face Spaces: | |
| 1. Create a new Space on Hugging Face | |
| 2. Select Gradio as the SDK | |
| 3. Upload the generated files | |
| 4. Your app will be live automatically | |
| ## Requirements | |
| All dependencies are listed in requirements.txt | |
| """ | |
| def create_basic_app_template(input_code: str) -> str: | |
| """Create a basic, guaranteed-valid app.py template""" | |
| code_snippet = input_code[:1000] | |
| return f'''import gradio as gr | |
| # Original code snippet | |
| {code_snippet} | |
| # Gradio interface | |
| def process_input(input_text): | |
| try: | |
| # Process the input | |
| return f"Processed: {{input_text}}" | |
| except Exception as e: | |
| return f"Error: {{str(e)}}" | |
| # Create the Gradio app | |
| with gr.Blocks(title="Generated Application", theme=gr.themes.Soft()) as demo: | |
| gr.Markdown("# Generated Application") | |
| with gr.Row(): | |
| with gr.Column(): | |
| input_box = gr.Textbox( | |
| label="Input Text", | |
| placeholder="Enter text to process...", | |
| lines=3 | |
| ) | |
| submit_btn = gr.Button("Process", variant="primary") | |
| with gr.Row(): | |
| output_box = gr.Textbox( | |
| label="Output", | |
| interactive=False, | |
| lines=5 | |
| ) | |
| submit_btn.click( | |
| fn=process_input, | |
| inputs=[input_box], | |
| outputs=[output_box] | |
| ) | |
| if __name__ == "__main__": | |
| demo.launch(share=False) | |
| ''' | |
| def create_basic_template(input_code: str) -> Dict[str, str]: | |
| """Create a basic template when conversion fails""" | |
| return { | |
| "app_py": create_basic_app_template(input_code), | |
| "requirements_txt": "gradio>=6.2.0\nlangchain-groq>=0.1.0\nhuggingface-hub>=0.20.0", # UPDATED | |
| "readme_md": create_default_readme() | |
| } |