fastapi-cli 0.0.17__tar.gz → 0.0.19__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.
Files changed (77) hide show
  1. {fastapi_cli-0.0.17 → fastapi_cli-0.0.19}/PKG-INFO +4 -3
  2. {fastapi_cli-0.0.17 → fastapi_cli-0.0.19}/pdm_build.py +3 -3
  3. {fastapi_cli-0.0.17 → fastapi_cli-0.0.19}/pyproject.toml +5 -3
  4. fastapi_cli-0.0.19/src/fastapi_cli/__init__.py +1 -0
  5. {fastapi_cli-0.0.17 → fastapi_cli-0.0.19}/src/fastapi_cli/cli.py +12 -3
  6. {fastapi_cli-0.0.17 → fastapi_cli-0.0.19}/src/fastapi_cli/config.py +2 -2
  7. {fastapi_cli-0.0.17 → fastapi_cli-0.0.19}/src/fastapi_cli/discover.py +2 -2
  8. {fastapi_cli-0.0.17 → fastapi_cli-0.0.19}/src/fastapi_cli/utils/cli.py +8 -3
  9. {fastapi_cli-0.0.17 → fastapi_cli-0.0.19}/tests/conftest.py +1 -1
  10. {fastapi_cli-0.0.17 → fastapi_cli-0.0.19}/tests/test_cli_pyproject.py +12 -9
  11. {fastapi_cli-0.0.17 → fastapi_cli-0.0.19}/tests/test_utils_cli.py +19 -0
  12. {fastapi_cli-0.0.17 → fastapi_cli-0.0.19}/tests/utils.py +2 -1
  13. fastapi_cli-0.0.17/src/fastapi_cli/__init__.py +0 -1
  14. {fastapi_cli-0.0.17 → fastapi_cli-0.0.19}/LICENSE +0 -0
  15. {fastapi_cli-0.0.17 → fastapi_cli-0.0.19}/README.md +0 -0
  16. {fastapi_cli-0.0.17 → fastapi_cli-0.0.19}/requirements-github-actions.txt +0 -0
  17. {fastapi_cli-0.0.17 → fastapi_cli-0.0.19}/requirements-tests.txt +0 -0
  18. {fastapi_cli-0.0.17 → fastapi_cli-0.0.19}/requirements.txt +0 -0
  19. {fastapi_cli-0.0.17 → fastapi_cli-0.0.19}/scripts/format.sh +0 -0
  20. {fastapi_cli-0.0.17 → fastapi_cli-0.0.19}/scripts/lint.sh +0 -0
  21. {fastapi_cli-0.0.17 → fastapi_cli-0.0.19}/scripts/test-cov-html.sh +0 -0
  22. {fastapi_cli-0.0.17 → fastapi_cli-0.0.19}/scripts/test.sh +0 -0
  23. {fastapi_cli-0.0.17 → fastapi_cli-0.0.19}/src/fastapi_cli/__main__.py +0 -0
  24. {fastapi_cli-0.0.17 → fastapi_cli-0.0.19}/src/fastapi_cli/exceptions.py +0 -0
  25. {fastapi_cli-0.0.17 → fastapi_cli-0.0.19}/src/fastapi_cli/logging.py +0 -0
  26. {fastapi_cli-0.0.17 → fastapi_cli-0.0.19}/src/fastapi_cli/py.typed +0 -0
  27. {fastapi_cli-0.0.17 → fastapi_cli-0.0.19}/src/fastapi_cli/utils/__init__.py +0 -0
  28. {fastapi_cli-0.0.17 → fastapi_cli-0.0.19}/tests/__init__.py +0 -0
  29. {fastapi_cli-0.0.17 → fastapi_cli-0.0.19}/tests/assets/broken_package/mod/__init__.py +0 -0
  30. {fastapi_cli-0.0.17 → fastapi_cli-0.0.19}/tests/assets/broken_package/mod/app.py +0 -0
  31. {fastapi_cli-0.0.17 → fastapi_cli-0.0.19}/tests/assets/broken_package/utils.py +0 -0
  32. {fastapi_cli-0.0.17 → fastapi_cli-0.0.19}/tests/assets/default_files/default_api/api.py +0 -0
  33. {fastapi_cli-0.0.17 → fastapi_cli-0.0.19}/tests/assets/default_files/default_app/api.py +0 -0
  34. {fastapi_cli-0.0.17 → fastapi_cli-0.0.19}/tests/assets/default_files/default_app/app.py +0 -0
  35. {fastapi_cli-0.0.17 → fastapi_cli-0.0.19}/tests/assets/default_files/default_app_dir_api/app/__init__.py +0 -0
  36. {fastapi_cli-0.0.17 → fastapi_cli-0.0.19}/tests/assets/default_files/default_app_dir_api/app/api.py +0 -0
  37. {fastapi_cli-0.0.17 → fastapi_cli-0.0.19}/tests/assets/default_files/default_app_dir_app/app/__init__.py +0 -0
  38. {fastapi_cli-0.0.17 → fastapi_cli-0.0.19}/tests/assets/default_files/default_app_dir_app/app/api.py +0 -0
  39. {fastapi_cli-0.0.17 → fastapi_cli-0.0.19}/tests/assets/default_files/default_app_dir_app/app/app.py +0 -0
  40. {fastapi_cli-0.0.17 → fastapi_cli-0.0.19}/tests/assets/default_files/default_app_dir_main/app/__init__.py +0 -0
  41. {fastapi_cli-0.0.17 → fastapi_cli-0.0.19}/tests/assets/default_files/default_app_dir_main/app/api.py +0 -0
  42. {fastapi_cli-0.0.17 → fastapi_cli-0.0.19}/tests/assets/default_files/default_app_dir_main/app/app.py +0 -0
  43. {fastapi_cli-0.0.17 → fastapi_cli-0.0.19}/tests/assets/default_files/default_app_dir_main/app/main.py +0 -0
  44. {fastapi_cli-0.0.17 → fastapi_cli-0.0.19}/tests/assets/default_files/default_app_dir_non_default/app/__init__.py +0 -0
  45. {fastapi_cli-0.0.17 → fastapi_cli-0.0.19}/tests/assets/default_files/default_app_dir_non_default/app/nondefault.py +0 -0
  46. {fastapi_cli-0.0.17 → fastapi_cli-0.0.19}/tests/assets/default_files/default_main/api.py +0 -0
  47. {fastapi_cli-0.0.17 → fastapi_cli-0.0.19}/tests/assets/default_files/default_main/app.py +0 -0
  48. {fastapi_cli-0.0.17 → fastapi_cli-0.0.19}/tests/assets/default_files/default_main/main.py +0 -0
  49. {fastapi_cli-0.0.17 → fastapi_cli-0.0.19}/tests/assets/default_files/non_default/nonstandard.py +0 -0
  50. {fastapi_cli-0.0.17 → fastapi_cli-0.0.19}/tests/assets/nested_package/__init__.py +0 -0
  51. {fastapi_cli-0.0.17 → fastapi_cli-0.0.19}/tests/assets/nested_package/package/__init__.py +0 -0
  52. {fastapi_cli-0.0.17 → fastapi_cli-0.0.19}/tests/assets/nested_package/package/core/__init__.py +0 -0
  53. {fastapi_cli-0.0.17 → fastapi_cli-0.0.19}/tests/assets/nested_package/package/core/utils.py +0 -0
  54. {fastapi_cli-0.0.17 → fastapi_cli-0.0.19}/tests/assets/nested_package/package/mod/__init__.py +0 -0
  55. {fastapi_cli-0.0.17 → fastapi_cli-0.0.19}/tests/assets/nested_package/package/mod/api.py +0 -0
  56. {fastapi_cli-0.0.17 → fastapi_cli-0.0.19}/tests/assets/nested_package/package/mod/app.py +0 -0
  57. {fastapi_cli-0.0.17 → fastapi_cli-0.0.19}/tests/assets/nested_package/package/mod/other.py +0 -0
  58. {fastapi_cli-0.0.17 → fastapi_cli-0.0.19}/tests/assets/package/__init__.py +0 -0
  59. {fastapi_cli-0.0.17 → fastapi_cli-0.0.19}/tests/assets/package/core/__init__.py +0 -0
  60. {fastapi_cli-0.0.17 → fastapi_cli-0.0.19}/tests/assets/package/core/utils.py +0 -0
  61. {fastapi_cli-0.0.17 → fastapi_cli-0.0.19}/tests/assets/package/mod/__init__.py +0 -0
  62. {fastapi_cli-0.0.17 → fastapi_cli-0.0.19}/tests/assets/package/mod/api.py +0 -0
  63. {fastapi_cli-0.0.17 → fastapi_cli-0.0.19}/tests/assets/package/mod/app.py +0 -0
  64. {fastapi_cli-0.0.17 → fastapi_cli-0.0.19}/tests/assets/package/mod/other.py +0 -0
  65. {fastapi_cli-0.0.17 → fastapi_cli-0.0.19}/tests/assets/pyproject_config/another_module.py +0 -0
  66. {fastapi_cli-0.0.17 → fastapi_cli-0.0.19}/tests/assets/pyproject_config/my_module.py +0 -0
  67. {fastapi_cli-0.0.17 → fastapi_cli-0.0.19}/tests/assets/pyproject_config/pyproject.toml +0 -0
  68. {fastapi_cli-0.0.17 → fastapi_cli-0.0.19}/tests/assets/single_file_api.py +0 -0
  69. {fastapi_cli-0.0.17 → fastapi_cli-0.0.19}/tests/assets/single_file_app.py +0 -0
  70. {fastapi_cli-0.0.17 → fastapi_cli-0.0.19}/tests/assets/single_file_other.py +0 -0
  71. {fastapi_cli-0.0.17 → fastapi_cli-0.0.19}/tests/test_cli.py +0 -0
  72. {fastapi_cli-0.0.17 → fastapi_cli-0.0.19}/tests/test_discover.py +0 -0
  73. {fastapi_cli-0.0.17 → fastapi_cli-0.0.19}/tests/test_requirements.py +0 -0
  74. {fastapi_cli-0.0.17 → fastapi_cli-0.0.19}/tests/test_utils_default_dir.py +0 -0
  75. {fastapi_cli-0.0.17 → fastapi_cli-0.0.19}/tests/test_utils_default_file.py +0 -0
  76. {fastapi_cli-0.0.17 → fastapi_cli-0.0.19}/tests/test_utils_package.py +0 -0
  77. {fastapi_cli-0.0.17 → fastapi_cli-0.0.19}/tests/test_utils_single_file.py +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: fastapi-cli
3
- Version: 0.0.17
3
+ Version: 0.0.19
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
@@ -19,7 +19,6 @@ Classifier: Development Status :: 4 - Beta
19
19
  Classifier: Framework :: FastAPI
20
20
  Classifier: Intended Audience :: Developers
21
21
  Classifier: Programming Language :: Python :: 3 :: Only
22
- Classifier: Programming Language :: Python :: 3.8
23
22
  Classifier: Programming Language :: Python :: 3.9
24
23
  Classifier: Programming Language :: Python :: 3.10
25
24
  Classifier: Programming Language :: Python :: 3.11
@@ -31,7 +30,7 @@ Project-URL: Documentation, https://fastapi.tiangolo.com/fastapi-cli/
31
30
  Project-URL: Repository, https://github.com/fastapi/fastapi-cli
32
31
  Project-URL: Issues, https://github.com/fastapi/fastapi-cli/issues
33
32
  Project-URL: Changelog, https://github.com/fastapi/fastapi-cli/blob/main/release-notes.md
34
- Requires-Python: >=3.8
33
+ Requires-Python: >=3.9
35
34
  Requires-Dist: typer>=0.15.1
36
35
  Requires-Dist: uvicorn[standard]>=0.15.0
37
36
  Requires-Dist: rich-toolkit>=0.14.8
@@ -41,6 +40,8 @@ Requires-Dist: uvicorn[standard]>=0.15.0; extra == "standard"
41
40
  Requires-Dist: fastapi-cloud-cli>=0.1.1; extra == "standard"
42
41
  Provides-Extra: standard-no-fastapi-cloud-cli
43
42
  Requires-Dist: uvicorn[standard]>=0.15.0; extra == "standard-no-fastapi-cloud-cli"
43
+ Provides-Extra: new
44
+ Requires-Dist: fastapi-new>=0.0.2; python_version >= "3.10" and extra == "new"
44
45
  Description-Content-Type: text/markdown
45
46
 
46
47
  # FastAPI CLI
@@ -1,5 +1,5 @@
1
1
  import os
2
- from typing import Any, Dict
2
+ from typing import Any
3
3
 
4
4
  from pdm.backend.hooks import Context
5
5
 
@@ -9,12 +9,12 @@ TIANGOLO_BUILD_PACKAGE = os.getenv("TIANGOLO_BUILD_PACKAGE", "fastapi-cli")
9
9
  def pdm_build_initialize(context: Context):
10
10
  metadata = context.config.metadata
11
11
  # Get custom config for the current package, from the env var
12
- config: Dict[str, Any] = context.config.data["tool"]["tiangolo"][
12
+ config: dict[str, Any] = context.config.data["tool"]["tiangolo"][
13
13
  "_internal-slim-build"
14
14
  ]["packages"].get(TIANGOLO_BUILD_PACKAGE)
15
15
  if not config:
16
16
  return
17
- project_config: Dict[str, Any] = config["project"]
17
+ project_config: dict[str, Any] = config["project"]
18
18
  # Override main [project] configs with custom configs for this package
19
19
  for key, value in project_config.items():
20
20
  metadata[key] = value
@@ -5,7 +5,7 @@ description = "Run and manage FastAPI apps from the command line with FastAPI CL
5
5
  authors = [
6
6
  { name = "Sebastián Ramírez", email = "tiangolo@gmail.com" },
7
7
  ]
8
- requires-python = ">=3.8"
8
+ requires-python = ">=3.9"
9
9
  readme = "README.md"
10
10
  license = "MIT"
11
11
  license-files = [
@@ -26,7 +26,6 @@ classifiers = [
26
26
  "Framework :: FastAPI",
27
27
  "Intended Audience :: Developers",
28
28
  "Programming Language :: Python :: 3 :: Only",
29
- "Programming Language :: Python :: 3.8",
30
29
  "Programming Language :: Python :: 3.9",
31
30
  "Programming Language :: Python :: 3.10",
32
31
  "Programming Language :: Python :: 3.11",
@@ -40,7 +39,7 @@ dependencies = [
40
39
  "rich-toolkit >= 0.14.8",
41
40
  "tomli >= 2.0.0; python_version < '3.11'",
42
41
  ]
43
- version = "0.0.17"
42
+ version = "0.0.19"
44
43
 
45
44
  [project.optional-dependencies]
46
45
  standard = [
@@ -50,6 +49,9 @@ standard = [
50
49
  standard-no-fastapi-cloud-cli = [
51
50
  "uvicorn[standard] >= 0.15.0",
52
51
  ]
52
+ new = [
53
+ "fastapi-new >= 0.0.2 ; python_version >= '3.10'",
54
+ ]
53
55
 
54
56
  [project.urls]
55
57
  Homepage = "https://github.com/fastapi/fastapi-cli"
@@ -0,0 +1 @@
1
+ __version__ = "0.0.19"
@@ -1,12 +1,11 @@
1
1
  import logging
2
2
  from pathlib import Path
3
- from typing import Any, List, Union
3
+ from typing import Annotated, Any, Union
4
4
 
5
5
  import typer
6
6
  from pydantic import ValidationError
7
7
  from rich import print
8
8
  from rich.tree import Tree
9
- from typing_extensions import Annotated
10
9
 
11
10
  from fastapi_cli.config import FastAPIConfig
12
11
  from fastapi_cli.discover import get_import_data, get_import_data_from_import_string
@@ -39,6 +38,16 @@ except ImportError: # pragma: no cover
39
38
  pass
40
39
 
41
40
 
41
+ try:
42
+ from fastapi_new.cli import ( # type: ignore[import-not-found]
43
+ app as fastapi_new_cli,
44
+ )
45
+
46
+ app.add_typer(fastapi_new_cli) # pragma: no cover
47
+ except ImportError: # pragma: no cover
48
+ pass
49
+
50
+
42
51
  def version_callback(value: bool) -> None:
43
52
  if value:
44
53
  print(f"FastAPI CLI version: [green]{__version__}[/green]")
@@ -68,7 +77,7 @@ def callback(
68
77
  setup_logging(level=log_level)
69
78
 
70
79
 
71
- def _get_module_tree(module_paths: List[Path]) -> Tree:
80
+ def _get_module_tree(module_paths: list[Path]) -> Tree:
72
81
  root = module_paths[0]
73
82
  name = f"🐍 {root.name}" if root.is_file() else f"📁 {root.name}"
74
83
 
@@ -1,6 +1,6 @@
1
1
  import logging
2
2
  from pathlib import Path
3
- from typing import Any, Dict, Optional
3
+ from typing import Any, Optional
4
4
 
5
5
  from pydantic import BaseModel, StrictStr
6
6
 
@@ -11,7 +11,7 @@ class FastAPIConfig(BaseModel):
11
11
  entrypoint: Optional[StrictStr] = None
12
12
 
13
13
  @classmethod
14
- def _read_pyproject_toml(cls) -> Dict[str, Any]:
14
+ def _read_pyproject_toml(cls) -> dict[str, Any]:
15
15
  """Read FastAPI configuration from pyproject.toml in current directory."""
16
16
  pyproject_path = Path.cwd() / "pyproject.toml"
17
17
 
@@ -3,7 +3,7 @@ import sys
3
3
  from dataclasses import dataclass
4
4
  from logging import getLogger
5
5
  from pathlib import Path
6
- from typing import List, Union
6
+ from typing import Union
7
7
 
8
8
  from fastapi_cli.exceptions import FastAPICLIException
9
9
 
@@ -39,7 +39,7 @@ def get_default_path() -> Path:
39
39
  class ModuleData:
40
40
  module_import_str: str
41
41
  extra_sys_path: Path
42
- module_paths: List[Path]
42
+ module_paths: list[Path]
43
43
 
44
44
 
45
45
  def get_module_data_from_path(path: Path) -> ModuleData:
@@ -1,5 +1,5 @@
1
1
  import logging
2
- from typing import Any, Dict
2
+ from typing import Any
3
3
 
4
4
  from rich_toolkit import RichToolkit, RichToolkitTheme
5
5
  from rich_toolkit.styles import TaggedStyle
@@ -12,10 +12,15 @@ class CustomFormatter(DefaultFormatter):
12
12
  self.toolkit = get_rich_toolkit()
13
13
 
14
14
  def formatMessage(self, record: logging.LogRecord) -> str:
15
- return self.toolkit.print_as_string(record.getMessage(), tag=record.levelname)
15
+ message = record.getMessage()
16
+ result = self.toolkit.print_as_string(message, tag=record.levelname)
17
+ # Prepend newline to fix alignment after ^C is printed by the terminal
18
+ if message == "Shutting down":
19
+ result = "\n" + result
20
+ return result
16
21
 
17
22
 
18
- def get_uvicorn_log_config() -> Dict[str, Any]:
23
+ def get_uvicorn_log_config() -> dict[str, Any]:
19
24
  return {
20
25
  "version": 1,
21
26
  "disable_existing_loggers": False,
@@ -1,5 +1,5 @@
1
1
  import sys
2
- from typing import Generator
2
+ from collections.abc import Generator
3
3
 
4
4
  import pytest
5
5
  from typer import rich_utils
@@ -13,9 +13,10 @@ assets_path = Path(__file__).parent / "assets"
13
13
 
14
14
 
15
15
  def test_dev_with_pyproject_app_config_uses() -> None:
16
- with changing_dir(assets_path / "pyproject_config"), patch.object(
17
- uvicorn, "run"
18
- ) as mock_run:
16
+ with (
17
+ changing_dir(assets_path / "pyproject_config"),
18
+ patch.object(uvicorn, "run") as mock_run,
19
+ ):
19
20
  result = runner.invoke(app, ["dev"])
20
21
  assert result.exit_code == 0, result.output
21
22
 
@@ -28,9 +29,10 @@ def test_dev_with_pyproject_app_config_uses() -> None:
28
29
 
29
30
 
30
31
  def test_run_with_pyproject_app_config() -> None:
31
- with changing_dir(assets_path / "pyproject_config"), patch.object(
32
- uvicorn, "run"
33
- ) as mock_run:
32
+ with (
33
+ changing_dir(assets_path / "pyproject_config"),
34
+ patch.object(uvicorn, "run") as mock_run,
35
+ ):
34
36
  result = runner.invoke(app, ["run"])
35
37
  assert result.exit_code == 0, result.output
36
38
 
@@ -43,9 +45,10 @@ def test_run_with_pyproject_app_config() -> None:
43
45
 
44
46
 
45
47
  def test_cli_arg_overrides_pyproject_config() -> None:
46
- with changing_dir(assets_path / "pyproject_config"), patch.object(
47
- uvicorn, "run"
48
- ) as mock_run:
48
+ with (
49
+ changing_dir(assets_path / "pyproject_config"),
50
+ patch.object(uvicorn, "run") as mock_run,
51
+ ):
49
52
  result = runner.invoke(app, ["dev", "another_module.py"])
50
53
 
51
54
  assert result.exit_code == 0, result.output
@@ -37,6 +37,25 @@ def test_custom_formatter() -> None:
37
37
  assert "200" in formatted
38
38
 
39
39
 
40
+ def test_custom_formatter_shutdown_prepends_newline() -> None:
41
+ formatter = CustomFormatter()
42
+
43
+ record = logging.LogRecord(
44
+ name="uvicorn.error",
45
+ level=logging.INFO,
46
+ pathname="",
47
+ lineno=0,
48
+ msg="Shutting down",
49
+ args=(),
50
+ exc_info=None,
51
+ )
52
+
53
+ formatted = formatter.formatMessage(record)
54
+
55
+ assert formatted.startswith("\n")
56
+ assert "Shutting down" in formatted
57
+
58
+
40
59
  def test_log_config_does_not_disable_existing_loggers(
41
60
  caplog: LogCaptureFixture,
42
61
  ) -> None:
@@ -1,7 +1,8 @@
1
1
  import os
2
+ from collections.abc import Generator
2
3
  from contextlib import contextmanager
3
4
  from pathlib import Path
4
- from typing import Generator, Union
5
+ from typing import Union
5
6
 
6
7
 
7
8
  @contextmanager
@@ -1 +0,0 @@
1
- __version__ = "0.0.17"
File without changes
File without changes