4
4
from dataclasses import dataclass
5
5
from logging import getLogger
6
6
from pathlib import Path
7
- from typing import Iterator , Union
7
+ from typing import Iterator , Tuple , Union
8
8
9
9
from rich import print
10
10
from rich .padding import Padding
@@ -149,9 +149,9 @@ def get_app_name(*, mod_data: ModuleData, app_name: Union[str, None] = None) ->
149
149
raise FastAPICLIException ("Could not find FastAPI app in module, try using --app" )
150
150
151
151
152
- def get_import_string (
152
+ def get_import_string_parts (
153
153
* , path : Union [Path , None ] = None , app_name : Union [str , None ] = None
154
- ) -> str :
154
+ ) -> Tuple [ ModuleData , str ] :
155
155
if not path :
156
156
path = get_default_path ()
157
157
logger .info (f"Using path [blue]{ path } [/blue]" )
@@ -161,6 +161,15 @@ def get_import_string(
161
161
mod_data = get_module_data_from_path (path )
162
162
sys .path .insert (0 , str (mod_data .extra_sys_path ))
163
163
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 } "
164
173
import_example = Syntax (
165
174
f"from { mod_data .module_import_str } import { use_app_name } " , "python"
166
175
)
@@ -175,57 +184,17 @@ def get_import_string(
175
184
)
176
185
logger .info ("Found importable FastAPI app" )
177
186
print (import_panel )
178
- import_string = f" { mod_data . module_import_str } : { use_app_name } "
187
+
179
188
logger .info (f"Using import string [b green]{ import_string } [/b green]" )
180
189
return import_string
181
190
182
191
183
192
def get_app (
184
193
* , path : Union [Path , None ] = None , app_name : Union [str , None ] = None
185
194
) -> 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