Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
19 changes: 9 additions & 10 deletions src/fastapi_cli/discover.py
Original file line number Diff line number Diff line change
Expand Up @@ -77,25 +77,24 @@ def get_app_name(*, mod_data: ModuleData, app_name: str | None = None) -> str:
raise FastAPICLIException(
"Could not import FastAPI, try running 'pip install fastapi'"
) from None
object_names = dir(mod)
object_names_set = set(object_names)
if app_name:
if app_name not in object_names_set:
app = getattr(mod, app_name, None)
if app is None:
raise FastAPICLIException(
f"Could not find app name {app_name} in {mod_data.module_import_str}"
)
app = getattr(mod, app_name)
if not isinstance(app, FastAPI):
raise FastAPICLIException(
f"The app name {app_name} in {mod_data.module_import_str} doesn't seem to be a FastAPI app"
)
return app_name
for preferred_name in ["app", "api"]:
if preferred_name in object_names_set:
obj = getattr(mod, preferred_name)
if isinstance(obj, FastAPI):
return preferred_name
for name in object_names:
for preferred_name in ("app", "api"):
obj = getattr(mod, preferred_name, None)
if isinstance(obj, FastAPI):
return preferred_name
for name in dir(mod):
if name in ("app", "api"):
continue
obj = getattr(mod, name)
if isinstance(obj, FastAPI):
return name
Expand Down
11 changes: 11 additions & 0 deletions tests/assets/single_file_non_app.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
from fastapi import FastAPI

app = "not a FastAPI instance"
api = 42

my_app = FastAPI()


@my_app.get("/")
def my_app_root():
return {"message": "my_app"}
11 changes: 11 additions & 0 deletions tests/test_utils_single_file.py
Original file line number Diff line number Diff line change
Expand Up @@ -53,6 +53,17 @@ def test_single_file_explicit_object(capsys: CaptureFixture[str]) -> None:
assert import_data.module_data.module_import_str == "single_file_app"


def test_single_file_non_fastapi_app_and_api(capsys: CaptureFixture[str]) -> None:
"""Fallback walks past non-FastAPI `app`/`api` names to find the real app."""
with changing_dir(assets_path):
import_data = get_import_data(path=Path("single_file_non_app.py"))

assert import_data.import_string == "single_file_non_app:my_app"

assert import_data.module_data.extra_sys_path == assets_path
assert import_data.module_data.module_import_str == "single_file_non_app"


def test_single_non_existing_file() -> None:
with changing_dir(assets_path):
with pytest.raises(FastAPICLIException) as e:
Expand Down
Loading