Skip to content

Commit

Permalink
Add tool to keep CLI usage in index.md in sync (encode#876)
Browse files Browse the repository at this point in the history
* Add tool to keep CLI usage in `index.md` in sync

* Ensure final newline

* Keep deployment.md in sync as well

* Rename and reorganize tool
  • Loading branch information
florimondmanca authored Dec 9, 2020
1 parent 1b36d69 commit 5311e11
Show file tree
Hide file tree
Showing 6 changed files with 143 additions and 15 deletions.
39 changes: 33 additions & 6 deletions docs/deployment.md
Original file line number Diff line number Diff line change
Expand Up @@ -23,36 +23,47 @@ When running locally, use `--reload` to turn on auto-reloading.

To see the complete set of available options, use `uvicorn --help`:

<!-- :cli_usage: -->
```
$ uvicorn --help
Usage: uvicorn [OPTIONS] APP
Options:
--host TEXT Bind socket to this host. [default:
127.0.0.1]
--port INTEGER Bind socket to this port. [default: 8000]
--uds TEXT Bind to a UNIX domain socket.
--fd INTEGER Bind to socket from this file descriptor.
--reload Enable auto-reload.
--reload-dir TEXT Set reload directories explicitly, instead
of using the current working directory.
--reload-delay FLOAT Delay between previous and next check if
application needs to be. Defaults to 0.25s.
[default: 0.25]
--workers INTEGER Number of worker processes. Defaults to the
$WEB_CONCURRENCY environment variable if
available. Not valid with --reload.
--loop [auto|asyncio|uvloop]
Event loop implementation. [default: auto]
--loop [auto|asyncio|uvloop] Event loop implementation. [default: auto]
--http [auto|h11|httptools] HTTP protocol implementation. [default:
auto]
--ws [auto|none|websockets|wsproto]
WebSocket protocol implementation.
[default: auto]
--lifespan [auto|on|off] Lifespan implementation. [default: auto]
--interface [auto|asgi3|asgi2|wsgi]
Select ASGI3, ASGI2, or WSGI as the
application interface. [default: auto]
--env-file PATH Environment configuration file.
--log-config PATH Logging configuration file.
Supported formats (.ini, .json, .yaml)
--log-config PATH Logging configuration file. Supported
formats: .ini, .json, .yaml.
--log-level [critical|error|warning|info|debug|trace]
Log level. [default: info]
--access-log / --no-access-log Enable/Disable access log.
Expand All @@ -61,37 +72,53 @@ Options:
Enable/Disable X-Forwarded-Proto,
X-Forwarded-For, X-Forwarded-Port to
populate remote address info.
--forwarded-allow-ips TEXT Comma seperated list of IPs to trust with
proxy headers. Defaults to the
$FORWARDED_ALLOW_IPS environment variable if
available, or '127.0.0.1'.
--root-path TEXT Set the ASGI 'root_path' for applications
submounted below a given URL path.
--limit-concurrency INTEGER Maximum number of concurrent connections or
tasks to allow, before issuing HTTP 503
responses.
--backlog INTEGER Maximum number of connections to hold in
backlog
--limit-max-requests INTEGER Maximum number of requests to service before
terminating the process.
--timeout-keep-alive INTEGER Close Keep-Alive connections if no new data
is received within this timeout. [default:
5]
--ssl-keyfile TEXT SSL key file
--ssl-certfile TEXT SSL certificate file
--ssl-keyfile-password TEXT SSL key file password
--ssl-keyfile-password TEXT SSL keyfile password
--ssl-version INTEGER SSL version to use (see stdlib ssl module's)
[default: 2]
--ssl-cert-reqs INTEGER Whether client certificate is required (see
stdlib ssl module's) [default: 0]
--ssl-ca-certs TEXT CA certificates file
--ssl-ciphers TEXT Ciphers to use (see stdlib ssl module's)
[default: TLSv1]
--header TEXT Specify custom default HTTP response headers
as a Name:Value pair
--version Display the uvicorn version and exit.
--app-dir TEXT Look for APP in the specified directory, by
adding this to the PYTHONPATH. Defaults to
the current working directory.
the current working directory. [default: .]
--factory Treat APP as an application factory, i.e. a
() -> <ASGI app> callable. [default: False]
--help Show this message and exit.
```

Expand Down
43 changes: 36 additions & 7 deletions docs/index.md
Original file line number Diff line number Diff line change
Expand Up @@ -93,35 +93,47 @@ The uvicorn command line tool is the easiest way to run your application...

### Command line options

<!-- :cli_usage: -->
```
$ uvicorn --help
Usage: uvicorn [OPTIONS] APP
Options:
--host TEXT Bind socket to this host. [default:
127.0.0.1]
--port INTEGER Bind socket to this port. [default: 8000]
--uds TEXT Bind to a UNIX domain socket.
--fd INTEGER Bind to socket from this file descriptor.
--reload Enable auto-reload.
--reload-dir TEXT Set reload directories explicitly, instead
of using the current working directory.
--reload-delay FLOAT Delay between previous and next check if
application needs to be. Defaults to 0.25s.
[default: 0.25]
--workers INTEGER Number of worker processes. Defaults to the
$WEB_CONCURRENCY environment variable if
available. Not valid with --reload.
--loop [auto|asyncio|uvloop]
Event loop implementation. [default: auto]
--loop [auto|asyncio|uvloop] Event loop implementation. [default: auto]
--http [auto|h11|httptools] HTTP protocol implementation. [default:
auto]
--ws [auto|none|websockets|wsproto]
WebSocket protocol implementation.
[default: auto]
--lifespan [auto|on|off] Lifespan implementation. [default: auto]
--interface [auto|asgi3|asgi2|wsgi]
Select ASGI3, ASGI2, or WSGI as the
application interface. [default: auto]
--env-file PATH Environment configuration file.
--log-config PATH Logging configuration file.
Supported formats (.ini, .json, .yaml)
--log-config PATH Logging configuration file. Supported
formats: .ini, .json, .yaml.
--log-level [critical|error|warning|info|debug|trace]
Log level. [default: info]
--access-log / --no-access-log Enable/Disable access log.
Expand All @@ -130,36 +142,53 @@ Options:
Enable/Disable X-Forwarded-Proto,
X-Forwarded-For, X-Forwarded-Port to
populate remote address info.
--forwarded-allow-ips TEXT Comma separated list of IPs to trust with
--forwarded-allow-ips TEXT Comma seperated list of IPs to trust with
proxy headers. Defaults to the
$FORWARDED_ALLOW_IPS environment variable if
available, or '127.0.0.1'.
--root-path TEXT Set the ASGI 'root_path' for applications
submounted below a given URL path.
--limit-concurrency INTEGER Maximum number of concurrent connections or
tasks to allow, before issuing HTTP 503
responses.
--backlog INTEGER Maximum number of connections to hold in
backlog
--limit-max-requests INTEGER Maximum number of requests to service before
terminating the process.
--timeout-keep-alive INTEGER Close Keep-Alive connections if no new data
is received within this timeout. [default:
5]
--ssl-keyfile TEXT SSL key file
--ssl-certfile TEXT SSL certificate file
--ssl-keyfile-password TEXT SSL key file password
--ssl-keyfile-password TEXT SSL keyfile password
--ssl-version INTEGER SSL version to use (see stdlib ssl module's)
[default: 2]
--ssl-cert-reqs INTEGER Whether client certificate is required (see
stdlib ssl module's) [default: 0]
--ssl-ca-certs TEXT CA certificates file
--ssl-ciphers TEXT Ciphers to use (see stdlib ssl module's)
[default: TLSv1]
--header TEXT Specify custom default HTTP response headers
as a Name:Value pair
--version Display the uvicorn version and exit.
--app-dir TEXT Look for APP in the specified directory, by
adding this to the PYTHONPATH. Defaults to
the current working directory. [default: .]
--factory Treat APP as an application factory, i.e. a
() -> <ASGI app> function. [default: False]
() -> <ASGI app> callable. [default: False]
--help Show this message and exit.
```

Expand Down
3 changes: 2 additions & 1 deletion scripts/check
Original file line number Diff line number Diff line change
Expand Up @@ -11,4 +11,5 @@ set -x
${PREFIX}black --check --diff --target-version=py36 $SOURCE_FILES
${PREFIX}flake8 $SOURCE_FILES
${PREFIX}mypy
${PREFIX}isort --check --diff --project=uvicorn $SOURCE_FILES
${PREFIX}isort --check --diff --project=uvicorn $SOURCE_FILES
${PREFIX}python -m tools.cli_usage --check
1 change: 1 addition & 0 deletions scripts/lint
Original file line number Diff line number Diff line change
Expand Up @@ -11,3 +11,4 @@ set -x
${PREFIX}autoflake --in-place --recursive $SOURCE_FILES
${PREFIX}isort --project=uvicorn $SOURCE_FILES
${PREFIX}black --target-version=py36 $SOURCE_FILES
${PREFIX}python -m tools.cli_usage
70 changes: 70 additions & 0 deletions tools/cli_usage.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,70 @@
"""
Look for a marker comment in docs pages, and place the output of
`$ uvicorn --help` there. Pass `--check` to ensure the content is in sync.
"""
import argparse
import subprocess
import sys
import typing
from pathlib import Path


def _get_usage_lines() -> typing.List[str]:
res = subprocess.run(["uvicorn", "--help"], stdout=subprocess.PIPE)
help_text = res.stdout.decode("utf-8")
return ["```", "$ uvicorn --help", *help_text.splitlines(), "```"]


def _find_next_codefence_lineno(lines: typing.List[str], after: int) -> int:
return next(
lineno for lineno, line in enumerate(lines[after:], after) if line == "```"
)


def _get_insert_location(lines: typing.List[str]) -> typing.Tuple[int, int]:
marker = lines.index("<!-- :cli_usage: -->")
start = marker + 1

if lines[start] == "```":
# Already generated.
# <!-- :cli_usage: -->
# ``` <- start
# [...]
# ``` <- end
next_codefence = _find_next_codefence_lineno(lines, after=start + 1)
end = next_codefence + 1
else:
# Not generated yet.
end = start

return start, end


def _generate_cli_usage(path: Path, check: bool = False) -> int:
content = path.read_text()

lines = content.splitlines()
usage_lines = _get_usage_lines()
start, end = _get_insert_location(lines)
lines = lines[:start] + usage_lines + lines[end:]
output = "\n".join(lines) + "\n"

if check:
if content == output:
return 0
print(f"ERROR: CLI usage in {path} is out of sync. Run scripts/lint to fix.")
return 1

path.write_text(output)
return 0


if __name__ == "__main__":
parser = argparse.ArgumentParser()
parser.add_argument("--check", action="store_true")
args = parser.parse_args()
paths = [Path("docs", "index.md"), Path("docs", "deployment.md")]
rv = 0
for path in paths:
rv |= _generate_cli_usage(path, check=args.check)
sys.exit(rv)
2 changes: 1 addition & 1 deletion uvicorn/main.py
Original file line number Diff line number Diff line change
Expand Up @@ -138,7 +138,7 @@ def print_version(ctx, param, value):
"--log-config",
type=click.Path(exists=True),
default=None,
help="Logging configuration file.",
help="Logging configuration file. Supported formats: .ini, .json, .yaml.",
show_default=True,
)
@click.option(
Expand Down

0 comments on commit 5311e11

Please sign in to comment.