Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Document how to run uvicorn programatically #1525

Merged
merged 5 commits into from Jun 20, 2022

Conversation

Kludex
Copy link
Sponsor Member

@Kludex Kludex commented Jun 18, 2022

Accepting suggestions on wording.

@Kludex Kludex added the docs Improve documentation label Jun 18, 2022
@Kludex Kludex mentioned this pull request Jun 18, 2022
5 tasks
Copy link
Member

@florimondmanca florimondmanca left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Nice addition!

I think we also need to change the introduction paragraphs in Settings:

Use the following options to configure Uvicorn, when running from the command line.

If you're running programmatically, using uvicorn.run(...), then use equivalent keyword arguments, eg. uvicorn.run("example:app", port=5000, reload=True, access_log=False). Please note that in this case, if you use reload=True or workers=NUM, you should put uvicorn.run into if __name__ == '__main__' clause in the main module.

You can also configure Uvicorn using environment variables with the prefix UVICORN_. For example, in case you want to run the app on port 5000, just set the environment variable UVICORN_PORT to 5000.

!!! note
    CLI options and the arguments for uvicorn.run() take precedence over environment variables.

    Also note that UVICORN_* prefixed settings cannot be used from within an environment configuration file. Using an environment configuration file with the --env-file flag is intended for configuring the ASGI application that uvicorn runs, rather than configuring uvicorn itself.

Suggestion ⬇️

Use the following options to configure Uvicorn, when running from the command line.

These options are mirrored as keyword arguments when [running programmatically](/index.md#running-programmatically).

Default settings can also be passed as environment variables using the `UVICORN_` prefix. For example, setting `UVICORN_PORT` to `5000` would make Uvicorn serve on port 5000 if `--port` (when using the CLI) or `port` (when running programmatically) have not been passed.

docs/index.md Outdated Show resolved Hide resolved
docs/index.md Outdated Show resolved Hide resolved
docs/index.md Outdated Show resolved Hide resolved
docs/index.md Outdated Show resolved Hide resolved
docs/index.md Outdated Show resolved Hide resolved

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

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

`uvicorn.run` accepts the following arguments:

* `app`: Either an ASGI application, or (as shown above) an import string to the target ASGI application. The latter is required if using auto-reload or multiple workers.
* `**kwargs`: Keyword arguments that mirror command line options (see [Settings](/settings.md)): `--host <str>` becomes `host=<str>`, `--log-level <str>` becomes `log_level=<str>`, etc.

(I think this kind of info is valuable in docs, but maybe we might want to kick off an API Reference page for this kind of thing. I'm OK if we defer this bit from this PR.)

Copy link
Sponsor Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We improved the uvicorn.run type annotation, so we can have autocomplete on it:

uvicorn/uvicorn/main.py

Lines 445 to 492 in b1a4582

def run(
app: typing.Union[ASGIApplication, str],
*,
host: str = "127.0.0.1",
port: int = 8000,
uds: typing.Optional[str] = None,
fd: typing.Optional[int] = None,
loop: LoopSetupType = "auto",
http: HTTPProtocolType = "auto",
ws: WSProtocolType = "auto",
ws_max_size: int = 16777216,
ws_ping_interval: float = 20.0,
ws_ping_timeout: float = 20.0,
ws_per_message_deflate: bool = True,
lifespan: LifespanType = "auto",
interface: InterfaceType = "auto",
debug: bool = False,
reload: bool = False,
reload_dirs: typing.Optional[typing.List[str]] = None,
reload_includes: typing.Optional[typing.List[str]] = None,
reload_excludes: typing.Optional[typing.List[str]] = None,
reload_delay: float = 0.25,
workers: typing.Optional[int] = None,
env_file: typing.Optional[str] = None,
log_config: typing.Optional[typing.Union[dict, str]] = None,
log_level: typing.Optional[str] = None,
access_log: bool = True,
proxy_headers: bool = True,
server_header: bool = True,
date_header: bool = True,
forwarded_allow_ips: typing.Optional[str] = None,
root_path: str = "",
limit_concurrency: typing.Optional[int] = None,
backlog: int = 2048,
limit_max_requests: typing.Optional[int] = None,
timeout_keep_alive: int = 5,
ssl_keyfile: typing.Optional[str] = None,
ssl_certfile: typing.Optional[str] = None,
ssl_keyfile_password: typing.Optional[str] = None,
ssl_version: int = int(SSL_PROTOCOL_VERSION),
ssl_cert_reqs: int = int(ssl.CERT_NONE),
ssl_ca_certs: typing.Optional[str] = None,
ssl_ciphers: str = "TLSv1",
headers: typing.Optional[typing.List[typing.Tuple[str, str]]] = None,
use_colors: typing.Optional[bool] = None,
app_dir: typing.Optional[str] = None,
factory: bool = False,
) -> None:

I'll not apply this for now. An API reference would be fine by me.

docs/index.md Outdated Show resolved Hide resolved
@Kludex
Copy link
Sponsor Member Author

Kludex commented Jun 19, 2022

I knew you would provide a lot of value here. Much appreciated @florimondmanca 🙏

I'm going to apply/reply those tonight. :)

Kludex and others added 3 commits June 19, 2022 18:17
Co-authored-by: Florimond Manca <florimond.manca@gmail.com>
Co-authored-by: Florimond Manca <florimond.manca@gmail.com>
@Kludex
Copy link
Sponsor Member Author

Kludex commented Jun 19, 2022

I've removed the host argument, as the visualization on the docs becomes more clear without it (either that or I need to format the python code...).

Applied the changes. 👍

@Kludex
Copy link
Sponsor Member Author

Kludex commented Jun 19, 2022

Nice addition!

I think we also need to change the introduction paragraphs in Settings:

Use the following options to configure Uvicorn, when running from the command line.

If you're running programmatically, using uvicorn.run(...), then use equivalent keyword arguments, eg. uvicorn.run("example:app", port=5000, reload=True, access_log=False). Please note that in this case, if you use reload=True or workers=NUM, you should put uvicorn.run into if __name__ == '__main__' clause in the main module.

You can also configure Uvicorn using environment variables with the prefix UVICORN_. For example, in case you want to run the app on port 5000, just set the environment variable UVICORN_PORT to 5000.

!!! note
    CLI options and the arguments for uvicorn.run() take precedence over environment variables.

    Also note that UVICORN_* prefixed settings cannot be used from within an environment configuration file. Using an environment configuration file with the --env-file flag is intended for configuring the ASGI application that uvicorn runs, rather than configuring uvicorn itself.

Suggestion ⬇️

Use the following options to configure Uvicorn, when running from the command line.

These options are mirrored as keyword arguments when [running programmatically](/index.md#running-programmatically).

Default settings can also be passed as environment variables using the `UVICORN_` prefix. For example, setting `UVICORN_PORT` to `5000` would make Uvicorn serve on port 5000 if `--port` (when using the CLI) or `port` (when running programmatically) have not been passed.

I think we should mention who takes precedence as well 🤔

@Kludex Kludex added this to the Version 0.18.0 milestone Jun 19, 2022
Copy link
Member

@euri10 euri10 left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

lgtm, with or without a minor comment


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

```python
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
```python
main.py
```python

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

just to say this is the name of the file, I'll approve it without this change but we have too many people not understanding how the app string works

Copy link
Sponsor Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Added on the first file here.

docs/index.md Show resolved Hide resolved
@Kludex Kludex merged commit 39621c2 into master Jun 20, 2022
@Kludex Kludex deleted the document-programmatically-uvicorn branch June 20, 2022 20:05
Kludex added a commit to sephioh/uvicorn that referenced this pull request Oct 29, 2022
* Document how to run uvicorn programatically

* Apply suggestions from code review

Co-authored-by: Florimond Manca <florimond.manca@gmail.com>

* Apply suggestions from code review

Co-authored-by: Florimond Manca <florimond.manca@gmail.com>

* Shrink configuration command

* Update docs/index.md

Co-authored-by: Florimond Manca <florimond.manca@gmail.com>
Kludex added a commit that referenced this pull request Oct 29, 2022
* Document how to run uvicorn programatically

* Apply suggestions from code review

Co-authored-by: Florimond Manca <florimond.manca@gmail.com>

* Apply suggestions from code review

Co-authored-by: Florimond Manca <florimond.manca@gmail.com>

* Shrink configuration command

* Update docs/index.md

Co-authored-by: Florimond Manca <florimond.manca@gmail.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
docs Improve documentation
Projects
None yet
Development

Successfully merging this pull request may close these issues.

Documentation for uvicorn.{Server, Config}
3 participants