@@ -1608,12 +1608,15 @@ def convert_data_role(data_role: Union[str, int]) -> Union[str, int]:
16081608 conversion = 1
16091609
16101610 return conversion
1611+
1612+
16111613
16121614 @classmethod
16131615 def create_requirements_json (
16141616 cls ,
16151617 model_path : Union [str , Path , None ] = Path .cwd (),
16161618 output_path : Union [str , Path , None ] = None ,
1619+ create_requirements_txt : bool = False
16171620 ) -> Union [dict , None ]:
16181621 """
16191622 Searches the model directory for Python scripts and pickle files and
@@ -1666,6 +1669,53 @@ def create_requirements_json(
16661669 missing_package_versions = [
16671670 item [0 ] for item in package_and_version if not item [1 ]
16681671 ]
1672+
1673+ IMPORT_TO_INSTALL_MAPPING = {
1674+ # Data Science & ML Core
1675+ 'sklearn' : 'scikit-learn' ,
1676+ 'skimage' : 'scikit-image' ,
1677+ 'cv2' : 'opencv-python' ,
1678+ 'PIL' : 'Pillow' ,
1679+
1680+ # Data Formats & Parsing
1681+ 'yaml' : 'PyYAML' ,
1682+ 'bs4' : 'beautifulsoup4' ,
1683+ 'docx' : 'python-docx' ,
1684+ 'pptx' : 'python-pptx' ,
1685+
1686+ # Date & Time Utilities
1687+ 'dateutil' : 'python-dateutil' ,
1688+
1689+ # Database Connectors
1690+ 'MySQLdb' : 'MySQL-python' ,
1691+ 'psycopg2' : 'psycopg2-binary' ,
1692+
1693+ # System & Platform
1694+ 'win32api' : 'pywin32' ,
1695+ 'win32com' : 'pywin32' ,
1696+
1697+ # Scientific Libraries
1698+ 'Bio' : 'biopython' ,
1699+ }
1700+
1701+ package_list = [IMPORT_TO_INSTALL_MAPPING .get (name , name ) for name in package_list ]
1702+
1703+
1704+ if create_requirements_txt :
1705+ requirements_txt = ""
1706+ if missing_package_versions :
1707+ requirements_txt += "# Warning- The existence and/or versions for the following packages could not be determined:\n "
1708+ requirements_txt += "# " + ", " .join (missing_package_versions ) + "\n "
1709+
1710+ for package , version in package_and_version :
1711+ if version :
1712+ requirements_txt += f"{ package } =={ version } \n "
1713+
1714+ if output_path :
1715+ with open ( # skipcq: PTC-W6004
1716+ Path (output_path ) / "requirements.txt" , "w"
1717+ ) as file :
1718+ file .write (requirements_txt )
16691719
16701720 # Create a list of dicts related to each package or warning
16711721 json_dicts = []
@@ -1800,16 +1850,16 @@ def find_imports(file_path: Union[str, Path]) -> List[str]:
18001850 file_text = file .read ()
18011851 # Parse the file to get the abstract syntax tree representation
18021852 tree = ast .parse (file_text )
1803- modules = []
1853+ modules = set ()
18041854
18051855 # Walk through each node in the ast to find import calls
18061856 for node in ast .walk (tree ):
18071857 # Determine parent module for `from * import *` calls
18081858 if isinstance (node , ast .ImportFrom ):
1809- modules .append (node .module )
1859+ modules .add (node .module . split ( '.' )[ 0 ] )
18101860 elif isinstance (node , ast .Import ):
18111861 for name in node .names :
1812- modules .append (name .name )
1862+ modules .add (name .name . split ( '.' )[ 0 ] )
18131863
18141864 modules = list (set (modules ))
18151865 try :
0 commit comments