fastapi-cli 0.0.1__py3-none-any.whl โ†’ 0.0.2__py3-none-any.whl

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/__init__.py CHANGED
@@ -1,3 +1 @@
1
- from importlib_metadata import version
2
-
3
- __version__ = version(__package__)
1
+ __version__ = "0.0.2"
@@ -0,0 +1,3 @@
1
+ from .cli import main
2
+
3
+ main()
fastapi_cli/cli.py ADDED
@@ -0,0 +1,260 @@
1
+ from logging import getLogger
2
+ from pathlib import Path
3
+ from typing import Any, Union
4
+
5
+ import typer
6
+ import uvicorn
7
+ from rich import print
8
+ from rich.padding import Padding
9
+ from rich.panel import Panel
10
+ from typing_extensions import Annotated
11
+
12
+ from fastapi_cli.discover import get_import_string
13
+ from fastapi_cli.exceptions import FastAPICLIException
14
+
15
+ from . import __version__
16
+ from .logging import setup_logging
17
+
18
+ app = typer.Typer(rich_markup_mode="rich")
19
+
20
+ setup_logging()
21
+ logger = getLogger(__name__)
22
+
23
+
24
+ def version_callback(value: bool) -> None:
25
+ if value:
26
+ print(f"FastAPI CLI version: [green]{__version__}[/green]")
27
+ raise typer.Exit()
28
+
29
+
30
+ @app.callback()
31
+ def callback(
32
+ version: Annotated[
33
+ Union[bool, None],
34
+ typer.Option(
35
+ "--version", help="Show the version and exit.", callback=version_callback
36
+ ),
37
+ ] = None,
38
+ ) -> None:
39
+ """
40
+ FastAPI CLI - The [bold]fastapi[/bold] command line app. ๐Ÿ˜Ž
41
+
42
+ Manage your [bold]FastAPI[/bold] projects, run your FastAPI apps, and more.
43
+
44
+ Read more in the docs: [link]https://fastapi.tiangolo.com/fastapi-cli/[/link].
45
+ """
46
+
47
+
48
+ def _run(
49
+ path: Union[Path, None] = None,
50
+ *,
51
+ host: str = "127.0.0.1",
52
+ port: int = 8000,
53
+ reload: bool = True,
54
+ root_path: str = "",
55
+ command: str,
56
+ app: Union[str, None] = None,
57
+ proxy_headers: bool = False,
58
+ ) -> None:
59
+ try:
60
+ use_uvicorn_app = get_import_string(path=path, app_name=app)
61
+ except FastAPICLIException as e:
62
+ logger.error(str(e))
63
+ raise typer.Exit(code=1) from None
64
+ serving_str = f"[dim]Serving at:[/dim] [link]http://{host}:{port}[/link]\n\n[dim]API docs:[/dim] [link]http://{host}:{port}/docs[/link]"
65
+
66
+ if command == "dev":
67
+ panel = Panel(
68
+ f"{serving_str}\n\n[dim]Running in development mode, for production use:[/dim] \n\n[b]fastapi run[/b]",
69
+ title="FastAPI CLI - Development mode",
70
+ expand=False,
71
+ padding=(1, 2),
72
+ style="black on yellow",
73
+ )
74
+ else:
75
+ panel = Panel(
76
+ f"{serving_str}\n\n[dim]Running in production mode, for development use:[/dim] \n\n[b]fastapi dev[/b]",
77
+ title="FastAPI CLI - Production mode",
78
+ expand=False,
79
+ padding=(1, 2),
80
+ style="green",
81
+ )
82
+ print(Padding(panel, 1))
83
+ uvicorn.run(
84
+ app=use_uvicorn_app,
85
+ host=host,
86
+ port=port,
87
+ reload=reload,
88
+ root_path=root_path,
89
+ proxy_headers=proxy_headers,
90
+ )
91
+
92
+
93
+ @app.command()
94
+ def dev(
95
+ path: Annotated[
96
+ Union[Path, None],
97
+ typer.Argument(
98
+ help="A path to a Python file or package directory (with [blue]__init__.py[/blue] files) containing a [bold]FastAPI[/bold] app. If not provided, a default set of paths will be tried."
99
+ ),
100
+ ] = None,
101
+ *,
102
+ host: Annotated[
103
+ str,
104
+ typer.Option(
105
+ help="The host to serve on. For local development in localhost use [blue]127.0.0.1[/blue]. To enable public access, e.g. in a container, use all the IP addresses available with [blue]0.0.0.0[/blue]."
106
+ ),
107
+ ] = "127.0.0.1",
108
+ port: Annotated[
109
+ int,
110
+ typer.Option(
111
+ help="The port to serve on. You would normally have a termination proxy on top (another program) handling HTTPS on port [blue]443[/blue] and HTTP on port [blue]80[/blue], transferring the communication to your app."
112
+ ),
113
+ ] = 8000,
114
+ reload: Annotated[
115
+ bool,
116
+ typer.Option(
117
+ help="Enable auto-reload of the server when (code) files change. This is [bold]resource intensive[/bold], use it only during development."
118
+ ),
119
+ ] = True,
120
+ root_path: Annotated[
121
+ str,
122
+ typer.Option(
123
+ help="The root path is used to tell your app that it is being served to the outside world with some [bold]path prefix[/bold] set up in some termination proxy or similar."
124
+ ),
125
+ ] = "",
126
+ app: Annotated[
127
+ Union[str, None],
128
+ typer.Option(
129
+ help="The name of the variable that contains the [bold]FastAPI[/bold] app in the imported module or package. If not provided, it is detected automatically."
130
+ ),
131
+ ] = None,
132
+ proxy_headers: Annotated[
133
+ bool,
134
+ typer.Option(
135
+ help="Enable/Disable X-Forwarded-Proto, X-Forwarded-For, X-Forwarded-Port to populate remote address info."
136
+ ),
137
+ ] = True,
138
+ ) -> Any:
139
+ """
140
+ Run a [bold]FastAPI[/bold] app in [yellow]development[/yellow] mode. ๐Ÿงช
141
+
142
+ This is equivalent to [bold]fastapi run[/bold] but with [bold]reload[/bold] enabled and listening on the [blue]127.0.0.1[/blue] address.
143
+
144
+ It automatically detects the Python module or package that needs to be imported based on the file or directory path passed.
145
+
146
+ If no path is passed, it tries with:
147
+
148
+ - [blue]main.py[/blue]
149
+ - [blue]app.py[/blue]
150
+ - [blue]api.py[/blue]
151
+ - [blue]app/main.py[/blue]
152
+ - [blue]app/app.py[/blue]
153
+ - [blue]app/api.py[/blue]
154
+
155
+ It also detects the directory that needs to be added to the [bold]PYTHONPATH[/bold] to make the app importable and adds it.
156
+
157
+ It detects the [bold]FastAPI[/bold] app object to use. By default it looks in the module or package for an object named:
158
+
159
+ - [blue]app[/blue]
160
+ - [blue]api[/blue]
161
+
162
+ Otherwise, it uses the first [bold]FastAPI[/bold] app found in the imported module or package.
163
+ """
164
+ _run(
165
+ path=path,
166
+ host=host,
167
+ port=port,
168
+ reload=reload,
169
+ root_path=root_path,
170
+ app=app,
171
+ command="dev",
172
+ proxy_headers=proxy_headers,
173
+ )
174
+
175
+
176
+ @app.command()
177
+ def run(
178
+ path: Annotated[
179
+ Union[Path, None],
180
+ typer.Argument(
181
+ help="A path to a Python file or package directory (with [blue]__init__.py[/blue] files) containing a [bold]FastAPI[/bold] app. If not provided, a default set of paths will be tried."
182
+ ),
183
+ ] = None,
184
+ *,
185
+ host: Annotated[
186
+ str,
187
+ typer.Option(
188
+ help="The host to serve on. For local development in localhost use [blue]127.0.0.1[/blue]. To enable public access, e.g. in a container, use all the IP addresses available with [blue]0.0.0.0[/blue]."
189
+ ),
190
+ ] = "0.0.0.0",
191
+ port: Annotated[
192
+ int,
193
+ typer.Option(
194
+ help="The port to serve on. You would normally have a termination proxy on top (another program) handling HTTPS on port [blue]443[/blue] and HTTP on port [blue]80[/blue], transferring the communication to your app."
195
+ ),
196
+ ] = 8000,
197
+ reload: Annotated[
198
+ bool,
199
+ typer.Option(
200
+ help="Enable auto-reload of the server when (code) files change. This is [bold]resource intensive[/bold], use it only during development."
201
+ ),
202
+ ] = False,
203
+ root_path: Annotated[
204
+ str,
205
+ typer.Option(
206
+ help="The root path is used to tell your app that it is being served to the outside world with some [bold]path prefix[/bold] set up in some termination proxy or similar."
207
+ ),
208
+ ] = "",
209
+ app: Annotated[
210
+ Union[str, None],
211
+ typer.Option(
212
+ help="The name of the variable that contains the [bold]FastAPI[/bold] app in the imported module or package. If not provided, it is detected automatically."
213
+ ),
214
+ ] = None,
215
+ proxy_headers: Annotated[
216
+ bool,
217
+ typer.Option(
218
+ help="Enable/Disable X-Forwarded-Proto, X-Forwarded-For, X-Forwarded-Port to populate remote address info."
219
+ ),
220
+ ] = True,
221
+ ) -> Any:
222
+ """
223
+ Run a [bold]FastAPI[/bold] app in [green]production[/green] mode. ๐Ÿš€
224
+
225
+ This is equivalent to [bold]fastapi dev[/bold] but with [bold]reload[/bold] disabled and listening on the [blue]0.0.0.0[/blue] address.
226
+
227
+ It automatically detects the Python module or package that needs to be imported based on the file or directory path passed.
228
+
229
+ If no path is passed, it tries with:
230
+
231
+ - [blue]main.py[/blue]
232
+ - [blue]app.py[/blue]
233
+ - [blue]api.py[/blue]
234
+ - [blue]app/main.py[/blue]
235
+ - [blue]app/app.py[/blue]
236
+ - [blue]app/api.py[/blue]
237
+
238
+ It also detects the directory that needs to be added to the [bold]PYTHONPATH[/bold] to make the app importable and adds it.
239
+
240
+ It detects the [bold]FastAPI[/bold] app object to use. By default it looks in the module or package for an object named:
241
+
242
+ - [blue]app[/blue]
243
+ - [blue]api[/blue]
244
+
245
+ Otherwise, it uses the first [bold]FastAPI[/bold] app found in the imported module or package.
246
+ """
247
+ _run(
248
+ path=path,
249
+ host=host,
250
+ port=port,
251
+ reload=reload,
252
+ root_path=root_path,
253
+ app=app,
254
+ command="run",
255
+ proxy_headers=proxy_headers,
256
+ )
257
+
258
+
259
+ def main() -> None:
260
+ app()
@@ -0,0 +1,163 @@
1
+ import importlib
2
+ import sys
3
+ from dataclasses import dataclass
4
+ from logging import getLogger
5
+ from pathlib import Path
6
+ from typing import Union
7
+
8
+ from fastapi import FastAPI
9
+ from rich import print
10
+ from rich.padding import Padding
11
+ from rich.panel import Panel
12
+ from rich.syntax import Syntax
13
+ from rich.tree import Tree
14
+
15
+ from fastapi_cli.exceptions import FastAPICLIException
16
+
17
+ logger = getLogger(__name__)
18
+
19
+
20
+ def get_default_path() -> Path:
21
+ path = Path("main.py")
22
+ if path.is_file():
23
+ return path
24
+ path = Path("app.py")
25
+ if path.is_file():
26
+ return path
27
+ path = Path("api.py")
28
+ if path.is_file():
29
+ return path
30
+ path = Path("app/main.py")
31
+ if path.is_file():
32
+ return path
33
+ path = Path("app/app.py")
34
+ if path.is_file():
35
+ return path
36
+ path = Path("app/api.py")
37
+ if path.is_file():
38
+ return path
39
+ raise FastAPICLIException(
40
+ "Could not find a default file to run, please provide an explicit path"
41
+ )
42
+
43
+
44
+ @dataclass
45
+ class ModuleData:
46
+ module_import_str: str
47
+ extra_sys_path: Path
48
+
49
+
50
+ def get_module_data_from_path(path: Path) -> ModuleData:
51
+ logger.info(
52
+ "Searching for package file structure from directories with [blue]__init__.py[/blue] files"
53
+ )
54
+ use_path = path.resolve()
55
+ module_path = use_path
56
+ if use_path.is_file() and use_path.stem == "__init__":
57
+ module_path = use_path.parent
58
+ module_paths = [module_path]
59
+ extra_sys_path = module_path.parent
60
+ for parent in module_path.parents:
61
+ init_path = parent / "__init__.py"
62
+ if init_path.is_file():
63
+ module_paths.insert(0, parent)
64
+ extra_sys_path = parent.parent
65
+ else:
66
+ break
67
+ logger.info(f"Importing from {extra_sys_path.resolve()}")
68
+ root = module_paths[0]
69
+ name = f"๐Ÿ {root.name}" if root.is_file() else f"๐Ÿ“ {root.name}"
70
+ root_tree = Tree(name)
71
+ if root.is_dir():
72
+ root_tree.add("[dim]๐Ÿ __init__.py[/dim]")
73
+ tree = root_tree
74
+ for sub_path in module_paths[1:]:
75
+ sub_name = (
76
+ f"๐Ÿ {sub_path.name}" if sub_path.is_file() else f"๐Ÿ“ {sub_path.name}"
77
+ )
78
+ tree = tree.add(sub_name)
79
+ if sub_path.is_dir():
80
+ tree.add("[dim]๐Ÿ __init__.py[/dim]")
81
+ title = "[b green]Python module file[/b green]"
82
+ if len(module_paths) > 1 or module_path.is_dir():
83
+ title = "[b green]Python package file structure[/b green]"
84
+ panel = Padding(
85
+ Panel(
86
+ root_tree,
87
+ title=title,
88
+ expand=False,
89
+ padding=(1, 2),
90
+ ),
91
+ 1,
92
+ )
93
+ print(panel)
94
+ module_str = ".".join(p.stem for p in module_paths)
95
+ logger.info(f"Importing module [green]{module_str}[/green]")
96
+ return ModuleData(
97
+ module_import_str=module_str, extra_sys_path=extra_sys_path.resolve()
98
+ )
99
+
100
+
101
+ def get_app_name(*, mod_data: ModuleData, app_name: Union[str, None] = None) -> str:
102
+ try:
103
+ mod = importlib.import_module(mod_data.module_import_str)
104
+ except (ImportError, ValueError) as e:
105
+ logger.error(f"Import error: {e}")
106
+ logger.warning(
107
+ "Ensure all the package directories have an [blue]__init__.py[/blue] file"
108
+ )
109
+ raise
110
+ object_names = dir(mod)
111
+ object_names_set = set(object_names)
112
+ if app_name:
113
+ if app_name not in object_names_set:
114
+ raise FastAPICLIException(
115
+ f"Could not find app name {app_name} in {mod_data.module_import_str}"
116
+ )
117
+ app = getattr(mod, app_name)
118
+ if not isinstance(app, FastAPI):
119
+ raise FastAPICLIException(
120
+ f"The app name {app_name} in {mod_data.module_import_str} doesn't seem to be a FastAPI app"
121
+ )
122
+ return app_name
123
+ for preferred_name in ["app", "api"]:
124
+ if preferred_name in object_names_set:
125
+ obj = getattr(mod, preferred_name)
126
+ if isinstance(obj, FastAPI):
127
+ return preferred_name
128
+ for name in object_names:
129
+ obj = getattr(mod, name)
130
+ if isinstance(obj, FastAPI):
131
+ return name
132
+ raise FastAPICLIException("Could not find FastAPI app in module, try using --app")
133
+
134
+
135
+ def get_import_string(
136
+ *, path: Union[Path, None] = None, app_name: Union[str, None] = None
137
+ ) -> str:
138
+ if not path:
139
+ path = get_default_path()
140
+ logger.info(f"Using path [blue]{path}[/blue]")
141
+ logger.info(f"Resolved absolute path {path.resolve()}")
142
+ if not path.exists():
143
+ raise FastAPICLIException(f"Path does not exist {path}")
144
+ mod_data = get_module_data_from_path(path)
145
+ sys.path.insert(0, str(mod_data.extra_sys_path))
146
+ use_app_name = get_app_name(mod_data=mod_data, app_name=app_name)
147
+ import_example = Syntax(
148
+ f"from {mod_data.module_import_str} import {use_app_name}", "python"
149
+ )
150
+ import_panel = Padding(
151
+ Panel(
152
+ import_example,
153
+ title="[b green]Importable FastAPI app[/b green]",
154
+ expand=False,
155
+ padding=(1, 2),
156
+ ),
157
+ 1,
158
+ )
159
+ logger.info("Found importable FastAPI app")
160
+ print(import_panel)
161
+ import_string = f"{mod_data.module_import_str}:{use_app_name}"
162
+ logger.info(f"Using import string [b green]{import_string}[/b green]")
163
+ return import_string
@@ -0,0 +1,2 @@
1
+ class FastAPICLIException(Exception):
2
+ pass
fastapi_cli/logging.py ADDED
@@ -0,0 +1,23 @@
1
+ import logging
2
+ from typing import Union
3
+
4
+ from rich.console import Console
5
+ from rich.logging import RichHandler
6
+
7
+
8
+ def setup_logging(terminal_width: Union[int, None] = None) -> None:
9
+ logger = logging.getLogger("fastapi_cli")
10
+ console = Console(width=terminal_width) if terminal_width else None
11
+ rich_handler = RichHandler(
12
+ show_time=False,
13
+ rich_tracebacks=True,
14
+ tracebacks_show_locals=True,
15
+ markup=True,
16
+ show_path=False,
17
+ console=console,
18
+ )
19
+ rich_handler.setFormatter(logging.Formatter("%(message)s"))
20
+ logger.addHandler(rich_handler)
21
+
22
+ logger.setLevel(logging.INFO)
23
+ logger.propagate = False
fastapi_cli/py.typed ADDED
File without changes
@@ -0,0 +1,143 @@
1
+ Metadata-Version: 2.1
2
+ Name: fastapi-cli
3
+ Version: 0.0.2
4
+ Summary: Run and manage FastAPI apps from the command line with FastAPI CLI. ๐Ÿš€
5
+ Home-page: https://github.com/tiangolo/fastapi-cli
6
+ Author-Email: =?utf-8?q?Sebasti=C3=A1n_Ram=C3=ADrez?= <tiangolo@gmail.com>
7
+ License: MIT
8
+ Classifier: Intended Audience :: Information Technology
9
+ Classifier: Intended Audience :: System Administrators
10
+ Classifier: Operating System :: OS Independent
11
+ Classifier: Programming Language :: Python :: 3
12
+ Classifier: Programming Language :: Python
13
+ Classifier: Topic :: Software Development :: Libraries :: Application Frameworks
14
+ Classifier: Topic :: Software Development :: Libraries :: Python Modules
15
+ Classifier: Topic :: Software Development :: Libraries
16
+ Classifier: Topic :: Software Development
17
+ Classifier: Typing :: Typed
18
+ Classifier: Development Status :: 4 - Beta
19
+ Classifier: Framework :: FastAPI
20
+ Classifier: Intended Audience :: Developers
21
+ Classifier: License :: OSI Approved :: MIT License
22
+ Classifier: Programming Language :: Python :: 3 :: Only
23
+ Classifier: Programming Language :: Python :: 3.7
24
+ Classifier: Programming Language :: Python :: 3.8
25
+ Classifier: Programming Language :: Python :: 3.9
26
+ Classifier: Programming Language :: Python :: 3.10
27
+ Classifier: Programming Language :: Python :: 3.11
28
+ Classifier: Programming Language :: Python :: 3.12
29
+ Classifier: License :: OSI Approved :: MIT License
30
+ Project-URL: Documentation, https://fastapi.tiangolo.com
31
+ Project-URL: Homepage, https://github.com/tiangolo/fastapi-cli
32
+ Project-URL: Repository, https://github.com/tiangolo/fastapi-cli
33
+ Requires-Python: >=3.8
34
+ Requires-Dist: typer>=0.12.3
35
+ Requires-Dist: fastapi
36
+ Requires-Dist: uvicorn[standard]>=0.29.0
37
+ Description-Content-Type: text/markdown
38
+
39
+ # FastAPI CLI
40
+
41
+ <a href="https://github.com/tiangolo/fastapi-cli/actions/workflows/test.yml" target="_blank">
42
+ <img src="https://github.com/tiangolo/fastapi-cli/actions/workflows/test.yml/badge.svg" alt="Test">
43
+ </a>
44
+ <a href="https://github.com/tiangolo/fastapi-cli/actions/workflows/publish.yml" target="_blank">
45
+ <img src="https://github.com/tiangolo/fastapi-cli/actions/workflows/publish.yml/badge.svg" alt="Publish">
46
+ </a>
47
+ <a href="https://coverage-badge.samuelcolvin.workers.dev/redirect/tiangolo/fastapi-cli" target="_blank">
48
+ <img src="https://coverage-badge.samuelcolvin.workers.dev/tiangolo/fastapi-cli.svg" alt="Coverage">
49
+ <a href="https://pypi.org/project/fastapi-cli" target="_blank">
50
+ <img src="https://img.shields.io/pypi/v/fastapi-cli?color=%2334D058&label=pypi%20package" alt="Package version">
51
+ </a>
52
+
53
+ ---
54
+
55
+ **Source Code**: <a href="https://github.com/tiangolo/fastapi-cli" target="_blank">https://github.com/tiangolo/fastapi-cli</a>
56
+
57
+ ---
58
+
59
+ Run and manage FastAPI apps from the command line with FastAPI CLI. ๐Ÿš€
60
+
61
+ ## Description
62
+
63
+ **FastAPI CLI** is a command line program `fastapi` that you can use to serve your FastAPI app, manage your FastAPI project, and more.
64
+
65
+ When you install FastAPI (e.g. with `pip install fastapi`), it includes a package called `fastapi-cli`, this package provides the `fastapi` command in the terminal.
66
+
67
+ To run your FastAPI app for development, you can use the `fastapi dev` command:
68
+
69
+ <div class="termy">
70
+
71
+ ```console
72
+ $ fastapi dev main.py
73
+ INFO Using path main.py
74
+ INFO Resolved absolute path /home/user/code/awesomeapp/main.py
75
+ INFO Searching for package file structure from directories with __init__.py files
76
+ INFO Importing from /home/user/code/awesomeapp
77
+
78
+ โ•ญโ”€ Python module file โ”€โ•ฎ
79
+ โ”‚ โ”‚
80
+ โ”‚ ๐Ÿ main.py โ”‚
81
+ โ”‚ โ”‚
82
+ โ•ฐโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ•ฏ
83
+
84
+ INFO Importing module main
85
+ INFO Found importable FastAPI app
86
+
87
+ โ•ญโ”€ Importable FastAPI app โ”€โ•ฎ
88
+ โ”‚ โ”‚
89
+ โ”‚ from main import app โ”‚
90
+ โ”‚ โ”‚
91
+ โ•ฐโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ•ฏ
92
+
93
+ INFO Using import string main:app
94
+
95
+ โ•ญโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€ FastAPI CLI - Development mode โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ•ฎ
96
+ โ”‚ โ”‚
97
+ โ”‚ Serving at: http://127.0.0.1:8000 โ”‚
98
+ โ”‚ โ”‚
99
+ โ”‚ API docs: http://127.0.0.1:8000/docs โ”‚
100
+ โ”‚ โ”‚
101
+ โ”‚ Running in development mode, for production use: โ”‚
102
+ โ”‚ โ”‚
103
+ โ”‚ fastapi run โ”‚
104
+ โ”‚ โ”‚
105
+ โ•ฐโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ•ฏ
106
+
107
+ INFO: Will watch for changes in these directories: ['/home/user/code/awesomeapp']
108
+ INFO: Uvicorn running on http://127.0.0.1:8000 (Press CTRL+C to quit)
109
+ INFO: Started reloader process [56345] using WatchFiles
110
+ INFO: Started server process [56352]
111
+ INFO: Waiting for application startup.
112
+ INFO: Application startup complete.
113
+ ```
114
+
115
+ </div>
116
+
117
+ That command line program called `fastapi` is **FastAPI CLI**.
118
+
119
+ FastAPI CLI takes the path to your Python program and automatically detects the variable with the FastAPI (commonly named `app`) and how to import it, and then serves it.
120
+
121
+ For production you would use `fastapi run` instead. ๐Ÿš€
122
+
123
+ ## `fastapi dev`
124
+
125
+ When you run `fastapi dev`, it will run on development mode.
126
+
127
+ By default, it will have **auto-reload** enabled, so it will automatically reload the server when you make changes to your code. This is resource intensive and could be less stable than without it, you should only use it for development.
128
+
129
+ By default it will listen on the IP address `127.0.0.1`, which is the IP for your machine to communicate with itself alone (`localhost`).
130
+
131
+ ## `fastapi run`
132
+
133
+ When you run `fastapi run`, it will run on production mode by default.
134
+
135
+ It will have **auto-reload disabled** by default.
136
+
137
+ It will listen on the IP address `0.0.0.0`, which means all the available IP addresses, this way it will be publicly accessible to anyone that can communicate with the machine. This is how you would normally run it in production, for example, in a container.
138
+
139
+ In most cases you would (and should) have a "termination proxy" handling HTTPS for you on top, this will depend on how you deploy your application, your provider might do this for you, or you might need to set it up yourself. You can learn more about it in the <a href="https://fastapi.tiangolo.com/deployment/" class="external-link" target="_blank">FastAPI Deployment documentation</a>.
140
+
141
+ ## License
142
+
143
+ This project is licensed under the terms of the MIT license.
@@ -0,0 +1,12 @@
1
+ fastapi_cli-0.0.2.dist-info/METADATA,sha256=DADt2yADHsKGZzCrzC4bcnF7ZKyHZnmaGPXSjmEzRVc,6780
2
+ fastapi_cli-0.0.2.dist-info/WHEEL,sha256=vnE8JVcI2Wz7GRKorsPArnBdnW2SWKWGow5gu5tHlRU,90
3
+ fastapi_cli-0.0.2.dist-info/entry_points.txt,sha256=RLUGtkrAf9gNKxCS3EeJNYN8AF1Er364vjW7bnEcCA8,50
4
+ fastapi_cli-0.0.2.dist-info/licenses/LICENSE,sha256=FqD5B4VbXJnefprQseE0U8llL6FxojC-i8muZy7YmSU,1086
5
+ fastapi_cli/__init__.py,sha256=QvlVh4JTl3JL7jQAja76yKtT-IvF4631ASjWY1wS6AQ,22
6
+ fastapi_cli/__main__.py,sha256=bYt9eEaoRQWdejEHFD8REx9jxVEdZptECFsV7F49Ink,30
7
+ fastapi_cli/cli.py,sha256=OkiQenSf9HgBN7FxTTAoLfzqySsX1Z6FGxlRU7ILcGM,8754
8
+ fastapi_cli/discover.py,sha256=5QbjDHEbfNUQoYG7ZXRfYWvSJkj74ojkFtzUftPb2VE,5285
9
+ fastapi_cli/exceptions.py,sha256=AHRSqd43fbqN5IpX-Fq389k9MoEK_q28wVFL7oqPNcc,47
10
+ fastapi_cli/logging.py,sha256=lI7rIsioTJQsxDuWpG5YR_brWpIAUY4vDnhYm5p91ws,664
11
+ fastapi_cli/py.typed,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
12
+ fastapi_cli-0.0.2.dist-info/RECORD,,
@@ -1,4 +1,4 @@
1
1
  Wheel-Version: 1.0
2
- Generator: poetry 0.12.17
2
+ Generator: pdm-backend (2.3.0)
3
3
  Root-Is-Purelib: true
4
4
  Tag: py3-none-any
@@ -0,0 +1,3 @@
1
+ [console_scripts]
2
+ fastapi = fastapi_cli.cli:main
3
+
@@ -0,0 +1,21 @@
1
+ The MIT License (MIT)
2
+
3
+ Copyright (c) 2024 Sebastiรกn Ramรญrez
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in
13
+ all copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
21
+ THE SOFTWARE.
@@ -1,11 +0,0 @@
1
- Metadata-Version: 2.1
2
- Name: fastapi-cli
3
- Version: 0.0.1
4
- Summary:
5
- Author: Sebastiรกn Ramรญrez
6
- Author-email: tiangolo@gmail.com
7
- Requires-Python: >=3.6,<4.0
8
- Classifier: Programming Language :: Python :: 3
9
- Classifier: Programming Language :: Python :: 3.6
10
- Classifier: Programming Language :: Python :: 3.7
11
- Requires-Dist: importlib_metadata (>=1.5,<2.0)
@@ -1,4 +0,0 @@
1
- fastapi_cli/__init__.py,sha256=5RpLGahop916SeM-IBybvWyDoKIuatfa3Aw-NIlBIgA,75
2
- fastapi_cli-0.0.1.dist-info/WHEEL,sha256=f_L0I4hqSDuunYLcjib7afhVEQa4uCwremk0_wPx54s,85
3
- fastapi_cli-0.0.1.dist-info/METADATA,sha256=w7fBwjwDWvtDXARBL_HqBIUjTa0r76nhlyhsXm2UEgw,349
4
- fastapi_cli-0.0.1.dist-info/RECORD,,