我正在开发一个在python中运行的应用程序(总是 - 它是热泵系统的控制器),我使用flask提供用户界面来控制应用程序。
烧瓶应用程序具有不同的控制项,例如用于打开或关闭系统的按钮。
我正在尝试从python模块执行一个特定的函数来响应" click"在按钮上(最终目标是更改mmap资源中的值,该值将在另一个模块中读取以更改系统状态)。
在烧瓶应用程序中,我有类似的东西:
@app.route('/cntr_hpauto',methods=['GET','POST'])
@basic_auth.required
def cntr_hpauto():
manage_globals.set_from_web()
return render_template('control.html',cur_hp_mode="auto")
但是,这会产生"内部服务器错误'
完整的烧瓶应用程序是(manage_globals是我要导入的* .py文件,其中包含我要调用的函数):
from flask import Flask, request, render_template
from flask_basicauth import BasicAuth
import sys
import os
import mmap
import manage_globals
app = Flask(__name__)
app.config['BASIC_AUTH_USERNAME'] = '***'
app.config['BASIC_AUTH_PASSWORD'] = '***'
basic_auth = BasicAuth(app)
@app.route('/')
def splash():
return render_template('splash.html')
@app.route('/dashboard', methods=['GET','POST'])
@basic_auth.required
def dashboard():
return render_template('dashboard.html')
@app.route('/control',methods=['GET','POST'])
@basic_auth.required
def control():
return render_template('control.html',cur_hp_mode="none")
@app.route('/cntr_hpauto',methods=['GET','POST'])
@basic_auth.required
def cntr_hpauto():
manage_globals.set_from_web()
return render_template('control.html',cur_hp_mode="auto")
@app.route('/cntr_hpon',methods=['GET','POST'])
@basic_auth.required
def cntr_hpon():
return render_template('control.html',cur_hp_mode="on")
@app.route('/cntr_hpoff',methods=['GET','POST'])
@basic_auth.required
def cntr_hpoff():
return render_template('control.html',cur_hp_mode="off")
if __name__ == '__main__':
app.run(ssl_context=('/home/groenhol/certs/groenhol.pem', '/home/groenhol/certs/groenhol.key'))
模块(例如,只将地图文件写入日志文件)是:
# 14/08/2017 henk witte / groenholland
# part of geotech project, ann controller dual source heat pump
# this module maintains the global database with mmap
import mmap
""" the mmap file is position dependent!
use readlines and split
line 1: heatpump auto/on/off
line 2: userpump off
line 3: srcselect air
"""
def init_conf_file():
dummy="a"
def set_from_web():
with open("geotech.conf", "r+b") as f:
mm = mmap.mmap(f.fileno(), 0)
for line in iter(mm.readline, b''):
with open("globals.log","ab") as f2:
f2.write(line)
f2.close()
mm.close()
if __name__ == '__main__':
init_conf_file()
烧瓶app在没有函数调用的情况下运行正常,我自己导入的模块也运行正常。
非常感谢任何帮助!
亨克
根据Kevin Pasquarella的建议,我添加了app.debug = true。但是,因为当apache在主启动页面中加载时出现错误(apache服务器错误),这没有帮助。但我接着看了一下apache错误日志:
[Tue Aug 15 21:33:14.638580 2017] [mpm_event:notice] [pid 959:tid 3067240448] AH00489: Apache/2.4.18 (Ubuntu) OpenSSL/1.0.2g mod_wsgi/4.5.17 Python/3.4 configured -- resuming normal operations
[Tue Aug 15 21:33:14.639152 2017] [core:notice] [pid 959:tid 3067240448] AH00094: Command line: '/usr/sbin/apache2'
[Tue Aug 15 21:33:19.825211 2017] [wsgi:error] [pid 2461:tid 3031819312] [remote 192.168.178.85:9676] mod_wsgi (pid=2461): Target WSGI script '/home/groenhol/py_control/ui/webapp/main.wsgi' cannot be loaded as Python module.
[Tue Aug 15 21:33:19.826502 2017] [wsgi:error] [pid 2461:tid 3031819312] [remote 192.168.178.85:9676] mod_wsgi (pid=2461): Exception occurred processing WSGI script '/home/groenhol/py_control/ui/webapp/main.wsgi'.
[Tue Aug 15 21:33:19.967421 2017] [wsgi:error] [pid 2461:tid 3031819312] [remote 192.168.178.85:9676] Traceback (most recent call last):
[Tue Aug 15 21:33:19.970377 2017] [wsgi:error] [pid 2461:tid 3031819312] [remote 192.168.178.85:9676] File "/home/groenhol/py_control/ui/webapp/main.wsgi", line 4, in <module>
[Tue Aug 15 21:33:19.970581 2017] [wsgi:error] [pid 2461:tid 3031819312] [remote 192.168.178.85:9676] from main import app as application
[Tue Aug 15 21:33:19.971031 2017] [wsgi:error] [pid 2461:tid 3031819312] [remote 192.168.178.85:9676] File "/home/groenhol/py_control/ui/webapp/main.py", line 41
然后我搜索 mod_wsgi无法加载为python模块
答案表明我正在使用的python版本(3.4)和wsgi版本之间存在差异。
所以我检查了/etc/apache2/mods-enabled/mod-wsgi.load中的wsgi版本:
LoadModule wsgi_module&#34; /home/groenhol/miniconda3/lib/python3.4/site-packages/mod_wsgi/server/mod_wsgi-py34.cpython-34m.so" WSGIPythonHome&#34; / home / groenhol / miniconda3&#34;
所以似乎使用python 3.4版本。
为了确保我在搜索过程中找到ldd:
groenhol@arm:~/mod_wsgi-4.5.15$ ldd LoadModule wsgi_module "/home/groenhol/miniconda3/lib/python3.4/site-packages/mod_wsgi/server/mod_wsgi-py34.cpython-34m.so"
LoadModule:
ldd: ./LoadModule: No such file or directory
wsgi_module:
ldd: ./wsgi_module: No such file or directory
/home/groenhol/miniconda3/lib/python3.4/site-packages/mod_wsgi/server/mod_wsgi-py34.cpython-34m.so:
linux-vdso.so.1 => (0xbee90000)
libpython3.4m.so.1.0 => /home/groenhol/miniconda3/lib/libpython3.4m.so.1.0 (0xb6d40000)
libpthread.so.0 => /lib/arm-linux-gnueabihf/libpthread.so.0 (0xb6d0f000)
libc.so.6 => /lib/arm-linux-gnueabihf/libc.so.6 (0xb6c23000)
/lib/ld-linux-armhf.so.3 (0x7f64d000)
libdl.so.2 => /lib/arm-linux-gnueabihf/libdl.so.2 (0xb6c10000)
libutil.so.1 => /lib/arm-linux-gnueabihf/libutil.so.1 (0xb6bfd000)
libm.so.6 => /lib/arm-linux-gnueabihf/libm.so.6 (0xb6b85000)
libgcc_s.so.1 => /lib/arm-linux-gnueabihf/libgcc_s.so.1 (0xb6b5c000)
groenhol@arm:~/mod_wsgi-4.5.15$ WSGIPythonHome "/home/groenhol/miniconda3"
-bash: WSGIPythonHome: command not found
据我所知(http://modwsgi.readthedocs.io/en/develop/user-guides/checking-your-installation.html#python-shared-library),这似乎没问题?
好的,下一步呢?
答案 0 :(得分:0)
代码:
def set_from_web():
with open("geotech.conf", "r+b") as f:
mm = mmap.mmap(f.fileno(), 0)
for line in iter(mm.readline, b''):
with open("globals.log","ab") as f2:
f2.write(line)
f2.close()
mm.close()
将成为一个问题,因为您正在使用文件的相对路径名。
进程的当前工作目录不是您的代码所在的位置,也不会写入Apache用户。您需要使用绝对路径并确保Apache用户具有文件的写入权限。
请参阅:
答案 1 :(得分:0)
解决方案结果非常简单:mod_wsgi不喜欢你用空格和制表符来识别。我将所有idents更改为选项卡,然后代码运行!
我通过将代码更改为非常简单的方法找到了这一点,只需返回一个字符串并将其打印在由flask模板创建的网页上。然后我可以在apache日志中看到wsgi错误。在完整的代码中,发生了其他故障,因此很难找出确切导致错误的原因。
我还处理了Graham Dumpleton的评论(apache无法写入目录),我创建了一个共享目录(/ home / py_shared),我将其添加到www-data组(python用户和apache是该组的成员)。然后我将文件夹的组设置为www-data,并使用chmod g + w py_shared和chmod g + s py_shared来设置正确的权限。
本主题将在几个页面中讨论,例如:
https://unix.stackexchange.com/questions/154776/create-files-that-both-www-data-and-myuser-can-edit
感谢你的所有建议!