Spaces:
Running
Running
fix requirements.txt issue
Browse files
app.py
CHANGED
|
@@ -483,6 +483,23 @@ When generating multi-file applications, use this exact format:
|
|
| 483 |
- Include supporting packages (accelerate, torch, tokenizers, etc.) when using ML libraries
|
| 484 |
- Your requirements.txt should ensure the application works smoothly in production
|
| 485 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 486 |
**Single vs Multi-File Decision:**
|
| 487 |
- Use single file for simple applications (< 100 lines) - but still generate requirements.txt if dependencies exist
|
| 488 |
- Use multi-file structure for complex applications with:
|
|
@@ -787,6 +804,23 @@ When generating multi-file applications, use this exact format:
|
|
| 787 |
[dependencies]
|
| 788 |
```
|
| 789 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 790 |
**Single vs Multi-File Decision:**
|
| 791 |
- Use single file for simple applications (< 100 lines) - but still generate requirements.txt if dependencies exist
|
| 792 |
- Use multi-file structure for complex applications with:
|
|
@@ -1465,6 +1499,23 @@ When generating multi-file applications, use this exact format:
|
|
| 1465 |
[dependencies]
|
| 1466 |
```
|
| 1467 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1468 |
**Single vs Multi-File Decision:**
|
| 1469 |
- Use single file for simple applications (< 100 lines) - but still generate requirements.txt if dependencies exist
|
| 1470 |
- Use multi-file structure for complex applications with:
|
|
@@ -1762,6 +1813,23 @@ You MUST use this exact format with file separators. DO NOT deviate from this fo
|
|
| 1762 |
- The system will automatically extract imports from app.py and generate requirements.txt
|
| 1763 |
- This prevents unnecessary changes to dependencies
|
| 1764 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1765 |
**File Modification Guidelines:**
|
| 1766 |
- Only output files that actually need changes
|
| 1767 |
- If a file doesn't need modification, don't include it in the output
|
|
@@ -5549,6 +5617,73 @@ def is_streamlit_code(code: str) -> bool:
|
|
| 5549 |
lowered = code.lower()
|
| 5550 |
return ("import streamlit" in lowered) or ("from streamlit" in lowered) or ("st." in code and "streamlit" in lowered)
|
| 5551 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 5552 |
def parse_multi_file_python_output(code: str) -> dict:
|
| 5553 |
"""Parse multi-file Python output (Gradio/Streamlit) into separate files"""
|
| 5554 |
files = {}
|
|
@@ -5566,6 +5701,11 @@ def parse_multi_file_python_output(code: str) -> dict:
|
|
| 5566 |
if i + 1 < len(parts):
|
| 5567 |
filename = parts[i].strip()
|
| 5568 |
content = parts[i + 1].strip()
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 5569 |
files[filename] = content
|
| 5570 |
else:
|
| 5571 |
# Single file - check if it's a space import or regular code
|
|
@@ -5579,7 +5719,11 @@ def parse_multi_file_python_output(code: str) -> dict:
|
|
| 5579 |
if line.startswith('=== ') and line.endswith(' ==='):
|
| 5580 |
# Save previous file
|
| 5581 |
if current_file and current_content:
|
| 5582 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
| 5583 |
# Start new file
|
| 5584 |
current_file = line[4:-4].strip()
|
| 5585 |
current_content = []
|
|
@@ -5588,7 +5732,11 @@ def parse_multi_file_python_output(code: str) -> dict:
|
|
| 5588 |
|
| 5589 |
# Save last file
|
| 5590 |
if current_file and current_content:
|
| 5591 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
| 5592 |
else:
|
| 5593 |
# Single file code - determine appropriate filename
|
| 5594 |
if is_streamlit_code(code):
|
|
@@ -5629,7 +5777,13 @@ def format_multi_file_python_output(files: dict) -> str:
|
|
| 5629 |
# Format output
|
| 5630 |
for filename in ordered_files:
|
| 5631 |
output.append(f"=== {filename} ===")
|
| 5632 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 5633 |
output.append("") # Empty line between files
|
| 5634 |
|
| 5635 |
return '\n'.join(output)
|
|
@@ -6803,10 +6957,17 @@ Instructions:
|
|
| 6803 |
- One package per line
|
| 6804 |
- If no external packages are needed, return "# No additional dependencies required"
|
| 6805 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 6806 |
Generate a comprehensive requirements.txt that ensures the application will work smoothly:"""
|
| 6807 |
|
| 6808 |
messages = [
|
| 6809 |
-
{"role": "system", "content": "You are a Python packaging expert specializing in creating comprehensive, production-ready requirements.txt files. Your goal is to ensure applications work smoothly by including not just direct dependencies but also commonly needed companion packages, popular extensions, and supporting libraries that developers typically need together."},
|
| 6810 |
{"role": "user", "content": prompt}
|
| 6811 |
]
|
| 6812 |
|
|
@@ -6823,18 +6984,40 @@ Generate a comprehensive requirements.txt that ensures the application will work
|
|
| 6823 |
if '```' in requirements_content:
|
| 6824 |
# Use the existing remove_code_block function for consistent cleaning
|
| 6825 |
requirements_content = remove_code_block(requirements_content)
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 6826 |
|
| 6827 |
-
#
|
| 6828 |
-
|
| 6829 |
-
|
| 6830 |
-
|
| 6831 |
-
|
| 6832 |
-
stripped_line
|
| 6833 |
-
# Skip
|
| 6834 |
-
|
| 6835 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 6836 |
clean_lines.append(line)
|
| 6837 |
-
|
|
|
|
| 6838 |
|
| 6839 |
# Ensure it ends with a newline
|
| 6840 |
if requirements_content and not requirements_content.endswith('\n'):
|
|
|
|
| 483 |
- Include supporting packages (accelerate, torch, tokenizers, etc.) when using ML libraries
|
| 484 |
- Your requirements.txt should ensure the application works smoothly in production
|
| 485 |
|
| 486 |
+
**🚨 CRITICAL: requirements.txt Formatting Rules**
|
| 487 |
+
- Output ONLY plain text package names, one per line
|
| 488 |
+
- Do NOT use markdown formatting (no ```, no bold, no headings, no lists with * or -)
|
| 489 |
+
- Do NOT add explanatory text or descriptions
|
| 490 |
+
- Do NOT wrap in code blocks
|
| 491 |
+
- Just raw package names as they would appear in a real requirements.txt file
|
| 492 |
+
- Example of CORRECT format:
|
| 493 |
+
gradio
|
| 494 |
+
torch
|
| 495 |
+
transformers
|
| 496 |
+
- Example of INCORRECT format (DO NOT DO THIS):
|
| 497 |
+
```
|
| 498 |
+
gradio # For web interface
|
| 499 |
+
**Core dependencies:**
|
| 500 |
+
- torch
|
| 501 |
+
```
|
| 502 |
+
|
| 503 |
**Single vs Multi-File Decision:**
|
| 504 |
- Use single file for simple applications (< 100 lines) - but still generate requirements.txt if dependencies exist
|
| 505 |
- Use multi-file structure for complex applications with:
|
|
|
|
| 804 |
[dependencies]
|
| 805 |
```
|
| 806 |
|
| 807 |
+
**🚨 CRITICAL: requirements.txt Formatting Rules**
|
| 808 |
+
- Output ONLY plain text package names, one per line
|
| 809 |
+
- Do NOT use markdown formatting (no ```, no bold, no headings, no lists with * or -)
|
| 810 |
+
- Do NOT add explanatory text or descriptions
|
| 811 |
+
- Do NOT wrap in code blocks
|
| 812 |
+
- Just raw package names as they would appear in a real requirements.txt file
|
| 813 |
+
- Example of CORRECT format:
|
| 814 |
+
gradio
|
| 815 |
+
torch
|
| 816 |
+
transformers
|
| 817 |
+
- Example of INCORRECT format (DO NOT DO THIS):
|
| 818 |
+
```
|
| 819 |
+
gradio # For web interface
|
| 820 |
+
**Core dependencies:**
|
| 821 |
+
- torch
|
| 822 |
+
```
|
| 823 |
+
|
| 824 |
**Single vs Multi-File Decision:**
|
| 825 |
- Use single file for simple applications (< 100 lines) - but still generate requirements.txt if dependencies exist
|
| 826 |
- Use multi-file structure for complex applications with:
|
|
|
|
| 1499 |
[dependencies]
|
| 1500 |
```
|
| 1501 |
|
| 1502 |
+
**🚨 CRITICAL: requirements.txt Formatting Rules**
|
| 1503 |
+
- Output ONLY plain text package names, one per line
|
| 1504 |
+
- Do NOT use markdown formatting (no ```, no bold, no headings, no lists with * or -)
|
| 1505 |
+
- Do NOT add explanatory text or descriptions
|
| 1506 |
+
- Do NOT wrap in code blocks
|
| 1507 |
+
- Just raw package names as they would appear in a real requirements.txt file
|
| 1508 |
+
- Example of CORRECT format:
|
| 1509 |
+
streamlit
|
| 1510 |
+
pandas
|
| 1511 |
+
numpy
|
| 1512 |
+
- Example of INCORRECT format (DO NOT DO THIS):
|
| 1513 |
+
```
|
| 1514 |
+
streamlit # For web interface
|
| 1515 |
+
**Core dependencies:**
|
| 1516 |
+
- pandas
|
| 1517 |
+
```
|
| 1518 |
+
|
| 1519 |
**Single vs Multi-File Decision:**
|
| 1520 |
- Use single file for simple applications (< 100 lines) - but still generate requirements.txt if dependencies exist
|
| 1521 |
- Use multi-file structure for complex applications with:
|
|
|
|
| 1813 |
- The system will automatically extract imports from app.py and generate requirements.txt
|
| 1814 |
- This prevents unnecessary changes to dependencies
|
| 1815 |
|
| 1816 |
+
**IF User Specifically Asks to Modify requirements.txt:**
|
| 1817 |
+
- Output ONLY plain text package names, one per line
|
| 1818 |
+
- Do NOT use markdown formatting (no ```, no bold, no headings, no lists with * or -)
|
| 1819 |
+
- Do NOT add explanatory text or descriptions
|
| 1820 |
+
- Do NOT wrap in code blocks
|
| 1821 |
+
- Just raw package names as they would appear in a real requirements.txt file
|
| 1822 |
+
- Example of CORRECT format:
|
| 1823 |
+
gradio
|
| 1824 |
+
torch
|
| 1825 |
+
transformers
|
| 1826 |
+
- Example of INCORRECT format (DO NOT DO THIS):
|
| 1827 |
+
```
|
| 1828 |
+
gradio # For web interface
|
| 1829 |
+
**Core dependencies:**
|
| 1830 |
+
- torch
|
| 1831 |
+
```
|
| 1832 |
+
|
| 1833 |
**File Modification Guidelines:**
|
| 1834 |
- Only output files that actually need changes
|
| 1835 |
- If a file doesn't need modification, don't include it in the output
|
|
|
|
| 5617 |
lowered = code.lower()
|
| 5618 |
return ("import streamlit" in lowered) or ("from streamlit" in lowered) or ("st." in code and "streamlit" in lowered)
|
| 5619 |
|
| 5620 |
+
def clean_requirements_txt_content(content: str) -> str:
|
| 5621 |
+
"""
|
| 5622 |
+
Clean up requirements.txt content to remove markdown formatting.
|
| 5623 |
+
This function removes code blocks, markdown lists, headers, and other formatting
|
| 5624 |
+
that might be mistakenly included by LLMs.
|
| 5625 |
+
"""
|
| 5626 |
+
if not content:
|
| 5627 |
+
return content
|
| 5628 |
+
|
| 5629 |
+
# First, remove code blocks if present
|
| 5630 |
+
if '```' in content:
|
| 5631 |
+
content = remove_code_block(content)
|
| 5632 |
+
|
| 5633 |
+
# Process line by line to remove markdown formatting
|
| 5634 |
+
lines = content.split('\n')
|
| 5635 |
+
clean_lines = []
|
| 5636 |
+
|
| 5637 |
+
for line in lines:
|
| 5638 |
+
stripped_line = line.strip()
|
| 5639 |
+
|
| 5640 |
+
# Skip empty lines
|
| 5641 |
+
if not stripped_line:
|
| 5642 |
+
continue
|
| 5643 |
+
|
| 5644 |
+
# Skip lines that are markdown formatting
|
| 5645 |
+
if (stripped_line == '```' or
|
| 5646 |
+
stripped_line.startswith('```') or
|
| 5647 |
+
# Skip markdown headers (## Header) but keep comments (# comment)
|
| 5648 |
+
(stripped_line.startswith('#') and len(stripped_line) > 1 and stripped_line[1] != ' ') or
|
| 5649 |
+
stripped_line.startswith('**') or # Skip bold text
|
| 5650 |
+
stripped_line.startswith('===') or # Skip section dividers
|
| 5651 |
+
stripped_line.startswith('---') or # Skip horizontal rules
|
| 5652 |
+
# Skip common explanatory text patterns
|
| 5653 |
+
stripped_line.lower().startswith('here') or
|
| 5654 |
+
stripped_line.lower().startswith('this') or
|
| 5655 |
+
stripped_line.lower().startswith('the ') or
|
| 5656 |
+
stripped_line.lower().startswith('based on') or
|
| 5657 |
+
stripped_line.lower().startswith('dependencies') or
|
| 5658 |
+
stripped_line.lower().startswith('requirements')):
|
| 5659 |
+
continue
|
| 5660 |
+
|
| 5661 |
+
# Handle markdown list items (- item or * item)
|
| 5662 |
+
if (stripped_line.startswith('- ') or stripped_line.startswith('* ')):
|
| 5663 |
+
# Extract the package name after the list marker
|
| 5664 |
+
stripped_line = stripped_line[2:].strip()
|
| 5665 |
+
if not stripped_line:
|
| 5666 |
+
continue
|
| 5667 |
+
|
| 5668 |
+
# Keep lines that look like valid package specifications
|
| 5669 |
+
# Valid lines: package names, git+https://, comments starting with "# "
|
| 5670 |
+
if (stripped_line.startswith('# ') or # Valid comments
|
| 5671 |
+
stripped_line.startswith('git+') or # Git dependencies
|
| 5672 |
+
stripped_line[0].isalnum() or # Package names start with alphanumeric
|
| 5673 |
+
'==' in stripped_line or # Version specifications
|
| 5674 |
+
'>=' in stripped_line or # Version specifications
|
| 5675 |
+
'<=' in stripped_line or # Version specifications
|
| 5676 |
+
'~=' in stripped_line): # Version specifications
|
| 5677 |
+
clean_lines.append(stripped_line)
|
| 5678 |
+
|
| 5679 |
+
result = '\n'.join(clean_lines)
|
| 5680 |
+
|
| 5681 |
+
# Ensure it ends with a newline
|
| 5682 |
+
if result and not result.endswith('\n'):
|
| 5683 |
+
result += '\n'
|
| 5684 |
+
|
| 5685 |
+
return result if result else "# No additional dependencies required\n"
|
| 5686 |
+
|
| 5687 |
def parse_multi_file_python_output(code: str) -> dict:
|
| 5688 |
"""Parse multi-file Python output (Gradio/Streamlit) into separate files"""
|
| 5689 |
files = {}
|
|
|
|
| 5701 |
if i + 1 < len(parts):
|
| 5702 |
filename = parts[i].strip()
|
| 5703 |
content = parts[i + 1].strip()
|
| 5704 |
+
|
| 5705 |
+
# Clean up requirements.txt to remove markdown formatting
|
| 5706 |
+
if filename == 'requirements.txt':
|
| 5707 |
+
content = clean_requirements_txt_content(content)
|
| 5708 |
+
|
| 5709 |
files[filename] = content
|
| 5710 |
else:
|
| 5711 |
# Single file - check if it's a space import or regular code
|
|
|
|
| 5719 |
if line.startswith('=== ') and line.endswith(' ==='):
|
| 5720 |
# Save previous file
|
| 5721 |
if current_file and current_content:
|
| 5722 |
+
content = '\n'.join(current_content)
|
| 5723 |
+
# Clean up requirements.txt to remove markdown formatting
|
| 5724 |
+
if current_file == 'requirements.txt':
|
| 5725 |
+
content = clean_requirements_txt_content(content)
|
| 5726 |
+
files[current_file] = content
|
| 5727 |
# Start new file
|
| 5728 |
current_file = line[4:-4].strip()
|
| 5729 |
current_content = []
|
|
|
|
| 5732 |
|
| 5733 |
# Save last file
|
| 5734 |
if current_file and current_content:
|
| 5735 |
+
content = '\n'.join(current_content)
|
| 5736 |
+
# Clean up requirements.txt to remove markdown formatting
|
| 5737 |
+
if current_file == 'requirements.txt':
|
| 5738 |
+
content = clean_requirements_txt_content(content)
|
| 5739 |
+
files[current_file] = content
|
| 5740 |
else:
|
| 5741 |
# Single file code - determine appropriate filename
|
| 5742 |
if is_streamlit_code(code):
|
|
|
|
| 5777 |
# Format output
|
| 5778 |
for filename in ordered_files:
|
| 5779 |
output.append(f"=== {filename} ===")
|
| 5780 |
+
|
| 5781 |
+
# Clean up requirements.txt content if it's being formatted
|
| 5782 |
+
content = files[filename]
|
| 5783 |
+
if filename == 'requirements.txt':
|
| 5784 |
+
content = clean_requirements_txt_content(content)
|
| 5785 |
+
|
| 5786 |
+
output.append(content)
|
| 5787 |
output.append("") # Empty line between files
|
| 5788 |
|
| 5789 |
return '\n'.join(output)
|
|
|
|
| 6957 |
- One package per line
|
| 6958 |
- If no external packages are needed, return "# No additional dependencies required"
|
| 6959 |
|
| 6960 |
+
🚨 CRITICAL OUTPUT FORMAT:
|
| 6961 |
+
- Output ONLY the package names, one per line (plain text format)
|
| 6962 |
+
- Do NOT use markdown formatting (no ```, no bold, no headings, no lists)
|
| 6963 |
+
- Do NOT add any explanatory text before or after the package list
|
| 6964 |
+
- Do NOT wrap the output in code blocks
|
| 6965 |
+
- Just output raw package names as they would appear in requirements.txt
|
| 6966 |
+
|
| 6967 |
Generate a comprehensive requirements.txt that ensures the application will work smoothly:"""
|
| 6968 |
|
| 6969 |
messages = [
|
| 6970 |
+
{"role": "system", "content": "You are a Python packaging expert specializing in creating comprehensive, production-ready requirements.txt files. Output ONLY plain text package names without any markdown formatting, code blocks, or explanatory text. Your goal is to ensure applications work smoothly by including not just direct dependencies but also commonly needed companion packages, popular extensions, and supporting libraries that developers typically need together."},
|
| 6971 |
{"role": "user", "content": prompt}
|
| 6972 |
]
|
| 6973 |
|
|
|
|
| 6984 |
if '```' in requirements_content:
|
| 6985 |
# Use the existing remove_code_block function for consistent cleaning
|
| 6986 |
requirements_content = remove_code_block(requirements_content)
|
| 6987 |
+
|
| 6988 |
+
# Enhanced cleanup for markdown and formatting
|
| 6989 |
+
lines = requirements_content.split('\n')
|
| 6990 |
+
clean_lines = []
|
| 6991 |
+
for line in lines:
|
| 6992 |
+
stripped_line = line.strip()
|
| 6993 |
|
| 6994 |
+
# Skip lines that are markdown formatting
|
| 6995 |
+
if (stripped_line == '```' or
|
| 6996 |
+
stripped_line.startswith('```') or
|
| 6997 |
+
stripped_line.startswith('#') and not stripped_line.startswith('# ') or # Skip markdown headers but keep comments
|
| 6998 |
+
stripped_line.startswith('**') or # Skip bold text
|
| 6999 |
+
stripped_line.startswith('*') and not stripped_line[1:2].isalnum() or # Skip markdown lists but keep package names starting with *
|
| 7000 |
+
stripped_line.startswith('-') and not stripped_line[1:2].isalnum() or # Skip markdown lists but keep package names starting with -
|
| 7001 |
+
stripped_line.startswith('===') or # Skip section dividers
|
| 7002 |
+
stripped_line.startswith('---') or # Skip horizontal rules
|
| 7003 |
+
stripped_line.lower().startswith('here') or # Skip explanatory text
|
| 7004 |
+
stripped_line.lower().startswith('this') or # Skip explanatory text
|
| 7005 |
+
stripped_line.lower().startswith('the') or # Skip explanatory text
|
| 7006 |
+
stripped_line.lower().startswith('based on') or # Skip explanatory text
|
| 7007 |
+
stripped_line == ''): # Skip empty lines unless they're at natural boundaries
|
| 7008 |
+
continue
|
| 7009 |
+
|
| 7010 |
+
# Keep lines that look like valid package specifications
|
| 7011 |
+
# Valid lines: package names, git+https://, comments starting with "# "
|
| 7012 |
+
if (stripped_line.startswith('# ') or # Valid comments
|
| 7013 |
+
stripped_line.startswith('git+') or # Git dependencies
|
| 7014 |
+
stripped_line[0].isalnum() or # Package names start with alphanumeric
|
| 7015 |
+
'==' in stripped_line or # Version specifications
|
| 7016 |
+
'>=' in stripped_line or # Version specifications
|
| 7017 |
+
'<=' in stripped_line): # Version specifications
|
| 7018 |
clean_lines.append(line)
|
| 7019 |
+
|
| 7020 |
+
requirements_content = '\n'.join(clean_lines).strip()
|
| 7021 |
|
| 7022 |
# Ensure it ends with a newline
|
| 7023 |
if requirements_content and not requirements_content.endswith('\n'):
|