Skip to content

Commit 64b4346

Browse files
Moved to Django's static files handler. (#1890)
* Moved to Django's static files handler. * Removed staticfiles.py file. * Added entry in the changelog.
1 parent 868a468 commit 64b4346

File tree

5 files changed

+11
-143
lines changed

5 files changed

+11
-143
lines changed

CHANGELOG.txt

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,8 @@ Next Release (will be 4.0)
66

77
* Drops support for Python 3.6.
88
* Minimum Django version is now Django 3.2.
9-
* Added compatiblity with Django 4.1.
9+
* Added compatibility with Django 4.1.
10+
* Removed deprecated static files handling in favor of ``django.contrib.staticfiles``.
1011

1112
3.0.5 (2022-06-24)
1213
------------------

channels/management/commands/runserver.py

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -6,14 +6,13 @@
66
from daphne.server import Server
77
from django.apps import apps
88
from django.conf import settings
9+
from django.contrib.staticfiles.handlers import ASGIStaticFilesHandler
910
from django.core.management import CommandError
1011
from django.core.management.commands.runserver import Command as RunserverCommand
1112

1213
from channels import __version__
1314
from channels.routing import get_default_application
1415

15-
from ...staticfiles import StaticFilesWrapper
16-
1716
logger = logging.getLogger("django.channels.server")
1817

1918

@@ -129,7 +128,7 @@ def get_application(self, options):
129128
use_static_handler = options.get("use_static_handler", staticfiles_installed)
130129
insecure_serving = options.get("insecure_serving", False)
131130
if use_static_handler and (settings.DEBUG or insecure_serving):
132-
return StaticFilesWrapper(get_default_application())
131+
return ASGIStaticFilesHandler(get_default_application())
133132
else:
134133
return get_default_application()
135134

channels/staticfiles.py

Lines changed: 0 additions & 82 deletions
This file was deleted.

channels/testing/live.py

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,11 @@
11
from daphne.testing import DaphneProcess
2+
from django.contrib.staticfiles.handlers import ASGIStaticFilesHandler
23
from django.core.exceptions import ImproperlyConfigured
34
from django.db import connections
45
from django.test.testcases import TransactionTestCase
56
from django.test.utils import modify_settings
67

78
from channels.routing import get_default_application
8-
from channels.staticfiles import StaticFilesWrapper
99

1010

1111
class ChannelsLiveServerTestCase(TransactionTestCase):
@@ -18,7 +18,7 @@ class ChannelsLiveServerTestCase(TransactionTestCase):
1818

1919
host = "localhost"
2020
ProtocolServerProcess = DaphneProcess
21-
static_wrapper = StaticFilesWrapper
21+
static_wrapper = ASGIStaticFilesHandler
2222
serve_static = True
2323

2424
@property

tests/test_staticfiles.py

Lines changed: 5 additions & 55 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,5 @@
1-
import os
2-
31
import pytest
4-
5-
from channels.staticfiles import StaticFilesHandler, StaticFilesWrapper
2+
from django.contrib.staticfiles.handlers import ASGIStaticFilesHandler
63

74

85
@pytest.fixture(autouse=True)
@@ -21,39 +18,16 @@ async def __call__(self, scope, receive, send):
2118
return self.return_value
2219

2320

24-
class MockStaticHandler:
25-
async def __call__(self, scope, receive, send):
26-
return scope["path"]
27-
28-
2921
def request_for_path(path, type="http"):
3022
return {
3123
"type": type,
3224
"path": path,
3325
}
3426

3527

36-
@pytest.mark.asyncio
37-
@pytest.mark.filterwarnings("ignore::DeprecationWarning")
38-
async def test_staticfiles_wrapper_serves_static_http_requests(settings):
39-
settings.STATIC_URL = "/mystatic/"
40-
41-
application = MockApplication("application")
42-
43-
wrapper = StaticFilesWrapper(application, staticfiles_handler=MockStaticHandler)
44-
45-
scope = request_for_path("/mystatic/image.png")
46-
assert (
47-
await wrapper(scope, None, None) == "/mystatic/image.png"
48-
), "StaticFilesWrapper should serve paths under the STATIC_URL path"
49-
assert (
50-
not application.was_called
51-
), "The inner application should not be called when serving static files"
52-
53-
5428
@pytest.mark.asyncio
5529
async def test_staticfiles_wrapper_calls_application_for_non_static_http_requests():
56-
wrapper = StaticFilesWrapper(MockApplication("application"))
30+
wrapper = ASGIStaticFilesHandler(MockApplication("application"))
5731

5832
non_static_path = request_for_path("/path/to/non/static/resource")
5933
assert (
@@ -70,7 +44,7 @@ async def test_staticfiles_wrapper_calls_application_for_non_static_http_request
7044
async def test_staticfiles_wrapper_calls_application_for_non_http_paths(settings):
7145
settings.STATIC_URL = "/mystatic/"
7246

73-
wrapper = StaticFilesWrapper(MockApplication("application"))
47+
wrapper = ASGIStaticFilesHandler(MockApplication("application"))
7448

7549
non_http_static_path = request_for_path("/mystatic/match", type="websocket")
7650
assert await wrapper(non_http_static_path, None, None) == "application", (
@@ -83,7 +57,7 @@ async def test_staticfiles_wrapper_calls_application_for_non_http_paths(settings
8357
async def test_staticfiles_wrapper_calls_application_if_static_url_has_host(settings):
8458
settings.STATIC_URL = "http://hostname.com/mystatic/"
8559

86-
wrapper = StaticFilesWrapper(MockApplication("application"))
60+
wrapper = ASGIStaticFilesHandler(MockApplication("application"))
8761

8862
scope = request_for_path("/mystatic/match")
8963
assert await wrapper(scope, None, None) == "application", (
@@ -95,33 +69,9 @@ async def test_staticfiles_wrapper_calls_application_if_static_url_has_host(sett
9569
def test_is_single_callable():
9670
from asgiref.compatibility import is_double_callable
9771

98-
wrapper = StaticFilesWrapper(None)
72+
wrapper = ASGIStaticFilesHandler(None)
9973

10074
assert not is_double_callable(wrapper), (
10175
"StaticFilesWrapper should be recognized as a single callable by "
10276
"asgiref compatibility tools"
10377
)
104-
105-
106-
@pytest.mark.asyncio
107-
async def test_staticfiles_handler_can_generate_file_path():
108-
"""
109-
StaticFilesHandler.file_path must not rely on scope being assigned to self.
110-
"""
111-
112-
class MockedHandler(StaticFilesHandler):
113-
async def __call__(self, scope, receive, send):
114-
# Equivalent setUp from real __call__.
115-
request = self.request_class(scope, "")
116-
self.static_base_url = scope["static_base_url"][2]
117-
# Method under test.
118-
return self.file_path(request.path)
119-
120-
wrapper = StaticFilesWrapper(
121-
MockApplication("application"), staticfiles_handler=MockedHandler
122-
)
123-
scope = request_for_path("/static/image.png")
124-
scope["method"] = "GET"
125-
assert await wrapper(scope, None, None) == os.path.normpath(
126-
"/image.png"
127-
), "StaticFilesWrapper should serve paths under the STATIC_URL path"

0 commit comments

Comments
 (0)