fastapi-cli 0.0.2__tar.gz → 0.0.4__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 (60) hide show
  1. {fastapi_cli-0.0.2 → fastapi_cli-0.0.4}/PKG-INFO +6 -3
  2. {fastapi_cli-0.0.2 → fastapi_cli-0.0.4}/README.md +2 -0
  3. {fastapi_cli-0.0.2 → fastapi_cli-0.0.4}/pyproject.toml +7 -7
  4. fastapi_cli-0.0.4/requirements-tests.txt +9 -0
  5. fastapi_cli-0.0.4/src/fastapi_cli/__init__.py +1 -0
  6. {fastapi_cli-0.0.2 → fastapi_cli-0.0.4}/src/fastapi_cli/cli.py +18 -1
  7. {fastapi_cli-0.0.2 → fastapi_cli-0.0.4}/src/fastapi_cli/discover.py +9 -1
  8. {fastapi_cli-0.0.2 → fastapi_cli-0.0.4}/tests/test_cli.py +8 -0
  9. fastapi_cli-0.0.4/tests/test_requirements.py +45 -0
  10. fastapi_cli-0.0.2/requirements-tests.txt +0 -6
  11. fastapi_cli-0.0.2/src/fastapi_cli/__init__.py +0 -1
  12. {fastapi_cli-0.0.2 → fastapi_cli-0.0.4}/LICENSE +0 -0
  13. {fastapi_cli-0.0.2 → fastapi_cli-0.0.4}/pdm_build.py +0 -0
  14. {fastapi_cli-0.0.2 → fastapi_cli-0.0.4}/requirements.txt +0 -0
  15. {fastapi_cli-0.0.2 → fastapi_cli-0.0.4}/scripts/format.sh +0 -0
  16. {fastapi_cli-0.0.2 → fastapi_cli-0.0.4}/scripts/lint.sh +0 -0
  17. {fastapi_cli-0.0.2 → fastapi_cli-0.0.4}/scripts/test-cov-html.sh +0 -0
  18. {fastapi_cli-0.0.2 → fastapi_cli-0.0.4}/scripts/test.sh +0 -0
  19. {fastapi_cli-0.0.2 → fastapi_cli-0.0.4}/src/fastapi_cli/__main__.py +0 -0
  20. {fastapi_cli-0.0.2 → fastapi_cli-0.0.4}/src/fastapi_cli/exceptions.py +0 -0
  21. {fastapi_cli-0.0.2 → fastapi_cli-0.0.4}/src/fastapi_cli/logging.py +0 -0
  22. {fastapi_cli-0.0.2 → fastapi_cli-0.0.4}/src/fastapi_cli/py.typed +0 -0
  23. {fastapi_cli-0.0.2 → fastapi_cli-0.0.4}/tests/__init__.py +0 -0
  24. {fastapi_cli-0.0.2 → fastapi_cli-0.0.4}/tests/assets/broken_package/mod/__init__.py +0 -0
  25. {fastapi_cli-0.0.2 → fastapi_cli-0.0.4}/tests/assets/broken_package/mod/app.py +0 -0
  26. {fastapi_cli-0.0.2 → fastapi_cli-0.0.4}/tests/assets/broken_package/utils.py +0 -0
  27. {fastapi_cli-0.0.2 → fastapi_cli-0.0.4}/tests/assets/default_files/default_api/api.py +0 -0
  28. {fastapi_cli-0.0.2 → fastapi_cli-0.0.4}/tests/assets/default_files/default_app/api.py +0 -0
  29. {fastapi_cli-0.0.2 → fastapi_cli-0.0.4}/tests/assets/default_files/default_app/app.py +0 -0
  30. {fastapi_cli-0.0.2 → fastapi_cli-0.0.4}/tests/assets/default_files/default_app_dir_api/app/__init__.py +0 -0
  31. {fastapi_cli-0.0.2 → fastapi_cli-0.0.4}/tests/assets/default_files/default_app_dir_api/app/api.py +0 -0
  32. {fastapi_cli-0.0.2 → fastapi_cli-0.0.4}/tests/assets/default_files/default_app_dir_app/app/__init__.py +0 -0
  33. {fastapi_cli-0.0.2 → fastapi_cli-0.0.4}/tests/assets/default_files/default_app_dir_app/app/api.py +0 -0
  34. {fastapi_cli-0.0.2 → fastapi_cli-0.0.4}/tests/assets/default_files/default_app_dir_app/app/app.py +0 -0
  35. {fastapi_cli-0.0.2 → fastapi_cli-0.0.4}/tests/assets/default_files/default_app_dir_main/app/__init__.py +0 -0
  36. {fastapi_cli-0.0.2 → fastapi_cli-0.0.4}/tests/assets/default_files/default_app_dir_main/app/api.py +0 -0
  37. {fastapi_cli-0.0.2 → fastapi_cli-0.0.4}/tests/assets/default_files/default_app_dir_main/app/app.py +0 -0
  38. {fastapi_cli-0.0.2 → fastapi_cli-0.0.4}/tests/assets/default_files/default_app_dir_main/app/main.py +0 -0
  39. {fastapi_cli-0.0.2 → fastapi_cli-0.0.4}/tests/assets/default_files/default_app_dir_non_default/app/__init__.py +0 -0
  40. {fastapi_cli-0.0.2 → fastapi_cli-0.0.4}/tests/assets/default_files/default_app_dir_non_default/app/nondefault.py +0 -0
  41. {fastapi_cli-0.0.2 → fastapi_cli-0.0.4}/tests/assets/default_files/default_main/api.py +0 -0
  42. {fastapi_cli-0.0.2 → fastapi_cli-0.0.4}/tests/assets/default_files/default_main/app.py +0 -0
  43. {fastapi_cli-0.0.2 → fastapi_cli-0.0.4}/tests/assets/default_files/default_main/main.py +0 -0
  44. {fastapi_cli-0.0.2 → fastapi_cli-0.0.4}/tests/assets/default_files/non_default/nonstandard.py +0 -0
  45. {fastapi_cli-0.0.2 → fastapi_cli-0.0.4}/tests/assets/package/__init__.py +0 -0
  46. {fastapi_cli-0.0.2 → fastapi_cli-0.0.4}/tests/assets/package/core/__init__.py +0 -0
  47. {fastapi_cli-0.0.2 → fastapi_cli-0.0.4}/tests/assets/package/core/utils.py +0 -0
  48. {fastapi_cli-0.0.2 → fastapi_cli-0.0.4}/tests/assets/package/mod/__init__.py +0 -0
  49. {fastapi_cli-0.0.2 → fastapi_cli-0.0.4}/tests/assets/package/mod/api.py +0 -0
  50. {fastapi_cli-0.0.2 → fastapi_cli-0.0.4}/tests/assets/package/mod/app.py +0 -0
  51. {fastapi_cli-0.0.2 → fastapi_cli-0.0.4}/tests/assets/package/mod/other.py +0 -0
  52. {fastapi_cli-0.0.2 → fastapi_cli-0.0.4}/tests/assets/single_file_api.py +0 -0
  53. {fastapi_cli-0.0.2 → fastapi_cli-0.0.4}/tests/assets/single_file_app.py +0 -0
  54. {fastapi_cli-0.0.2 → fastapi_cli-0.0.4}/tests/assets/single_file_other.py +0 -0
  55. {fastapi_cli-0.0.2 → fastapi_cli-0.0.4}/tests/conftest.py +0 -0
  56. {fastapi_cli-0.0.2 → fastapi_cli-0.0.4}/tests/test_utils_default_dir.py +0 -0
  57. {fastapi_cli-0.0.2 → fastapi_cli-0.0.4}/tests/test_utils_default_file.py +0 -0
  58. {fastapi_cli-0.0.2 → fastapi_cli-0.0.4}/tests/test_utils_package.py +0 -0
  59. {fastapi_cli-0.0.2 → fastapi_cli-0.0.4}/tests/test_utils_single_file.py +0 -0
  60. {fastapi_cli-0.0.2 → fastapi_cli-0.0.4}/tests/utils.py +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.1
2
2
  Name: fastapi-cli
3
- Version: 0.0.2
3
+ Version: 0.0.4
4
4
  Summary: Run and manage FastAPI apps from the command line with FastAPI CLI. 🚀
5
5
  Home-page: https://github.com/tiangolo/fastapi-cli
6
6
  Author-Email: =?utf-8?q?Sebasti=C3=A1n_Ram=C3=ADrez?= <tiangolo@gmail.com>
@@ -32,8 +32,9 @@ Project-URL: Homepage, https://github.com/tiangolo/fastapi-cli
32
32
  Project-URL: Repository, https://github.com/tiangolo/fastapi-cli
33
33
  Requires-Python: >=3.8
34
34
  Requires-Dist: typer>=0.12.3
35
- Requires-Dist: fastapi
36
- Requires-Dist: uvicorn[standard]>=0.29.0
35
+ Requires-Dist: fastapi; extra == "standard"
36
+ Requires-Dist: uvicorn[standard]>=0.15.0; extra == "standard"
37
+ Provides-Extra: standard
37
38
  Description-Content-Type: text/markdown
38
39
 
39
40
  # FastAPI CLI
@@ -120,6 +121,8 @@ FastAPI CLI takes the path to your Python program and automatically detects the
120
121
 
121
122
  For production you would use `fastapi run` instead. 🚀
122
123
 
124
+ Internally, **FastAPI CLI** uses <a href="https://www.uvicorn.org" class="external-link" target="_blank">Uvicorn</a>, a high-performance, production-ready, ASGI server. 😎
125
+
123
126
  ## `fastapi dev`
124
127
 
125
128
  When you run `fastapi dev`, it will run on development mode.
@@ -82,6 +82,8 @@ FastAPI CLI takes the path to your Python program and automatically detects the
82
82
 
83
83
  For production you would use `fastapi run` instead. 🚀
84
84
 
85
+ Internally, **FastAPI CLI** uses <a href="https://www.uvicorn.org" class="external-link" target="_blank">Uvicorn</a>, a high-performance, production-ready, ASGI server. 😎
86
+
85
87
  ## `fastapi dev`
86
88
 
87
89
  When you run `fastapi dev`, it will run on development mode.
@@ -33,15 +33,17 @@ classifiers = [
33
33
  ]
34
34
  dependencies = [
35
35
  "typer >= 0.12.3",
36
- "fastapi",
37
- "uvicorn[standard] >= 0.29.0",
38
36
  ]
39
- version = "0.0.2"
37
+ version = "0.0.4"
40
38
 
41
39
  [project.license]
42
40
  text = "MIT"
43
41
 
44
42
  [project.optional-dependencies]
43
+ standard = [
44
+ "fastapi",
45
+ "uvicorn[standard] >= 0.15.0",
46
+ ]
45
47
 
46
48
  [project.urls]
47
49
  Documentation = "https://fastapi.tiangolo.com"
@@ -75,11 +77,9 @@ source-includes = [
75
77
  name = "fastapi-cli-slim"
76
78
 
77
79
  [tool.tiangolo._internal-slim-build.packages.fastapi-cli]
78
- include-optional-dependencies = [
79
- "standard",
80
- ]
80
+ include-optional-dependencies = []
81
81
 
82
- [tool.tiangolo._internal-slim-build.packages.fastapi-cli.project.optional-dependencies]
82
+ [tool.tiangolo._internal-slim-build.packages.fastapi-cli.project]
83
83
 
84
84
  [tool.pytest.ini_options]
85
85
  addopts = [
@@ -0,0 +1,9 @@
1
+ -e .
2
+
3
+ pytest >=4.4.0,<9.0.0
4
+ coverage[toml] >=6.2,<8.0
5
+ mypy ==1.10.0
6
+ ruff ==0.4.3
7
+ # Needed explicitly by fastapi-cli-slim
8
+ fastapi-slim
9
+ uvicorn
@@ -0,0 +1 @@
1
+ __version__ = "0.0.4"
@@ -3,7 +3,6 @@ from pathlib import Path
3
3
  from typing import Any, Union
4
4
 
5
5
  import typer
6
- import uvicorn
7
6
  from rich import print
8
7
  from rich.padding import Padding
9
8
  from rich.panel import Panel
@@ -20,6 +19,11 @@ app = typer.Typer(rich_markup_mode="rich")
20
19
  setup_logging()
21
20
  logger = getLogger(__name__)
22
21
 
22
+ try:
23
+ import uvicorn
24
+ except ImportError: # pragma: no cover
25
+ uvicorn = None # type: ignore[assignment]
26
+
23
27
 
24
28
  def version_callback(value: bool) -> None:
25
29
  if value:
@@ -51,6 +55,7 @@ def _run(
51
55
  host: str = "127.0.0.1",
52
56
  port: int = 8000,
53
57
  reload: bool = True,
58
+ workers: Union[int, None] = None,
54
59
  root_path: str = "",
55
60
  command: str,
56
61
  app: Union[str, None] = None,
@@ -80,11 +85,16 @@ def _run(
80
85
  style="green",
81
86
  )
82
87
  print(Padding(panel, 1))
88
+ if not uvicorn:
89
+ raise FastAPICLIException(
90
+ "Could not import Uvicorn, try running 'pip install uvicorn'"
91
+ ) from None
83
92
  uvicorn.run(
84
93
  app=use_uvicorn_app,
85
94
  host=host,
86
95
  port=port,
87
96
  reload=reload,
97
+ workers=workers,
88
98
  root_path=root_path,
89
99
  proxy_headers=proxy_headers,
90
100
  )
@@ -200,6 +210,12 @@ def run(
200
210
  help="Enable auto-reload of the server when (code) files change. This is [bold]resource intensive[/bold], use it only during development."
201
211
  ),
202
212
  ] = False,
213
+ workers: Annotated[
214
+ Union[int, None],
215
+ typer.Option(
216
+ help="Use multiple worker processes. Mutually exclusive with the --reload flag."
217
+ ),
218
+ ] = None,
203
219
  root_path: Annotated[
204
220
  str,
205
221
  typer.Option(
@@ -249,6 +265,7 @@ def run(
249
265
  host=host,
250
266
  port=port,
251
267
  reload=reload,
268
+ workers=workers,
252
269
  root_path=root_path,
253
270
  app=app,
254
271
  command="run",
@@ -5,7 +5,6 @@ from logging import getLogger
5
5
  from pathlib import Path
6
6
  from typing import Union
7
7
 
8
- from fastapi import FastAPI
9
8
  from rich import print
10
9
  from rich.padding import Padding
11
10
  from rich.panel import Panel
@@ -16,6 +15,11 @@ from fastapi_cli.exceptions import FastAPICLIException
16
15
 
17
16
  logger = getLogger(__name__)
18
17
 
18
+ try:
19
+ from fastapi import FastAPI
20
+ except ImportError: # pragma: no cover
21
+ FastAPI = None # type: ignore[misc, assignment]
22
+
19
23
 
20
24
  def get_default_path() -> Path:
21
25
  path = Path("main.py")
@@ -107,6 +111,10 @@ def get_app_name(*, mod_data: ModuleData, app_name: Union[str, None] = None) ->
107
111
  "Ensure all the package directories have an [blue]__init__.py[/blue] file"
108
112
  )
109
113
  raise
114
+ if not FastAPI: # type: ignore[truthy-function]
115
+ raise FastAPICLIException(
116
+ "Could not import FastAPI, try running 'pip install fastapi'"
117
+ ) from None
110
118
  object_names = dir(mod)
111
119
  object_names_set = set(object_names)
112
120
  if app_name:
@@ -26,6 +26,7 @@ def test_dev() -> None:
26
26
  "host": "127.0.0.1",
27
27
  "port": 8000,
28
28
  "reload": True,
29
+ "workers": None,
29
30
  "root_path": "",
30
31
  "proxy_headers": True,
31
32
  }
@@ -67,6 +68,7 @@ def test_dev_args() -> None:
67
68
  "host": "192.168.0.2",
68
69
  "port": 8080,
69
70
  "reload": False,
71
+ "workers": None,
70
72
  "root_path": "/api",
71
73
  "proxy_headers": False,
72
74
  }
@@ -92,6 +94,7 @@ def test_run() -> None:
92
94
  "host": "0.0.0.0",
93
95
  "port": 8000,
94
96
  "reload": False,
97
+ "workers": None,
95
98
  "root_path": "",
96
99
  "proxy_headers": True,
97
100
  }
@@ -118,6 +121,8 @@ def test_run_args() -> None:
118
121
  "--port",
119
122
  "8080",
120
123
  "--no-reload",
124
+ "--workers",
125
+ "2",
121
126
  "--root-path",
122
127
  "/api",
123
128
  "--app",
@@ -133,6 +138,7 @@ def test_run_args() -> None:
133
138
  "host": "192.168.0.2",
134
139
  "port": 8080,
135
140
  "reload": False,
141
+ "workers": 2,
136
142
  "root_path": "/api",
137
143
  "proxy_headers": False,
138
144
  }
@@ -171,6 +177,7 @@ def test_dev_help() -> None:
171
177
  assert "Enable auto-reload of the server when (code) files change." in result.output
172
178
  assert "The root path is used to tell your app" in result.output
173
179
  assert "The name of the variable that contains the FastAPI app" in result.output
180
+ assert "Use multiple worker processes." not in result.output
174
181
 
175
182
 
176
183
  def test_run_help() -> None:
@@ -191,6 +198,7 @@ def test_run_help() -> None:
191
198
  assert "Enable auto-reload of the server when (code) files change." in result.output
192
199
  assert "The root path is used to tell your app" in result.output
193
200
  assert "The name of the variable that contains the FastAPI app" in result.output
201
+ assert "Use multiple worker processes." in result.output
194
202
 
195
203
 
196
204
  def test_callback_help() -> None:
@@ -0,0 +1,45 @@
1
+ from pathlib import Path
2
+
3
+ import pytest
4
+ from fastapi_cli.discover import get_import_string
5
+ from fastapi_cli.exceptions import FastAPICLIException
6
+ from typer.testing import CliRunner
7
+
8
+ from .utils import changing_dir
9
+
10
+ runner = CliRunner()
11
+
12
+ assets_path = Path(__file__).parent / "assets"
13
+
14
+
15
+ def test_no_uvicorn() -> None:
16
+ import fastapi_cli.cli
17
+ import uvicorn
18
+
19
+ fastapi_cli.cli.uvicorn = None # type: ignore[attr-defined, assignment]
20
+
21
+ with changing_dir(assets_path):
22
+ result = runner.invoke(fastapi_cli.cli.app, ["dev", "single_file_app.py"])
23
+ assert result.exit_code == 1
24
+ assert result.exception is not None
25
+ assert (
26
+ "Could not import Uvicorn, try running 'pip install uvicorn'"
27
+ in result.exception.args[0]
28
+ )
29
+
30
+ fastapi_cli.cli.uvicorn = uvicorn # type: ignore[attr-defined]
31
+
32
+
33
+ def test_no_fastapi() -> None:
34
+ import fastapi_cli.discover
35
+ from fastapi import FastAPI
36
+
37
+ fastapi_cli.discover.FastAPI = None # type: ignore[attr-defined, assignment]
38
+ with changing_dir(assets_path):
39
+ with pytest.raises(FastAPICLIException) as exc_info:
40
+ get_import_string(path=Path("single_file_app.py"))
41
+ assert "Could not import FastAPI, try running 'pip install fastapi'" in str(
42
+ exc_info.value
43
+ )
44
+
45
+ fastapi_cli.discover.FastAPI = FastAPI # type: ignore[attr-defined]
@@ -1,6 +0,0 @@
1
- -e .
2
-
3
- pytest >=4.4.0,<8.0.0
4
- coverage[toml] >=6.2,<8.0
5
- mypy ==1.4.1
6
- ruff ==0.2.0
@@ -1 +0,0 @@
1
- __version__ = "0.0.2"
File without changes
File without changes
File without changes
File without changes
File without changes