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
36 changes: 29 additions & 7 deletions src/fastapi_cli/cli.py
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
import logging
import sys
from pathlib import Path
from typing import Any, List, Union

Expand Down Expand Up @@ -70,21 +71,37 @@ def callback(

def _get_module_tree(module_paths: List[Path]) -> Tree:
root = module_paths[0]
name = f"🐍 {root.name}" if root.is_file() else f"📁 {root.name}"
if sys.platform == "win32":
name = f"Python {root.name}" if root.is_file() else f"Folder {root.name}"
else:
name = f"🐍 {root.name}" if root.is_file() else f"📁 {root.name}"

root_tree = Tree(name)

if root.is_dir():
root_tree.add("[dim]🐍 __init__.py[/dim]")
if sys.platform == "win32":
root_tree.add("[dim]Python __init__.py[/dim]")
else:
root_tree.add("[dim]🐍 __init__.py[/dim]")

tree = root_tree
for sub_path in module_paths[1:]:
sub_name = (
f"🐍 {sub_path.name}" if sub_path.is_file() else f"📁 {sub_path.name}"
)
if sys.platform == "win32":
sub_name = (
f"Python {sub_path.name}"
if sub_path.is_file()
else f"Folder {sub_path.name}"
)
else:
sub_name = (
f"🐍 {sub_path.name}" if sub_path.is_file() else f"📁 {sub_path.name}"
)
tree = tree.add(sub_name)
if sub_path.is_dir():
tree.add("[dim]🐍 __init__.py[/dim]")
if sys.platform == "win32":
tree.add("[dim]Python __init__.py[/dim]")
else:
tree.add("[dim]🐍 __init__.py[/dim]")

return root_tree

Expand All @@ -106,7 +123,12 @@ def _run(
with get_rich_toolkit() as toolkit:
server_type = "development" if command == "dev" else "production"

toolkit.print_title(f"Starting {server_type} server 🚀", tag="FastAPI")
if sys.platform == "win32":
title = f"Starting {server_type} server"
else:
title = f"Starting {server_type} server 🚀"

toolkit.print_title(title, tag="FastAPI")
toolkit.print_line()

toolkit.print(
Expand Down
6 changes: 5 additions & 1 deletion src/fastapi_cli/logging.py
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
import logging
import sys
from typing import Union

from rich.console import Console
Expand All @@ -9,7 +10,10 @@ def setup_logging(
terminal_width: Union[int, None] = None, level: int = logging.INFO
) -> None:
logger = logging.getLogger("fastapi_cli")
console = Console(width=terminal_width) if terminal_width else None
if sys.platform == "win32":
console = Console(width=terminal_width or 80, emoji=False, legacy_windows=True)
else:
console = Console(width=terminal_width or 80)
rich_handler = RichHandler(
show_time=False,
rich_tracebacks=True,
Expand Down
69 changes: 54 additions & 15 deletions tests/test_cli.py
Original file line number Diff line number Diff line change
Expand Up @@ -34,15 +34,21 @@ def test_dev() -> None:
"log_config": get_uvicorn_log_config(),
}
assert "Using import string: single_file_app:app" in result.output
assert "Starting development server 🚀" in result.output
if sys.platform == "win32":
assert "Starting development server" in result.output
else:
assert "Starting development server 🚀" in result.output
assert "Server started at http://127.0.0.1:8000" in result.output
assert "Documentation at http://127.0.0.1:8000/docs" in result.output
assert (
"Running in development mode, for production use: fastapi run"
in result.output
)

assert "🐍 single_file_app.py" in result.output
if sys.platform == "win32":
assert "Python single_file_app.py" in result.output
else:
assert "🐍 single_file_app.py" in result.output


def test_dev_no_args_auto_discovery() -> None:
Expand Down Expand Up @@ -79,18 +85,27 @@ def test_dev_package() -> None:
"log_config": get_uvicorn_log_config(),
}
assert "Using import string: nested_package.package:app" in result.output
assert "Starting development server 🚀" in result.output
if sys.platform == "win32":
assert "Starting development server" in result.output
else:
assert "Starting development server 🚀" in result.output
assert "Server started at http://127.0.0.1:8000" in result.output
assert "Documentation at http://127.0.0.1:8000/docs" in result.output
assert (
"Running in development mode, for production use: fastapi run"
in result.output
)

assert "📁 package" in result.output
assert "└── 🐍 __init__.py" in result.output
assert "└── 📁 package" in result.output
assert " └── 🐍 __init__.py" in result.output
if sys.platform == "win32":
assert "Folder package" in result.output
assert "└── Python __init__.py" in result.output
assert "└── Folder package" in result.output
assert " └── Python __init__.py" in result.output
else:
assert "📁 package" in result.output
assert "└── 🐍 __init__.py" in result.output
assert "└── 📁 package" in result.output
assert " └── 🐍 __init__.py" in result.output


def test_dev_args() -> None:
Expand Down Expand Up @@ -128,7 +143,10 @@ def test_dev_args() -> None:
"log_config": get_uvicorn_log_config(),
}
assert "Using import string: single_file_app:api" in result.output
assert "Starting development server 🚀" in result.output
if sys.platform == "win32":
assert "Starting development server" in result.output
else:
assert "Starting development server 🚀" in result.output
assert "Server started at http://192.168.0.2:8080" in result.output
assert "Documentation at http://192.168.0.2:8080/docs" in result.output
assert (
Expand Down Expand Up @@ -158,7 +176,10 @@ def test_dev_env_vars() -> None:
"log_config": get_uvicorn_log_config(),
}
assert "Using import string: single_file_app:app" in result.output
assert "Starting development server 🚀" in result.output
if sys.platform == "win32":
assert "Starting development server" in result.output
else:
assert "Starting development server 🚀" in result.output
assert "Server started at http://127.0.0.1:8111" in result.output
assert "Documentation at http://127.0.0.1:8111/docs" in result.output
assert (
Expand Down Expand Up @@ -195,7 +216,10 @@ def test_dev_env_vars_and_args() -> None:
"log_config": get_uvicorn_log_config(),
}
assert "Using import string: single_file_app:app" in result.output
assert "Starting development server 🚀" in result.output
if sys.platform == "win32":
assert "Starting development server" in result.output
else:
assert "Starting development server 🚀" in result.output
assert "Server started at http://127.0.0.1:8080" in result.output
assert "Documentation at http://127.0.0.1:8080/docs" in result.output
assert (
Expand Down Expand Up @@ -240,7 +264,10 @@ def test_run() -> None:
"log_config": get_uvicorn_log_config(),
}
assert "Using import string: single_file_app:app" in result.output
assert "Starting production server 🚀" in result.output
if sys.platform == "win32":
assert "Starting production server" in result.output
else:
assert "Starting production server 🚀" in result.output
assert "Server started at http://0.0.0.0:8000" in result.output
assert "Documentation at http://0.0.0.0:8000/docs" in result.output

Expand All @@ -266,7 +293,10 @@ def test_run_trust_proxy() -> None:
"log_config": get_uvicorn_log_config(),
}
assert "Using import string: single_file_app:app" in result.output
assert "Starting production server 🚀" in result.output
if sys.platform == "win32":
assert "Starting production server" in result.output
else:
assert "Starting production server 🚀" in result.output
assert "Server started at http://0.0.0.0:8000" in result.output
assert "Documentation at http://0.0.0.0:8000/docs" in result.output
assert (
Expand Down Expand Up @@ -313,7 +343,10 @@ def test_run_args() -> None:
}

assert "Using import string: single_file_app:api" in result.output
assert "Starting production server 🚀" in result.output
if sys.platform == "win32":
assert "Starting production server" in result.output
else:
assert "Starting production server 🚀" in result.output
assert "Server started at http://192.168.0.2:8080" in result.output
assert "Documentation at http://192.168.0.2:8080/docs" in result.output
assert (
Expand Down Expand Up @@ -343,7 +376,10 @@ def test_run_env_vars() -> None:
"log_config": get_uvicorn_log_config(),
}
assert "Using import string: single_file_app:app" in result.output
assert "Starting production server 🚀" in result.output
if sys.platform == "win32":
assert "Starting production server" in result.output
else:
assert "Starting production server 🚀" in result.output
assert "Server started at http://0.0.0.0:8111" in result.output
assert "Documentation at http://0.0.0.0:8111/docs" in result.output

Expand Down Expand Up @@ -376,7 +412,10 @@ def test_run_env_vars_and_args() -> None:
"log_config": get_uvicorn_log_config(),
}
assert "Using import string: single_file_app:app" in result.output
assert "Starting production server 🚀" in result.output
if sys.platform == "win32":
assert "Starting production server" in result.output
else:
assert "Starting production server 🚀" in result.output
assert "Server started at http://0.0.0.0:8080" in result.output
assert "Documentation at http://0.0.0.0:8080/docs" in result.output

Expand Down
Loading