#apache #plotly-dash
#apache #plotly-dash
Вопрос:
Я пытаюсь обслуживать (python3.8.2) dash
приложение, используя сервер Apache2 и mod_wsgi
, но приложение останавливается на экране «Загрузка …». Сервер возвращает 404 секунды для каждого из сценариев dash .js. У меня не было проблем при использовании встроенного локального сервера dash… но я не пытаюсь обслуживать это локально.
Мне бы хотелось получить совет о том, где я ошибаюсь, и как запустить это конкретное приложение.
Симптомы
Я могу обслуживать как простой python «hello world», так и простое приложение flask, используя мои настройки. Однако при создании простого приложения ‘dash’…
[Error] Failed to load resource: the server responded with a status of 404 (Not Found) (polyfill@7.v1_6_0m1598005008.8.7.min.js, line 0)
... followed by 12 more similar error messages...
[Error] Failed to load resource: the server responded with a status of 404 (Not Found) (dash_renderer.v1_6_0m1598005008.min.js, line 0)
[Error] ReferenceError: Can't find variable: DashRenderer
Global Code (hazcurves:28:103)
мой журнал доступа apache показывает серию запросов GET, которые получили 404 (вот один пример):
... "GET /_dash-component-suites/dash_renderer/dash_renderer.v1_6_0m1598005008.min.js HTTP/1.1" 404 495 "http://efehr-dev.ethz.ch/hazcurves/" "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_6) AppleWebKit/605.1.15 (KHTML, like Gecko) Version/13.1.2 Safari/605.1.15"
Дополнительные замечания
Когда я сравнил свой отправленный html с html из правильно функционирующего приложения Dash, я заметил разницу в именах .js. Похоже, что мой каким-то образом искажен.
Действующая версия, от https://dash-gallery.plotly.host/dash-wind-streaming /
# Excerpt from functioning app's "footer" section
<footer>
<script id="_dash-config" type="application/json">{"url_base_pathname": null, "requests_pathname_prefix": "/dash-wind-streaming/", "ui": false, "props_check": false, "show_undo_redo": false}</script>
# [CGR] then there are several components here that are variations of the following
<script src="/dash-wind-streaming/_dash-component-suites/dash_renderer/dash_renderer.min.js?v=1.0.0amp;m=1583853516"></script>
<script id="_dash-renderer" type="application/javascript">
var renderer = new DashRenderer();
</script>
Нижний колонтитул моего приложения делает запрос скремблированным, с параметрами запроса, включенными в имя файла.
<footer>
<script id="_dash-config" type="application/json">{"url_base_pathname": null, "requests_pathname_prefix": "/", "ui": false, "props_check": false, "show_undo_redo": false, "suppress_callback_exceptions": false, "update_title": "Updating..."}</script>
# [CGR] then there are several components here that are variations of the following
<script src="/_dash-component-suites/dash_html_components/dash_html_components.v1_0_3m1598005008.min.js"></script>
<script src="/_dash-component-suites/dash_renderer/dash_renderer.v1_6_0m1598005008.min.js"></script>
<script id="_dash-renderer" type="application/javascript">var renderer = new DashRenderer();</script>
</footer>
Теперь, эти файлы .js [расшифрованные версии] СУЩЕСТВУЕТ и _dash-component-suites
, похоже, отображается в моей .local/lib/python3.8/site-packages
папке.
Итак, из того, что я показал выше, у меня есть .../dash_renderer/dash_renderer.min.js
и .../dash_html_components.min.js
Моя система:
Чистая система с Ubuntu 20.04.1 LTS, Apache 2.4 с установленным mod_wsgi.
В Python 3.8.2 установлены следующие соответствующие пакеты [с использованием sudo pip3] :
dash==1.14.0
dash-core-components==1.10.2
dash-html-components==1.0.3
dash-renderer==1.6.0
dash-table==4.9.0
Flask==1.1.2
Flask-Compres=1.5.0
Вот мое приложение.wsgi:
from flask import Flask
server = Flask(__name__)
import dash
import dash_core_components as dcc
import dash_html_components as html
app = dash.Dash(server=server)
app.css.config.serve_locally = True
app.scripts.config.serve_locally = True
app.layout = html.Div(children=["hello"])
application = app.server
Я смог запустить это с помощью встроенного сервера, обслуживая его на локальном сервере.
Файл конфигурации моего сайта:
<VirtualHost *:80>
ServerAdmin webmaster@localhost
DocumentRoot /home/username/public_html
WSGIDaemonProcess /home/username/public_html/myapp.wsgi processes=2 threads=15 display-name=%{GROUP}
WSGIScriptAlias /hazcurves /home/username/public_html/myapp.wsgi
<Directory /home/username/public_html>
AllowOverride all
Options Indexes FollowSymLinks
<Limit GET POST OPTIONS>
Require all granted
</Limit>
</Directory>
ErrorLog ${APACHE_LOG_DIR}/error.log
CustomLog ${APACHE_LOG_DIR}/access.log combined
</VirtualHost>
Некоторые из вещей, которые я признаю, пытались
- Привет, мир в flask: работает нормально
- Привет, мир в Dash: сбой
- Создание псевдонима в конфигурации сервера
alias _dash-component-suites/ .local/lib/python3.8/site-packages
- изменение request_pathnames_prefix : похоже, не имеет никакого эффекта и не отображается в выходных данных html. Это дало мне 403 вместо 404. Но затем я также заметил несоответствия имен.
- app.css.config.serve_locally = True # также попробовал False: никакого очевидного эффекта
- app.scripts.config.serve_locally = True #также попробовал False: никакого очевидного эффекта
После попытки включить советы с веб-сайтов, которые имеют непосредственное отношение к этому вопросу, я начинаю чувствовать себя обезьяной, стучащей по клавишам, что, гм, неправильно (и небезопасно)
последнее предостережение: это мой первый опыт управления приложением на стороне сервера в мире.
Ответ №1:
Я рад сообщить, что в конце концов разобрался с этим, и что мои приложения теперь работают отлично. Вот что я узнал.
Я должен был помнить о следующем при вызове dash.Dash(...)
Вместо того, что я написал, мне нужно:
dash.Dash(__name__, requests_pathname_prefix='/hazcurves/')
Важные уроки следующие:
- Не перезаписывайте переменную сервера. Каким-то образом я терял все созданные мной конфигурации.
requests_pathname_prefix
необходимо сопоставить псевдоним URL (начиная с конца, заканчивающегося косой чертой).
Отвлекающий маневр (вещи, которые на самом деле не имели значения):
- сначала создайте экземпляр Flask
- конфигурации в отношении локального обслуживания
app.css.config.serve_locally = True
app.scripts.config.serve_locally = True
Итак, вот выдержки из трех моих файлов, представляющих интерес:
mysite.conf : /etc/apache2/sites-available/mysite.conf
<VirtualHost *:80>
ServerAdmin webmaster@localhost
DocumentRoot /home/myusername/public_html
# ---- Hazard Curves App ---- #
# using WSGIProcessGroup within Location allows multiple apps to run
# without interfering with each other
WSGIDaemonProcess curves/wsgi.py processes=2 threads=15 display-name=%{GROUP}
WSGIScriptAlias /curves /home/myusername/public_html/curves/wsgi.py
<Location /curves>
WSGIProcessGroup curves/wsgi.py
</Location>
</VirtualHost>
wsgi.py : ~/public_html/curves/wsgi.py
#!/usr/bin/python3
from myapp import app
application = app.server
myapp.py : ~/public_html/curves/myapp.py
import dash
import dash_html_components as html
app = dash.Dash(__name__, requests_pathname_prefix='/curves/')
app.title = "Some Test"
app.layout = html.Div([html.H6("Hello World")])
if __name__ == '__main__':
app.run_server(port=8051, debug=True) # unimportant in this context