akhaliq HF Staff commited on
Commit
e68be88
·
1 Parent(s): 69a31aa

fix requirements.txt issue

Browse files
Files changed (1) hide show
  1. app.py +197 -14
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
- files[current_file] = '\n'.join(current_content)
 
 
 
 
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
- files[current_file] = '\n'.join(current_content)
 
 
 
 
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
- output.append(files[filename])
 
 
 
 
 
 
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
- # Additional cleanup for any remaining backticks
6828
- # Remove any remaining standalone backticks at start/end of lines
6829
- lines = requirements_content.split('\n')
6830
- clean_lines = []
6831
- for line in lines:
6832
- stripped_line = line.strip()
6833
- # Skip lines that are just backticks or backticks with language markers
6834
- if stripped_line == '```' or stripped_line.startswith('```'):
6835
- continue
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
6836
  clean_lines.append(line)
6837
- requirements_content = '\n'.join(clean_lines).strip()
 
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'):