44from dataclasses import dataclass
55from logging import getLogger
66from pathlib import Path
7- from typing import Iterator , Union
7+ from typing import Iterator , Tuple , Union
88
99from rich import print
1010from rich .padding import Padding
@@ -149,9 +149,9 @@ def get_app_name(*, mod_data: ModuleData, app_name: Union[str, None] = None) ->
149149 raise FastAPICLIException ("Could not find FastAPI app in module, try using --app" )
150150
151151
152- def get_import_string (
152+ def get_import_string_parts (
153153 * , path : Union [Path , None ] = None , app_name : Union [str , None ] = None
154- ) -> str :
154+ ) -> Tuple [ ModuleData , str ] :
155155 if not path :
156156 path = get_default_path ()
157157 logger .info (f"Using path [blue]{ path } [/blue]" )
@@ -161,6 +161,15 @@ def get_import_string(
161161 mod_data = get_module_data_from_path (path )
162162 sys .path .insert (0 , str (mod_data .extra_sys_path ))
163163 use_app_name = get_app_name (mod_data = mod_data , app_name = app_name )
164+
165+ return mod_data , use_app_name
166+
167+
168+ def get_import_string (
169+ * , path : Union [Path , None ] = None , app_name : Union [str , None ] = None
170+ ) -> str :
171+ mod_data , use_app_name = get_import_string_parts (path = path , app_name = app_name )
172+ import_string = f"{ mod_data .module_import_str } :{ use_app_name } "
164173 import_example = Syntax (
165174 f"from { mod_data .module_import_str } import { use_app_name } " , "python"
166175 )
@@ -175,57 +184,17 @@ def get_import_string(
175184 )
176185 logger .info ("Found importable FastAPI app" )
177186 print (import_panel )
178- import_string = f" { mod_data . module_import_str } : { use_app_name } "
187+
179188 logger .info (f"Using import string [b green]{ import_string } [/b green]" )
180189 return import_string
181190
182191
183192def get_app (
184193 * , path : Union [Path , None ] = None , app_name : Union [str , None ] = None
185194) -> FastAPI :
186- if not path :
187- path = get_default_path ()
188- logger .debug (f"Using path [blue]{ path } [/blue]" )
189- logger .debug (f"Resolved absolute path { path .resolve ()} " )
190- if not path .exists ():
191- raise FastAPICLIException (f"Path does not exist { path } " )
192- mod_data = get_module_data_from_path (path )
193- try :
194- with mod_data .sys_path ():
195- mod = importlib .import_module (mod_data .module_import_str )
196- except (ImportError , ValueError ) as e :
197- logger .error (f"Import error: { e } " )
198- logger .warning (
199- "Ensure all the package directories have an [blue]__init__.py["
200- "/blue] file"
201- )
202- raise
203- if not FastAPI : # type: ignore[truthy-function]
204- raise FastAPICLIException (
205- "Could not import FastAPI, try running 'pip install fastapi'"
206- ) from None
207- object_names = dir (mod )
208- object_names_set = set (object_names )
209- if app_name :
210- if app_name not in object_names_set :
211- raise FastAPICLIException (
212- f"Could not find app name { app_name } in "
213- f"{ mod_data .module_import_str } "
214- )
215- app = getattr (mod , app_name )
216- if not isinstance (app , FastAPI ):
217- raise FastAPICLIException (
218- f"The app name { app_name } in { mod_data .module_import_str } "
219- f"doesn't seem to be a FastAPI app"
220- )
221- return app
222- for preferred_name in ["app" , "api" ]:
223- if preferred_name in object_names_set :
224- obj = getattr (mod , preferred_name )
225- if isinstance (obj , FastAPI ):
226- return obj
227- for name in object_names :
228- obj = getattr (mod , name )
229- if isinstance (obj , FastAPI ):
230- return obj
231- raise FastAPICLIException ("Could not find FastAPI app in module, try using --app" )
195+ mod_data , use_app_name = get_import_string_parts (path = path , app_name = app_name )
196+ with mod_data .sys_path ():
197+ mod = importlib .import_module (mod_data .module_import_str )
198+ app = getattr (mod , use_app_name )
199+ ## get_import_string_parts guarantees app is FastAPI object
200+ return app # type: ignore[no-any-return]
0 commit comments