Skip to content

Commit

Permalink
Add example how to run the server programmatically with reload (#1572)
Browse files Browse the repository at this point in the history
Co-authored-by: Sergei Tsaplin <s_tsaplin@wargaming.net>
Co-authored-by: Marcelo Trylesinski <marcelotryle@gmail.com>
  • Loading branch information
3 people committed Oct 29, 2022
1 parent e05c6e8 commit aaff189
Show file tree
Hide file tree
Showing 4 changed files with 42 additions and 18 deletions.
6 changes: 3 additions & 3 deletions README.md
Expand Up @@ -52,9 +52,9 @@ Moreover, "optional extras" means that:
- `python-dotenv` will be installed should you want to use the `--env-file` option.
- `PyYAML` will be installed to allow you to provide a `.yaml` file to `--log-config`, if desired.

Create an application, in `example.py`:
Create an application:

```python
```py title="main.py"
async def app(scope, receive, send):
assert scope['type'] == 'http'

Expand All @@ -74,7 +74,7 @@ async def app(scope, receive, send):
Run the server:

```shell
$ uvicorn example:app
$ uvicorn main:app
```

---
Expand Down
34 changes: 30 additions & 4 deletions docs/deployment.md
Expand Up @@ -135,9 +135,7 @@ See the [settings documentation](settings.md) for more details on the supported

To run directly from within a Python program, you should use `uvicorn.run(app, **config)`. For example:

**example.py**:

```python
```py title="main.py"
import uvicorn

class App:
Expand All @@ -146,7 +144,7 @@ class App:
app = App()

if __name__ == "__main__":
uvicorn.run("example:app", host="127.0.0.1", port=5000, log_level="info")
uvicorn.run("main:app", host="127.0.0.1", port=5000, log_level="info")
```

The set of configuration options is the same as for the command line tool.
Expand All @@ -166,6 +164,34 @@ Also note that in this case, you should put `uvicorn.run` into `if __name__ == '
!!! note
The `reload` and `workers` parameters are **mutually exclusive**.


To run the server programmatically with the `reload` option, you should additionally use the `ChangeReload` supervisor. For example:

```py title="main.py"
import os
import uvicorn
from uvicorn.supervisors import ChangeReload

class App:
...

app = App()

if __name__ == "__main__":
reload_dir = os.path.dirname(__file__)
config = uvicorn.Config(
"main:app",
host="127.0.0.1",
port=5000,
log_level="info",
reload=True,
reload_dirs=[reload_dir]
)
server = uvicorn.Server(config)
sock = config.bind_socket()
ChangeReload(config, target=server.run, sockets=[sock]).run()
```

## Using a process manager

Running Uvicorn using a process manager ensures that you can run multiple processes in a resilient manner, and allows you to perform server upgrades without dropping requests.
Expand Down
19 changes: 8 additions & 11 deletions docs/index.md
Expand Up @@ -59,9 +59,9 @@ Moreover, "optional extras" means that:
- `python-dotenv` will be installed should you want to use the `--env-file` option.
- `PyYAML` will be installed to allow you to provide a `.yaml` file to `--log-config`, if desired.

Create an application, in `example.py`:
Create an application:

```python
```py title="main.py"
async def app(scope, receive, send):
assert scope['type'] == 'http'

Expand All @@ -81,7 +81,7 @@ async def app(scope, receive, send):
Run the server:

```shell
$ uvicorn example:app
$ uvicorn main:app
```

---
Expand Down Expand Up @@ -205,8 +205,7 @@ There are several ways to run uvicorn directly from your application.

If you're looking for a programmatic equivalent of the `uvicorn` command line interface, use `uvicorn.run()`:

```python
# main.py
```py title="main.py"
import uvicorn

async def app(scope, receive, send):
Expand All @@ -220,7 +219,7 @@ if __name__ == "__main__":

For more control over configuration and server lifecycle, use `uvicorn.Config` and `uvicorn.Server`:

```python
```py title="main.py"
import uvicorn

async def app(scope, receive, send):
Expand All @@ -234,7 +233,7 @@ if __name__ == "__main__":

If you'd like to run Uvicorn from an already running async environment, use `uvicorn.Server.serve()` instead:

```python
```py title="main.py"
import asyncio
import uvicorn

Expand Down Expand Up @@ -275,16 +274,14 @@ For more information, see the [deployment documentation](deployment.md).

The `--factory` flag allows loading the application from a factory function, rather than an application instance directly. The factory will be called with no arguments and should return an ASGI application.

**example.py**:

```python
```py title="main.py"
def create_app():
app = ...
return app
```

```shell
$ uvicorn --factory example:create_app
$ uvicorn --factory main:create_app
```

## The ASGI interface
Expand Down
1 change: 1 addition & 0 deletions mkdocs.yml
Expand Up @@ -29,6 +29,7 @@ nav:
- Contributing: "contributing.md"

markdown_extensions:
- pymdownx.superfences
- admonition
- codehilite:
css_class: highlight
Expand Down

0 comments on commit aaff189

Please sign in to comment.