forked from reactive-python/reactpy-django
-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathchecks.py
224 lines (202 loc) · 7.95 KB
/
checks.py
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
import sys
from django.contrib.staticfiles.finders import find
from django.core.checks import Error, Tags, Warning, register
from django.template import loader
@register(Tags.compatibility)
def reactpy_warnings(app_configs, **kwargs):
from django.conf import settings
from django.urls import reverse
from reactpy_django.config import REACTPY_FAILED_COMPONENTS
warnings = []
# REACTPY_DATABASE is not an in-memory database.
if (
getattr(settings, "DATABASES", {})
.get(getattr(settings, "REACTPY_DATABASE", "default"), {})
.get("NAME", None)
== ":memory:"
):
warnings.append(
Warning(
"Using ReactPy with an in-memory database can cause unexpected "
"behaviors.",
hint="Configure settings.py:DATABASES[REACTPY_DATABASE], to use a "
"multiprocessing and thread safe database.",
id="reactpy_django.W001",
)
)
# ReactPy URLs exist
try:
reverse("reactpy:web_modules", kwargs={"file": "example"})
reverse("reactpy:view_to_component", kwargs={"view_path": "example"})
except Exception:
warnings.append(
Warning(
"ReactPy URLs have not been registered.",
hint="""Add 'path("reactpy/", include("reactpy_django.http.urls"))' """
"to your application's urlpatterns.",
id="reactpy_django.W002",
)
)
# Warn if REACTPY_BACKHAUL_THREAD is set to True on Linux with Daphne
if (
sys.argv
and sys.argv[0].endswith("daphne")
and getattr(settings, "REACTPY_BACKHAUL_THREAD", False)
and sys.platform == "linux"
):
warnings.append(
Warning(
"REACTPY_BACKHAUL_THREAD is enabled but you running with Daphne on Linux. "
"This configuration is known to be unstable.",
hint="Set settings.py:REACTPY_BACKHAUL_THREAD to False or use a different webserver.",
id="reactpy_django.W003",
)
)
# Check if reactpy_django/client.js is available
if not find("reactpy_django/client.js"):
warnings.append(
Warning(
"ReactPy client.js could not be found within Django static files!",
hint="Check your Django static file configuration.",
id="reactpy_django.W004",
)
)
# Check if any components failed to be registered
if REACTPY_FAILED_COMPONENTS:
warnings.append(
Warning(
"ReactPy failed to register the following components:\n\t+ "
+ "\n\t+ ".join(REACTPY_FAILED_COMPONENTS),
hint="Check if these paths are valid, or if an exception is being "
"raised during import.",
id="reactpy_django.W005",
)
)
# Check if the reactpy/component.html template exists
try:
loader.get_template("reactpy/component.html")
except Exception:
warnings.append(
Warning(
"ReactPy HTML templates could not be found!",
hint="Check your settings.py:TEMPLATES configuration and make sure "
"ReactPy-Django is installed properly.",
id="reactpy_django.W006",
)
)
# Check if REACTPY_WEBSOCKET_URL doesn't end with a slash
REACTPY_WEBSOCKET_URL = getattr(settings, "REACTPY_WEBSOCKET_URL", "reactpy/")
if isinstance(REACTPY_WEBSOCKET_URL, str):
if not REACTPY_WEBSOCKET_URL or not REACTPY_WEBSOCKET_URL.endswith("/"):
warnings.append(
Warning(
"REACTPY_WEBSOCKET_URL did not end with a forward slash.",
hint="Change your URL to be written in the following format: 'example_url/'",
id="reactpy_django.W007",
)
)
# Check if REACTPY_WEBSOCKET_URL doesn't start with an alphanumeric character
if not REACTPY_WEBSOCKET_URL or not REACTPY_WEBSOCKET_URL[0].isalnum():
warnings.append(
Warning(
"REACTPY_WEBSOCKET_URL did not start with an alphanumeric character.",
hint="Change your URL to be written in the following format: 'example_url/'",
id="reactpy_django.W008",
)
)
return warnings
@register(Tags.compatibility)
def reactpy_errors(app_configs, **kwargs):
from django.conf import settings
errors = []
# Make sure ASGI is enabled
if not getattr(settings, "ASGI_APPLICATION", None):
errors.append(
Error(
"ASGI_APPLICATION is not defined, but ReactPy requires ASGI.",
hint="Add ASGI_APPLICATION to settings.py.",
id="reactpy_django.E001",
)
)
# DATABASE_ROUTERS is properly configured when REACTPY_DATABASE is defined
if getattr(
settings, "REACTPY_DATABASE", None
) and "reactpy_django.database.Router" not in getattr(
settings, "DATABASE_ROUTERS", []
):
errors.append(
Error(
"ReactPy database has been changed but the database router is "
"not configured.",
hint="Set settings.py:DATABASE_ROUTERS to "
"['reactpy_django.database.Router', ...]",
id="reactpy_django.E002",
)
)
# All settings in reactpy_django.conf are the correct data type
if not isinstance(getattr(settings, "REACTPY_WEBSOCKET_URL", ""), str):
errors.append(
Error(
"Invalid type for REACTPY_WEBSOCKET_URL.",
hint="REACTPY_WEBSOCKET_URL should be a string.",
obj=settings.REACTPY_WEBSOCKET_URL,
id="reactpy_django.E003",
)
)
if not isinstance(getattr(settings, "REACTPY_RECONNECT_MAX", 0), int):
errors.append(
Error(
"Invalid type for REACTPY_RECONNECT_MAX.",
hint="REACTPY_RECONNECT_MAX should be an integer.",
obj=settings.REACTPY_RECONNECT_MAX,
id="reactpy_django.E004",
)
)
if not isinstance(getattr(settings, "REACTPY_CACHE", ""), str):
errors.append(
Error(
"Invalid type for REACTPY_CACHE.",
hint="REACTPY_CACHE should be a string.",
obj=settings.REACTPY_CACHE,
id="reactpy_django.E005",
)
)
if not isinstance(getattr(settings, "REACTPY_DATABASE", ""), str):
errors.append(
Error(
"Invalid type for REACTPY_DATABASE.",
hint="REACTPY_DATABASE should be a string.",
obj=settings.REACTPY_DATABASE,
id="reactpy_django.E006",
)
)
if not isinstance(
getattr(settings, "REACTPY_DEFAULT_QUERY_POSTPROCESSOR", ""), str
):
errors.append(
Error(
"Invalid type for REACTPY_DEFAULT_QUERY_POSTPROCESSOR.",
hint="REACTPY_DEFAULT_QUERY_POSTPROCESSOR should be a string.",
obj=settings.REACTPY_DEFAULT_QUERY_POSTPROCESSOR,
id="reactpy_django.E007",
)
)
if not isinstance(getattr(settings, "REACTPY_AUTH_BACKEND", ""), str):
errors.append(
Error(
"Invalid type for REACTPY_AUTH_BACKEND.",
hint="REACTPY_AUTH_BACKEND should be a string.",
obj=settings.REACTPY_AUTH_BACKEND,
id="reactpy_django.E008",
)
)
# Check for dependencies
if "channels" not in settings.INSTALLED_APPS:
errors.append(
Error(
"Django Channels is not installed.",
hint="Add 'channels' to settings.py:INSTALLED_APPS.",
id="reactpy_django.E009",
)
)
return errors