fastapi-cli 0.0.26__tar.gz → 0.0.28__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.26 → fastapi_cli-0.0.28}/PKG-INFO +1 -4
- {fastapi_cli-0.0.26 → fastapi_cli-0.0.28}/README.md +0 -3
- {fastapi_cli-0.0.26 → fastapi_cli-0.0.28}/pyproject.toml +6 -2
- fastapi_cli-0.0.28/src/fastapi_cli/__init__.py +1 -0
- {fastapi_cli-0.0.26 → fastapi_cli-0.0.28}/src/fastapi_cli/cli.py +5 -1
- {fastapi_cli-0.0.26 → fastapi_cli-0.0.28}/src/fastapi_cli/utils/cli.py +5 -1
- {fastapi_cli-0.0.26 → fastapi_cli-0.0.28}/tests/test_cli.py +49 -0
- {fastapi_cli-0.0.26 → fastapi_cli-0.0.28}/tests/test_utils_cli.py +1 -0
- fastapi_cli-0.0.26/src/fastapi_cli/__init__.py +0 -1
- {fastapi_cli-0.0.26 → fastapi_cli-0.0.28}/LICENSE +0 -0
- {fastapi_cli-0.0.26 → fastapi_cli-0.0.28}/scripts/add_latest_release_date.py +0 -0
- {fastapi_cli-0.0.26 → fastapi_cli-0.0.28}/scripts/format.sh +0 -0
- {fastapi_cli-0.0.26 → fastapi_cli-0.0.28}/scripts/lint.sh +0 -0
- {fastapi_cli-0.0.26 → fastapi_cli-0.0.28}/scripts/prepare_release.py +0 -0
- {fastapi_cli-0.0.26 → fastapi_cli-0.0.28}/scripts/test-cov-html.sh +0 -0
- {fastapi_cli-0.0.26 → fastapi_cli-0.0.28}/scripts/test.sh +0 -0
- {fastapi_cli-0.0.26 → fastapi_cli-0.0.28}/src/fastapi_cli/__main__.py +0 -0
- {fastapi_cli-0.0.26 → fastapi_cli-0.0.28}/src/fastapi_cli/config.py +0 -0
- {fastapi_cli-0.0.26 → fastapi_cli-0.0.28}/src/fastapi_cli/discover.py +0 -0
- {fastapi_cli-0.0.26 → fastapi_cli-0.0.28}/src/fastapi_cli/exceptions.py +0 -0
- {fastapi_cli-0.0.26 → fastapi_cli-0.0.28}/src/fastapi_cli/logging.py +0 -0
- {fastapi_cli-0.0.26 → fastapi_cli-0.0.28}/src/fastapi_cli/py.typed +0 -0
- {fastapi_cli-0.0.26 → fastapi_cli-0.0.28}/src/fastapi_cli/utils/__init__.py +0 -0
- {fastapi_cli-0.0.26 → fastapi_cli-0.0.28}/tests/__init__.py +0 -0
- {fastapi_cli-0.0.26 → fastapi_cli-0.0.28}/tests/assets/broken_package/mod/__init__.py +0 -0
- {fastapi_cli-0.0.26 → fastapi_cli-0.0.28}/tests/assets/broken_package/mod/app.py +0 -0
- {fastapi_cli-0.0.26 → fastapi_cli-0.0.28}/tests/assets/broken_package/utils.py +0 -0
- {fastapi_cli-0.0.26 → fastapi_cli-0.0.28}/tests/assets/default_files/default_api/api.py +0 -0
- {fastapi_cli-0.0.26 → fastapi_cli-0.0.28}/tests/assets/default_files/default_app/api.py +0 -0
- {fastapi_cli-0.0.26 → fastapi_cli-0.0.28}/tests/assets/default_files/default_app/app.py +0 -0
- {fastapi_cli-0.0.26 → fastapi_cli-0.0.28}/tests/assets/default_files/default_app_dir_api/app/__init__.py +0 -0
- {fastapi_cli-0.0.26 → fastapi_cli-0.0.28}/tests/assets/default_files/default_app_dir_api/app/api.py +0 -0
- {fastapi_cli-0.0.26 → fastapi_cli-0.0.28}/tests/assets/default_files/default_app_dir_app/app/__init__.py +0 -0
- {fastapi_cli-0.0.26 → fastapi_cli-0.0.28}/tests/assets/default_files/default_app_dir_app/app/api.py +0 -0
- {fastapi_cli-0.0.26 → fastapi_cli-0.0.28}/tests/assets/default_files/default_app_dir_app/app/app.py +0 -0
- {fastapi_cli-0.0.26 → fastapi_cli-0.0.28}/tests/assets/default_files/default_app_dir_main/app/__init__.py +0 -0
- {fastapi_cli-0.0.26 → fastapi_cli-0.0.28}/tests/assets/default_files/default_app_dir_main/app/api.py +0 -0
- {fastapi_cli-0.0.26 → fastapi_cli-0.0.28}/tests/assets/default_files/default_app_dir_main/app/app.py +0 -0
- {fastapi_cli-0.0.26 → fastapi_cli-0.0.28}/tests/assets/default_files/default_app_dir_main/app/main.py +0 -0
- {fastapi_cli-0.0.26 → fastapi_cli-0.0.28}/tests/assets/default_files/default_app_dir_non_default/app/__init__.py +0 -0
- {fastapi_cli-0.0.26 → fastapi_cli-0.0.28}/tests/assets/default_files/default_app_dir_non_default/app/nondefault.py +0 -0
- {fastapi_cli-0.0.26 → fastapi_cli-0.0.28}/tests/assets/default_files/default_main/api.py +0 -0
- {fastapi_cli-0.0.26 → fastapi_cli-0.0.28}/tests/assets/default_files/default_main/app.py +0 -0
- {fastapi_cli-0.0.26 → fastapi_cli-0.0.28}/tests/assets/default_files/default_main/main.py +0 -0
- {fastapi_cli-0.0.26 → fastapi_cli-0.0.28}/tests/assets/default_files/non_default/nonstandard.py +0 -0
- {fastapi_cli-0.0.26 → fastapi_cli-0.0.28}/tests/assets/nested_package/__init__.py +0 -0
- {fastapi_cli-0.0.26 → fastapi_cli-0.0.28}/tests/assets/nested_package/package/__init__.py +0 -0
- {fastapi_cli-0.0.26 → fastapi_cli-0.0.28}/tests/assets/nested_package/package/core/__init__.py +0 -0
- {fastapi_cli-0.0.26 → fastapi_cli-0.0.28}/tests/assets/nested_package/package/core/utils.py +0 -0
- {fastapi_cli-0.0.26 → fastapi_cli-0.0.28}/tests/assets/nested_package/package/mod/__init__.py +0 -0
- {fastapi_cli-0.0.26 → fastapi_cli-0.0.28}/tests/assets/nested_package/package/mod/api.py +0 -0
- {fastapi_cli-0.0.26 → fastapi_cli-0.0.28}/tests/assets/nested_package/package/mod/app.py +0 -0
- {fastapi_cli-0.0.26 → fastapi_cli-0.0.28}/tests/assets/nested_package/package/mod/other.py +0 -0
- {fastapi_cli-0.0.26 → fastapi_cli-0.0.28}/tests/assets/package/__init__.py +0 -0
- {fastapi_cli-0.0.26 → fastapi_cli-0.0.28}/tests/assets/package/core/__init__.py +0 -0
- {fastapi_cli-0.0.26 → fastapi_cli-0.0.28}/tests/assets/package/core/utils.py +0 -0
- {fastapi_cli-0.0.26 → fastapi_cli-0.0.28}/tests/assets/package/mod/__init__.py +0 -0
- {fastapi_cli-0.0.26 → fastapi_cli-0.0.28}/tests/assets/package/mod/api.py +0 -0
- {fastapi_cli-0.0.26 → fastapi_cli-0.0.28}/tests/assets/package/mod/app.py +0 -0
- {fastapi_cli-0.0.26 → fastapi_cli-0.0.28}/tests/assets/package/mod/other.py +0 -0
- {fastapi_cli-0.0.26 → fastapi_cli-0.0.28}/tests/assets/pyproject_config/another_module.py +0 -0
- {fastapi_cli-0.0.26 → fastapi_cli-0.0.28}/tests/assets/pyproject_config/my_module.py +0 -0
- {fastapi_cli-0.0.26 → fastapi_cli-0.0.28}/tests/assets/pyproject_config/pyproject.toml +0 -0
- {fastapi_cli-0.0.26 → fastapi_cli-0.0.28}/tests/assets/single_file_api.py +0 -0
- {fastapi_cli-0.0.26 → fastapi_cli-0.0.28}/tests/assets/single_file_app.py +0 -0
- {fastapi_cli-0.0.26 → fastapi_cli-0.0.28}/tests/assets/single_file_other.py +0 -0
- {fastapi_cli-0.0.26 → fastapi_cli-0.0.28}/tests/conftest.py +0 -0
- {fastapi_cli-0.0.26 → fastapi_cli-0.0.28}/tests/test_cli_pyproject.py +0 -0
- {fastapi_cli-0.0.26 → fastapi_cli-0.0.28}/tests/test_discover.py +0 -0
- {fastapi_cli-0.0.26 → fastapi_cli-0.0.28}/tests/test_prepare_release.py +0 -0
- {fastapi_cli-0.0.26 → fastapi_cli-0.0.28}/tests/test_requirements.py +0 -0
- {fastapi_cli-0.0.26 → fastapi_cli-0.0.28}/tests/test_utils_default_dir.py +0 -0
- {fastapi_cli-0.0.26 → fastapi_cli-0.0.28}/tests/test_utils_default_file.py +0 -0
- {fastapi_cli-0.0.26 → fastapi_cli-0.0.28}/tests/test_utils_package.py +0 -0
- {fastapi_cli-0.0.26 → fastapi_cli-0.0.28}/tests/test_utils_single_file.py +0 -0
- {fastapi_cli-0.0.26 → fastapi_cli-0.0.28}/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.28
|
|
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.28"
|
|
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.28"
|
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import logging
|
|
2
|
+
import os
|
|
2
3
|
from pathlib import Path
|
|
3
4
|
from typing import Annotated, Any
|
|
4
5
|
|
|
@@ -136,6 +137,7 @@ def _run(
|
|
|
136
137
|
entrypoint: str | None = None,
|
|
137
138
|
proxy_headers: bool = False,
|
|
138
139
|
forwarded_allow_ips: str | None = None,
|
|
140
|
+
public_url: str | None = None,
|
|
139
141
|
) -> None:
|
|
140
142
|
with get_rich_toolkit() as toolkit:
|
|
141
143
|
server_type = "development" if command == "dev" else "production"
|
|
@@ -243,7 +245,7 @@ def _run(
|
|
|
243
245
|
)
|
|
244
246
|
)
|
|
245
247
|
|
|
246
|
-
url = f"http://{host}:{port}"
|
|
248
|
+
url = public_url.rstrip("/") if public_url else f"http://{host}:{port}"
|
|
247
249
|
url_docs = f"{url}/docs"
|
|
248
250
|
|
|
249
251
|
toolkit.print_line()
|
|
@@ -391,6 +393,7 @@ def dev(
|
|
|
391
393
|
command="dev",
|
|
392
394
|
proxy_headers=proxy_headers,
|
|
393
395
|
forwarded_allow_ips=forwarded_allow_ips,
|
|
396
|
+
public_url=os.getenv("FASTAPI_PUBLIC_URL"),
|
|
394
397
|
)
|
|
395
398
|
|
|
396
399
|
|
|
@@ -498,6 +501,7 @@ def run(
|
|
|
498
501
|
command="run",
|
|
499
502
|
proxy_headers=proxy_headers,
|
|
500
503
|
forwarded_allow_ips=forwarded_allow_ips,
|
|
504
|
+
public_url=os.getenv("FASTAPI_PUBLIC_URL"),
|
|
501
505
|
)
|
|
502
506
|
|
|
503
507
|
|
|
@@ -48,7 +48,11 @@ def get_uvicorn_log_config() -> dict[str, Any]:
|
|
|
48
48
|
},
|
|
49
49
|
},
|
|
50
50
|
"loggers": {
|
|
51
|
-
"uvicorn": {
|
|
51
|
+
"uvicorn": {
|
|
52
|
+
"handlers": ["default"],
|
|
53
|
+
"level": "INFO",
|
|
54
|
+
"propagate": False,
|
|
55
|
+
},
|
|
52
56
|
"uvicorn.error": {"level": "INFO"},
|
|
53
57
|
"uvicorn.access": {
|
|
54
58
|
"handlers": ["access"],
|
|
@@ -3,6 +3,7 @@ import sys
|
|
|
3
3
|
from pathlib import Path
|
|
4
4
|
from unittest.mock import patch
|
|
5
5
|
|
|
6
|
+
import pytest
|
|
6
7
|
import uvicorn
|
|
7
8
|
from typer.testing import CliRunner
|
|
8
9
|
|
|
@@ -424,6 +425,54 @@ def test_run_env_vars_and_args() -> None:
|
|
|
424
425
|
assert "Documentation at http://0.0.0.0:8080/docs" in result.output
|
|
425
426
|
|
|
426
427
|
|
|
428
|
+
@pytest.mark.parametrize("command", ["dev", "run"])
|
|
429
|
+
@pytest.mark.parametrize(
|
|
430
|
+
"public_url",
|
|
431
|
+
[
|
|
432
|
+
"https://myapp.example.com",
|
|
433
|
+
"https://myapp.example.com/",
|
|
434
|
+
"https://myapp.example.com/subpath/",
|
|
435
|
+
],
|
|
436
|
+
)
|
|
437
|
+
def test_public_url_env_var(command: str, public_url: str) -> None:
|
|
438
|
+
with changing_dir(assets_path):
|
|
439
|
+
with patch.object(uvicorn, "run") as mock_run:
|
|
440
|
+
result = runner.invoke(
|
|
441
|
+
app,
|
|
442
|
+
[
|
|
443
|
+
command,
|
|
444
|
+
"single_file_app.py",
|
|
445
|
+
"--host",
|
|
446
|
+
"0.0.0.0",
|
|
447
|
+
],
|
|
448
|
+
env={"FASTAPI_PUBLIC_URL": public_url},
|
|
449
|
+
)
|
|
450
|
+
assert result.exit_code == 0, result.output
|
|
451
|
+
assert mock_run.called
|
|
452
|
+
assert mock_run.call_args
|
|
453
|
+
assert mock_run.call_args.kwargs == {
|
|
454
|
+
"app": "single_file_app:app",
|
|
455
|
+
"host": "0.0.0.0",
|
|
456
|
+
"port": 8000,
|
|
457
|
+
"reload": True if command == "dev" else False,
|
|
458
|
+
"reload_dirs": None,
|
|
459
|
+
"workers": None,
|
|
460
|
+
"root_path": "",
|
|
461
|
+
"proxy_headers": True,
|
|
462
|
+
"forwarded_allow_ips": None,
|
|
463
|
+
"log_config": get_uvicorn_log_config(),
|
|
464
|
+
}
|
|
465
|
+
|
|
466
|
+
assert "Using import string: single_file_app:app" in result.output
|
|
467
|
+
assert (
|
|
468
|
+
f"Starting {'development' if command == 'dev' else 'production'} server 🚀"
|
|
469
|
+
in result.output
|
|
470
|
+
)
|
|
471
|
+
expected_url_base = public_url.rstrip("/")
|
|
472
|
+
assert f"Server started at {expected_url_base}" in result.output
|
|
473
|
+
assert f"Documentation at {expected_url_base}/docs" in result.output
|
|
474
|
+
|
|
475
|
+
|
|
427
476
|
def test_run_error() -> None:
|
|
428
477
|
with changing_dir(assets_path):
|
|
429
478
|
result = runner.invoke(app, ["run", "non_existing_file.py"])
|
|
@@ -11,6 +11,7 @@ def test_get_uvicorn_config_uses_custom_formatter() -> None:
|
|
|
11
11
|
|
|
12
12
|
assert config["formatters"]["default"]["()"] is CustomFormatter
|
|
13
13
|
assert config["formatters"]["access"]["()"] is CustomFormatter
|
|
14
|
+
assert config["loggers"]["uvicorn"]["propagate"] is False
|
|
14
15
|
|
|
15
16
|
|
|
16
17
|
def test_custom_formatter() -> None:
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
__version__ = "0.0.26"
|
|
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.26 → fastapi_cli-0.0.28}/tests/assets/default_files/default_app_dir_api/app/api.py
RENAMED
|
File without changes
|
|
File without changes
|
{fastapi_cli-0.0.26 → fastapi_cli-0.0.28}/tests/assets/default_files/default_app_dir_app/app/api.py
RENAMED
|
File without changes
|
{fastapi_cli-0.0.26 → fastapi_cli-0.0.28}/tests/assets/default_files/default_app_dir_app/app/app.py
RENAMED
|
File without changes
|
|
File without changes
|
{fastapi_cli-0.0.26 → fastapi_cli-0.0.28}/tests/assets/default_files/default_app_dir_main/app/api.py
RENAMED
|
File without changes
|
{fastapi_cli-0.0.26 → fastapi_cli-0.0.28}/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.26 → fastapi_cli-0.0.28}/tests/assets/default_files/non_default/nonstandard.py
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
{fastapi_cli-0.0.26 → fastapi_cli-0.0.28}/tests/assets/nested_package/package/core/__init__.py
RENAMED
|
File without changes
|
|
File without changes
|
{fastapi_cli-0.0.26 → fastapi_cli-0.0.28}/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
|