From ca611621299bcfab04a22cd6ae7c569b72d5877c Mon Sep 17 00:00:00 2001 From: Adam Johnson Date: Wed, 7 Apr 2021 19:11:21 +0100 Subject: [PATCH 01/76] Lint with pre-commit (#365) * Lint with pre-commit * Move existing tox qa hooks into pre-commit. * Set up GitHub Action based on https://github.com/pre-commit/action/ (we could also use https://pre-commit.ci ). * Add `pyupgrade` to drop old Python syntax. * Add `flake8-bugbear` plugin to prevent flake8 errors. * Drop custom GHA --- .github/workflows/pre-commit.yml | 24 ++++++++++++++++++++++++ .github/workflows/tests.yml | 14 -------------- .pre-commit-config.yaml | 21 +++++++++++++++++++++ daphne/access.py | 2 +- daphne/cli.py | 4 ++-- daphne/server.py | 2 +- daphne/twisted/plugins/fd_endpoint.py | 2 +- daphne/ws_protocol.py | 4 ++-- setup.py | 2 +- tests/http_base.py | 4 ++-- tests/test_cli.py | 2 -- tests/test_http_request.py | 2 -- tests/test_http_response.py | 2 -- tests/test_utils.py | 2 -- tests/test_websocket.py | 2 -- tox.ini | 11 ----------- 16 files changed, 55 insertions(+), 45 deletions(-) create mode 100644 .github/workflows/pre-commit.yml create mode 100644 .pre-commit-config.yaml diff --git a/.github/workflows/pre-commit.yml b/.github/workflows/pre-commit.yml new file mode 100644 index 0000000..d939432 --- /dev/null +++ b/.github/workflows/pre-commit.yml @@ -0,0 +1,24 @@ +name: pre-commit + +on: + push: + branches: + - main + pull_request: + +jobs: + pre-commit: + runs-on: ubuntu-20.04 + + steps: + - uses: actions/checkout@v2 + with: + fetch-depth: 0 + + - uses: actions/setup-python@v2 + with: + python-version: 3.9 + + - uses: pre-commit/action@v2.0.0 + with: + token: ${{ secrets.GITHUB_TOKEN }} diff --git a/.github/workflows/tests.yml b/.github/workflows/tests.yml index 0756665..d388dea 100644 --- a/.github/workflows/tests.yml +++ b/.github/workflows/tests.yml @@ -31,17 +31,3 @@ jobs: run: | ENV_PREFIX=$(tr -C -d "0-9" <<< "${{ matrix.python-version }}") TOXENV=$(tox --listenvs | grep "^py$ENV_PREFIX" | tr '\n' ',') python -m tox - - lint: - runs-on: ubuntu-latest - steps: - - uses: actions/checkout@v2 - - name: Set up Python - uses: actions/setup-python@v2 - with: - python-version: 3.9 - - name: Install dependencies - run: | - python -m pip install --upgrade pip tox - - name: Run lint - run: tox -e qa diff --git a/.pre-commit-config.yaml b/.pre-commit-config.yaml new file mode 100644 index 0000000..5de3ae5 --- /dev/null +++ b/.pre-commit-config.yaml @@ -0,0 +1,21 @@ +repos: + - repo: https://github.com/asottile/pyupgrade + rev: v2.11.0 + hooks: + - id: pyupgrade + args: [--py36-plus] + - repo: https://github.com/psf/black + rev: 20.8b1 + hooks: + - id: black + language_version: python3 + - repo: https://github.com/pycqa/isort + rev: 5.8.0 + hooks: + - id: isort + - repo: https://github.com/PyCQA/flake8 + rev: 3.9.0 + hooks: + - id: flake8 + additional_dependencies: + - flake8-bugbear diff --git a/daphne/access.py b/daphne/access.py index 2b3b1cd..e18138a 100644 --- a/daphne/access.py +++ b/daphne/access.py @@ -1,7 +1,7 @@ import datetime -class AccessLogGenerator(object): +class AccessLogGenerator: """ Object that implements the Daphne "action logger" internal interface in order to provide an access log in something resembling NCSA format. diff --git a/daphne/cli.py b/daphne/cli.py index 8c42c43..923b9d3 100755 --- a/daphne/cli.py +++ b/daphne/cli.py @@ -16,7 +16,7 @@ DEFAULT_HOST = "127.0.0.1" DEFAULT_PORT = 8000 -class CommandLineInterface(object): +class CommandLineInterface: """ Acts as the main CLI entry point for running the server. """ @@ -258,7 +258,7 @@ class CommandLineInterface(object): ) endpoints = sorted(args.socket_strings + endpoints) # Start the server - logger.info("Starting server at %s" % (", ".join(endpoints),)) + logger.info("Starting server at {}".format(", ".join(endpoints))) self.server = self.server_class( application=application, endpoints=endpoints, diff --git a/daphne/server.py b/daphne/server.py index 77bd2d1..0ec72cc 100755 --- a/daphne/server.py +++ b/daphne/server.py @@ -34,7 +34,7 @@ from .ws_protocol import WebSocketFactory logger = logging.getLogger(__name__) -class Server(object): +class Server: def __init__( self, application, diff --git a/daphne/twisted/plugins/fd_endpoint.py b/daphne/twisted/plugins/fd_endpoint.py index ff5a4c7..313a315 100644 --- a/daphne/twisted/plugins/fd_endpoint.py +++ b/daphne/twisted/plugins/fd_endpoint.py @@ -7,7 +7,7 @@ from zope.interface import implementer @implementer(IPlugin, IStreamServerEndpointStringParser) -class _FDParser(object): +class _FDParser: prefix = "fd" def _parseServer(self, reactor, fileno, domain=socket.AF_INET): diff --git a/daphne/ws_protocol.py b/daphne/ws_protocol.py index 1962450..975b1a9 100755 --- a/daphne/ws_protocol.py +++ b/daphne/ws_protocol.py @@ -297,7 +297,7 @@ class WebSocketProtocol(WebSocketServerProtocol): return id(self) == id(other) def __repr__(self): - return "" % (self.client_addr, self.path) + return f"" class WebSocketFactory(WebSocketServerFactory): @@ -318,7 +318,7 @@ class WebSocketFactory(WebSocketServerFactory): Builds protocol instances. We use this to inject the factory object into the protocol. """ try: - protocol = super(WebSocketFactory, self).buildProtocol(addr) + protocol = super().buildProtocol(addr) protocol.factory = self return protocol except Exception: diff --git a/setup.py b/setup.py index 57341ca..af3b3b9 100755 --- a/setup.py +++ b/setup.py @@ -23,7 +23,7 @@ setup( packages=find_packages() + ["twisted.plugins"], include_package_data=True, install_requires=["twisted[tls]>=18.7", "autobahn>=0.18", "asgiref>=3.2.10,<4"], - python_requires='>=3.6', + python_requires=">=3.6", setup_requires=["pytest-runner"], extras_require={ "tests": ["hypothesis==4.23", "pytest~=3.10", "pytest-asyncio~=0.8"] diff --git a/tests/http_base.py b/tests/http_base.py index 7ea796c..e5a80c2 100644 --- a/tests/http_base.py +++ b/tests/http_base.py @@ -182,7 +182,7 @@ class DaphneTestCase(unittest.TestCase): if response.status != 101: raise RuntimeError("WebSocket upgrade did not result in status code 101") # Prepare headers for subprotocol searching - response_headers = dict((n.lower(), v) for n, v in response.getheaders()) + response_headers = {n.lower(): v for n, v in response.getheaders()} response.read() assert not response.closed # Return the raw socket and any subprotocol @@ -252,7 +252,7 @@ class DaphneTestCase(unittest.TestCase): """ try: socket.inet_aton(address) - except socket.error: + except OSError: self.fail("'%s' is not a valid IP address." % address) def assert_key_sets(self, required_keys, optional_keys, actual_keys): diff --git a/tests/test_cli.py b/tests/test_cli.py index 2bbcc42..17335ed 100644 --- a/tests/test_cli.py +++ b/tests/test_cli.py @@ -1,5 +1,3 @@ -# coding: utf8 - import logging from argparse import ArgumentError from unittest import TestCase diff --git a/tests/test_http_request.py b/tests/test_http_request.py index 7048326..52f6dd1 100644 --- a/tests/test_http_request.py +++ b/tests/test_http_request.py @@ -1,5 +1,3 @@ -# coding: utf8 - import collections from urllib import parse diff --git a/tests/test_http_response.py b/tests/test_http_response.py index 9dd728d..0f42df2 100644 --- a/tests/test_http_response.py +++ b/tests/test_http_response.py @@ -1,5 +1,3 @@ -# coding: utf8 - import http_strategies from http_base import DaphneTestCase from hypothesis import given, settings diff --git a/tests/test_utils.py b/tests/test_utils.py index 6b04939..b8ef1e1 100644 --- a/tests/test_utils.py +++ b/tests/test_utils.py @@ -1,5 +1,3 @@ -# coding: utf8 - from unittest import TestCase from twisted.web.http_headers import Headers diff --git a/tests/test_websocket.py b/tests/test_websocket.py index 26572e7..9b67aa1 100644 --- a/tests/test_websocket.py +++ b/tests/test_websocket.py @@ -1,5 +1,3 @@ -# coding: utf8 - import collections import time from urllib import parse diff --git a/tox.ini b/tox.ini index a4010d7..c507a8b 100644 --- a/tox.ini +++ b/tox.ini @@ -1,7 +1,6 @@ [tox] envlist = py{36,37,38,39}-twisted{187,latest} - qa [testenv] usedevelop = true @@ -11,13 +10,3 @@ commands = deps = twisted187: twisted==18.7.0 twistedlatest: twisted>=20.3.0 - -[testenv:qa] -deps = - black - flake8 - isort -commands = - flake8 daphne tests - black --check daphne tests - isort --check-only --diff daphne tests From 2b6f15361646093e76e990675bf24304aad205bd Mon Sep 17 00:00:00 2001 From: Adam Johnson Date: Wed, 7 Apr 2021 19:14:02 +0100 Subject: [PATCH 02/76] Used partial() to wrap Server.handle_reply() (#364) Fixes #332. --- CHANGELOG.txt | 4 ++++ daphne/server.py | 3 ++- 2 files changed, 6 insertions(+), 1 deletion(-) diff --git a/CHANGELOG.txt b/CHANGELOG.txt index 4e0b0a9..0584eb9 100644 --- a/CHANGELOG.txt +++ b/CHANGELOG.txt @@ -1,3 +1,7 @@ +* Fixed a bug where ``send`` passed to applications wasn't a true async + function but a lambda wrapper, preventing it from being used with + ``asgiref.sync.async_to_sync()``. + 3.0.1 (2020-11-12) ------------------ diff --git a/daphne/server.py b/daphne/server.py index 0ec72cc..0d463d0 100755 --- a/daphne/server.py +++ b/daphne/server.py @@ -22,6 +22,7 @@ else: import logging import time from concurrent.futures import CancelledError +from functools import partial from twisted.internet import defer, reactor from twisted.internet.endpoints import serverFromString @@ -203,7 +204,7 @@ class Server: application_instance = self.application( scope=scope, receive=input_queue.get, - send=lambda message: self.handle_reply(protocol, message), + send=partial(self.handle_reply, protocol), ) # Run it, and stash the future for later checking if protocol not in self.connections: From d5c41bf6418a26b1a672e718dfa1e18c707268eb Mon Sep 17 00:00:00 2001 From: Carlton Gibson Date: Wed, 7 Apr 2021 20:18:05 +0200 Subject: [PATCH 03/76] Updated various README URLs. --- README.rst | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/README.rst b/README.rst index 16e806c..7525b27 100644 --- a/README.rst +++ b/README.rst @@ -5,8 +5,8 @@ daphne :target: https://pypi.python.org/pypi/daphne Daphne is a HTTP, HTTP2 and WebSocket protocol server for -`ASGI `_ and -`ASGI-HTTP `_, +`ASGI `_ and +`ASGI-HTTP `_, developed to power Django Channels. It supports automatic negotiation of protocols; there's no need for URL @@ -115,7 +115,7 @@ Contributing ------------ Please refer to the -`main Channels contributing docs `_. +`main Channels contributing docs `_. To run tests, make sure you have installed the ``tests`` extra with the package:: @@ -134,4 +134,4 @@ https://docs.djangoproject.com/en/dev/internals/security/. To report bugs or request new features, please open a new GitHub issue. This repository is part of the Channels project. For the shepherd and maintenance team, please see the -`main Channels readme `_. +`main Channels readme `_. From e480917c1a68baf9beb5d8b61981750c4e49dcb0 Mon Sep 17 00:00:00 2001 From: Carlton Gibson Date: Wed, 7 Apr 2021 20:21:36 +0200 Subject: [PATCH 04/76] Bumped version and change notes for 3.0.2 release. --- CHANGELOG.txt | 4 ++++ daphne/__init__.py | 2 +- 2 files changed, 5 insertions(+), 1 deletion(-) diff --git a/CHANGELOG.txt b/CHANGELOG.txt index 0584eb9..8463751 100644 --- a/CHANGELOG.txt +++ b/CHANGELOG.txt @@ -1,7 +1,11 @@ +3.0.2 (2021-04-07) +------------------ + * Fixed a bug where ``send`` passed to applications wasn't a true async function but a lambda wrapper, preventing it from being used with ``asgiref.sync.async_to_sync()``. + 3.0.1 (2020-11-12) ------------------ diff --git a/daphne/__init__.py b/daphne/__init__.py index 9a235f3..530cbd0 100755 --- a/daphne/__init__.py +++ b/daphne/__init__.py @@ -1,6 +1,6 @@ import sys -__version__ = "3.0.1" +__version__ = "3.0.2" # Windows on Python 3.8+ uses ProactorEventLoop, which is not compatible with From 36ce9fd1edd9fcc1826ecc3968503aa6fd43726a Mon Sep 17 00:00:00 2001 From: Adam Johnson Date: Fri, 16 Apr 2021 17:21:51 +0100 Subject: [PATCH 05/76] Use tox-py in CI (#369) --- .github/workflows/tests.yml | 10 ++++++---- 1 file changed, 6 insertions(+), 4 deletions(-) diff --git a/.github/workflows/tests.yml b/.github/workflows/tests.yml index d388dea..ea93fa7 100644 --- a/.github/workflows/tests.yml +++ b/.github/workflows/tests.yml @@ -20,14 +20,16 @@ jobs: steps: - uses: actions/checkout@v2 + - name: Set up Python ${{ matrix.python-version }} uses: actions/setup-python@v2 with: python-version: ${{ matrix.python-version }} + - name: Install dependencies run: | - python -m pip install --upgrade pip wheel setuptools tox + python -m pip install --upgrade pip setuptools wheel + python -m pip install --upgrade tox tox-py + - name: Run tox targets for ${{ matrix.python-version }} - run: | - ENV_PREFIX=$(tr -C -d "0-9" <<< "${{ matrix.python-version }}") - TOXENV=$(tox --listenvs | grep "^py$ENV_PREFIX" | tr '\n' ',') python -m tox + run: tox --py current From 15a754d903b3febe7015a0b92884cfebd0b74a6f Mon Sep 17 00:00:00 2001 From: Carlton Gibson Date: Tue, 9 Nov 2021 15:55:18 +0100 Subject: [PATCH 06/76] Unpinned test dependencies. (#391) --- setup.py | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/setup.py b/setup.py index af3b3b9..56214f4 100755 --- a/setup.py +++ b/setup.py @@ -25,9 +25,7 @@ setup( install_requires=["twisted[tls]>=18.7", "autobahn>=0.18", "asgiref>=3.2.10,<4"], python_requires=">=3.6", setup_requires=["pytest-runner"], - extras_require={ - "tests": ["hypothesis==4.23", "pytest~=3.10", "pytest-asyncio~=0.8"] - }, + extras_require={"tests": ["hypothesis", "pytest", "pytest-asyncio"]}, entry_points={ "console_scripts": ["daphne = daphne.cli:CommandLineInterface.entrypoint"] }, From b62e58a02365ac38a6dfb175fa2cde0aad96049e Mon Sep 17 00:00:00 2001 From: Carlton Gibson Date: Tue, 9 Nov 2021 15:58:09 +0100 Subject: [PATCH 07/76] Added Python 3.10 to CI. (#392) --- .github/workflows/tests.yml | 9 +++++---- setup.py | 1 + tox.ini | 2 +- 3 files changed, 7 insertions(+), 5 deletions(-) diff --git a/.github/workflows/tests.yml b/.github/workflows/tests.yml index ea93fa7..3f81964 100644 --- a/.github/workflows/tests.yml +++ b/.github/workflows/tests.yml @@ -13,10 +13,11 @@ jobs: fail-fast: false matrix: python-version: - - 3.6 - - 3.7 - - 3.8 - - 3.9 + - "3.6" + - "3.7" + - "3.8" + - "3.9" + - "3.10" steps: - uses: actions/checkout@v2 diff --git a/setup.py b/setup.py index 56214f4..1ea8341 100755 --- a/setup.py +++ b/setup.py @@ -41,6 +41,7 @@ setup( "Programming Language :: Python :: 3.7", "Programming Language :: Python :: 3.8", "Programming Language :: Python :: 3.9", + "Programming Language :: Python :: 3.10", "Topic :: Internet :: WWW/HTTP", ], ) diff --git a/tox.ini b/tox.ini index c507a8b..3bba274 100644 --- a/tox.ini +++ b/tox.ini @@ -1,6 +1,6 @@ [tox] envlist = - py{36,37,38,39}-twisted{187,latest} + py{36,37,38,39,310}-twisted{187,latest} [testenv] usedevelop = true From 6a5093982ca1eaffbc41f0114ac5bea7cb3902be Mon Sep 17 00:00:00 2001 From: Carlton Gibson Date: Tue, 9 Nov 2021 20:12:29 +0100 Subject: [PATCH 08/76] Run CI tests on Windows. (#393) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * Updated minimum twisted to 19.7 Co-authored-by: Michael Käufl --- .github/workflows/tests.yml | 7 +++++-- setup.py | 2 +- tox.ini | 4 ++-- 3 files changed, 8 insertions(+), 5 deletions(-) diff --git a/.github/workflows/tests.yml b/.github/workflows/tests.yml index 3f81964..5a3d042 100644 --- a/.github/workflows/tests.yml +++ b/.github/workflows/tests.yml @@ -3,15 +3,18 @@ name: Tests on: push: branches: - - master + - master pull_request: jobs: tests: - runs-on: ubuntu-latest + runs-on: ${{ matrix.os }}-latest strategy: fail-fast: false matrix: + os: + - ubuntu + - windows python-version: - "3.6" - "3.7" diff --git a/setup.py b/setup.py index 1ea8341..214df0d 100755 --- a/setup.py +++ b/setup.py @@ -22,7 +22,7 @@ setup( package_dir={"twisted": "daphne/twisted"}, packages=find_packages() + ["twisted.plugins"], include_package_data=True, - install_requires=["twisted[tls]>=18.7", "autobahn>=0.18", "asgiref>=3.2.10,<4"], + install_requires=["twisted[tls]>=19.7", "autobahn>=0.18", "asgiref>=3.2.10,<4"], python_requires=">=3.6", setup_requires=["pytest-runner"], extras_require={"tests": ["hypothesis", "pytest", "pytest-asyncio"]}, diff --git a/tox.ini b/tox.ini index 3bba274..da7d4d9 100644 --- a/tox.ini +++ b/tox.ini @@ -1,6 +1,6 @@ [tox] envlist = - py{36,37,38,39,310}-twisted{187,latest} + py{36,37,38,39,310}-twisted{197,latest} [testenv] usedevelop = true @@ -8,5 +8,5 @@ extras = tests commands = pytest -v {posargs} deps = - twisted187: twisted==18.7.0 + twisted187: twisted==19.7.0 twistedlatest: twisted>=20.3.0 From eae1ff0df4603843d412feb9f0a27dff5f76c471 Mon Sep 17 00:00:00 2001 From: Marcin Muszynski Date: Mon, 14 Feb 2022 15:12:56 +0000 Subject: [PATCH 09/76] Set default attributes on WebRequest (#406) --- daphne/http_protocol.py | 5 ++-- tests/test_http_protocol.py | 49 +++++++++++++++++++++++++++++++++++++ 2 files changed, 51 insertions(+), 3 deletions(-) create mode 100644 tests/test_http_protocol.py diff --git a/daphne/http_protocol.py b/daphne/http_protocol.py index 7df7bae..a289e93 100755 --- a/daphne/http_protocol.py +++ b/daphne/http_protocol.py @@ -50,6 +50,8 @@ class WebRequest(http.Request): ) # Shorten it a bit, bytes wise def __init__(self, *args, **kwargs): + self.client_addr = None + self.server_addr = None try: http.Request.__init__(self, *args, **kwargs) # Easy server link @@ -77,9 +79,6 @@ class WebRequest(http.Request): # requires unicode string. self.client_addr = [str(self.client.host), self.client.port] self.server_addr = [str(self.host.host), self.host.port] - else: - self.client_addr = None - self.server_addr = None self.client_scheme = "https" if self.isSecure() else "http" diff --git a/tests/test_http_protocol.py b/tests/test_http_protocol.py new file mode 100644 index 0000000..024479d --- /dev/null +++ b/tests/test_http_protocol.py @@ -0,0 +1,49 @@ +import unittest + +from daphne.http_protocol import WebRequest + + +class MockServer: + """ + Mock server object for testing. + """ + + def protocol_connected(self, *args, **kwargs): + pass + + +class MockFactory: + """ + Mock factory object for testing. + """ + + def __init__(self): + self.server = MockServer() + + +class MockChannel: + """ + Mock channel object for testing. + """ + + def __init__(self): + self.factory = MockFactory() + self.transport = None + + def getPeer(self, *args, **kwargs): + return "peer" + + def getHost(self, *args, **kwargs): + return "host" + + +class TestHTTPProtocol(unittest.TestCase): + """ + Tests the HTTP protocol classes. + """ + + def test_web_request_initialisation(self): + channel = MockChannel() + request = WebRequest(channel) + self.assertIsNone(request.client_addr) + self.assertIsNone(request.server_addr) From 5e709795b4015c6ef71fe47a7ba025de066c11d4 Mon Sep 17 00:00:00 2001 From: Carlton Gibson Date: Mon, 23 May 2022 15:34:29 +0200 Subject: [PATCH 10/76] Updated supported Python and dependency versions. (#417) * Updated Python support and dependencies. * Updated Python support in README. * Removed PY36 from GHA workflow. * Remove pre-commit workflow. Fixes #397 * Updated Black in pre-commit to 22.3.0. * Update all pre-commit hooks. * [pre-commit.ci] auto fixes from pre-commit.com hooks --- .github/workflows/pre-commit.yml | 24 ------------------------ .github/workflows/tests.yml | 1 - .pre-commit-config.yaml | 8 ++++---- CHANGELOG.txt | 13 +++++++++++++ README.rst | 2 +- setup.cfg | 1 + setup.py | 5 ++--- tests/test_http_response.py | 8 +++----- tox.ini | 6 +----- 9 files changed, 25 insertions(+), 43 deletions(-) delete mode 100644 .github/workflows/pre-commit.yml diff --git a/.github/workflows/pre-commit.yml b/.github/workflows/pre-commit.yml deleted file mode 100644 index d939432..0000000 --- a/.github/workflows/pre-commit.yml +++ /dev/null @@ -1,24 +0,0 @@ -name: pre-commit - -on: - push: - branches: - - main - pull_request: - -jobs: - pre-commit: - runs-on: ubuntu-20.04 - - steps: - - uses: actions/checkout@v2 - with: - fetch-depth: 0 - - - uses: actions/setup-python@v2 - with: - python-version: 3.9 - - - uses: pre-commit/action@v2.0.0 - with: - token: ${{ secrets.GITHUB_TOKEN }} diff --git a/.github/workflows/tests.yml b/.github/workflows/tests.yml index 5a3d042..8cbbff3 100644 --- a/.github/workflows/tests.yml +++ b/.github/workflows/tests.yml @@ -16,7 +16,6 @@ jobs: - ubuntu - windows python-version: - - "3.6" - "3.7" - "3.8" - "3.9" diff --git a/.pre-commit-config.yaml b/.pre-commit-config.yaml index 5de3ae5..1367879 100644 --- a/.pre-commit-config.yaml +++ b/.pre-commit-config.yaml @@ -1,20 +1,20 @@ repos: - repo: https://github.com/asottile/pyupgrade - rev: v2.11.0 + rev: v2.32.1 hooks: - id: pyupgrade args: [--py36-plus] - repo: https://github.com/psf/black - rev: 20.8b1 + rev: 22.3.0 hooks: - id: black language_version: python3 - repo: https://github.com/pycqa/isort - rev: 5.8.0 + rev: 5.10.1 hooks: - id: isort - repo: https://github.com/PyCQA/flake8 - rev: 3.9.0 + rev: 4.0.1 hooks: - id: flake8 additional_dependencies: diff --git a/CHANGELOG.txt b/CHANGELOG.txt index 8463751..7e6a120 100644 --- a/CHANGELOG.txt +++ b/CHANGELOG.txt @@ -1,3 +1,16 @@ +Unreleased +---------- + +* Dropped support for Python 3.6. + +* Updated dependencies to the latest versions. + + Previously a range of Twisted versions have been supported. Recent Twisted + releases (22.2, 22.4) have issued security fixes, so those are now the + minimum supported version. Given the stability of Twisted, supporting a + range of versions does not represent a good use of maintainer time. Going + forward the latest Twisted version will be required. + 3.0.2 (2021-04-07) ------------------ diff --git a/README.rst b/README.rst index 7525b27..70c4ba5 100644 --- a/README.rst +++ b/README.rst @@ -108,7 +108,7 @@ should start with a slash, but not end with one; for example:: Python Support -------------- -Daphne requires Python 3.6 or later. +Daphne requires Python 3.7 or later. Contributing diff --git a/setup.cfg b/setup.cfg index ddb3d5d..e7c19e5 100644 --- a/setup.cfg +++ b/setup.cfg @@ -8,3 +8,4 @@ profile = black [tool:pytest] testpaths = tests +asyncio_mode = strict diff --git a/setup.py b/setup.py index 214df0d..274e8f8 100755 --- a/setup.py +++ b/setup.py @@ -22,8 +22,8 @@ setup( package_dir={"twisted": "daphne/twisted"}, packages=find_packages() + ["twisted.plugins"], include_package_data=True, - install_requires=["twisted[tls]>=19.7", "autobahn>=0.18", "asgiref>=3.2.10,<4"], - python_requires=">=3.6", + install_requires=["twisted[tls]>=22.4", "autobahn>=22.4.2", "asgiref>=3.5.2,<4"], + python_requires=">=3.7", setup_requires=["pytest-runner"], extras_require={"tests": ["hypothesis", "pytest", "pytest-asyncio"]}, entry_points={ @@ -37,7 +37,6 @@ setup( "Operating System :: OS Independent", "Programming Language :: Python", "Programming Language :: Python :: 3", - "Programming Language :: Python :: 3.6", "Programming Language :: Python :: 3.7", "Programming Language :: Python :: 3.8", "Programming Language :: Python :: 3.9", diff --git a/tests/test_http_response.py b/tests/test_http_response.py index 0f42df2..1fc2439 100644 --- a/tests/test_http_response.py +++ b/tests/test_http_response.py @@ -13,11 +13,9 @@ class TestHTTPResponse(DaphneTestCase): Lowercases and sorts headers, and strips transfer-encoding ones. """ return sorted( - [ - (name.lower(), value.strip()) - for name, value in headers - if name.lower() != b"transfer-encoding" - ] + (name.lower(), value.strip()) + for name, value in headers + if name.lower() != b"transfer-encoding" ) def encode_headers(self, headers): diff --git a/tox.ini b/tox.ini index da7d4d9..876ff99 100644 --- a/tox.ini +++ b/tox.ini @@ -1,12 +1,8 @@ [tox] envlist = - py{36,37,38,39,310}-twisted{197,latest} - + py{37,38,39,310} [testenv] usedevelop = true extras = tests commands = pytest -v {posargs} -deps = - twisted187: twisted==19.7.0 - twistedlatest: twisted>=20.3.0 From 87bc5a7975e3e77ec64a183058b6e875cf744cf4 Mon Sep 17 00:00:00 2001 From: Abhimanyu Saharan Date: Fri, 8 Apr 2022 21:59:57 +0530 Subject: [PATCH 11/76] Added argument to change log format. (#414) --- CHANGELOG.txt | 2 ++ daphne/cli.py | 7 ++++++- 2 files changed, 8 insertions(+), 1 deletion(-) diff --git a/CHANGELOG.txt b/CHANGELOG.txt index 7e6a120..630c0fa 100644 --- a/CHANGELOG.txt +++ b/CHANGELOG.txt @@ -11,6 +11,8 @@ Unreleased range of versions does not represent a good use of maintainer time. Going forward the latest Twisted version will be required. +* Added `log-fmt` CLI argument. + 3.0.2 (2021-04-07) ------------------ diff --git a/daphne/cli.py b/daphne/cli.py index 923b9d3..2e83a5c 100755 --- a/daphne/cli.py +++ b/daphne/cli.py @@ -90,6 +90,11 @@ class CommandLineInterface: help="Where to write the access log (- for stdout, the default for verbosity=1)", default=None, ) + self.parser.add_argument( + "--log-fmt", + help="Log format to use", + default="%(asctime)-15s %(levelname)-8s %(message)s" + ) self.parser.add_argument( "--ping-interval", type=int, @@ -215,7 +220,7 @@ class CommandLineInterface: 2: logging.DEBUG, 3: logging.DEBUG, # Also turns on asyncio debug }[args.verbosity], - format="%(asctime)-15s %(levelname)-8s %(message)s", + format=args.log_fmt, ) # If verbosity is 1 or greater, or they told us explicitly, set up access log access_log_stream = None From 54745d0f839a4f8e90156f897f86976e55074eb5 Mon Sep 17 00:00:00 2001 From: baseplate-admin <61817579+baseplate-admin@users.noreply.github.com> Date: Tue, 24 May 2022 16:40:02 +0600 Subject: [PATCH 12/76] Set a default `Server` header for HTTP responses (#396) Co-authored-by: Carlton Gibson --- CHANGELOG.txt | 9 ++++++++- daphne/cli.py | 7 +++++-- daphne/http_protocol.py | 4 ++-- daphne/server.py | 2 +- tests/test_cli.py | 15 +++++++++++++++ tests/test_http_response.py | 9 ++++++--- 6 files changed, 37 insertions(+), 9 deletions(-) diff --git a/CHANGELOG.txt b/CHANGELOG.txt index 630c0fa..31e4650 100644 --- a/CHANGELOG.txt +++ b/CHANGELOG.txt @@ -11,7 +11,14 @@ Unreleased range of versions does not represent a good use of maintainer time. Going forward the latest Twisted version will be required. -* Added `log-fmt` CLI argument. +* Set ``daphne`` as default ``Server`` header. + + This can be configured with the ``--server-name`` CLI argument. + + Added the new ``--no-server-name`` CLI argument to disable the ``Server`` + header, which is equivalent to ``--server-name=` (an empty name). + +* Added ``--log-fmt`` CLI argument. 3.0.2 (2021-04-07) ------------------ diff --git a/daphne/cli.py b/daphne/cli.py index 2e83a5c..accafe1 100755 --- a/daphne/cli.py +++ b/daphne/cli.py @@ -93,7 +93,7 @@ class CommandLineInterface: self.parser.add_argument( "--log-fmt", help="Log format to use", - default="%(asctime)-15s %(levelname)-8s %(message)s" + default="%(asctime)-15s %(levelname)-8s %(message)s", ) self.parser.add_argument( "--ping-interval", @@ -162,7 +162,10 @@ class CommandLineInterface: "--server-name", dest="server_name", help="specify which value should be passed to response header Server attribute", - default="Daphne", + default="daphne", + ) + self.parser.add_argument( + "--no-server-name", dest="server_name", action="store_const", const="" ) self.server = None diff --git a/daphne/http_protocol.py b/daphne/http_protocol.py index a289e93..f0657fd 100755 --- a/daphne/http_protocol.py +++ b/daphne/http_protocol.py @@ -249,8 +249,8 @@ class WebRequest(http.Request): # Write headers for header, value in message.get("headers", {}): self.responseHeaders.addRawHeader(header, value) - if self.server.server_name and self.server.server_name.lower() != "daphne": - self.setHeader(b"server", self.server.server_name.encode("utf-8")) + if self.server.server_name and not self.responseHeaders.hasHeader("server"): + self.setHeader(b"server", self.server.server_name.encode()) logger.debug( "HTTP %s response started for %s", message["status"], self.client_addr ) diff --git a/daphne/server.py b/daphne/server.py index 0d463d0..4334217 100755 --- a/daphne/server.py +++ b/daphne/server.py @@ -56,7 +56,7 @@ class Server: websocket_handshake_timeout=5, application_close_timeout=10, ready_callable=None, - server_name="Daphne", + server_name="daphne", # Deprecated and does not work, remove in version 2.2 ws_protocols=None, ): diff --git a/tests/test_cli.py b/tests/test_cli.py index 17335ed..51eab2e 100644 --- a/tests/test_cli.py +++ b/tests/test_cli.py @@ -240,3 +240,18 @@ class TestCLIInterface(TestCase): exc.exception.message, "--proxy-headers has to be passed for this parameter.", ) + + def test_custom_servername(self): + """ + Passing `--server-name` will set the default server header + from 'daphne' to the passed one. + """ + self.assertCLI([], {"server_name": "daphne"}) + self.assertCLI(["--server-name", ""], {"server_name": ""}) + self.assertCLI(["--server-name", "python"], {"server_name": "python"}) + + def test_no_servername(self): + """ + Passing `--no-server-name` will set server name to '' (empty string) + """ + self.assertCLI(["--no-server-name"], {"server_name": ""}) diff --git a/tests/test_http_response.py b/tests/test_http_response.py index 1fc2439..22f6480 100644 --- a/tests/test_http_response.py +++ b/tests/test_http_response.py @@ -13,9 +13,12 @@ class TestHTTPResponse(DaphneTestCase): Lowercases and sorts headers, and strips transfer-encoding ones. """ return sorted( - (name.lower(), value.strip()) - for name, value in headers - if name.lower() != b"transfer-encoding" + [(b"server", b"daphne")] + + [ + (name.lower(), value.strip()) + for name, value in headers + if name.lower() not in (b"server", b"transfer-encoding") + ] ) def encode_headers(self, headers): From 7d4316fd4a87a7febaa48f77f77b51a9486d5d88 Mon Sep 17 00:00:00 2001 From: "pre-commit-ci[bot]" <66853113+pre-commit-ci[bot]@users.noreply.github.com> Date: Mon, 13 Jun 2022 23:58:38 +0100 Subject: [PATCH 13/76] [pre-commit.ci] pre-commit autoupdate (#418) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit updates: - [github.com/asottile/pyupgrade: v2.32.1 → v2.34.0](https://github.com/asottile/pyupgrade/compare/v2.32.1...v2.34.0) Co-authored-by: pre-commit-ci[bot] <66853113+pre-commit-ci[bot]@users.noreply.github.com> --- .pre-commit-config.yaml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.pre-commit-config.yaml b/.pre-commit-config.yaml index 1367879..0875ff8 100644 --- a/.pre-commit-config.yaml +++ b/.pre-commit-config.yaml @@ -1,6 +1,6 @@ repos: - repo: https://github.com/asottile/pyupgrade - rev: v2.32.1 + rev: v2.34.0 hooks: - id: pyupgrade args: [--py36-plus] From 1df4f08fac93d382c911b6791632adbe51781a52 Mon Sep 17 00:00:00 2001 From: "pre-commit-ci[bot]" <66853113+pre-commit-ci[bot]@users.noreply.github.com> Date: Mon, 4 Jul 2022 19:40:09 +0000 Subject: [PATCH 14/76] [pre-commit.ci] pre-commit autoupdate MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit updates: - [github.com/psf/black: 22.3.0 → 22.6.0](https://github.com/psf/black/compare/22.3.0...22.6.0) --- .pre-commit-config.yaml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.pre-commit-config.yaml b/.pre-commit-config.yaml index 0875ff8..072a7c8 100644 --- a/.pre-commit-config.yaml +++ b/.pre-commit-config.yaml @@ -5,7 +5,7 @@ repos: - id: pyupgrade args: [--py36-plus] - repo: https://github.com/psf/black - rev: 22.3.0 + rev: 22.6.0 hooks: - id: black language_version: python3 From 71ba4407617c29ed35ace3e3b83f3256f02808bd Mon Sep 17 00:00:00 2001 From: Carlton Gibson Date: Wed, 6 Jul 2022 12:37:26 +0200 Subject: [PATCH 15/76] Added support for ASGI_THREADS max worker limit. (#422) Closes #319 --- CHANGELOG.txt | 6 ++++++ daphne/server.py | 8 ++++++++ tests/test_cli.py | 12 +++++++++++- 3 files changed, 25 insertions(+), 1 deletion(-) diff --git a/CHANGELOG.txt b/CHANGELOG.txt index 31e4650..8eb5463 100644 --- a/CHANGELOG.txt +++ b/CHANGELOG.txt @@ -20,6 +20,12 @@ Unreleased * Added ``--log-fmt`` CLI argument. +* Added support for ``ASGI_THREADS`` environment variable, setting the maximum + number of workers used by a ``SyncToAsync`` thread-pool executor. + + Set e.g. ``ASGI_THREADS=4 daphne ...`` when running to limit the number of + workers. + 3.0.2 (2021-04-07) ------------------ diff --git a/daphne/server.py b/daphne/server.py index 4334217..e5728b3 100755 --- a/daphne/server.py +++ b/daphne/server.py @@ -1,10 +1,18 @@ # This has to be done first as Twisted is import-order-sensitive with reactors import asyncio # isort:skip +import os # isort:skip import sys # isort:skip import warnings # isort:skip +from concurrent.futures import ThreadPoolExecutor # isort:skip from twisted.internet import asyncioreactor # isort:skip + twisted_loop = asyncio.new_event_loop() +if "ASGI_THREADS" in os.environ: + twisted_loop.set_default_executor( + ThreadPoolExecutor(max_workers=int(os.environ["ASGI_THREADS"])) + ) + current_reactor = sys.modules.get("twisted.internet.reactor", None) if current_reactor is not None: if not isinstance(current_reactor, asyncioreactor.AsyncioSelectorReactor): diff --git a/tests/test_cli.py b/tests/test_cli.py index 51eab2e..8368488 100644 --- a/tests/test_cli.py +++ b/tests/test_cli.py @@ -1,6 +1,7 @@ import logging +import os from argparse import ArgumentError -from unittest import TestCase +from unittest import TestCase, skipUnless from daphne.cli import CommandLineInterface from daphne.endpoints import build_endpoint_description_strings as build @@ -255,3 +256,12 @@ class TestCLIInterface(TestCase): Passing `--no-server-name` will set server name to '' (empty string) """ self.assertCLI(["--no-server-name"], {"server_name": ""}) + + +@skipUnless(os.getenv("ASGI_THREADS"), "ASGI_THREADS environment variable not set.") +class TestASGIThreads(TestCase): + def test_default_executor(self): + from daphne.server import twisted_loop + + executor = twisted_loop._default_executor + self.assertEqual(executor._max_workers, int(os.getenv("ASGI_THREADS"))) From 5502d1d37b06ad03b4228d38cb0c2cc24dfd5801 Mon Sep 17 00:00:00 2001 From: "pre-commit-ci[bot]" <66853113+pre-commit-ci[bot]@users.noreply.github.com> Date: Wed, 13 Jul 2022 06:24:58 +0100 Subject: [PATCH 16/76] [pre-commit.ci] pre-commit autoupdate (#424) --- .pre-commit-config.yaml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.pre-commit-config.yaml b/.pre-commit-config.yaml index 072a7c8..6d41dcf 100644 --- a/.pre-commit-config.yaml +++ b/.pre-commit-config.yaml @@ -1,6 +1,6 @@ repos: - repo: https://github.com/asottile/pyupgrade - rev: v2.34.0 + rev: v2.37.1 hooks: - id: pyupgrade args: [--py36-plus] From e04b4077f401e2e69cb9ec68e3bc0167828b6e1f Mon Sep 17 00:00:00 2001 From: "pre-commit-ci[bot]" <66853113+pre-commit-ci[bot]@users.noreply.github.com> Date: Mon, 25 Jul 2022 23:59:09 +0100 Subject: [PATCH 17/76] [pre-commit.ci] pre-commit autoupdate (#426) Co-authored-by: pre-commit-ci[bot] <66853113+pre-commit-ci[bot]@users.noreply.github.com> --- .pre-commit-config.yaml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.pre-commit-config.yaml b/.pre-commit-config.yaml index 6d41dcf..a049802 100644 --- a/.pre-commit-config.yaml +++ b/.pre-commit-config.yaml @@ -1,6 +1,6 @@ repos: - repo: https://github.com/asottile/pyupgrade - rev: v2.37.1 + rev: v2.37.2 hooks: - id: pyupgrade args: [--py36-plus] From 438b7ad06d07648ce03a2a376b561a244ac81bb1 Mon Sep 17 00:00:00 2001 From: "pre-commit-ci[bot]" <66853113+pre-commit-ci[bot]@users.noreply.github.com> Date: Tue, 2 Aug 2022 08:56:41 +0200 Subject: [PATCH 18/76] [pre-commit.ci] pre-commit autoupdate (#427) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit updates: - [github.com/asottile/pyupgrade: v2.37.2 → v2.37.3](https://github.com/asottile/pyupgrade/compare/v2.37.2...v2.37.3) - [github.com/PyCQA/flake8: 4.0.1 → 5.0.2](https://github.com/PyCQA/flake8/compare/4.0.1...5.0.2) Co-authored-by: pre-commit-ci[bot] <66853113+pre-commit-ci[bot]@users.noreply.github.com> --- .pre-commit-config.yaml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/.pre-commit-config.yaml b/.pre-commit-config.yaml index a049802..1b2ef2c 100644 --- a/.pre-commit-config.yaml +++ b/.pre-commit-config.yaml @@ -1,6 +1,6 @@ repos: - repo: https://github.com/asottile/pyupgrade - rev: v2.37.2 + rev: v2.37.3 hooks: - id: pyupgrade args: [--py36-plus] @@ -14,7 +14,7 @@ repos: hooks: - id: isort - repo: https://github.com/PyCQA/flake8 - rev: 4.0.1 + rev: 5.0.2 hooks: - id: flake8 additional_dependencies: From 2b13b74ce266fedf1cad9122314a2a3579cee576 Mon Sep 17 00:00:00 2001 From: Carlton Gibson Date: Mon, 8 Aug 2022 14:10:03 +0200 Subject: [PATCH 19/76] Added runserver to Daphne. (#429) * Made daphne installable as a Django app. * Added system check to ensure daphne is installed before django.contrib.staticfiles. * Moved runserver command from Channels. * Added changelog entry for runserver command. --- CHANGELOG.txt | 10 ++ daphne/apps.py | 16 ++ daphne/checks.py | 21 +++ daphne/management/__init__.py | 0 daphne/management/commands/__init__.py | 0 daphne/management/commands/runserver.py | 191 ++++++++++++++++++++++++ setup.py | 2 +- tests/test_checks.py | 21 +++ 8 files changed, 260 insertions(+), 1 deletion(-) create mode 100644 daphne/apps.py create mode 100644 daphne/checks.py create mode 100644 daphne/management/__init__.py create mode 100644 daphne/management/commands/__init__.py create mode 100644 daphne/management/commands/runserver.py create mode 100644 tests/test_checks.py diff --git a/CHANGELOG.txt b/CHANGELOG.txt index 8eb5463..d8dd5b9 100644 --- a/CHANGELOG.txt +++ b/CHANGELOG.txt @@ -26,6 +26,16 @@ Unreleased Set e.g. ``ASGI_THREADS=4 daphne ...`` when running to limit the number of workers. +* Added a ``runserver`` command to run an ASGI Django development server. + + Added ``"daphne"`` to the ``INSTALLED_APPS`` setting, before + ``"django.contrib.staticfiles"`` to enable: + + INSTALLED_APPS = [ + "daphne", + ... + ] + 3.0.2 (2021-04-07) ------------------ diff --git a/daphne/apps.py b/daphne/apps.py new file mode 100644 index 0000000..de104db --- /dev/null +++ b/daphne/apps.py @@ -0,0 +1,16 @@ +# Import the server here to ensure the reactor is installed very early on in case other +# packages import twisted.internet.reactor (e.g. raven does this). +from django.apps import AppConfig +from django.core import checks + +import daphne.server # noqa: F401 + +from .checks import check_daphne_installed + + +class DaphneConfig(AppConfig): + name = "daphne" + verbose_name = "Daphne" + + def ready(self): + checks.register(check_daphne_installed, checks.Tags.staticfiles) diff --git a/daphne/checks.py b/daphne/checks.py new file mode 100644 index 0000000..058ad7e --- /dev/null +++ b/daphne/checks.py @@ -0,0 +1,21 @@ +# Django system check to ensure daphne app is listed in INSTALLED_APPS before django.contrib.staticfiles. +from django.core.checks import Error, register + + +@register() +def check_daphne_installed(app_configs, **kwargs): + from django.apps import apps + from django.contrib.staticfiles.apps import StaticFilesConfig + + from daphne.apps import DaphneConfig + + for app in apps.get_app_configs(): + if isinstance(app, DaphneConfig): + return [] + if isinstance(app, StaticFilesConfig): + return [ + Error( + "Daphne must be listed before django.contrib.staticfiles in INSTALLED_APPS.", + id="daphne.E001", + ) + ] diff --git a/daphne/management/__init__.py b/daphne/management/__init__.py new file mode 100644 index 0000000..e69de29 diff --git a/daphne/management/commands/__init__.py b/daphne/management/commands/__init__.py new file mode 100644 index 0000000..e69de29 diff --git a/daphne/management/commands/runserver.py b/daphne/management/commands/runserver.py new file mode 100644 index 0000000..b2fd2ee --- /dev/null +++ b/daphne/management/commands/runserver.py @@ -0,0 +1,191 @@ +import datetime +import importlib +import logging +import sys + +from django.apps import apps +from django.conf import settings +from django.contrib.staticfiles.handlers import ASGIStaticFilesHandler +from django.core.exceptions import ImproperlyConfigured +from django.core.management import CommandError +from django.core.management.commands.runserver import Command as RunserverCommand + +from daphne import __version__ +from daphne.endpoints import build_endpoint_description_strings +from daphne.server import Server + +logger = logging.getLogger("django.channels.server") + + +def get_default_application(): + """ + Gets the default application, set in the ASGI_APPLICATION setting. + """ + try: + path, name = settings.ASGI_APPLICATION.rsplit(".", 1) + except (ValueError, AttributeError): + raise ImproperlyConfigured("Cannot find ASGI_APPLICATION setting.") + try: + module = importlib.import_module(path) + except ImportError: + raise ImproperlyConfigured("Cannot import ASGI_APPLICATION module %r" % path) + try: + value = getattr(module, name) + except AttributeError: + raise ImproperlyConfigured( + f"Cannot find {name!r} in ASGI_APPLICATION module {path}" + ) + return value + + +class Command(RunserverCommand): + protocol = "http" + server_cls = Server + + def add_arguments(self, parser): + super().add_arguments(parser) + parser.add_argument( + "--noasgi", + action="store_false", + dest="use_asgi", + default=True, + help="Run the old WSGI-based runserver rather than the ASGI-based one", + ) + parser.add_argument( + "--http_timeout", + action="store", + dest="http_timeout", + type=int, + default=None, + help=( + "Specify the daphne http_timeout interval in seconds " + "(default: no timeout)" + ), + ) + parser.add_argument( + "--websocket_handshake_timeout", + action="store", + dest="websocket_handshake_timeout", + type=int, + default=5, + help=( + "Specify the daphne websocket_handshake_timeout interval in " + "seconds (default: 5)" + ), + ) + + def handle(self, *args, **options): + self.http_timeout = options.get("http_timeout", None) + self.websocket_handshake_timeout = options.get("websocket_handshake_timeout", 5) + # Check Channels is installed right + if options["use_asgi"] and not hasattr(settings, "ASGI_APPLICATION"): + raise CommandError( + "You have not set ASGI_APPLICATION, which is needed to run the server." + ) + # Dispatch upward + super().handle(*args, **options) + + def inner_run(self, *args, **options): + # Maybe they want the wsgi one? + if not options.get("use_asgi", True): + if hasattr(RunserverCommand, "server_cls"): + self.server_cls = RunserverCommand.server_cls + return RunserverCommand.inner_run(self, *args, **options) + # Run checks + self.stdout.write("Performing system checks...\n\n") + self.check(display_num_errors=True) + self.check_migrations() + # Print helpful text + quit_command = "CTRL-BREAK" if sys.platform == "win32" else "CONTROL-C" + now = datetime.datetime.now().strftime("%B %d, %Y - %X") + self.stdout.write(now) + self.stdout.write( + ( + "Django version %(version)s, using settings %(settings)r\n" + "Starting ASGI/Daphne version %(daphne_version)s development server" + " at %(protocol)s://%(addr)s:%(port)s/\n" + "Quit the server with %(quit_command)s.\n" + ) + % { + "version": self.get_version(), + "daphne_version": __version__, + "settings": settings.SETTINGS_MODULE, + "protocol": self.protocol, + "addr": "[%s]" % self.addr if self._raw_ipv6 else self.addr, + "port": self.port, + "quit_command": quit_command, + } + ) + + # Launch server in 'main' thread. Signals are disabled as it's still + # actually a subthread under the autoreloader. + logger.debug("Daphne running, listening on %s:%s", self.addr, self.port) + + # build the endpoint description string from host/port options + endpoints = build_endpoint_description_strings(host=self.addr, port=self.port) + try: + self.server_cls( + application=self.get_application(options), + endpoints=endpoints, + signal_handlers=not options["use_reloader"], + action_logger=self.log_action, + http_timeout=self.http_timeout, + root_path=getattr(settings, "FORCE_SCRIPT_NAME", "") or "", + websocket_handshake_timeout=self.websocket_handshake_timeout, + ).run() + logger.debug("Daphne exited") + except KeyboardInterrupt: + shutdown_message = options.get("shutdown_message", "") + if shutdown_message: + self.stdout.write(shutdown_message) + return + + def get_application(self, options): + """ + Returns the static files serving application wrapping the default application, + if static files should be served. Otherwise just returns the default + handler. + """ + staticfiles_installed = apps.is_installed("django.contrib.staticfiles") + use_static_handler = options.get("use_static_handler", staticfiles_installed) + insecure_serving = options.get("insecure_serving", False) + if use_static_handler and (settings.DEBUG or insecure_serving): + return ASGIStaticFilesHandler(get_default_application()) + else: + return get_default_application() + + def log_action(self, protocol, action, details): + """ + Logs various different kinds of requests to the console. + """ + # HTTP requests + if protocol == "http" and action == "complete": + msg = "HTTP %(method)s %(path)s %(status)s [%(time_taken).2f, %(client)s]" + + # Utilize terminal colors, if available + if 200 <= details["status"] < 300: + # Put 2XX first, since it should be the common case + logger.info(self.style.HTTP_SUCCESS(msg), details) + elif 100 <= details["status"] < 200: + logger.info(self.style.HTTP_INFO(msg), details) + elif details["status"] == 304: + logger.info(self.style.HTTP_NOT_MODIFIED(msg), details) + elif 300 <= details["status"] < 400: + logger.info(self.style.HTTP_REDIRECT(msg), details) + elif details["status"] == 404: + logger.warning(self.style.HTTP_NOT_FOUND(msg), details) + elif 400 <= details["status"] < 500: + logger.warning(self.style.HTTP_BAD_REQUEST(msg), details) + else: + # Any 5XX, or any other response + logger.error(self.style.HTTP_SERVER_ERROR(msg), details) + + # Websocket requests + elif protocol == "websocket" and action == "connected": + logger.info("WebSocket CONNECT %(path)s [%(client)s]", details) + elif protocol == "websocket" and action == "disconnected": + logger.info("WebSocket DISCONNECT %(path)s [%(client)s]", details) + elif protocol == "websocket" and action == "connecting": + logger.info("WebSocket HANDSHAKING %(path)s [%(client)s]", details) + elif protocol == "websocket" and action == "rejected": + logger.info("WebSocket REJECT %(path)s [%(client)s]", details) diff --git a/setup.py b/setup.py index 274e8f8..ae19f5d 100755 --- a/setup.py +++ b/setup.py @@ -25,7 +25,7 @@ setup( install_requires=["twisted[tls]>=22.4", "autobahn>=22.4.2", "asgiref>=3.5.2,<4"], python_requires=">=3.7", setup_requires=["pytest-runner"], - extras_require={"tests": ["hypothesis", "pytest", "pytest-asyncio"]}, + extras_require={"tests": ["hypothesis", "pytest", "pytest-asyncio", "django"]}, entry_points={ "console_scripts": ["daphne = daphne.cli:CommandLineInterface.entrypoint"] }, diff --git a/tests/test_checks.py b/tests/test_checks.py new file mode 100644 index 0000000..48b23bd --- /dev/null +++ b/tests/test_checks.py @@ -0,0 +1,21 @@ +import django +from django.conf import settings +from django.test.utils import override_settings + +from daphne.checks import check_daphne_installed + + +def test_check_daphne_installed(): + """ + Test check error is raised if daphne is not listed before staticfiles, and vice versa. + """ + settings.configure( + INSTALLED_APPS=["daphne.apps.DaphneConfig", "django.contrib.staticfiles"] + ) + django.setup() + errors = check_daphne_installed(None) + assert len(errors) == 0 + with override_settings(INSTALLED_APPS=["django.contrib.staticfiles", "daphne"]): + errors = check_daphne_installed(None) + assert len(errors) == 1 + assert errors[0].id == "daphne.E001" From 7453ad9cc50b4bfb7fe13f61338793e9fe075e61 Mon Sep 17 00:00:00 2001 From: "pre-commit-ci[bot]" <66853113+pre-commit-ci[bot]@users.noreply.github.com> Date: Mon, 8 Aug 2022 21:40:53 +0100 Subject: [PATCH 20/76] [pre-commit.ci] pre-commit autoupdate (#430) Co-authored-by: pre-commit-ci[bot] <66853113+pre-commit-ci[bot]@users.noreply.github.com> --- .pre-commit-config.yaml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.pre-commit-config.yaml b/.pre-commit-config.yaml index 1b2ef2c..c47198d 100644 --- a/.pre-commit-config.yaml +++ b/.pre-commit-config.yaml @@ -14,7 +14,7 @@ repos: hooks: - id: isort - repo: https://github.com/PyCQA/flake8 - rev: 5.0.2 + rev: 5.0.4 hooks: - id: flake8 additional_dependencies: From 6a466b7beee77ef96dce44b6f1f4af61088602bb Mon Sep 17 00:00:00 2001 From: Carlton Gibson Date: Thu, 25 Aug 2022 12:04:14 +0200 Subject: [PATCH 21/76] Bumped version and changelog for 4.0b1 release. (#434) --- CHANGELOG.txt | 7 +++++-- daphne/__init__.py | 2 +- 2 files changed, 6 insertions(+), 3 deletions(-) diff --git a/CHANGELOG.txt b/CHANGELOG.txt index d8dd5b9..9416110 100644 --- a/CHANGELOG.txt +++ b/CHANGELOG.txt @@ -1,5 +1,8 @@ -Unreleased ----------- +4.0.0b1 (2022-08-25) +-------------------- + +This is a beta release to allow testing compatibility with the upcoming Channels +4.0. * Dropped support for Python 3.6. diff --git a/daphne/__init__.py b/daphne/__init__.py index 530cbd0..6ac6f94 100755 --- a/daphne/__init__.py +++ b/daphne/__init__.py @@ -1,6 +1,6 @@ import sys -__version__ = "3.0.2" +__version__ = "4.0.0b1" # Windows on Python 3.8+ uses ProactorEventLoop, which is not compatible with From c9a7fdc66911f31169d4a130af87acbb83dbcdc1 Mon Sep 17 00:00:00 2001 From: Michael K Date: Tue, 30 Aug 2022 05:35:56 +0000 Subject: [PATCH 22/76] Run tests on `main` branch, not `master` (#435) --- .github/workflows/tests.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/tests.yml b/.github/workflows/tests.yml index 8cbbff3..9792252 100644 --- a/.github/workflows/tests.yml +++ b/.github/workflows/tests.yml @@ -3,7 +3,7 @@ name: Tests on: push: branches: - - master + - main pull_request: jobs: From b3bfbd61353c0e639af50e9dd7844e28ba80f2ab Mon Sep 17 00:00:00 2001 From: "pre-commit-ci[bot]" <66853113+pre-commit-ci[bot]@users.noreply.github.com> Date: Tue, 6 Sep 2022 09:35:26 +0200 Subject: [PATCH 23/76] [pre-commit.ci] pre-commit autoupdate (#438) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit updates: - [github.com/psf/black: 22.6.0 → 22.8.0](https://github.com/psf/black/compare/22.6.0...22.8.0) Co-authored-by: pre-commit-ci[bot] <66853113+pre-commit-ci[bot]@users.noreply.github.com> --- .pre-commit-config.yaml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.pre-commit-config.yaml b/.pre-commit-config.yaml index c47198d..fba2292 100644 --- a/.pre-commit-config.yaml +++ b/.pre-commit-config.yaml @@ -5,7 +5,7 @@ repos: - id: pyupgrade args: [--py36-plus] - repo: https://github.com/psf/black - rev: 22.6.0 + rev: 22.8.0 hooks: - id: black language_version: python3 From e9637419df41548297226ffc23d3ab57415aa262 Mon Sep 17 00:00:00 2001 From: "pre-commit-ci[bot]" <66853113+pre-commit-ci[bot]@users.noreply.github.com> Date: Tue, 20 Sep 2022 10:07:55 +0100 Subject: [PATCH 24/76] [pre-commit.ci] pre-commit autoupdate (#439) Co-authored-by: pre-commit-ci[bot] <66853113+pre-commit-ci[bot]@users.noreply.github.com> --- .pre-commit-config.yaml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.pre-commit-config.yaml b/.pre-commit-config.yaml index fba2292..574f5d1 100644 --- a/.pre-commit-config.yaml +++ b/.pre-commit-config.yaml @@ -1,6 +1,6 @@ repos: - repo: https://github.com/asottile/pyupgrade - rev: v2.37.3 + rev: v2.38.0 hooks: - id: pyupgrade args: [--py36-plus] From 898529c48947692ed329ccda6c8d38eb7df3d57d Mon Sep 17 00:00:00 2001 From: "pre-commit-ci[bot]" <66853113+pre-commit-ci[bot]@users.noreply.github.com> Date: Mon, 26 Sep 2022 21:47:43 +0100 Subject: [PATCH 25/76] [pre-commit.ci] pre-commit autoupdate (#441) Co-authored-by: pre-commit-ci[bot] <66853113+pre-commit-ci[bot]@users.noreply.github.com> --- .pre-commit-config.yaml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.pre-commit-config.yaml b/.pre-commit-config.yaml index 574f5d1..de5f780 100644 --- a/.pre-commit-config.yaml +++ b/.pre-commit-config.yaml @@ -1,6 +1,6 @@ repos: - repo: https://github.com/asottile/pyupgrade - rev: v2.38.0 + rev: v2.38.2 hooks: - id: pyupgrade args: [--py36-plus] From fef1490eff28e106c93ff6539faa196ce5aee626 Mon Sep 17 00:00:00 2001 From: Jakub Stawowy Date: Fri, 7 Oct 2022 12:21:22 +0200 Subject: [PATCH 26/76] =?UTF-8?q?Removed=20deprecated=20=E2=80=94ws-protoc?= =?UTF-8?q?ols=20CLI=20option.=20(#387)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- CHANGELOG.txt | 2 ++ daphne/cli.py | 8 -------- daphne/server.py | 2 -- 3 files changed, 2 insertions(+), 10 deletions(-) diff --git a/CHANGELOG.txt b/CHANGELOG.txt index 9416110..eb2c58a 100644 --- a/CHANGELOG.txt +++ b/CHANGELOG.txt @@ -39,6 +39,8 @@ This is a beta release to allow testing compatibility with the upcoming Channels ... ] +* Removed deprecated ``--ws_protocols`` CLI option. + 3.0.2 (2021-04-07) ------------------ diff --git a/daphne/cli.py b/daphne/cli.py index accafe1..7c0c3c9 100755 --- a/daphne/cli.py +++ b/daphne/cli.py @@ -113,13 +113,6 @@ class CommandLineInterface: help="The number of seconds an ASGI application has to exit after client disconnect before it is killed", default=10, ) - self.parser.add_argument( - "--ws-protocol", - nargs="*", - dest="ws_protocols", - help="The WebSocket protocols you wish to support", - default=None, - ) self.parser.add_argument( "--root-path", dest="root_path", @@ -280,7 +273,6 @@ class CommandLineInterface: action_logger=AccessLogGenerator(access_log_stream) if access_log_stream else None, - ws_protocols=args.ws_protocols, root_path=args.root_path, verbosity=args.verbosity, proxy_forwarded_address_header=self._get_forwarded_host(args=args), diff --git a/daphne/server.py b/daphne/server.py index e5728b3..8da4a61 100755 --- a/daphne/server.py +++ b/daphne/server.py @@ -65,8 +65,6 @@ class Server: application_close_timeout=10, ready_callable=None, server_name="daphne", - # Deprecated and does not work, remove in version 2.2 - ws_protocols=None, ): self.application = application self.endpoints = endpoints or [] From 12e543750b0c3c4792904f5b80ae11ef7bcff0fc Mon Sep 17 00:00:00 2001 From: Adam Johnson Date: Fri, 7 Oct 2022 12:22:40 +0100 Subject: [PATCH 27/76] Make DaphneProcess pickleable (#440) --- CHANGELOG.txt | 3 +++ daphne/testing.py | 23 +++++++++++++++-------- tests/test_websocket.py | 2 +- 3 files changed, 19 insertions(+), 9 deletions(-) diff --git a/CHANGELOG.txt b/CHANGELOG.txt index eb2c58a..c462568 100644 --- a/CHANGELOG.txt +++ b/CHANGELOG.txt @@ -41,6 +41,9 @@ This is a beta release to allow testing compatibility with the upcoming Channels * Removed deprecated ``--ws_protocols`` CLI option. +* Made the ``DaphneProcess`` tests helper class compatible with the ``spawn`` + process start method, which is used on macOS and Windows. + 3.0.2 (2021-04-07) ------------------ diff --git a/daphne/testing.py b/daphne/testing.py index e2c7200..785edf9 100644 --- a/daphne/testing.py +++ b/daphne/testing.py @@ -26,6 +26,9 @@ class BaseDaphneTestingInstance: self.request_buffer_size = request_buffer_size self.application = application + def get_application(self): + return self.application + def __enter__(self): # Option Daphne features kwargs = {} @@ -41,7 +44,7 @@ class BaseDaphneTestingInstance: # Start up process self.process = DaphneProcess( host=self.host, - application=self.application, + get_application=self.get_application, kwargs=kwargs, setup=self.process_setup, teardown=self.process_teardown, @@ -123,13 +126,13 @@ class DaphneProcess(multiprocessing.Process): port it ends up listening on back to the parent process. """ - def __init__(self, host, application, kwargs=None, setup=None, teardown=None): + def __init__(self, host, get_application, kwargs=None, setup=None, teardown=None): super().__init__() self.host = host - self.application = application + self.get_application = get_application self.kwargs = kwargs or {} - self.setup = setup or (lambda: None) - self.teardown = teardown or (lambda: None) + self.setup = setup + self.teardown = teardown self.port = multiprocessing.Value("i") self.ready = multiprocessing.Event() self.errors = multiprocessing.Queue() @@ -146,11 +149,13 @@ class DaphneProcess(multiprocessing.Process): from .endpoints import build_endpoint_description_strings from .server import Server + application = self.get_application() + try: # Create the server class endpoints = build_endpoint_description_strings(host=self.host, port=0) self.server = Server( - application=self.application, + application=application, endpoints=endpoints, signal_handlers=False, **self.kwargs @@ -158,11 +163,13 @@ class DaphneProcess(multiprocessing.Process): # Set up a poller to look for the port reactor.callLater(0.1, self.resolve_port) # Run with setup/teardown - self.setup() + if self.setup is not None: + self.setup() try: self.server.run() finally: - self.teardown() + if self.teardown is not None: + self.teardown() except BaseException as e: # Put the error on our queue so the parent gets it self.errors.put((e, traceback.format_exc())) diff --git a/tests/test_websocket.py b/tests/test_websocket.py index 9b67aa1..e954486 100644 --- a/tests/test_websocket.py +++ b/tests/test_websocket.py @@ -288,7 +288,7 @@ async def cancelling_application(scope, receive, send): from twisted.internet import reactor # Stop the server after a short delay so that the teardown is run. - reactor.callLater(2, lambda: reactor.stop()) + reactor.callLater(2, reactor.stop) await send({"type": "websocket.accept"}) raise asyncio.CancelledError() From 060202f4914b0f46fc2d7398d9b769a8481300ef Mon Sep 17 00:00:00 2001 From: Carlton Gibson Date: Fri, 7 Oct 2022 14:53:16 +0200 Subject: [PATCH 28/76] Updated change log and version for v4.0 release. --- CHANGELOG.txt | 39 ++++++++++++++++++++++----------------- daphne/__init__.py | 2 +- 2 files changed, 23 insertions(+), 18 deletions(-) diff --git a/CHANGELOG.txt b/CHANGELOG.txt index c462568..996b763 100644 --- a/CHANGELOG.txt +++ b/CHANGELOG.txt @@ -1,8 +1,26 @@ -4.0.0b1 (2022-08-25) --------------------- +4.0.0 (2022-10-07) +------------------ -This is a beta release to allow testing compatibility with the upcoming Channels -4.0. +Major versioning targeting use with Channels 4.0 and beyond. Except where +noted should remain usable with Channels v3 projects, but updating Channels to the latest version is recommended. + +* Added a ``runserver`` command to run an ASGI Django development server. + + Added ``"daphne"`` to the ``INSTALLED_APPS`` setting, before + ``"django.contrib.staticfiles"`` to enable: + + INSTALLED_APPS = [ + "daphne", + ... + ] + + This replaces the Channels implementation of ``runserver``, which is removed + in Channels 4.0. + +* Made the ``DaphneProcess`` tests helper class compatible with the ``spawn`` + process start method, which is used on macOS and Windows. + + Note that requires Channels v4 if using with ``ChannelsLiveServerTestCase``. * Dropped support for Python 3.6. @@ -29,21 +47,8 @@ This is a beta release to allow testing compatibility with the upcoming Channels Set e.g. ``ASGI_THREADS=4 daphne ...`` when running to limit the number of workers. -* Added a ``runserver`` command to run an ASGI Django development server. - - Added ``"daphne"`` to the ``INSTALLED_APPS`` setting, before - ``"django.contrib.staticfiles"`` to enable: - - INSTALLED_APPS = [ - "daphne", - ... - ] - * Removed deprecated ``--ws_protocols`` CLI option. -* Made the ``DaphneProcess`` tests helper class compatible with the ``spawn`` - process start method, which is used on macOS and Windows. - 3.0.2 (2021-04-07) ------------------ diff --git a/daphne/__init__.py b/daphne/__init__.py index 6ac6f94..ae556a6 100755 --- a/daphne/__init__.py +++ b/daphne/__init__.py @@ -1,6 +1,6 @@ import sys -__version__ = "4.0.0b1" +__version__ = "4.0.0" # Windows on Python 3.8+ uses ProactorEventLoop, which is not compatible with From 91c61f4ff4148d8e540520c5c8962672753263d6 Mon Sep 17 00:00:00 2001 From: "pre-commit-ci[bot]" <66853113+pre-commit-ci[bot]@users.noreply.github.com> Date: Mon, 10 Oct 2022 23:39:20 +0100 Subject: [PATCH 29/76] [pre-commit.ci] pre-commit autoupdate (#443) Co-authored-by: pre-commit-ci[bot] <66853113+pre-commit-ci[bot]@users.noreply.github.com> --- .pre-commit-config.yaml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/.pre-commit-config.yaml b/.pre-commit-config.yaml index de5f780..c4c1dec 100644 --- a/.pre-commit-config.yaml +++ b/.pre-commit-config.yaml @@ -1,11 +1,11 @@ repos: - repo: https://github.com/asottile/pyupgrade - rev: v2.38.2 + rev: v3.0.0 hooks: - id: pyupgrade args: [--py36-plus] - repo: https://github.com/psf/black - rev: 22.8.0 + rev: 22.10.0 hooks: - id: black language_version: python3 From 71be46265dffb11ad2da7560e67dfa95be246755 Mon Sep 17 00:00:00 2001 From: "pre-commit-ci[bot]" <66853113+pre-commit-ci[bot]@users.noreply.github.com> Date: Mon, 17 Oct 2022 23:09:03 +0100 Subject: [PATCH 30/76] [pre-commit.ci] pre-commit autoupdate (#444) Co-authored-by: pre-commit-ci[bot] <66853113+pre-commit-ci[bot]@users.noreply.github.com> --- .pre-commit-config.yaml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.pre-commit-config.yaml b/.pre-commit-config.yaml index c4c1dec..a4c0210 100644 --- a/.pre-commit-config.yaml +++ b/.pre-commit-config.yaml @@ -1,6 +1,6 @@ repos: - repo: https://github.com/asottile/pyupgrade - rev: v3.0.0 + rev: v3.1.0 hooks: - id: pyupgrade args: [--py36-plus] From d5fbdfc4cbca77fa7c3b9a4d0ff7fcc285f6e971 Mon Sep 17 00:00:00 2001 From: Michael K Date: Tue, 25 Oct 2022 12:46:20 +0000 Subject: [PATCH 31/76] Run tests against Python 3.11 and add trove classifier (#446) --- .github/workflows/tests.yml | 1 + setup.py | 1 + tox.ini | 2 +- 3 files changed, 3 insertions(+), 1 deletion(-) diff --git a/.github/workflows/tests.yml b/.github/workflows/tests.yml index 9792252..3a00cce 100644 --- a/.github/workflows/tests.yml +++ b/.github/workflows/tests.yml @@ -20,6 +20,7 @@ jobs: - "3.8" - "3.9" - "3.10" + - "3.11" steps: - uses: actions/checkout@v2 diff --git a/setup.py b/setup.py index ae19f5d..b95f0e9 100755 --- a/setup.py +++ b/setup.py @@ -41,6 +41,7 @@ setup( "Programming Language :: Python :: 3.8", "Programming Language :: Python :: 3.9", "Programming Language :: Python :: 3.10", + "Programming Language :: Python :: 3.11", "Topic :: Internet :: WWW/HTTP", ], ) diff --git a/tox.ini b/tox.ini index 876ff99..20e9a33 100644 --- a/tox.ini +++ b/tox.ini @@ -1,6 +1,6 @@ [tox] envlist = - py{37,38,39,310} + py{37,38,39,310,311} [testenv] usedevelop = true extras = tests From afd0d51b83f7d4ac9deab44257e3064e064f0b11 Mon Sep 17 00:00:00 2001 From: "pre-commit-ci[bot]" <66853113+pre-commit-ci[bot]@users.noreply.github.com> Date: Tue, 1 Nov 2022 11:09:39 +0000 Subject: [PATCH 32/76] [pre-commit.ci] pre-commit autoupdate (#448) Co-authored-by: pre-commit-ci[bot] <66853113+pre-commit-ci[bot]@users.noreply.github.com> --- .pre-commit-config.yaml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.pre-commit-config.yaml b/.pre-commit-config.yaml index a4c0210..97db8ed 100644 --- a/.pre-commit-config.yaml +++ b/.pre-commit-config.yaml @@ -1,6 +1,6 @@ repos: - repo: https://github.com/asottile/pyupgrade - rev: v3.1.0 + rev: v3.2.0 hooks: - id: pyupgrade args: [--py36-plus] From a0b2ac0e8f8409a9e183e1f123e3ecc0a2983ff9 Mon Sep 17 00:00:00 2001 From: "pre-commit-ci[bot]" <66853113+pre-commit-ci[bot]@users.noreply.github.com> Date: Mon, 14 Nov 2022 20:47:53 +0000 Subject: [PATCH 33/76] [pre-commit.ci] pre-commit autoupdate (#452) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit updates: - [github.com/asottile/pyupgrade: v3.2.0 → v3.2.2](https://github.com/asottile/pyupgrade/compare/v3.2.0...v3.2.2) Co-authored-by: pre-commit-ci[bot] <66853113+pre-commit-ci[bot]@users.noreply.github.com> --- .pre-commit-config.yaml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.pre-commit-config.yaml b/.pre-commit-config.yaml index 97db8ed..490fc85 100644 --- a/.pre-commit-config.yaml +++ b/.pre-commit-config.yaml @@ -1,6 +1,6 @@ repos: - repo: https://github.com/asottile/pyupgrade - rev: v3.2.0 + rev: v3.2.2 hooks: - id: pyupgrade args: [--py36-plus] From ef946d56379115e4593622d627eadb93e1187d4b Mon Sep 17 00:00:00 2001 From: Michael K Date: Fri, 18 Nov 2022 10:33:03 +0000 Subject: [PATCH 34/76] Upgrade GitHub Actions actions (#454) And set up dependabot to take care of them in the future. --- .github/dependabot.yml | 6 ++++++ .github/workflows/tests.yml | 4 ++-- 2 files changed, 8 insertions(+), 2 deletions(-) create mode 100644 .github/dependabot.yml diff --git a/.github/dependabot.yml b/.github/dependabot.yml new file mode 100644 index 0000000..e5903e0 --- /dev/null +++ b/.github/dependabot.yml @@ -0,0 +1,6 @@ +version: 2 +updates: +- package-ecosystem: github-actions + directory: "/" + schedule: + interval: weekly diff --git a/.github/workflows/tests.yml b/.github/workflows/tests.yml index 3a00cce..36e0589 100644 --- a/.github/workflows/tests.yml +++ b/.github/workflows/tests.yml @@ -23,10 +23,10 @@ jobs: - "3.11" steps: - - uses: actions/checkout@v2 + - uses: actions/checkout@v3 - name: Set up Python ${{ matrix.python-version }} - uses: actions/setup-python@v2 + uses: actions/setup-python@v4 with: python-version: ${{ matrix.python-version }} From 18e936eed11a908bb7f3783f755a373f5d65c3c4 Mon Sep 17 00:00:00 2001 From: "pre-commit-ci[bot]" <66853113+pre-commit-ci[bot]@users.noreply.github.com> Date: Tue, 29 Nov 2022 20:34:37 +0000 Subject: [PATCH 35/76] [pre-commit.ci] pre-commit autoupdate (#456) Co-authored-by: pre-commit-ci[bot] <66853113+pre-commit-ci[bot]@users.noreply.github.com> --- .pre-commit-config.yaml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.pre-commit-config.yaml b/.pre-commit-config.yaml index 490fc85..b4f91a3 100644 --- a/.pre-commit-config.yaml +++ b/.pre-commit-config.yaml @@ -14,7 +14,7 @@ repos: hooks: - id: isort - repo: https://github.com/PyCQA/flake8 - rev: 5.0.4 + rev: 6.0.0 hooks: - id: flake8 additional_dependencies: From 2015ecdd8fcef5910a6f4c7383bda182161fe975 Mon Sep 17 00:00:00 2001 From: "pre-commit-ci[bot]" <66853113+pre-commit-ci[bot]@users.noreply.github.com> Date: Tue, 6 Dec 2022 09:01:28 +0000 Subject: [PATCH 36/76] [pre-commit.ci] pre-commit autoupdate (#457) Co-authored-by: pre-commit-ci[bot] <66853113+pre-commit-ci[bot]@users.noreply.github.com> --- .pre-commit-config.yaml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.pre-commit-config.yaml b/.pre-commit-config.yaml index b4f91a3..e2b915e 100644 --- a/.pre-commit-config.yaml +++ b/.pre-commit-config.yaml @@ -1,6 +1,6 @@ repos: - repo: https://github.com/asottile/pyupgrade - rev: v3.2.2 + rev: v3.3.0 hooks: - id: pyupgrade args: [--py36-plus] From d59c2bd4242f81206f5aaa04832d7aba898b4cd6 Mon Sep 17 00:00:00 2001 From: Adam Johnson Date: Thu, 8 Dec 2022 01:06:41 +0000 Subject: [PATCH 37/76] Upgrade to tox 4 (#458) --- .github/workflows/tests.yml | 4 +-- pyproject.toml | 3 +++ setup.cfg | 50 +++++++++++++++++++++++++++++++++++++ setup.py | 47 ---------------------------------- tox.ini | 2 +- 5 files changed, 56 insertions(+), 50 deletions(-) create mode 100644 pyproject.toml delete mode 100755 setup.py diff --git a/.github/workflows/tests.yml b/.github/workflows/tests.yml index 36e0589..8d4d1c4 100644 --- a/.github/workflows/tests.yml +++ b/.github/workflows/tests.yml @@ -33,7 +33,7 @@ jobs: - name: Install dependencies run: | python -m pip install --upgrade pip setuptools wheel - python -m pip install --upgrade tox tox-py + python -m pip install --upgrade tox - name: Run tox targets for ${{ matrix.python-version }} - run: tox --py current + run: tox run -f py$(echo ${{ matrix.python-version }} | tr -d .) diff --git a/pyproject.toml b/pyproject.toml new file mode 100644 index 0000000..fed528d --- /dev/null +++ b/pyproject.toml @@ -0,0 +1,3 @@ +[build-system] +requires = ["setuptools"] +build-backend = "setuptools.build_meta" diff --git a/setup.cfg b/setup.cfg index e7c19e5..cdde703 100644 --- a/setup.cfg +++ b/setup.cfg @@ -1,3 +1,53 @@ +[metadata] +name = daphne +version = attr: daphne.__version__ +url = https://github.com/django/daphne +author = Django Software Foundation +author_email = foundation@djangoproject.com +description = Django ASGI (HTTP/WebSocket) server +long_description = file: README.rst +long_description_content_type = text/x-rst +license = BSD +classifiers = + Development Status :: 4 - Beta + Environment :: Web Environment + Intended Audience :: Developers + License :: OSI Approved :: BSD License + Operating System :: OS Independent + Programming Language :: Python + Programming Language :: Python :: 3 + Programming Language :: Python :: 3.7 + Programming Language :: Python :: 3.8 + Programming Language :: Python :: 3.9 + Programming Language :: Python :: 3.10 + Programming Language :: Python :: 3.11 + Topic :: Internet :: WWW/HTTP + +[options] +package_dir = + twisted=daphne/twisted +packages = find: +include_package_data = True +install_requires = + asgiref>=3.5.2,<4 + autobahn>=22.4.2 + twisted[tls]>=22.4 +python_requires = >=3.7 +setup_requires = + pytest-runner +zip_safe = False + +[options.entry_points] +console_scripts = + daphne = daphne.cli:CommandLineInterface.entrypoint + +[options.extras_require] +tests = + django + hypothesis + pytest + pytest-asyncio + [flake8] exclude = venv/*,tox/*,docs/*,testproject/*,js_client/*,.eggs/* extend-ignore = E123, E128, E266, E402, W503, E731, W601 diff --git a/setup.py b/setup.py deleted file mode 100755 index b95f0e9..0000000 --- a/setup.py +++ /dev/null @@ -1,47 +0,0 @@ -import os - -from setuptools import find_packages, setup - -from daphne import __version__ - -# We use the README as the long_description -readme_path = os.path.join(os.path.dirname(__file__), "README.rst") -with open(readme_path) as fp: - long_description = fp.read() - -setup( - name="daphne", - version=__version__, - url="https://github.com/django/daphne", - author="Django Software Foundation", - author_email="foundation@djangoproject.com", - description="Django ASGI (HTTP/WebSocket) server", - long_description=long_description, - license="BSD", - zip_safe=False, - package_dir={"twisted": "daphne/twisted"}, - packages=find_packages() + ["twisted.plugins"], - include_package_data=True, - install_requires=["twisted[tls]>=22.4", "autobahn>=22.4.2", "asgiref>=3.5.2,<4"], - python_requires=">=3.7", - setup_requires=["pytest-runner"], - extras_require={"tests": ["hypothesis", "pytest", "pytest-asyncio", "django"]}, - entry_points={ - "console_scripts": ["daphne = daphne.cli:CommandLineInterface.entrypoint"] - }, - classifiers=[ - "Development Status :: 4 - Beta", - "Environment :: Web Environment", - "Intended Audience :: Developers", - "License :: OSI Approved :: BSD License", - "Operating System :: OS Independent", - "Programming Language :: Python", - "Programming Language :: Python :: 3", - "Programming Language :: Python :: 3.7", - "Programming Language :: Python :: 3.8", - "Programming Language :: Python :: 3.9", - "Programming Language :: Python :: 3.10", - "Programming Language :: Python :: 3.11", - "Topic :: Internet :: WWW/HTTP", - ], -) diff --git a/tox.ini b/tox.ini index 20e9a33..305bf14 100644 --- a/tox.ini +++ b/tox.ini @@ -1,8 +1,8 @@ [tox] envlist = py{37,38,39,310,311} + [testenv] -usedevelop = true extras = tests commands = pytest -v {posargs} From c9343aa9d6a2f63bb49d39462a78170a3dd52c8f Mon Sep 17 00:00:00 2001 From: "pre-commit-ci[bot]" <66853113+pre-commit-ci[bot]@users.noreply.github.com> Date: Mon, 12 Dec 2022 23:15:35 +0000 Subject: [PATCH 38/76] [pre-commit.ci] pre-commit autoupdate (#460) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit updates: - [github.com/asottile/pyupgrade: v3.3.0 → v3.3.1](https://github.com/asottile/pyupgrade/compare/v3.3.0...v3.3.1) - [github.com/psf/black: 22.10.0 → 22.12.0](https://github.com/psf/black/compare/22.10.0...22.12.0) - [github.com/pycqa/isort: 5.10.1 → 5.11.0](https://github.com/pycqa/isort/compare/5.10.1...5.11.0) Co-authored-by: pre-commit-ci[bot] <66853113+pre-commit-ci[bot]@users.noreply.github.com> --- .pre-commit-config.yaml | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/.pre-commit-config.yaml b/.pre-commit-config.yaml index e2b915e..758f79c 100644 --- a/.pre-commit-config.yaml +++ b/.pre-commit-config.yaml @@ -1,16 +1,16 @@ repos: - repo: https://github.com/asottile/pyupgrade - rev: v3.3.0 + rev: v3.3.1 hooks: - id: pyupgrade args: [--py36-plus] - repo: https://github.com/psf/black - rev: 22.10.0 + rev: 22.12.0 hooks: - id: black language_version: python3 - repo: https://github.com/pycqa/isort - rev: 5.10.1 + rev: 5.11.0 hooks: - id: isort - repo: https://github.com/PyCQA/flake8 From fdc944a28016d1e3e45ceb128264b1d3c07e5d00 Mon Sep 17 00:00:00 2001 From: "pre-commit-ci[bot]" <66853113+pre-commit-ci[bot]@users.noreply.github.com> Date: Tue, 20 Dec 2022 10:37:51 +0100 Subject: [PATCH 39/76] [pre-commit.ci] pre-commit autoupdate (#461) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit updates: - [github.com/pycqa/isort: 5.11.0 → v5.11.3](https://github.com/pycqa/isort/compare/5.11.0...v5.11.3) Co-authored-by: pre-commit-ci[bot] <66853113+pre-commit-ci[bot]@users.noreply.github.com> --- .pre-commit-config.yaml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.pre-commit-config.yaml b/.pre-commit-config.yaml index 758f79c..bd5e7bb 100644 --- a/.pre-commit-config.yaml +++ b/.pre-commit-config.yaml @@ -10,7 +10,7 @@ repos: - id: black language_version: python3 - repo: https://github.com/pycqa/isort - rev: 5.11.0 + rev: v5.11.3 hooks: - id: isort - repo: https://github.com/PyCQA/flake8 From 5681d71c1791cf83acfd8464946b8993320ac7ba Mon Sep 17 00:00:00 2001 From: "pre-commit-ci[bot]" <66853113+pre-commit-ci[bot]@users.noreply.github.com> Date: Thu, 29 Dec 2022 12:19:00 +0000 Subject: [PATCH 40/76] [pre-commit.ci] pre-commit autoupdate (#462) Co-authored-by: pre-commit-ci[bot] <66853113+pre-commit-ci[bot]@users.noreply.github.com> --- .pre-commit-config.yaml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.pre-commit-config.yaml b/.pre-commit-config.yaml index bd5e7bb..0b2411a 100644 --- a/.pre-commit-config.yaml +++ b/.pre-commit-config.yaml @@ -10,7 +10,7 @@ repos: - id: black language_version: python3 - repo: https://github.com/pycqa/isort - rev: v5.11.3 + rev: 5.11.4 hooks: - id: isort - repo: https://github.com/PyCQA/flake8 From 79fd65dec38826819ebb7aaf5514a2792fb31aaa Mon Sep 17 00:00:00 2001 From: "pre-commit-ci[bot]" <66853113+pre-commit-ci[bot]@users.noreply.github.com> Date: Tue, 31 Jan 2023 06:52:32 +0000 Subject: [PATCH 41/76] [pre-commit.ci] pre-commit autoupdate (#464) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit updates: - [github.com/pycqa/isort: 5.11.4 → 5.12.0](https://github.com/pycqa/isort/compare/5.11.4...5.12.0) Co-authored-by: pre-commit-ci[bot] <66853113+pre-commit-ci[bot]@users.noreply.github.com> --- .pre-commit-config.yaml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.pre-commit-config.yaml b/.pre-commit-config.yaml index 0b2411a..bd89b14 100644 --- a/.pre-commit-config.yaml +++ b/.pre-commit-config.yaml @@ -10,7 +10,7 @@ repos: - id: black language_version: python3 - repo: https://github.com/pycqa/isort - rev: 5.11.4 + rev: 5.12.0 hooks: - id: isort - repo: https://github.com/PyCQA/flake8 From b0204165b1fc1ccb786e9ba65ad32d20f1fc83f5 Mon Sep 17 00:00:00 2001 From: "pre-commit-ci[bot]" <66853113+pre-commit-ci[bot]@users.noreply.github.com> Date: Tue, 7 Feb 2023 15:20:08 +0000 Subject: [PATCH 42/76] [pre-commit.ci] pre-commit autoupdate (#466) Co-authored-by: pre-commit-ci[bot] <66853113+pre-commit-ci[bot]@users.noreply.github.com> --- .pre-commit-config.yaml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.pre-commit-config.yaml b/.pre-commit-config.yaml index bd89b14..00bac0b 100644 --- a/.pre-commit-config.yaml +++ b/.pre-commit-config.yaml @@ -5,7 +5,7 @@ repos: - id: pyupgrade args: [--py36-plus] - repo: https://github.com/psf/black - rev: 22.12.0 + rev: 23.1.0 hooks: - id: black language_version: python3 From 077dd8180968d75c222c1f84d62ff5c630e6b38a Mon Sep 17 00:00:00 2001 From: Carlton Gibson Date: Fri, 14 Apr 2023 14:53:12 +0200 Subject: [PATCH 43/76] Added missing stacklevel warning parameter. (#471) --- daphne/server.py | 1 + 1 file changed, 1 insertion(+) diff --git a/daphne/server.py b/daphne/server.py index 8da4a61..a6d3819 100755 --- a/daphne/server.py +++ b/daphne/server.py @@ -21,6 +21,7 @@ if current_reactor is not None: + "you can fix this warning by importing daphne.server early in your codebase or " + "finding the package that imports Twisted and importing it later on.", UserWarning, + stacklevel=2, ) del sys.modules["twisted.internet.reactor"] asyncioreactor.install(twisted_loop) From 21513b84da2558ba84cc35ed77985e77f8308754 Mon Sep 17 00:00:00 2001 From: "pre-commit-ci[bot]" <66853113+pre-commit-ci[bot]@users.noreply.github.com> Date: Fri, 14 Apr 2023 15:03:51 +0200 Subject: [PATCH 44/76] [pre-commit.ci] pre-commit autoupdate (#470) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit updates: - [github.com/psf/black: 23.1.0 → 23.3.0](https://github.com/psf/black/compare/23.1.0...23.3.0) Co-authored-by: pre-commit-ci[bot] <66853113+pre-commit-ci[bot]@users.noreply.github.com> Co-authored-by: Carlton Gibson --- .pre-commit-config.yaml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.pre-commit-config.yaml b/.pre-commit-config.yaml index 00bac0b..3f61b80 100644 --- a/.pre-commit-config.yaml +++ b/.pre-commit-config.yaml @@ -5,7 +5,7 @@ repos: - id: pyupgrade args: [--py36-plus] - repo: https://github.com/psf/black - rev: 23.1.0 + rev: 23.3.0 hooks: - id: black language_version: python3 From 09da15dc4e6c542325bad9f1b4f060cd55fd12ba Mon Sep 17 00:00:00 2001 From: Abenezer Belachew <43050633+abenezerBelachew@users.noreply.github.com> Date: Fri, 14 Apr 2023 16:10:16 +0300 Subject: [PATCH 45/76] Double quotes during pip (#467) Single quotes return => ERROR: Invalid requirement: "'Twisted[tls,http2]'" --- README.rst | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.rst b/README.rst index 70c4ba5..aa18798 100644 --- a/README.rst +++ b/README.rst @@ -54,7 +54,7 @@ Daphne supports terminating HTTP/2 connections natively. You'll need to do a couple of things to get it working, though. First, you need to make sure you install the Twisted ``http2`` and ``tls`` extras:: - pip install -U 'Twisted[tls,http2]' + pip install -U "Twisted[tls,http2]" Next, because all current browsers only support HTTP/2 when using TLS, you will need to start Daphne with TLS turned on, which can be done using the Twisted endpoint syntax:: From 1eaf2206cce86d7ada71875a4ff5651201f101a7 Mon Sep 17 00:00:00 2001 From: Carlton Gibson Date: Sun, 16 Apr 2023 10:33:27 +0200 Subject: [PATCH 46/76] Set pre-commit to quarterly updates. (#472) --- .pre-commit-config.yaml | 2 ++ 1 file changed, 2 insertions(+) diff --git a/.pre-commit-config.yaml b/.pre-commit-config.yaml index 3f61b80..02e0fa6 100644 --- a/.pre-commit-config.yaml +++ b/.pre-commit-config.yaml @@ -19,3 +19,5 @@ repos: - id: flake8 additional_dependencies: - flake8-bugbear +ci: + autoupdate_schedule: quarterly From e49c39a4e5fac8ec170dd653641a9e90844fd3f1 Mon Sep 17 00:00:00 2001 From: "pre-commit-ci[bot]" <66853113+pre-commit-ci[bot]@users.noreply.github.com> Date: Tue, 4 Jul 2023 05:48:51 +0100 Subject: [PATCH 47/76] [pre-commit.ci] pre-commit autoupdate (#477) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit updates: - [github.com/asottile/pyupgrade: v3.3.1 → v3.8.0](https://github.com/asottile/pyupgrade/compare/v3.3.1...v3.8.0) Co-authored-by: pre-commit-ci[bot] <66853113+pre-commit-ci[bot]@users.noreply.github.com> --- .pre-commit-config.yaml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.pre-commit-config.yaml b/.pre-commit-config.yaml index 02e0fa6..e7a2b46 100644 --- a/.pre-commit-config.yaml +++ b/.pre-commit-config.yaml @@ -1,6 +1,6 @@ repos: - repo: https://github.com/asottile/pyupgrade - rev: v3.3.1 + rev: v3.8.0 hooks: - id: pyupgrade args: [--py36-plus] From f108bbc7c1076fbdbce10809da8ee3e73ecb68c6 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Tue, 5 Sep 2023 07:51:07 +0200 Subject: [PATCH 48/76] Bump actions/checkout from 3 to 4 (#480) Bumps [actions/checkout](https://github.com/actions/checkout) from 3 to 4. - [Release notes](https://github.com/actions/checkout/releases) - [Changelog](https://github.com/actions/checkout/blob/main/CHANGELOG.md) - [Commits](https://github.com/actions/checkout/compare/v3...v4) --- updated-dependencies: - dependency-name: actions/checkout dependency-type: direct:production update-type: version-update:semver-major ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- .github/workflows/tests.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/tests.yml b/.github/workflows/tests.yml index 8d4d1c4..357d648 100644 --- a/.github/workflows/tests.yml +++ b/.github/workflows/tests.yml @@ -23,7 +23,7 @@ jobs: - "3.11" steps: - - uses: actions/checkout@v3 + - uses: actions/checkout@v4 - name: Set up Python ${{ matrix.python-version }} uses: actions/setup-python@v4 From 3758c514fdedfdfd8df32cfbecc5df2c00bb2d1a Mon Sep 17 00:00:00 2001 From: InvalidInterrupt Date: Thu, 7 Sep 2023 00:09:10 -0700 Subject: [PATCH 49/76] Raise minimum supported Python version to 3.8 (#481) --- .github/workflows/tests.yml | 1 - README.rst | 2 +- setup.cfg | 3 +-- tox.ini | 2 +- 4 files changed, 3 insertions(+), 5 deletions(-) diff --git a/.github/workflows/tests.yml b/.github/workflows/tests.yml index 357d648..a719751 100644 --- a/.github/workflows/tests.yml +++ b/.github/workflows/tests.yml @@ -16,7 +16,6 @@ jobs: - ubuntu - windows python-version: - - "3.7" - "3.8" - "3.9" - "3.10" diff --git a/README.rst b/README.rst index aa18798..d93ad02 100644 --- a/README.rst +++ b/README.rst @@ -108,7 +108,7 @@ should start with a slash, but not end with one; for example:: Python Support -------------- -Daphne requires Python 3.7 or later. +Daphne requires Python 3.8 or later. Contributing diff --git a/setup.cfg b/setup.cfg index cdde703..c73c92a 100644 --- a/setup.cfg +++ b/setup.cfg @@ -16,7 +16,6 @@ classifiers = Operating System :: OS Independent Programming Language :: Python Programming Language :: Python :: 3 - Programming Language :: Python :: 3.7 Programming Language :: Python :: 3.8 Programming Language :: Python :: 3.9 Programming Language :: Python :: 3.10 @@ -32,7 +31,7 @@ install_requires = asgiref>=3.5.2,<4 autobahn>=22.4.2 twisted[tls]>=22.4 -python_requires = >=3.7 +python_requires = >=3.8 setup_requires = pytest-runner zip_safe = False diff --git a/tox.ini b/tox.ini index 305bf14..b638f4c 100644 --- a/tox.ini +++ b/tox.ini @@ -1,6 +1,6 @@ [tox] envlist = - py{37,38,39,310,311} + py{38,39,310,311} [testenv] extras = tests From 2d4dcbf14952458e1abe8e5451910f463c97a218 Mon Sep 17 00:00:00 2001 From: "pre-commit-ci[bot]" <66853113+pre-commit-ci[bot]@users.noreply.github.com> Date: Tue, 3 Oct 2023 12:59:12 +0200 Subject: [PATCH 50/76] [pre-commit.ci] pre-commit autoupdate (#485) --- .pre-commit-config.yaml | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/.pre-commit-config.yaml b/.pre-commit-config.yaml index e7a2b46..db154b8 100644 --- a/.pre-commit-config.yaml +++ b/.pre-commit-config.yaml @@ -1,11 +1,11 @@ repos: - repo: https://github.com/asottile/pyupgrade - rev: v3.8.0 + rev: v3.14.0 hooks: - id: pyupgrade args: [--py36-plus] - repo: https://github.com/psf/black - rev: 23.3.0 + rev: 23.9.1 hooks: - id: black language_version: python3 @@ -14,7 +14,7 @@ repos: hooks: - id: isort - repo: https://github.com/PyCQA/flake8 - rev: 6.0.0 + rev: 6.1.0 hooks: - id: flake8 additional_dependencies: From 4d24e22c72e1545ad753f53753291f301bd3dae5 Mon Sep 17 00:00:00 2001 From: Paolo Melchiorre Date: Sun, 26 Nov 2023 16:12:23 +0100 Subject: [PATCH 51/76] Fixed #489 -- Add support for Python 3.12 (#490) --- .github/workflows/tests.yml | 1 + .pre-commit-config.yaml | 6 +++--- CHANGELOG.txt | 6 ++++++ setup.cfg | 1 + tox.ini | 2 +- 5 files changed, 12 insertions(+), 4 deletions(-) diff --git a/.github/workflows/tests.yml b/.github/workflows/tests.yml index a719751..670a8ac 100644 --- a/.github/workflows/tests.yml +++ b/.github/workflows/tests.yml @@ -20,6 +20,7 @@ jobs: - "3.9" - "3.10" - "3.11" + - "3.12" steps: - uses: actions/checkout@v4 diff --git a/.pre-commit-config.yaml b/.pre-commit-config.yaml index db154b8..c1fd822 100644 --- a/.pre-commit-config.yaml +++ b/.pre-commit-config.yaml @@ -1,11 +1,11 @@ repos: - repo: https://github.com/asottile/pyupgrade - rev: v3.14.0 + rev: v3.15.0 hooks: - id: pyupgrade - args: [--py36-plus] + args: [--py38-plus] - repo: https://github.com/psf/black - rev: 23.9.1 + rev: 23.11.0 hooks: - id: black language_version: python3 diff --git a/CHANGELOG.txt b/CHANGELOG.txt index 996b763..5a15c1d 100644 --- a/CHANGELOG.txt +++ b/CHANGELOG.txt @@ -1,3 +1,9 @@ +4.1.0 (unreleased) +------------------ + +* Added support for Python 3.12 + + 4.0.0 (2022-10-07) ------------------ diff --git a/setup.cfg b/setup.cfg index c73c92a..26b3352 100644 --- a/setup.cfg +++ b/setup.cfg @@ -20,6 +20,7 @@ classifiers = Programming Language :: Python :: 3.9 Programming Language :: Python :: 3.10 Programming Language :: Python :: 3.11 + Programming Language :: Python :: 3.12 Topic :: Internet :: WWW/HTTP [options] diff --git a/tox.ini b/tox.ini index b638f4c..a741f0e 100644 --- a/tox.ini +++ b/tox.ini @@ -1,6 +1,6 @@ [tox] envlist = - py{38,39,310,311} + py{38,39,310,311,312} [testenv] extras = tests From c07925d53fa2f29e8ec79a91aade6f515a201305 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Tue, 12 Dec 2023 07:19:48 +0100 Subject: [PATCH 52/76] Bump actions/setup-python from 4 to 5 (#491) --- .github/workflows/tests.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/tests.yml b/.github/workflows/tests.yml index 670a8ac..af816f7 100644 --- a/.github/workflows/tests.yml +++ b/.github/workflows/tests.yml @@ -26,7 +26,7 @@ jobs: - uses: actions/checkout@v4 - name: Set up Python ${{ matrix.python-version }} - uses: actions/setup-python@v4 + uses: actions/setup-python@v5 with: python-version: ${{ matrix.python-version }} From 993efe62ce9e9c1cd64c81b6ee7dfa7b819482c7 Mon Sep 17 00:00:00 2001 From: "pre-commit-ci[bot]" <66853113+pre-commit-ci[bot]@users.noreply.github.com> Date: Mon, 1 Jan 2024 19:58:51 +0100 Subject: [PATCH 53/76] [pre-commit.ci] pre-commit autoupdate (#492) --- .pre-commit-config.yaml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/.pre-commit-config.yaml b/.pre-commit-config.yaml index c1fd822..05fe3f8 100644 --- a/.pre-commit-config.yaml +++ b/.pre-commit-config.yaml @@ -5,12 +5,12 @@ repos: - id: pyupgrade args: [--py38-plus] - repo: https://github.com/psf/black - rev: 23.11.0 + rev: 23.12.1 hooks: - id: black language_version: python3 - repo: https://github.com/pycqa/isort - rev: 5.12.0 + rev: 5.13.2 hooks: - id: isort - repo: https://github.com/PyCQA/flake8 From 5fdc9176e53e730338c51205bf216c108e669a5a Mon Sep 17 00:00:00 2001 From: Carlton Gibson Date: Tue, 6 Feb 2024 09:04:10 +0100 Subject: [PATCH 54/76] Ignored flake8-bugbear B036. (#499) "except BaseException: without re-raising" used in testing.py --- setup.cfg | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/setup.cfg b/setup.cfg index 26b3352..a78e654 100644 --- a/setup.cfg +++ b/setup.cfg @@ -50,7 +50,7 @@ tests = [flake8] exclude = venv/*,tox/*,docs/*,testproject/*,js_client/*,.eggs/* -extend-ignore = E123, E128, E266, E402, W503, E731, W601 +extend-ignore = E123, E128, E266, E402, W503, E731, W601, B036 max-line-length = 120 [isort] From 9a282dd6277f4b921e494a9fc30a534a7f0d6ca6 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Alejandro=20R=2E=20Sede=C3=B1o?= Date: Tue, 6 Feb 2024 03:15:03 -0500 Subject: [PATCH 55/76] Handle Daphne-Root-Path for websockets, adding root_path to scope. (#453) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Alejandro R. Sedeño --- daphne/ws_protocol.py | 9 +++++++-- tests/test_websocket.py | 24 ++++++++++++++++++++++++ 2 files changed, 31 insertions(+), 2 deletions(-) diff --git a/daphne/ws_protocol.py b/daphne/ws_protocol.py index 975b1a9..184515d 100755 --- a/daphne/ws_protocol.py +++ b/daphne/ws_protocol.py @@ -31,17 +31,21 @@ class WebSocketProtocol(WebSocketServerProtocol): self.server.protocol_connected(self) self.request = request self.protocol_to_accept = None + self.root_path = self.server.root_path self.socket_opened = time.time() self.last_ping = time.time() try: - # Sanitize and decode headers + # Sanitize and decode headers, potentially extracting root path self.clean_headers = [] for name, value in request.headers.items(): name = name.encode("ascii") # Prevent CVE-2015-0219 if b"_" in name: continue - self.clean_headers.append((name.lower(), value.encode("latin1"))) + if name.lower() == b"daphne-root-path": + self.root_path = unquote(value) + else: + self.clean_headers.append((name.lower(), value.encode("latin1"))) # Get client address if possible peer = self.transport.getPeer() host = self.transport.getHost() @@ -76,6 +80,7 @@ class WebSocketProtocol(WebSocketServerProtocol): "type": "websocket", "path": unquote(self.path.decode("ascii")), "raw_path": self.path, + "root_path": self.root_path, "headers": self.clean_headers, "query_string": self._raw_query_string, # Passed by HTTP protocol "client": self.client_addr, diff --git a/tests/test_websocket.py b/tests/test_websocket.py index e954486..851143c 100644 --- a/tests/test_websocket.py +++ b/tests/test_websocket.py @@ -192,6 +192,30 @@ class TestWebsocket(DaphneTestCase): self.assertEqual(scope["path"], "/foo/bar") self.assertEqual(scope["raw_path"], b"/foo%2Fbar") + @given(daphne_path=http_strategies.http_path()) + @settings(max_examples=5, deadline=2000) + def test_root_path(self, *, daphne_path): + """ + Tests root_path handling. + """ + headers = [("Daphne-Root-Path", parse.quote(daphne_path))] + with DaphneTestingInstance() as test_app: + test_app.add_send_messages([{"type": "websocket.accept"}]) + self.websocket_handshake( + test_app, + path="/", + headers=headers, + ) + # Validate the scope and messages we got + scope, _ = test_app.get_received() + + # Daphne-Root-Path is not included in the returned 'headers' section. + self.assertNotIn( + "daphne-root-path", (header[0].lower() for header in scope["headers"]) + ) + # And what we're looking for, root_path being set. + self.assertEqual(scope["root_path"], daphne_path) + def test_text_frames(self): """ Tests we can send and receive text frames. From ef247962439eb19c52ae36e431307b98ed16b7f5 Mon Sep 17 00:00:00 2001 From: Carlton Gibson Date: Sat, 10 Feb 2024 15:31:37 +0100 Subject: [PATCH 56/76] Validate HTTP header names as per RFC 9110. (#500) Fixes #497. --- daphne/http_protocol.py | 9 ++++++++- daphne/utils.py | 5 +++++ tests/test_http_request.py | 12 ++++++++++++ 3 files changed, 25 insertions(+), 1 deletion(-) diff --git a/daphne/http_protocol.py b/daphne/http_protocol.py index f0657fd..b7da1bf 100755 --- a/daphne/http_protocol.py +++ b/daphne/http_protocol.py @@ -9,7 +9,7 @@ from twisted.protocols.policies import ProtocolWrapper from twisted.web import http from zope.interface import implementer -from .utils import parse_x_forwarded_for +from .utils import HEADER_NAME_RE, parse_x_forwarded_for logger = logging.getLogger(__name__) @@ -69,6 +69,13 @@ class WebRequest(http.Request): def process(self): try: self.request_start = time.time() + + # Validate header names. + for name, _ in self.requestHeaders.getAllRawHeaders(): + if not HEADER_NAME_RE.fullmatch(name): + self.basic_error(400, b"Bad Request", "Invalid header name") + return + # Get upgrade header upgrade_header = None if self.requestHeaders.hasHeader(b"Upgrade"): diff --git a/daphne/utils.py b/daphne/utils.py index 81f1f9d..0699314 100644 --- a/daphne/utils.py +++ b/daphne/utils.py @@ -1,7 +1,12 @@ import importlib +import re from twisted.web.http_headers import Headers +# Header name regex as per h11. +# https://github.com/python-hyper/h11/blob/a2c68948accadc3876dffcf979d98002e4a4ed27/h11/_abnf.py#L10-L21 +HEADER_NAME_RE = re.compile(rb"[-!#$%&'*+.^_`|~0-9a-zA-Z]+") + def import_by_path(path): """ diff --git a/tests/test_http_request.py b/tests/test_http_request.py index 52f6dd1..dca5bd7 100644 --- a/tests/test_http_request.py +++ b/tests/test_http_request.py @@ -310,3 +310,15 @@ class TestHTTPRequest(DaphneTestCase): b"GET /?\xc3\xa4\xc3\xb6\xc3\xbc HTTP/1.0\r\n\r\n" ) self.assertTrue(response.startswith(b"HTTP/1.0 400 Bad Request")) + + def test_invalid_header_name(self): + """ + Tests that requests with invalid header names fail. + """ + # Test cases follow those used by h11 + # https://github.com/python-hyper/h11/blob/a2c68948accadc3876dffcf979d98002e4a4ed27/h11/tests/test_headers.py#L24-L35 + for header_name in [b"foo bar", b"foo\x00bar", b"foo\xffbar", b"foo\x01bar"]: + response = self.run_daphne_raw( + f"GET / HTTP/1.0\r\n{header_name}: baz\r\n\r\n".encode("ascii") + ) + self.assertTrue(response.startswith(b"HTTP/1.0 400 Bad Request")) From df0680c9ad699817725e18a9264df17fff2927da Mon Sep 17 00:00:00 2001 From: Carlton Gibson Date: Sat, 10 Feb 2024 15:39:05 +0100 Subject: [PATCH 57/76] Updated change notes and version for 4.1 release. --- CHANGELOG.txt | 9 +++++++-- daphne/__init__.py | 2 +- 2 files changed, 8 insertions(+), 3 deletions(-) diff --git a/CHANGELOG.txt b/CHANGELOG.txt index 5a15c1d..3f37b37 100644 --- a/CHANGELOG.txt +++ b/CHANGELOG.txt @@ -1,8 +1,13 @@ -4.1.0 (unreleased) +4.1.0 (2024-02-10) ------------------ -* Added support for Python 3.12 +* Added support for Python 3.12. +* Dropped support for EOL Python 3.7. + +* Handled root path for websocket scopes. + +* Validate HTTP header names as per RFC 9110. 4.0.0 (2022-10-07) ------------------ diff --git a/daphne/__init__.py b/daphne/__init__.py index ae556a6..9c10154 100755 --- a/daphne/__init__.py +++ b/daphne/__init__.py @@ -1,6 +1,6 @@ import sys -__version__ = "4.0.0" +__version__ = "4.1.0" # Windows on Python 3.8+ uses ProactorEventLoop, which is not compatible with From 63790936d1f5728ff358ff9c5d519454c36f4e33 Mon Sep 17 00:00:00 2001 From: "pre-commit-ci[bot]" <66853113+pre-commit-ci[bot]@users.noreply.github.com> Date: Tue, 2 Apr 2024 07:14:14 +0200 Subject: [PATCH 58/76] [pre-commit.ci] pre-commit autoupdate (#503) --- .pre-commit-config.yaml | 6 +++--- daphne/cli.py | 12 ++++++------ daphne/http_protocol.py | 8 +++++--- daphne/ws_protocol.py | 24 ++++++++++++------------ 4 files changed, 26 insertions(+), 24 deletions(-) diff --git a/.pre-commit-config.yaml b/.pre-commit-config.yaml index 05fe3f8..16c31cf 100644 --- a/.pre-commit-config.yaml +++ b/.pre-commit-config.yaml @@ -1,11 +1,11 @@ repos: - repo: https://github.com/asottile/pyupgrade - rev: v3.15.0 + rev: v3.15.2 hooks: - id: pyupgrade args: [--py38-plus] - repo: https://github.com/psf/black - rev: 23.12.1 + rev: 24.3.0 hooks: - id: black language_version: python3 @@ -14,7 +14,7 @@ repos: hooks: - id: isort - repo: https://github.com/PyCQA/flake8 - rev: 6.1.0 + rev: 7.0.0 hooks: - id: flake8 additional_dependencies: diff --git a/daphne/cli.py b/daphne/cli.py index 7c0c3c9..a036821 100755 --- a/daphne/cli.py +++ b/daphne/cli.py @@ -270,16 +270,16 @@ class CommandLineInterface: websocket_connect_timeout=args.websocket_connect_timeout, websocket_handshake_timeout=args.websocket_connect_timeout, application_close_timeout=args.application_close_timeout, - action_logger=AccessLogGenerator(access_log_stream) - if access_log_stream - else None, + action_logger=( + AccessLogGenerator(access_log_stream) if access_log_stream else None + ), root_path=args.root_path, verbosity=args.verbosity, proxy_forwarded_address_header=self._get_forwarded_host(args=args), proxy_forwarded_port_header=self._get_forwarded_port(args=args), - proxy_forwarded_proto_header="X-Forwarded-Proto" - if args.proxy_headers - else None, + proxy_forwarded_proto_header=( + "X-Forwarded-Proto" if args.proxy_headers else None + ), server_name=args.server_name, ) self.server.run() diff --git a/daphne/http_protocol.py b/daphne/http_protocol.py index b7da1bf..e9eba96 100755 --- a/daphne/http_protocol.py +++ b/daphne/http_protocol.py @@ -286,9 +286,11 @@ class WebRequest(http.Request): "path": uri, "status": self.code, "method": self.method.decode("ascii", "replace"), - "client": "%s:%s" % tuple(self.client_addr) - if self.client_addr - else None, + "client": ( + "%s:%s" % tuple(self.client_addr) + if self.client_addr + else None + ), "time_taken": self.duration(), "size": self.sentLength, }, diff --git a/daphne/ws_protocol.py b/daphne/ws_protocol.py index 184515d..b1e29c3 100755 --- a/daphne/ws_protocol.py +++ b/daphne/ws_protocol.py @@ -115,9 +115,9 @@ class WebSocketProtocol(WebSocketServerProtocol): "connecting", { "path": self.request.path, - "client": "%s:%s" % tuple(self.client_addr) - if self.client_addr - else None, + "client": ( + "%s:%s" % tuple(self.client_addr) if self.client_addr else None + ), }, ) @@ -138,9 +138,9 @@ class WebSocketProtocol(WebSocketServerProtocol): "connected", { "path": self.request.path, - "client": "%s:%s" % tuple(self.client_addr) - if self.client_addr - else None, + "client": ( + "%s:%s" % tuple(self.client_addr) if self.client_addr else None + ), }, ) @@ -175,9 +175,9 @@ class WebSocketProtocol(WebSocketServerProtocol): "disconnected", { "path": self.request.path, - "client": "%s:%s" % tuple(self.client_addr) - if self.client_addr - else None, + "client": ( + "%s:%s" % tuple(self.client_addr) if self.client_addr else None + ), }, ) @@ -242,9 +242,9 @@ class WebSocketProtocol(WebSocketServerProtocol): "rejected", { "path": self.request.path, - "client": "%s:%s" % tuple(self.client_addr) - if self.client_addr - else None, + "client": ( + "%s:%s" % tuple(self.client_addr) if self.client_addr else None + ), }, ) From c0b630834cc5a794bfc7b4855b30e4631c32e88e Mon Sep 17 00:00:00 2001 From: sdc50 Date: Wed, 10 Apr 2024 09:33:21 -0600 Subject: [PATCH 59/76] Fix twisted.plugin install (#507) --- setup.cfg | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/setup.cfg b/setup.cfg index a78e654..cef2824 100644 --- a/setup.cfg +++ b/setup.cfg @@ -26,7 +26,9 @@ classifiers = [options] package_dir = twisted=daphne/twisted -packages = find: +packages = + daphne + twisted.plugins include_package_data = True install_requires = asgiref>=3.5.2,<4 From cf9145985b17ecab2bb260ef30a592328b87a599 Mon Sep 17 00:00:00 2001 From: Carlton Gibson Date: Wed, 10 Apr 2024 17:42:01 +0200 Subject: [PATCH 60/76] Updated version and changelog for v4.1.1 release. --- CHANGELOG.txt | 7 +++++++ daphne/__init__.py | 2 +- 2 files changed, 8 insertions(+), 1 deletion(-) diff --git a/CHANGELOG.txt b/CHANGELOG.txt index 3f37b37..82521fe 100644 --- a/CHANGELOG.txt +++ b/CHANGELOG.txt @@ -1,3 +1,10 @@ +4.1.1 (2024-04-10) +------------------ + +* Fixed a twisted.plugin packaging error in 4.1.0. + + Thanks to sdc50. + 4.1.0 (2024-02-10) ------------------ diff --git a/daphne/__init__.py b/daphne/__init__.py index 9c10154..ee354c7 100755 --- a/daphne/__init__.py +++ b/daphne/__init__.py @@ -1,6 +1,6 @@ import sys -__version__ = "4.1.0" +__version__ = "4.1.1" # Windows on Python 3.8+ uses ProactorEventLoop, which is not compatible with From 0f15e4595b195a7d6c0cb4df58df69afd6b17045 Mon Sep 17 00:00:00 2001 From: Carlton Gibson Date: Thu, 11 Apr 2024 15:23:49 +0200 Subject: [PATCH 61/76] Fixed packaging configuration. (#510) Use auto-discovery, but make sure daphne package is correctly listed. --- CHANGELOG.txt | 5 +++++ daphne/__init__.py | 2 +- setup.cfg | 4 +--- 3 files changed, 7 insertions(+), 4 deletions(-) diff --git a/CHANGELOG.txt b/CHANGELOG.txt index 82521fe..5df13c7 100644 --- a/CHANGELOG.txt +++ b/CHANGELOG.txt @@ -1,3 +1,8 @@ +4.1.2 (2024-04-11) +------------------ + +* Fixed a setuptools configuration error in 4.1.1. + 4.1.1 (2024-04-10) ------------------ diff --git a/daphne/__init__.py b/daphne/__init__.py index ee354c7..19ba8ff 100755 --- a/daphne/__init__.py +++ b/daphne/__init__.py @@ -1,6 +1,6 @@ import sys -__version__ = "4.1.1" +__version__ = "4.1.2" # Windows on Python 3.8+ uses ProactorEventLoop, which is not compatible with diff --git a/setup.cfg b/setup.cfg index cef2824..8e08789 100644 --- a/setup.cfg +++ b/setup.cfg @@ -25,10 +25,8 @@ classifiers = [options] package_dir = + daphne=daphne twisted=daphne/twisted -packages = - daphne - twisted.plugins include_package_data = True install_requires = asgiref>=3.5.2,<4 From 4a55faca45db2e2a4c275ee02c44893e6af0b5c7 Mon Sep 17 00:00:00 2001 From: "pre-commit-ci[bot]" <66853113+pre-commit-ci[bot]@users.noreply.github.com> Date: Tue, 2 Jul 2024 09:38:28 +0200 Subject: [PATCH 62/76] [pre-commit.ci] pre-commit autoupdate (#515) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit updates: - [github.com/asottile/pyupgrade: v3.15.2 → v3.16.0](https://github.com/asottile/pyupgrade/compare/v3.15.2...v3.16.0) - [github.com/psf/black: 24.3.0 → 24.4.2](https://github.com/psf/black/compare/24.3.0...24.4.2) - [github.com/PyCQA/flake8: 7.0.0 → 7.1.0](https://github.com/PyCQA/flake8/compare/7.0.0...7.1.0) Co-authored-by: pre-commit-ci[bot] <66853113+pre-commit-ci[bot]@users.noreply.github.com> --- .pre-commit-config.yaml | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/.pre-commit-config.yaml b/.pre-commit-config.yaml index 16c31cf..8c5f5b0 100644 --- a/.pre-commit-config.yaml +++ b/.pre-commit-config.yaml @@ -1,11 +1,11 @@ repos: - repo: https://github.com/asottile/pyupgrade - rev: v3.15.2 + rev: v3.16.0 hooks: - id: pyupgrade args: [--py38-plus] - repo: https://github.com/psf/black - rev: 24.3.0 + rev: 24.4.2 hooks: - id: black language_version: python3 @@ -14,7 +14,7 @@ repos: hooks: - id: isort - repo: https://github.com/PyCQA/flake8 - rev: 7.0.0 + rev: 7.1.0 hooks: - id: flake8 additional_dependencies: From 420f065d9e85df332f6f1f6ba28688efb09b4bc3 Mon Sep 17 00:00:00 2001 From: Jon Janzen Date: Sat, 24 Aug 2024 11:34:29 -0700 Subject: [PATCH 63/76] Remove pytest-runner Closes: https://github.com/django/daphne/issues/523 --- setup.cfg | 2 -- 1 file changed, 2 deletions(-) diff --git a/setup.cfg b/setup.cfg index 8e08789..790bd16 100644 --- a/setup.cfg +++ b/setup.cfg @@ -33,8 +33,6 @@ install_requires = autobahn>=22.4.2 twisted[tls]>=22.4 python_requires = >=3.8 -setup_requires = - pytest-runner zip_safe = False [options.entry_points] From 3607351212ea01159c95e05868733f804fcea48b Mon Sep 17 00:00:00 2001 From: Jon Janzen Date: Sat, 24 Aug 2024 11:36:44 -0700 Subject: [PATCH 64/76] Revert "Remove pytest-runner" This reverts commit 420f065d9e85df332f6f1f6ba28688efb09b4bc3. --- setup.cfg | 2 ++ 1 file changed, 2 insertions(+) diff --git a/setup.cfg b/setup.cfg index 790bd16..8e08789 100644 --- a/setup.cfg +++ b/setup.cfg @@ -33,6 +33,8 @@ install_requires = autobahn>=22.4.2 twisted[tls]>=22.4 python_requires = >=3.8 +setup_requires = + pytest-runner zip_safe = False [options.entry_points] From 9ec5798c0d17f0858229dd800955abab4fa803fb Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Robert=20Sch=C3=BCtz?= Date: Sat, 24 Aug 2024 11:47:58 -0700 Subject: [PATCH 65/76] fix tests with Twisted 24.7.0 (#526) In the fixed test cases the responses now contain `HTTP/1.1` rather than `HTTP/1.0`. --- tests/test_http_request.py | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/tests/test_http_request.py b/tests/test_http_request.py index dca5bd7..f0fe376 100644 --- a/tests/test_http_request.py +++ b/tests/test_http_request.py @@ -304,12 +304,12 @@ class TestHTTPRequest(DaphneTestCase): response = self.run_daphne_raw( b"GET /\xc3\xa4\xc3\xb6\xc3\xbc HTTP/1.0\r\n\r\n" ) - self.assertTrue(response.startswith(b"HTTP/1.0 400 Bad Request")) + self.assertTrue(b"400 Bad Request" in response) # Bad querystring response = self.run_daphne_raw( b"GET /?\xc3\xa4\xc3\xb6\xc3\xbc HTTP/1.0\r\n\r\n" ) - self.assertTrue(response.startswith(b"HTTP/1.0 400 Bad Request")) + self.assertTrue(b"400 Bad Request" in response) def test_invalid_header_name(self): """ @@ -321,4 +321,4 @@ class TestHTTPRequest(DaphneTestCase): response = self.run_daphne_raw( f"GET / HTTP/1.0\r\n{header_name}: baz\r\n\r\n".encode("ascii") ) - self.assertTrue(response.startswith(b"HTTP/1.0 400 Bad Request")) + self.assertTrue(b"400 Bad Request" in response) From b1902e8ccda05d3fed3513e5c534f25607712052 Mon Sep 17 00:00:00 2001 From: Jon Janzen Date: Sat, 24 Aug 2024 11:51:43 -0700 Subject: [PATCH 66/76] Remove pytest-runner (#528) Closes: https://github.com/django/daphne/issues/523 --- setup.cfg | 2 -- 1 file changed, 2 deletions(-) diff --git a/setup.cfg b/setup.cfg index 8e08789..790bd16 100644 --- a/setup.cfg +++ b/setup.cfg @@ -33,8 +33,6 @@ install_requires = autobahn>=22.4.2 twisted[tls]>=22.4 python_requires = >=3.8 -setup_requires = - pytest-runner zip_safe = False [options.entry_points] From 862ebcd08dcd9f392e9603a880fb00a6e710f3b6 Mon Sep 17 00:00:00 2001 From: Jon Janzen Date: Mon, 26 Aug 2024 07:02:23 -0700 Subject: [PATCH 67/76] Include test support files in sdist (#530) Closes: https://github.com/django/daphne/issues/522 --- CHANGELOG.txt | 6 ++++++ MANIFEST.in | 1 + daphne/__init__.py | 2 +- 3 files changed, 8 insertions(+), 1 deletion(-) diff --git a/CHANGELOG.txt b/CHANGELOG.txt index 5df13c7..437c517 100644 --- a/CHANGELOG.txt +++ b/CHANGELOG.txt @@ -1,3 +1,9 @@ +4.1.3 (to be released) +------------------ + +* Removed unused pytest-runner +* Fixed sdist file to ensure it includes all tests + 4.1.2 (2024-04-11) ------------------ diff --git a/MANIFEST.in b/MANIFEST.in index 1aba38f..90b3902 100644 --- a/MANIFEST.in +++ b/MANIFEST.in @@ -1 +1,2 @@ include LICENSE +recursive-include tests *.py \ No newline at end of file diff --git a/daphne/__init__.py b/daphne/__init__.py index 19ba8ff..2a21298 100755 --- a/daphne/__init__.py +++ b/daphne/__init__.py @@ -1,6 +1,6 @@ import sys -__version__ = "4.1.2" +__version__ = "4.1.3" # Windows on Python 3.8+ uses ProactorEventLoop, which is not compatible with From ffad9c3cfdeec25a9014ce416c601587273bf190 Mon Sep 17 00:00:00 2001 From: "pre-commit-ci[bot]" <66853113+pre-commit-ci[bot]@users.noreply.github.com> Date: Mon, 7 Oct 2024 17:10:56 -0700 Subject: [PATCH 68/76] [pre-commit.ci] pre-commit autoupdate (#532) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit updates: - [github.com/asottile/pyupgrade: v3.16.0 → v3.17.0](https://github.com/asottile/pyupgrade/compare/v3.16.0...v3.17.0) - [github.com/psf/black: 24.4.2 → 24.10.0](https://github.com/psf/black/compare/24.4.2...24.10.0) - [github.com/PyCQA/flake8: 7.1.0 → 7.1.1](https://github.com/PyCQA/flake8/compare/7.1.0...7.1.1) Co-authored-by: pre-commit-ci[bot] <66853113+pre-commit-ci[bot]@users.noreply.github.com> --- .pre-commit-config.yaml | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/.pre-commit-config.yaml b/.pre-commit-config.yaml index 8c5f5b0..38c1361 100644 --- a/.pre-commit-config.yaml +++ b/.pre-commit-config.yaml @@ -1,11 +1,11 @@ repos: - repo: https://github.com/asottile/pyupgrade - rev: v3.16.0 + rev: v3.17.0 hooks: - id: pyupgrade args: [--py38-plus] - repo: https://github.com/psf/black - rev: 24.4.2 + rev: 24.10.0 hooks: - id: black language_version: python3 @@ -14,7 +14,7 @@ repos: hooks: - id: isort - repo: https://github.com/PyCQA/flake8 - rev: 7.1.0 + rev: 7.1.1 hooks: - id: flake8 additional_dependencies: From 06afd9b94aa82ebdfea945a1810ce25d32d3593b Mon Sep 17 00:00:00 2001 From: Carlton Gibson Date: Tue, 29 Oct 2024 03:03:41 +0100 Subject: [PATCH 69/76] Drop support for EOL Python 3.8. (#536) --- .github/workflows/tests.yml | 1 - CHANGELOG.txt | 5 ++++- README.rst | 2 +- setup.cfg | 3 +-- tox.ini | 2 +- 5 files changed, 7 insertions(+), 6 deletions(-) diff --git a/.github/workflows/tests.yml b/.github/workflows/tests.yml index af816f7..749d897 100644 --- a/.github/workflows/tests.yml +++ b/.github/workflows/tests.yml @@ -16,7 +16,6 @@ jobs: - ubuntu - windows python-version: - - "3.8" - "3.9" - "3.10" - "3.11" diff --git a/CHANGELOG.txt b/CHANGELOG.txt index 437c517..72738ff 100644 --- a/CHANGELOG.txt +++ b/CHANGELOG.txt @@ -1,7 +1,10 @@ -4.1.3 (to be released) +4.2.0 (to be released) ------------------ +* Drop support for EOL Python 3.8. + * Removed unused pytest-runner + * Fixed sdist file to ensure it includes all tests 4.1.2 (2024-04-11) diff --git a/README.rst b/README.rst index d93ad02..f7b8e32 100644 --- a/README.rst +++ b/README.rst @@ -108,7 +108,7 @@ should start with a slash, but not end with one; for example:: Python Support -------------- -Daphne requires Python 3.8 or later. +Daphne requires Python 3.9 or later. Contributing diff --git a/setup.cfg b/setup.cfg index 790bd16..a717acc 100644 --- a/setup.cfg +++ b/setup.cfg @@ -16,7 +16,6 @@ classifiers = Operating System :: OS Independent Programming Language :: Python Programming Language :: Python :: 3 - Programming Language :: Python :: 3.8 Programming Language :: Python :: 3.9 Programming Language :: Python :: 3.10 Programming Language :: Python :: 3.11 @@ -32,7 +31,7 @@ install_requires = asgiref>=3.5.2,<4 autobahn>=22.4.2 twisted[tls]>=22.4 -python_requires = >=3.8 +python_requires = >=3.9 zip_safe = False [options.entry_points] diff --git a/tox.ini b/tox.ini index a741f0e..95eb7f9 100644 --- a/tox.ini +++ b/tox.ini @@ -1,6 +1,6 @@ [tox] envlist = - py{38,39,310,311,312} + py{39,310,311,312} [testenv] extras = tests From e25b4bcc3165c844e7f0cc33ebaed25a27998479 Mon Sep 17 00:00:00 2001 From: David Smith <39445562+smithdc1@users.noreply.github.com> Date: Mon, 18 Nov 2024 19:56:40 +0000 Subject: [PATCH 70/76] Target py39-plus with pyupgrade. (#540) --- .pre-commit-config.yaml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/.pre-commit-config.yaml b/.pre-commit-config.yaml index 38c1361..4397d89 100644 --- a/.pre-commit-config.yaml +++ b/.pre-commit-config.yaml @@ -1,9 +1,9 @@ repos: - repo: https://github.com/asottile/pyupgrade - rev: v3.17.0 + rev: v3.19.0 hooks: - id: pyupgrade - args: [--py38-plus] + args: [--py39-plus] - repo: https://github.com/psf/black rev: 24.10.0 hooks: From 32ac73e1a0fb87af0e3280c89fe4cc3ff1231b37 Mon Sep 17 00:00:00 2001 From: David Smith <39445562+smithdc1@users.noreply.github.com> Date: Mon, 18 Nov 2024 19:57:11 +0000 Subject: [PATCH 71/76] Added support for Python 3.13. (#539) --- .github/workflows/tests.yml | 1 + CHANGELOG.txt | 2 ++ setup.cfg | 1 + tox.ini | 2 +- 4 files changed, 5 insertions(+), 1 deletion(-) diff --git a/.github/workflows/tests.yml b/.github/workflows/tests.yml index 749d897..c68ac58 100644 --- a/.github/workflows/tests.yml +++ b/.github/workflows/tests.yml @@ -20,6 +20,7 @@ jobs: - "3.10" - "3.11" - "3.12" + - "3.13" steps: - uses: actions/checkout@v4 diff --git a/CHANGELOG.txt b/CHANGELOG.txt index 72738ff..40e6e3f 100644 --- a/CHANGELOG.txt +++ b/CHANGELOG.txt @@ -1,6 +1,8 @@ 4.2.0 (to be released) ------------------ +* Added support for Python 3.13. + * Drop support for EOL Python 3.8. * Removed unused pytest-runner diff --git a/setup.cfg b/setup.cfg index a717acc..8d2b2e7 100644 --- a/setup.cfg +++ b/setup.cfg @@ -20,6 +20,7 @@ classifiers = Programming Language :: Python :: 3.10 Programming Language :: Python :: 3.11 Programming Language :: Python :: 3.12 + Programming Language :: Python :: 3.13 Topic :: Internet :: WWW/HTTP [options] diff --git a/tox.ini b/tox.ini index 95eb7f9..e3bae91 100644 --- a/tox.ini +++ b/tox.ini @@ -1,6 +1,6 @@ [tox] envlist = - py{39,310,311,312} + py{39,310,311,312,313} [testenv] extras = tests From f0a3ec60e949ee181e09aa11965ed0e25403d4c2 Mon Sep 17 00:00:00 2001 From: David Fuentes Baldomir Date: Sat, 4 Jan 2025 09:37:17 +0100 Subject: [PATCH 72/76] Add --nostatic and --insecure args to runserver command. (#450) Fixes #449 --- daphne/management/commands/runserver.py | 12 ++++++++++++ 1 file changed, 12 insertions(+) diff --git a/daphne/management/commands/runserver.py b/daphne/management/commands/runserver.py index b2fd2ee..7e67e07 100644 --- a/daphne/management/commands/runserver.py +++ b/daphne/management/commands/runserver.py @@ -73,6 +73,18 @@ class Command(RunserverCommand): "seconds (default: 5)" ), ) + parser.add_argument( + "--nostatic", + action="store_false", + dest="use_static_handler", + help="Tells Django to NOT automatically serve static files at STATIC_URL.", + ) + parser.add_argument( + "--insecure", + action="store_true", + dest="insecure_serving", + help="Allows serving static files even if DEBUG is False.", + ) def handle(self, *args, **options): self.http_timeout = options.get("http_timeout", None) From 786e4c120a6e0f4819570901ab848fb08522ea8b Mon Sep 17 00:00:00 2001 From: "pre-commit-ci[bot]" <66853113+pre-commit-ci[bot]@users.noreply.github.com> Date: Tue, 7 Jan 2025 07:33:08 +0100 Subject: [PATCH 73/76] [pre-commit.ci] pre-commit autoupdate (#546) --- .pre-commit-config.yaml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.pre-commit-config.yaml b/.pre-commit-config.yaml index 4397d89..bdb453c 100644 --- a/.pre-commit-config.yaml +++ b/.pre-commit-config.yaml @@ -1,6 +1,6 @@ repos: - repo: https://github.com/asottile/pyupgrade - rev: v3.19.0 + rev: v3.19.1 hooks: - id: pyupgrade args: [--py39-plus] From 630caed9153f8eb62aecfade3e349d3cc6ee1bb0 Mon Sep 17 00:00:00 2001 From: Andrew Sears Date: Wed, 22 Jan 2025 11:34:39 -0500 Subject: [PATCH 74/76] Upgrade project metadata (#542) --- .flake8 | 11 ++++++ .github/workflows/tests.yml | 4 ++ .gitignore | 1 + daphne/testing.py | 2 +- pyproject.toml | 78 +++++++++++++++++++++++++++++++++++++ setup.cfg | 59 ---------------------------- 6 files changed, 95 insertions(+), 60 deletions(-) create mode 100644 .flake8 delete mode 100644 setup.cfg diff --git a/.flake8 b/.flake8 new file mode 100644 index 0000000..d60ef28 --- /dev/null +++ b/.flake8 @@ -0,0 +1,11 @@ +[flake8] +exclude = + .venv, + .tox, + docs, + testproject, + js_client, + .eggs + +extend-ignore = E123, E128, E266, E402, W503, E731, W601, B036 +max-line-length = 120 diff --git a/.github/workflows/tests.yml b/.github/workflows/tests.yml index c68ac58..68b91f7 100644 --- a/.github/workflows/tests.yml +++ b/.github/workflows/tests.yml @@ -5,6 +5,10 @@ on: branches: - main pull_request: + workflow_dispatch: + +permissions: + contents: read jobs: tests: diff --git a/.gitignore b/.gitignore index 20cb4bd..0616f8a 100644 --- a/.gitignore +++ b/.gitignore @@ -13,3 +13,4 @@ test_consumer* .python-version .pytest_cache/ .vscode +.coverage diff --git a/daphne/testing.py b/daphne/testing.py index 785edf9..46787bb 100644 --- a/daphne/testing.py +++ b/daphne/testing.py @@ -158,7 +158,7 @@ class DaphneProcess(multiprocessing.Process): application=application, endpoints=endpoints, signal_handlers=False, - **self.kwargs + **self.kwargs, ) # Set up a poller to look for the port reactor.callLater(0.1, self.resolve_port) diff --git a/pyproject.toml b/pyproject.toml index fed528d..7a2e796 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -1,3 +1,81 @@ +[project] +name = "daphne" +dynamic = ["version"] +description = "Django ASGI (HTTP/WebSocket) server" +requires-python = ">=3.9" +authors = [ + { name = "Django Software Foundation", email = "foundation@djangoproject.com" }, +] + +license = { text = "BSD" } +classifiers = [ + "Development Status :: 4 - Beta", + "Environment :: Web Environment", + "Intended Audience :: Developers", + "License :: OSI Approved :: BSD License", + "Operating System :: OS Independent", + "Programming Language :: Python", + "Programming Language :: Python :: 3", + "Programming Language :: Python :: 3.9", + "Programming Language :: Python :: 3.10", + "Programming Language :: Python :: 3.11", + "Programming Language :: Python :: 3.12", + "Programming Language :: Python :: 3.13", + "Topic :: Internet :: WWW/HTTP", +] + +dependencies = ["asgiref>=3.5.2,<4", "autobahn>=22.4.2", "twisted[tls]>=22.4"] + +[project.optional-dependencies] +tests = [ + "django", + "hypothesis", + "pytest", + "pytest-asyncio", + "pytest-cov", + "black", + "tox", + "flake8", + "flake8-bugbear", + "mypy", +] + +[project.urls] +homepage = "https://github.com/django/daphne" +documentation = "https://channels.readthedocs.io" +repository = "https://github.com/django/daphne.git" +changelog = "https://github.com/django/daphne/blob/main/CHANGELOG.txt" +issues = "https://github.com/django/daphne/issues" + +[project.scripts] +daphne = "daphne.cli:CommandLineInterface.entrypoint" + [build-system] requires = ["setuptools"] build-backend = "setuptools.build_meta" + +[tool.setuptools] +packages = ["daphne"] + +[tool.setuptools.dynamic] +version = { attr = "daphne.__version__" } +readme = { file = "README.rst", content-type = "text/x-rst" } + +[tool.isort] +profile = "black" + +[tool.pytest] +testpaths = ["tests"] +asyncio_mode = "strict" +filterwarnings = ["ignore::pytest.PytestDeprecationWarning"] + +[tool.coverage.run] +omit = ["tests/*"] +concurrency = ["multiprocessing"] + +[tool.coverage.report] +show_missing = "true" +skip_covered = "true" + +[tool.coverage.html] +directory = "reports/coverage_html_report" diff --git a/setup.cfg b/setup.cfg deleted file mode 100644 index 8d2b2e7..0000000 --- a/setup.cfg +++ /dev/null @@ -1,59 +0,0 @@ -[metadata] -name = daphne -version = attr: daphne.__version__ -url = https://github.com/django/daphne -author = Django Software Foundation -author_email = foundation@djangoproject.com -description = Django ASGI (HTTP/WebSocket) server -long_description = file: README.rst -long_description_content_type = text/x-rst -license = BSD -classifiers = - Development Status :: 4 - Beta - Environment :: Web Environment - Intended Audience :: Developers - License :: OSI Approved :: BSD License - Operating System :: OS Independent - Programming Language :: Python - Programming Language :: Python :: 3 - Programming Language :: Python :: 3.9 - Programming Language :: Python :: 3.10 - Programming Language :: Python :: 3.11 - Programming Language :: Python :: 3.12 - Programming Language :: Python :: 3.13 - Topic :: Internet :: WWW/HTTP - -[options] -package_dir = - daphne=daphne - twisted=daphne/twisted -include_package_data = True -install_requires = - asgiref>=3.5.2,<4 - autobahn>=22.4.2 - twisted[tls]>=22.4 -python_requires = >=3.9 -zip_safe = False - -[options.entry_points] -console_scripts = - daphne = daphne.cli:CommandLineInterface.entrypoint - -[options.extras_require] -tests = - django - hypothesis - pytest - pytest-asyncio - -[flake8] -exclude = venv/*,tox/*,docs/*,testproject/*,js_client/*,.eggs/* -extend-ignore = E123, E128, E266, E402, W503, E731, W601, B036 -max-line-length = 120 - -[isort] -profile = black - -[tool:pytest] -testpaths = tests -asyncio_mode = strict From 7c9334952d2b0282543f04bc63b77d77616a92df Mon Sep 17 00:00:00 2001 From: "pre-commit-ci[bot]" <66853113+pre-commit-ci[bot]@users.noreply.github.com> Date: Fri, 18 Apr 2025 06:58:38 -0700 Subject: [PATCH 75/76] [pre-commit.ci] pre-commit autoupdate (#551) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit updates: - [github.com/psf/black: 24.10.0 → 25.1.0](https://github.com/psf/black/compare/24.10.0...25.1.0) - [github.com/pycqa/isort: 5.13.2 → 6.0.1](https://github.com/pycqa/isort/compare/5.13.2...6.0.1) - [github.com/PyCQA/flake8: 7.1.1 → 7.2.0](https://github.com/PyCQA/flake8/compare/7.1.1...7.2.0) Co-authored-by: pre-commit-ci[bot] <66853113+pre-commit-ci[bot]@users.noreply.github.com> --- .pre-commit-config.yaml | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/.pre-commit-config.yaml b/.pre-commit-config.yaml index bdb453c..c315a04 100644 --- a/.pre-commit-config.yaml +++ b/.pre-commit-config.yaml @@ -5,16 +5,16 @@ repos: - id: pyupgrade args: [--py39-plus] - repo: https://github.com/psf/black - rev: 24.10.0 + rev: 25.1.0 hooks: - id: black language_version: python3 - repo: https://github.com/pycqa/isort - rev: 5.13.2 + rev: 6.0.1 hooks: - id: isort - repo: https://github.com/PyCQA/flake8 - rev: 7.1.1 + rev: 7.2.0 hooks: - id: flake8 additional_dependencies: From beef1c15142250ed145bea1d968d0276f7892f63 Mon Sep 17 00:00:00 2001 From: Mohammed <74480856+MohammedSaleh2001@users.noreply.github.com> Date: Wed, 7 May 2025 08:33:22 -0600 Subject: [PATCH 76/76] Allowed assigning a port in DaphneProcess test helper. (#550) --- daphne/testing.py | 10 +++++++--- 1 file changed, 7 insertions(+), 3 deletions(-) diff --git a/daphne/testing.py b/daphne/testing.py index 46787bb..9120327 100644 --- a/daphne/testing.py +++ b/daphne/testing.py @@ -126,14 +126,16 @@ class DaphneProcess(multiprocessing.Process): port it ends up listening on back to the parent process. """ - def __init__(self, host, get_application, kwargs=None, setup=None, teardown=None): + def __init__( + self, host, get_application, kwargs=None, setup=None, teardown=None, port=None + ): super().__init__() self.host = host self.get_application = get_application self.kwargs = kwargs or {} self.setup = setup self.teardown = teardown - self.port = multiprocessing.Value("i") + self.port = multiprocessing.Value("i", port if port is not None else 0) self.ready = multiprocessing.Event() self.errors = multiprocessing.Queue() @@ -153,7 +155,9 @@ class DaphneProcess(multiprocessing.Process): try: # Create the server class - endpoints = build_endpoint_description_strings(host=self.host, port=0) + endpoints = build_endpoint_description_strings( + host=self.host, port=self.port.value + ) self.server = Server( application=application, endpoints=endpoints,