Skip to content

Commit

Permalink
Align most of scripts of httpx here (#739)
Browse files Browse the repository at this point in the history
* WIP switch to same layout as httpx

* Align scripts on httpx layout

* Added scripts, they were ignre by my global gitignore

* Mimic httpx workflow better

* version is in init file

* Added twine and wheel for new scripts

* Added mkdocs for win build

* Putting the failing overage level to 80 to please windows CI, once this lands we're gonna grind coverage !

* Removed mypy from check

* Removed useless marker

* Removed check script
  • Loading branch information
euri10 authored Aug 6, 2020
1 parent 52e1bf4 commit e77e596
Show file tree
Hide file tree
Showing 22 changed files with 158 additions and 52 deletions.
11 changes: 0 additions & 11 deletions .codecov.yml

This file was deleted.

6 changes: 5 additions & 1 deletion .github/workflows/publish.yml
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,11 @@ jobs:
- uses: "actions/setup-python@v1"
with:
python-version: 3.7
- name: "Publish"
- name: "Install dependencies"
run: "scripts/install"
- name: "Build package & docs"
run: "scripts/build"
- name: "Publish to PyPI & deploy docs"
run: "scripts/publish"
env:
TWINE_USERNAME: __token__
Expand Down
9 changes: 9 additions & 0 deletions .github/workflows/test-suite.yml
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,15 @@ jobs:
- name: "Install dependencies"
run: "scripts/install"
shell: bash
- name: "Run linting checks"
run: "scripts/check"
shell: bash
- name: "Build package & docs"
run: "scripts/build"
shell: bash
- name: "Run tests"
run: "scripts/test"
shell: bash
- name: "Enforce coverage"
run: "scripts/coverage"
shell: bash
5 changes: 5 additions & 0 deletions requirements.txt
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,10 @@ uvloop>=0.14.0
websockets==8.*
wsproto==0.13.*

# Packaging
twine
wheel

# Testing
autoflake
black
Expand All @@ -16,6 +20,7 @@ isort
pytest
pytest-cov
requests
seed-isort-config

# Documentation
mkdocs
Expand Down
9 changes: 9 additions & 0 deletions requirements_windows.txt
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,10 @@ h11
websockets==8.*
wsproto==0.13.*

# Packaging
twine
wheel

# Testing
autoflake
black
Expand All @@ -14,6 +18,11 @@ isort
pytest
pytest-cov
requests
seed-isort-config

# Documentation
mkdocs
mkdocs-material

# Efficient debug reload
watchgod>=0.6,<0.7
13 changes: 13 additions & 0 deletions scripts/build
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
#!/bin/sh -e

if [ -d 'venv' ] ; then
PREFIX="venv/bin/"
else
PREFIX=""
fi

set -x

${PREFIX}python setup.py sdist bdist_wheel
${PREFIX}twine check dist/*
${PREFIX}mkdocs build
13 changes: 13 additions & 0 deletions scripts/check
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
#!/bin/sh -e

export PREFIX=""
if [ -d 'venv' ] ; then
export PREFIX="venv/bin/"
fi
export SOURCE_FILES="uvicorn tests"

set -x

${PREFIX}black --check --diff --target-version=py36 $SOURCE_FILES
${PREFIX}flake8 $SOURCE_FILES
${PREFIX}isort --check --diff --project=uvicorn $SOURCE_FILES
11 changes: 11 additions & 0 deletions scripts/coverage
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
#!/bin/sh -e

export PREFIX=""
if [ -d 'venv' ] ; then
export PREFIX="venv/bin/"
fi
export SOURCE_FILES="uvicorn tests"

set -x

${PREFIX}coverage report --show-missing --skip-covered --fail-under=80
8 changes: 5 additions & 3 deletions scripts/lint
Original file line number Diff line number Diff line change
Expand Up @@ -4,9 +4,11 @@ export PREFIX=""
if [ -d 'venv' ] ; then
export PREFIX="venv/bin/"
fi
export SOURCE_FILES="uvicorn tests"

set -x

${PREFIX}autoflake --in-place --recursive uvicorn tests
${PREFIX}black uvicorn tests
${PREFIX}isort --multi-line=3 --trailing-comma --force-grid-wrap=0 --combine-as --line-width 88 --recursive --apply uvicorn tests
${PREFIX}autoflake --in-place --recursive $SOURCE_FILES
${PREFIX}seed-isort-config --application-directories=uvicorn
${PREFIX}isort --project=uvicorn $SOURCE_FILES
${PREFIX}black --target-version=py36 $SOURCE_FILES
9 changes: 3 additions & 6 deletions scripts/publish
Original file line number Diff line number Diff line change
@@ -1,5 +1,7 @@
#!/bin/sh -e

VERSION_FILE="uvicorn/__init__.py"

if [ -d 'venv' ] ; then
PREFIX="venv/bin/"
else
Expand All @@ -10,7 +12,7 @@ if [ ! -z "$GITHUB_ACTIONS" ]; then
git config --local user.email "41898282+github-actions[bot]@users.noreply.github.com"
git config --local user.name "GitHub Action"

VERSION=`grep __version__ ./uvicorn/__init__.py | grep -o '[0-9][^"]*'`
VERSION=`grep __version__ ${VERSION_FILE} | grep -o '[0-9][^"]*'`

if [ "refs/tags/${VERSION}" != "${GITHUB_REF}" ] ; then
echo "GitHub Ref '${GITHUB_REF}' did not match package version '${VERSION}'"
Expand All @@ -20,10 +22,5 @@ fi

set -x

find uvicorn -type f -name "*.py[co]" -delete
find uvicorn -type d -name __pycache__ -delete

${PREFIX}pip install twine wheel mkdocs mkdocs-material mkautodoc
${PREFIX}python setup.py sdist bdist_wheel
${PREFIX}twine upload dist/*
${PREFIX}mkdocs gh-deploy --force
18 changes: 11 additions & 7 deletions scripts/test
Original file line number Diff line number Diff line change
@@ -1,14 +1,18 @@
#!/bin/sh -e
#!/bin/sh

export PREFIX=""
if [ -d 'venv' ] ; then
export PREFIX="venv/bin/"
fi

set -x
set -ex

PYTHONPATH=. ${PREFIX}pytest --ignore venv --cov=uvicorn --cov=tests --cov-report=term-missing ${@}
${PREFIX}coverage html
${PREFIX}autoflake --recursive uvicorn tests
${PREFIX}flake8 uvicorn tests --ignore=W503,E203,E501,E731
${PREFIX}black uvicorn tests --check
if [ -z $GITHUB_ACTIONS ]; then
scripts/check
fi

${PREFIX}pytest $@

if [ -z $GITHUB_ACTIONS ]; then
scripts/coverage
fi
20 changes: 20 additions & 0 deletions setup.cfg
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
[flake8]
ignore = W503, E203, B305
max-line-length = 88

[mypy]
disallow_untyped_defs = True
ignore_missing_imports = True

[mypy-tests.*]
disallow_untyped_defs = False
check_untyped_defs = True

[tool:isort]
profile = black
combine_as_imports = True
known_first_party = uvicorn,tests
known_third_party = click,does_not_exist,gunicorn,h11,httptools,pytest,requests,setuptools,urllib3,uvloop,watchgod,websockets,wsproto

[tool:pytest]
addopts = --cov=uvicorn --cov=tests -rxXs
4 changes: 2 additions & 2 deletions tests/middleware/test_trace_logging.py
Original file line number Diff line number Diff line change
Expand Up @@ -13,10 +13,10 @@
"disable_existing_loggers": False,
"formatters": {
"test_formatter_default": {
"format": "[TEST_DEFAULT] %(levelname)-9s %(name)s - %(lineno)d - %(message)s"
"format": "[TEST_DEFAULT] %(levelname)-9s %(name)s - %(lineno)d - %(message)s" # noqa: E501
},
"test_formatter_access": {
"format": "[TEST_ACCESS] %(levelname)-9s %(name)s - %(lineno)d - %(message)s"
"format": "[TEST_ACCESS] %(levelname)-9s %(name)s - %(lineno)d - %(message)s" # noqa: E501
},
"test_formatter_asgi": {
"format": "[TEST_ASGI] %(levelname)-9s %(name)s - %(lineno)d - %(message)s"
Expand Down
11 changes: 7 additions & 4 deletions tests/protocols/test_websocket.py
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@

try:
import websockets

from uvicorn.protocols.websockets.websockets_impl import WebSocketProtocol
except ImportError: # pragma: nocover
websockets = None
Expand Down Expand Up @@ -78,8 +79,8 @@ def run_server(app, protocol_cls, path="/"):

@pytest.mark.parametrize("protocol_cls", WS_PROTOCOLS)
def test_invalid_upgrade(protocol_cls):

app = lambda scope: None
def app(scope):
return None

with run_server(app, protocol_cls=protocol_cls) as url:
url = url.replace("ws://", "http://")
Expand All @@ -95,8 +96,10 @@ def test_invalid_upgrade(protocol_cls):
"missing sec-websocket-key header",
"missing sec-websocket-version header", # websockets
"missing or empty sec-websocket-key header", # wsproto
"failed to open a websocket connection: missing sec-websocket-key header",
"failed to open a websocket connection: missing or empty sec-websocket-key header",
"failed to open a websocket connection: missing "
"sec-websocket-key header",
"failed to open a websocket connection: missing or empty "
"sec-websocket-key header",
]


Expand Down
2 changes: 1 addition & 1 deletion uvicorn/config.py
Original file line number Diff line number Diff line change
Expand Up @@ -67,7 +67,7 @@
},
"access": {
"()": "uvicorn.logging.AccessFormatter",
"fmt": '%(levelprefix)s %(client_addr)s - "%(request_line)s" %(status_code)s',
"fmt": '%(levelprefix)s %(client_addr)s - "%(request_line)s" %(status_code)s', # noqa: E501
},
},
"handlers": {
Expand Down
9 changes: 7 additions & 2 deletions uvicorn/logging.py
Original file line number Diff line number Diff line change
Expand Up @@ -37,7 +37,9 @@ def __init__(self, fmt=None, datefmt=None, style="%", use_colors=None):
super().__init__(fmt=fmt, datefmt=datefmt, style=style)

def color_level_name(self, level_name, level_no):
default = lambda level_name: str(level_name)
def default(level_name):
return str(level_name)

func = self.level_name_colors.get(level_no, default)
return func(level_name)

Expand Down Expand Up @@ -96,7 +98,10 @@ def get_status_code(self, record):
status_and_phrase = "%s %s" % (status_code, status_phrase)

if self.use_colors:
default = lambda code: status_and_phrase

def default(code):
return status_and_phrase

func = self.status_code_colours.get(status_code // 100, default)
return func(status_and_phrase)
return status_and_phrase
Expand Down
23 changes: 15 additions & 8 deletions uvicorn/main.py
Original file line number Diff line number Diff line change
Expand Up @@ -85,13 +85,15 @@ def print_version(ctx, param, value):
"--reload-dir",
"reload_dirs",
multiple=True,
help="Set reload directories explicitly, instead of using the current working directory.",
help="Set reload directories explicitly, instead of using the current working"
" directory.",
)
@click.option(
"--workers",
default=None,
type=int,
help="Number of worker processes. Defaults to the $WEB_CONCURRENCY environment variable if available. Not valid with --reload.",
help="Number of worker processes. Defaults to the $WEB_CONCURRENCY environment"
" variable if available. Not valid with --reload.",
)
@click.option(
"--loop",
Expand Down Expand Up @@ -165,13 +167,15 @@ def print_version(ctx, param, value):
"--proxy-headers/--no-proxy-headers",
is_flag=True,
default=True,
help="Enable/Disable X-Forwarded-Proto, X-Forwarded-For, X-Forwarded-Port to populate remote address info.",
help="Enable/Disable X-Forwarded-Proto, X-Forwarded-For, X-Forwarded-Port to "
"populate remote address info.",
)
@click.option(
"--forwarded-allow-ips",
type=str,
default=None,
help="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'.",
help="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'.",
)
@click.option(
"--root-path",
Expand All @@ -183,7 +187,8 @@ def print_version(ctx, param, value):
"--limit-concurrency",
type=int,
default=None,
help="Maximum number of concurrent connections or tasks to allow, before issuing HTTP 503 responses.",
help="Maximum number of concurrent connections or tasks to allow, before issuing"
" HTTP 503 responses.",
)
@click.option(
"--backlog",
Expand Down Expand Up @@ -261,7 +266,8 @@ def print_version(ctx, param, value):
"app_dir",
default=".",
show_default=True,
help="Look for APP in the specified directory, by adding this to the PYTHONPATH. Defaults to the current working directory.",
help="Look for APP in the specified directory, by adding this to the PYTHONPATH."
" Defaults to the current working directory.",
)
def main(
app,
Expand Down Expand Up @@ -345,8 +351,9 @@ def run(app, **kwargs):

if (config.reload or config.workers > 1) and not isinstance(app, str):
logger = logging.getLogger("uvicorn.error")
logger.warn(
"You must pass the application as an import string to enable 'reload' or 'workers'."
logger.warning(
"You must pass the application as an import string to enable 'reload' or "
"'workers'."
)
sys.exit(1)

Expand Down
3 changes: 2 additions & 1 deletion uvicorn/middleware/wsgi.py
Original file line number Diff line number Diff line change
Expand Up @@ -44,7 +44,8 @@ def build_environ(scope, message, body):
corrected_name = "CONTENT_TYPE"
else:
corrected_name = "HTTP_%s" % name.upper().replace("-", "_")
# HTTPbis say only ASCII chars are allowed in headers, but we latin1 just in case
# HTTPbis say only ASCII chars are allowed in headers, but we latin1
# just in case
value = value.decode("latin1")
if corrected_name in environ:
value = environ[corrected_name] + "," + value
Expand Down
3 changes: 2 additions & 1 deletion uvicorn/protocols/http/h11_impl.py
Original file line number Diff line number Diff line change
Expand Up @@ -336,7 +336,8 @@ def resume_writing(self):

def timeout_keep_alive_handler(self):
"""
Called on a keep-alive connection if no new data is received after a short delay.
Called on a keep-alive connection if no new data is received after a short
delay.
"""
if not self.transport.is_closing():
event = h11.ConnectionClosed()
Expand Down
3 changes: 2 additions & 1 deletion uvicorn/protocols/http/httptools_impl.py
Original file line number Diff line number Diff line change
Expand Up @@ -338,7 +338,8 @@ def resume_writing(self):

def timeout_keep_alive_handler(self):
"""
Called on a keep-alive connection if no new data is received after a short delay.
Called on a keep-alive connection if no new data is received after a short
delay.
"""
if not self.transport.is_closing():
self.transport.close()
Expand Down
Loading

0 comments on commit e77e596

Please sign in to comment.