Skip to content

Commit

Permalink
Merge branch 'main' into master
Browse files Browse the repository at this point in the history
  • Loading branch information
albertas authored Jun 23, 2021
2 parents d467616 + 36ce9fd commit a9a2cb1
Show file tree
Hide file tree
Showing 24 changed files with 323 additions and 156 deletions.
24 changes: 24 additions & 0 deletions .github/workflows/pre-commit.yml
Original file line number Diff line number Diff line change
@@ -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/[email protected]
with:
token: ${{ secrets.GITHUB_TOKEN }}
35 changes: 35 additions & 0 deletions .github/workflows/tests.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
name: Tests

on:
push:
branches:
- master
pull_request:

jobs:
tests:
runs-on: ubuntu-latest
strategy:
fail-fast: false
matrix:
python-version:
- 3.6
- 3.7
- 3.8
- 3.9

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 setuptools wheel
python -m pip install --upgrade tox tox-py
- name: Run tox targets for ${{ matrix.python-version }}
run: tox --py current
21 changes: 21 additions & 0 deletions .pre-commit-config.yaml
Original file line number Diff line number Diff line change
@@ -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
48 changes: 0 additions & 48 deletions .travis.yml

This file was deleted.

44 changes: 39 additions & 5 deletions CHANGELOG.txt
Original file line number Diff line number Diff line change
@@ -1,21 +1,53 @@
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)
------------------

* Fixed a bug where ``asyncio.CancelledError`` was not correctly handled on
Python 3.8+, resulting in incorrect protocol application cleanup.


3.0.0 (2020-10-28)
------------------

* Updates internals to use ASGI v3 throughout. ``asgiref.compatibility`` is
used for older applications.

* Consequently, the `--asgi-protocol` command-line option is removed.

* HTTP request bodies are now read, and passed to the application, in chunks.

* Added support for Python 3.9.

* Dropped support for Python 3.5.


2.5.0 (2020-04-15)
------------------

* Fixes compatability for twisted when running Python 3.8+ on Windows, by
setting ``asyncio.WindowsSelectorEventLoopPolicy`` as the event loop policy
in this case.
* Fixes compatability for twisted when running Python 3.8+ on Windows, by
setting ``asyncio.WindowsSelectorEventLoopPolicy`` as the event loop policy
in this case.

* The internal ``daphne.testing.TestApplication`` now requires an addition
``lock`` argument to ``__init__()``. This is expected to be an instance of
* The internal ``daphne.testing.TestApplication`` now requires an addition
``lock`` argument to ``__init__()``. This is expected to be an instance of
``multiprocessing.Lock``.


2.4.1 (2019-12-18)
------------------

* Avoids Twisted using the default event loop, for compatibility with Django
3.0's ``async_unsafe()`` decorator in threaded contexts, such as using the
auto-reloader.


2.4.0 (2019-11-20)
------------------

Expand All @@ -33,11 +65,13 @@

* Adds missing LICENSE to distribution.


2.3.0 (2019-04-09)
------------------

* Added support for ASGI v3.


2.2.5 (2019-01-31)
------------------

Expand Down
21 changes: 7 additions & 14 deletions README.rst
Original file line number Diff line number Diff line change
@@ -1,24 +1,17 @@
daphne
======

.. image:: https://api.travis-ci.org/django/daphne.svg
:target: https://travis-ci.org/django/daphne

.. image:: https://img.shields.io/pypi/v/daphne.svg
:target: https://pypi.python.org/pypi/daphne

Daphne is a HTTP, HTTP2 and WebSocket protocol server for
`ASGI <https://github.com/django/asgiref/blob/master/specs/asgi.rst>`_ and
`ASGI-HTTP <https://github.com/django/asgiref/blob/master/specs/www.rst>`_,
`ASGI <https://github.com/django/asgiref/blob/main/specs/asgi.rst>`_ and
`ASGI-HTTP <https://github.com/django/asgiref/blob/main/specs/www.rst>`_,
developed to power Django Channels.

It supports automatic negotiation of protocols; there's no need for URL
prefixing to determine WebSocket endpoints versus HTTP endpoints.

*Note:* Daphne 2 is not compatible with Channels 1.x applications, only with
Channels 2.x and other ASGI applications. Install a 1.x version of Daphne
for Channels 1.x support.


Running
-------
Expand Down Expand Up @@ -61,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::
Expand Down Expand Up @@ -115,19 +108,19 @@ should start with a slash, but not end with one; for example::
Python Support
--------------

Daphne requires Python 3.5 or later.
Daphne requires Python 3.6 or later.


Contributing
------------

Please refer to the
`main Channels contributing docs <https://github.com/django/channels/blob/master/CONTRIBUTING.rst>`_.
`main Channels contributing docs <https://github.com/django/channels/blob/main/CONTRIBUTING.rst>`_.

To run tests, make sure you have installed the ``tests`` extra with the package::

cd daphne/
pip install -e .[tests]
pip install -e '.[tests]'
pytest


Expand All @@ -141,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 <https://github.com/django/channels/blob/master/README.rst>`_.
`main Channels readme <https://github.com/django/channels/blob/main/README.rst>`_.
2 changes: 1 addition & 1 deletion daphne/__init__.py
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import sys

__version__ = "2.5.0"
__version__ = "3.0.2"


# Windows on Python 3.8+ uses ProactorEventLoop, which is not compatible with
Expand Down
3 changes: 3 additions & 0 deletions daphne/__main__.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
from daphne.cli import CommandLineInterface

CommandLineInterface.entrypoint()
2 changes: 1 addition & 1 deletion daphne/access.py
Original file line number Diff line number Diff line change
@@ -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.
Expand Down
36 changes: 5 additions & 31 deletions daphne/cli.py
Original file line number Diff line number Diff line change
@@ -1,10 +1,9 @@
import argparse
import functools
import logging
import sys
from argparse import ArgumentError, Namespace

from asgiref.compatibility import is_double_callable
from asgiref.compatibility import guarantee_single_callable

from .access import AccessLogGenerator
from .endpoints import build_endpoint_description_strings
Expand All @@ -17,20 +16,7 @@
DEFAULT_PORT = 8000


class ASGI3Middleware:
def __init__(self, app):
self.app = app

def __call__(self, scope):
scope.setdefault("asgi", {})
scope["asgi"]["version"] = "3.0"
return functools.partial(self.asgi, scope=scope)

async def asgi(self, receive, send, scope):
await self.app(scope, receive, send)


class CommandLineInterface(object):
class CommandLineInterface:
"""
Acts as the main CLI entry point for running the server.
"""
Expand Down Expand Up @@ -129,13 +115,6 @@ def __init__(self):
help="The WebSocket protocols you wish to support",
default=None,
)
self.parser.add_argument(
"--asgi-protocol",
dest="asgi_protocol",
help="The version of the ASGI protocol to use",
default="auto",
choices=["asgi2", "asgi3", "auto"],
)
self.parser.add_argument(
"--root-path",
dest="root_path",
Expand Down Expand Up @@ -247,16 +226,11 @@ def run(self, args):
access_log_stream = open(args.access_log, "a", 1)
elif args.verbosity >= 1:
access_log_stream = sys.stdout

# Import application
sys.path.insert(0, ".")
application = import_by_path(args.application)

asgi_protocol = args.asgi_protocol
if asgi_protocol == "auto":
asgi_protocol = "asgi2" if is_double_callable(application) else "asgi3"

if asgi_protocol == "asgi3":
application = ASGI3Middleware(application)
application = guarantee_single_callable(application)

# Set up port/host bindings
if not any(
Expand Down Expand Up @@ -284,7 +258,7 @@ def run(self, args):
)
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,
Expand Down
16 changes: 13 additions & 3 deletions daphne/http_protocol.py
Original file line number Diff line number Diff line change
Expand Up @@ -185,9 +185,19 @@ def process(self):
# Not much we can do, the request is prematurely abandoned.
return
# Run application against request
self.application_queue.put_nowait(
{"type": "http.request", "body": self.content.read()}
)
buffer_size = self.server.request_buffer_size
while True:
chunk = self.content.read(buffer_size)
more_body = not (len(chunk) < buffer_size)
payload = {
"type": "http.request",
"body": chunk,
"more_body": more_body,
}
self.application_queue.put_nowait(payload)
if not more_body:
break

except Exception:
logger.error(traceback.format_exc())
self.basic_error(
Expand Down
Loading

0 comments on commit a9a2cb1

Please sign in to comment.