fastapi-cli 0.0.27__tar.gz → 0.0.29__tar.gz
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- {fastapi_cli-0.0.27 → fastapi_cli-0.0.29}/PKG-INFO +1 -4
- {fastapi_cli-0.0.27 → fastapi_cli-0.0.29}/README.md +0 -3
- {fastapi_cli-0.0.27 → fastapi_cli-0.0.29}/pyproject.toml +6 -2
- fastapi_cli-0.0.29/src/fastapi_cli/__init__.py +1 -0
- {fastapi_cli-0.0.27 → fastapi_cli-0.0.29}/src/fastapi_cli/cli.py +10 -2
- {fastapi_cli-0.0.27 → fastapi_cli-0.0.29}/src/fastapi_cli/utils/cli.py +11 -1
- {fastapi_cli-0.0.27 → fastapi_cli-0.0.29}/tests/test_cli.py +20 -0
- {fastapi_cli-0.0.27 → fastapi_cli-0.0.29}/tests/test_utils_cli.py +17 -2
- fastapi_cli-0.0.27/src/fastapi_cli/__init__.py +0 -1
- {fastapi_cli-0.0.27 → fastapi_cli-0.0.29}/LICENSE +0 -0
- {fastapi_cli-0.0.27 → fastapi_cli-0.0.29}/scripts/add_latest_release_date.py +0 -0
- {fastapi_cli-0.0.27 → fastapi_cli-0.0.29}/scripts/format.sh +0 -0
- {fastapi_cli-0.0.27 → fastapi_cli-0.0.29}/scripts/lint.sh +0 -0
- {fastapi_cli-0.0.27 → fastapi_cli-0.0.29}/scripts/prepare_release.py +0 -0
- {fastapi_cli-0.0.27 → fastapi_cli-0.0.29}/scripts/test-cov-html.sh +0 -0
- {fastapi_cli-0.0.27 → fastapi_cli-0.0.29}/scripts/test.sh +0 -0
- {fastapi_cli-0.0.27 → fastapi_cli-0.0.29}/src/fastapi_cli/__main__.py +0 -0
- {fastapi_cli-0.0.27 → fastapi_cli-0.0.29}/src/fastapi_cli/config.py +0 -0
- {fastapi_cli-0.0.27 → fastapi_cli-0.0.29}/src/fastapi_cli/discover.py +0 -0
- {fastapi_cli-0.0.27 → fastapi_cli-0.0.29}/src/fastapi_cli/exceptions.py +0 -0
- {fastapi_cli-0.0.27 → fastapi_cli-0.0.29}/src/fastapi_cli/logging.py +0 -0
- {fastapi_cli-0.0.27 → fastapi_cli-0.0.29}/src/fastapi_cli/py.typed +0 -0
- {fastapi_cli-0.0.27 → fastapi_cli-0.0.29}/src/fastapi_cli/utils/__init__.py +0 -0
- {fastapi_cli-0.0.27 → fastapi_cli-0.0.29}/tests/__init__.py +0 -0
- {fastapi_cli-0.0.27 → fastapi_cli-0.0.29}/tests/assets/broken_package/mod/__init__.py +0 -0
- {fastapi_cli-0.0.27 → fastapi_cli-0.0.29}/tests/assets/broken_package/mod/app.py +0 -0
- {fastapi_cli-0.0.27 → fastapi_cli-0.0.29}/tests/assets/broken_package/utils.py +0 -0
- {fastapi_cli-0.0.27 → fastapi_cli-0.0.29}/tests/assets/default_files/default_api/api.py +0 -0
- {fastapi_cli-0.0.27 → fastapi_cli-0.0.29}/tests/assets/default_files/default_app/api.py +0 -0
- {fastapi_cli-0.0.27 → fastapi_cli-0.0.29}/tests/assets/default_files/default_app/app.py +0 -0
- {fastapi_cli-0.0.27 → fastapi_cli-0.0.29}/tests/assets/default_files/default_app_dir_api/app/__init__.py +0 -0
- {fastapi_cli-0.0.27 → fastapi_cli-0.0.29}/tests/assets/default_files/default_app_dir_api/app/api.py +0 -0
- {fastapi_cli-0.0.27 → fastapi_cli-0.0.29}/tests/assets/default_files/default_app_dir_app/app/__init__.py +0 -0
- {fastapi_cli-0.0.27 → fastapi_cli-0.0.29}/tests/assets/default_files/default_app_dir_app/app/api.py +0 -0
- {fastapi_cli-0.0.27 → fastapi_cli-0.0.29}/tests/assets/default_files/default_app_dir_app/app/app.py +0 -0
- {fastapi_cli-0.0.27 → fastapi_cli-0.0.29}/tests/assets/default_files/default_app_dir_main/app/__init__.py +0 -0
- {fastapi_cli-0.0.27 → fastapi_cli-0.0.29}/tests/assets/default_files/default_app_dir_main/app/api.py +0 -0
- {fastapi_cli-0.0.27 → fastapi_cli-0.0.29}/tests/assets/default_files/default_app_dir_main/app/app.py +0 -0
- {fastapi_cli-0.0.27 → fastapi_cli-0.0.29}/tests/assets/default_files/default_app_dir_main/app/main.py +0 -0
- {fastapi_cli-0.0.27 → fastapi_cli-0.0.29}/tests/assets/default_files/default_app_dir_non_default/app/__init__.py +0 -0
- {fastapi_cli-0.0.27 → fastapi_cli-0.0.29}/tests/assets/default_files/default_app_dir_non_default/app/nondefault.py +0 -0
- {fastapi_cli-0.0.27 → fastapi_cli-0.0.29}/tests/assets/default_files/default_main/api.py +0 -0
- {fastapi_cli-0.0.27 → fastapi_cli-0.0.29}/tests/assets/default_files/default_main/app.py +0 -0
- {fastapi_cli-0.0.27 → fastapi_cli-0.0.29}/tests/assets/default_files/default_main/main.py +0 -0
- {fastapi_cli-0.0.27 → fastapi_cli-0.0.29}/tests/assets/default_files/non_default/nonstandard.py +0 -0
- {fastapi_cli-0.0.27 → fastapi_cli-0.0.29}/tests/assets/nested_package/__init__.py +0 -0
- {fastapi_cli-0.0.27 → fastapi_cli-0.0.29}/tests/assets/nested_package/package/__init__.py +0 -0
- {fastapi_cli-0.0.27 → fastapi_cli-0.0.29}/tests/assets/nested_package/package/core/__init__.py +0 -0
- {fastapi_cli-0.0.27 → fastapi_cli-0.0.29}/tests/assets/nested_package/package/core/utils.py +0 -0
- {fastapi_cli-0.0.27 → fastapi_cli-0.0.29}/tests/assets/nested_package/package/mod/__init__.py +0 -0
- {fastapi_cli-0.0.27 → fastapi_cli-0.0.29}/tests/assets/nested_package/package/mod/api.py +0 -0
- {fastapi_cli-0.0.27 → fastapi_cli-0.0.29}/tests/assets/nested_package/package/mod/app.py +0 -0
- {fastapi_cli-0.0.27 → fastapi_cli-0.0.29}/tests/assets/nested_package/package/mod/other.py +0 -0
- {fastapi_cli-0.0.27 → fastapi_cli-0.0.29}/tests/assets/package/__init__.py +0 -0
- {fastapi_cli-0.0.27 → fastapi_cli-0.0.29}/tests/assets/package/core/__init__.py +0 -0
- {fastapi_cli-0.0.27 → fastapi_cli-0.0.29}/tests/assets/package/core/utils.py +0 -0
- {fastapi_cli-0.0.27 → fastapi_cli-0.0.29}/tests/assets/package/mod/__init__.py +0 -0
- {fastapi_cli-0.0.27 → fastapi_cli-0.0.29}/tests/assets/package/mod/api.py +0 -0
- {fastapi_cli-0.0.27 → fastapi_cli-0.0.29}/tests/assets/package/mod/app.py +0 -0
- {fastapi_cli-0.0.27 → fastapi_cli-0.0.29}/tests/assets/package/mod/other.py +0 -0
- {fastapi_cli-0.0.27 → fastapi_cli-0.0.29}/tests/assets/pyproject_config/another_module.py +0 -0
- {fastapi_cli-0.0.27 → fastapi_cli-0.0.29}/tests/assets/pyproject_config/my_module.py +0 -0
- {fastapi_cli-0.0.27 → fastapi_cli-0.0.29}/tests/assets/pyproject_config/pyproject.toml +0 -0
- {fastapi_cli-0.0.27 → fastapi_cli-0.0.29}/tests/assets/single_file_api.py +0 -0
- {fastapi_cli-0.0.27 → fastapi_cli-0.0.29}/tests/assets/single_file_app.py +0 -0
- {fastapi_cli-0.0.27 → fastapi_cli-0.0.29}/tests/assets/single_file_other.py +0 -0
- {fastapi_cli-0.0.27 → fastapi_cli-0.0.29}/tests/conftest.py +0 -0
- {fastapi_cli-0.0.27 → fastapi_cli-0.0.29}/tests/test_cli_pyproject.py +0 -0
- {fastapi_cli-0.0.27 → fastapi_cli-0.0.29}/tests/test_discover.py +0 -0
- {fastapi_cli-0.0.27 → fastapi_cli-0.0.29}/tests/test_prepare_release.py +0 -0
- {fastapi_cli-0.0.27 → fastapi_cli-0.0.29}/tests/test_requirements.py +0 -0
- {fastapi_cli-0.0.27 → fastapi_cli-0.0.29}/tests/test_utils_default_dir.py +0 -0
- {fastapi_cli-0.0.27 → fastapi_cli-0.0.29}/tests/test_utils_default_file.py +0 -0
- {fastapi_cli-0.0.27 → fastapi_cli-0.0.29}/tests/test_utils_package.py +0 -0
- {fastapi_cli-0.0.27 → fastapi_cli-0.0.29}/tests/test_utils_single_file.py +0 -0
- {fastapi_cli-0.0.27 → fastapi_cli-0.0.29}/tests/utils.py +0 -0
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: fastapi-cli
|
|
3
|
-
Version: 0.0.
|
|
3
|
+
Version: 0.0.29
|
|
4
4
|
Summary: Run and manage FastAPI apps from the command line with FastAPI CLI. 🚀
|
|
5
5
|
Author-Email: =?utf-8?q?Sebasti=C3=A1n_Ram=C3=ADrez?= <tiangolo@gmail.com>
|
|
6
6
|
License-Expression: MIT
|
|
@@ -48,9 +48,6 @@ Description-Content-Type: text/markdown
|
|
|
48
48
|
<a href="https://github.com/fastapi/fastapi-cli/actions/workflows/test.yml" target="_blank">
|
|
49
49
|
<img src="https://github.com/fastapi/fastapi-cli/actions/workflows/test.yml/badge.svg" alt="Test">
|
|
50
50
|
</a>
|
|
51
|
-
<a href="https://github.com/fastapi/fastapi-cli/actions/workflows/publish.yml" target="_blank">
|
|
52
|
-
<img src="https://github.com/fastapi/fastapi-cli/actions/workflows/publish.yml/badge.svg" alt="Publish">
|
|
53
|
-
</a>
|
|
54
51
|
<a href="https://coverage-badge.samuelcolvin.workers.dev/redirect/fastapi/fastapi-cli" target="_blank">
|
|
55
52
|
<img src="https://coverage-badge.samuelcolvin.workers.dev/fastapi/fastapi-cli.svg" alt="Coverage">
|
|
56
53
|
<a href="https://pypi.org/project/fastapi-cli" target="_blank">
|
|
@@ -3,9 +3,6 @@
|
|
|
3
3
|
<a href="https://github.com/fastapi/fastapi-cli/actions/workflows/test.yml" target="_blank">
|
|
4
4
|
<img src="https://github.com/fastapi/fastapi-cli/actions/workflows/test.yml/badge.svg" alt="Test">
|
|
5
5
|
</a>
|
|
6
|
-
<a href="https://github.com/fastapi/fastapi-cli/actions/workflows/publish.yml" target="_blank">
|
|
7
|
-
<img src="https://github.com/fastapi/fastapi-cli/actions/workflows/publish.yml/badge.svg" alt="Publish">
|
|
8
|
-
</a>
|
|
9
6
|
<a href="https://coverage-badge.samuelcolvin.workers.dev/redirect/fastapi/fastapi-cli" target="_blank">
|
|
10
7
|
<img src="https://coverage-badge.samuelcolvin.workers.dev/fastapi/fastapi-cli.svg" alt="Coverage">
|
|
11
8
|
<a href="https://pypi.org/project/fastapi-cli" target="_blank">
|
|
@@ -38,7 +38,7 @@ dependencies = [
|
|
|
38
38
|
"rich-toolkit >= 0.14.8",
|
|
39
39
|
"tomli >= 2.0.0; python_version < '3.11'",
|
|
40
40
|
]
|
|
41
|
-
version = "0.0.
|
|
41
|
+
version = "0.0.29"
|
|
42
42
|
|
|
43
43
|
[project.optional-dependencies]
|
|
44
44
|
standard = [
|
|
@@ -171,10 +171,14 @@ error-on-warning = true
|
|
|
171
171
|
extend-exclude = [
|
|
172
172
|
"coverage/",
|
|
173
173
|
"dist/",
|
|
174
|
-
"release-notes.md",
|
|
175
174
|
"htmlcov/",
|
|
176
175
|
"uv.lock",
|
|
177
176
|
]
|
|
178
177
|
|
|
178
|
+
[tool.typos.default]
|
|
179
|
+
extend-ignore-re = [
|
|
180
|
+
"@[a-zA-Z0-9](?:-?[a-zA-Z0-9])*",
|
|
181
|
+
]
|
|
182
|
+
|
|
179
183
|
[tool.typos.default.extend-identifiers]
|
|
180
184
|
alls = "alls"
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
__version__ = "0.0.29"
|
|
@@ -20,7 +20,11 @@ from fastapi_cli.exceptions import FastAPICLIException
|
|
|
20
20
|
|
|
21
21
|
from . import __version__
|
|
22
22
|
from .logging import setup_logging
|
|
23
|
-
from .utils.cli import
|
|
23
|
+
from .utils.cli import (
|
|
24
|
+
get_rich_toolkit,
|
|
25
|
+
get_uvicorn_log_config,
|
|
26
|
+
should_use_rich_logs,
|
|
27
|
+
)
|
|
24
28
|
|
|
25
29
|
app = typer.Typer(
|
|
26
30
|
rich_markup_mode="rich", context_settings={"help_option_names": ["-h", "--help"]}
|
|
@@ -271,6 +275,10 @@ def _run(
|
|
|
271
275
|
toolkit.print("Logs:")
|
|
272
276
|
toolkit.print_line()
|
|
273
277
|
|
|
278
|
+
extra_uvicorn_kwargs: dict[str, Any] = (
|
|
279
|
+
{"log_config": get_uvicorn_log_config()} if should_use_rich_logs() else {}
|
|
280
|
+
)
|
|
281
|
+
|
|
274
282
|
uvicorn.run(
|
|
275
283
|
app=import_string,
|
|
276
284
|
host=host,
|
|
@@ -285,7 +293,7 @@ def _run(
|
|
|
285
293
|
root_path=root_path,
|
|
286
294
|
proxy_headers=proxy_headers,
|
|
287
295
|
forwarded_allow_ips=forwarded_allow_ips,
|
|
288
|
-
|
|
296
|
+
**extra_uvicorn_kwargs,
|
|
289
297
|
)
|
|
290
298
|
|
|
291
299
|
|
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import logging
|
|
2
|
+
import sys
|
|
2
3
|
from typing import Any
|
|
3
4
|
|
|
4
5
|
from rich_toolkit import RichToolkit, RichToolkitTheme
|
|
@@ -20,6 +21,11 @@ class CustomFormatter(DefaultFormatter):
|
|
|
20
21
|
return result
|
|
21
22
|
|
|
22
23
|
|
|
24
|
+
def should_use_rich_logs() -> bool:
|
|
25
|
+
"""Return True when stdout is a TTY and rich logs should be used, False otherwise."""
|
|
26
|
+
return sys.stdout.isatty()
|
|
27
|
+
|
|
28
|
+
|
|
23
29
|
def get_uvicorn_log_config() -> dict[str, Any]:
|
|
24
30
|
return {
|
|
25
31
|
"version": 1,
|
|
@@ -48,7 +54,11 @@ def get_uvicorn_log_config() -> dict[str, Any]:
|
|
|
48
54
|
},
|
|
49
55
|
},
|
|
50
56
|
"loggers": {
|
|
51
|
-
"uvicorn": {
|
|
57
|
+
"uvicorn": {
|
|
58
|
+
"handlers": ["default"],
|
|
59
|
+
"level": "INFO",
|
|
60
|
+
"propagate": False,
|
|
61
|
+
},
|
|
52
62
|
"uvicorn.error": {"level": "INFO"},
|
|
53
63
|
"uvicorn.access": {
|
|
54
64
|
"handlers": ["access"],
|
|
@@ -16,6 +16,11 @@ runner = CliRunner()
|
|
|
16
16
|
assets_path = Path(__file__).parent / "assets"
|
|
17
17
|
|
|
18
18
|
|
|
19
|
+
@pytest.fixture(autouse=True)
|
|
20
|
+
def force_rich_logs(monkeypatch: pytest.MonkeyPatch) -> None:
|
|
21
|
+
monkeypatch.setattr("fastapi_cli.cli.should_use_rich_logs", lambda: True)
|
|
22
|
+
|
|
23
|
+
|
|
19
24
|
def test_dev() -> None:
|
|
20
25
|
with changing_dir(assets_path):
|
|
21
26
|
with patch.object(uvicorn, "run") as mock_run:
|
|
@@ -51,6 +56,21 @@ def test_dev() -> None:
|
|
|
51
56
|
assert "🐍 single_file_app.py" in result.output
|
|
52
57
|
|
|
53
58
|
|
|
59
|
+
def test_run_uses_uvicorn_default_log_config_without_rich_logs(
|
|
60
|
+
monkeypatch: pytest.MonkeyPatch,
|
|
61
|
+
) -> None:
|
|
62
|
+
monkeypatch.setattr("fastapi_cli.cli.should_use_rich_logs", lambda: False)
|
|
63
|
+
|
|
64
|
+
with changing_dir(assets_path):
|
|
65
|
+
with patch.object(uvicorn, "run") as mock_run:
|
|
66
|
+
result = runner.invoke(app, ["run", "single_file_app.py"])
|
|
67
|
+
assert result.exit_code == 0, result.output
|
|
68
|
+
assert mock_run.called
|
|
69
|
+
assert mock_run.call_args
|
|
70
|
+
|
|
71
|
+
assert "log_config" not in mock_run.call_args.kwargs
|
|
72
|
+
|
|
73
|
+
|
|
54
74
|
def test_dev_no_args_auto_discovery() -> None:
|
|
55
75
|
"""Test that auto-discovery works when no args and no pyproject.toml entrypoint"""
|
|
56
76
|
with changing_dir(assets_path / "default_files" / "default_main"):
|
|
@@ -1,9 +1,15 @@
|
|
|
1
|
+
import io
|
|
1
2
|
import logging
|
|
3
|
+
import sys
|
|
2
4
|
from logging.config import dictConfig
|
|
3
5
|
|
|
4
|
-
from pytest import LogCaptureFixture
|
|
6
|
+
from pytest import LogCaptureFixture, MonkeyPatch
|
|
5
7
|
|
|
6
|
-
from fastapi_cli.utils.cli import
|
|
8
|
+
from fastapi_cli.utils.cli import (
|
|
9
|
+
CustomFormatter,
|
|
10
|
+
get_uvicorn_log_config,
|
|
11
|
+
should_use_rich_logs,
|
|
12
|
+
)
|
|
7
13
|
|
|
8
14
|
|
|
9
15
|
def test_get_uvicorn_config_uses_custom_formatter() -> None:
|
|
@@ -11,6 +17,15 @@ def test_get_uvicorn_config_uses_custom_formatter() -> None:
|
|
|
11
17
|
|
|
12
18
|
assert config["formatters"]["default"]["()"] is CustomFormatter
|
|
13
19
|
assert config["formatters"]["access"]["()"] is CustomFormatter
|
|
20
|
+
assert config["loggers"]["uvicorn"]["propagate"] is False
|
|
21
|
+
|
|
22
|
+
|
|
23
|
+
def test_should_use_rich_logs_is_false_without_tty(
|
|
24
|
+
monkeypatch: MonkeyPatch,
|
|
25
|
+
) -> None:
|
|
26
|
+
monkeypatch.setattr(sys, "stdout", io.StringIO())
|
|
27
|
+
|
|
28
|
+
assert should_use_rich_logs() is False
|
|
14
29
|
|
|
15
30
|
|
|
16
31
|
def test_custom_formatter() -> None:
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
__version__ = "0.0.27"
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{fastapi_cli-0.0.27 → fastapi_cli-0.0.29}/tests/assets/default_files/default_app_dir_api/app/api.py
RENAMED
|
File without changes
|
|
File without changes
|
{fastapi_cli-0.0.27 → fastapi_cli-0.0.29}/tests/assets/default_files/default_app_dir_app/app/api.py
RENAMED
|
File without changes
|
{fastapi_cli-0.0.27 → fastapi_cli-0.0.29}/tests/assets/default_files/default_app_dir_app/app/app.py
RENAMED
|
File without changes
|
|
File without changes
|
{fastapi_cli-0.0.27 → fastapi_cli-0.0.29}/tests/assets/default_files/default_app_dir_main/app/api.py
RENAMED
|
File without changes
|
{fastapi_cli-0.0.27 → fastapi_cli-0.0.29}/tests/assets/default_files/default_app_dir_main/app/app.py
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{fastapi_cli-0.0.27 → fastapi_cli-0.0.29}/tests/assets/default_files/non_default/nonstandard.py
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
{fastapi_cli-0.0.27 → fastapi_cli-0.0.29}/tests/assets/nested_package/package/core/__init__.py
RENAMED
|
File without changes
|
|
File without changes
|
{fastapi_cli-0.0.27 → fastapi_cli-0.0.29}/tests/assets/nested_package/package/mod/__init__.py
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|