@@ -101,6 +101,7 @@ def create_python_environment(
101101 python : typing .Optional [str ] = None ,
102102 override_python_version : typing .Optional [str ] = None ,
103103 app_file : typing .Optional [str ] = None ,
104+ require_requirements_txt : bool = True ,
104105 ) -> "Environment" :
105106 """Given a project directory and a Python executable, return Environment information.
106107
@@ -122,7 +123,7 @@ def create_python_environment(
122123
123124 # click.secho(' Deploying %s to server "%s"' % (directory, connect_server.url))
124125 _warn_on_ignored_manifest (directory )
125- _warn_if_no_requirements_file (directory )
126+ _check_requirements_file (directory , require_requirements_txt )
126127 _warn_if_environment_directory (directory )
127128
128129 python_version_requirement = pyproject .detect_python_version_requirement (directory )
@@ -145,7 +146,7 @@ def create_python_environment(
145146 python_version_requirement = f"=={ override_python_version } "
146147
147148 # with cli_feedback("Inspecting Python environment"):
148- environment = cls ._get_python_env_info (module_file , python , force_generate )
149+ environment = cls ._get_python_env_info (module_file , python , force_generate , require_requirements_txt )
149150 environment .python_version_requirement = python_version_requirement
150151
151152 if override_python_version :
@@ -160,7 +161,7 @@ def create_python_environment(
160161
161162 @classmethod
162163 def _get_python_env_info (
163- cls , file_name : str , python : typing .Optional [str ], force_generate : bool = False
164+ cls , file_name : str , python : typing .Optional [str ], force_generate : bool = False , require_requirements_txt : bool = True
164165 ) -> "Environment" :
165166 """
166167 Gathers the python and environment information relating to the specified file
@@ -175,7 +176,7 @@ def _get_python_env_info(
175176 """
176177 python = which_python (python )
177178 logger .debug ("Python: %s" % python )
178- environment = cls ._inspect_environment (python , os .path .dirname (file_name ), force_generate = force_generate )
179+ environment = cls ._inspect_environment (python , os .path .dirname (file_name ), force_generate = force_generate , require_requirements_txt = require_requirements_txt )
179180 if environment .error :
180181 raise RSConnectException (environment .error )
181182 logger .debug ("Python: %s" % python )
@@ -189,6 +190,7 @@ def _inspect_environment(
189190 directory : str ,
190191 force_generate : bool = False ,
191192 check_output : typing .Callable [..., bytes ] = subprocess .check_output ,
193+ require_requirements_txt : bool = True ,
192194 ) -> "Environment" :
193195 """Run the environment inspector using the specified python binary.
194196
@@ -202,7 +204,12 @@ def _inspect_environment(
202204 args = [python , "-m" , "rsconnect.subprocesses.inspect_environment" ]
203205 if flags :
204206 args .append ("-" + "" .join (flags ))
207+
208+ # Add arguments for inspect_environment.py
205209 args .append (directory )
210+
211+ if not require_requirements_txt :
212+ args .append ("--no-require-requirements" )
206213
207214 try :
208215 environment_json = check_output (args , text = True )
@@ -293,19 +300,31 @@ def _warn_on_ignored_manifest(directory: str) -> None:
293300 )
294301
295302
296- def _warn_if_no_requirements_file (directory : str ) -> None :
303+ def _check_requirements_file (directory : str , require_requirements_txt : bool = True ) -> None :
297304 """
298305 Checks for the existence of a file called requirements.txt in the given directory.
299- If it's not there, a warning will be printed .
306+ Raises RSConnectException if it doesn't exist and require_requirements_txt is True .
300307
301308 :param directory: the directory to check in.
309+ :param require_requirements_txt: if True, raises exception when requirements.txt is missing.
310+ if False, prints a warning instead (for backwards compatibility in tests).
311+ :raises: RSConnectException if requirements.txt is missing and require_requirements_txt is True.
302312 """
303313 if not os .path .exists (os .path .join (directory , "requirements.txt" )):
304- click .secho (
305- " Warning: Capturing the environment using 'pip freeze'.\n "
306- " Consider creating a requirements.txt file instead." ,
307- fg = "yellow" ,
308- )
314+ if require_requirements_txt :
315+ raise RSConnectException (
316+ "requirements.txt file is required for deployment. \n "
317+ "Please create a requirements.txt file in your project directory.\n "
318+ "For best results, use a virtual environment and create your requirements.txt file with:\n "
319+ "pip freeze > requirements.txt"
320+ )
321+ else :
322+ # For backwards compatibility in tests
323+ click .secho (
324+ " Warning: Capturing the environment using 'pip freeze'.\n "
325+ " Consider creating a requirements.txt file instead." ,
326+ fg = "yellow" ,
327+ )
309328
310329
311330def _warn_if_environment_directory (directory : typing .Union [str , pathlib .Path ]) -> None :
0 commit comments