Flask + Apache (mod_wsgi) + boto3: 名称 'ssl' 未定义

Flask + Apache (mod_wsgi) + boto3: name 'ssl' is not defined

我正在尝试构建一个 REST API 来监视 AWS EC2 服务上实例的状态。当我使用托管在 Apache 上的 Flask 应用程序时,我得到一个回溯信息,通知我 name 'ssl' is not defined.

为了查看我的应用程序有什么问题,我 运行 它在独立服务器(仅限 Flask)上使用调试模式。令我惊讶的是,申请 运行 成功了。

我的 Flask 应用程序(flask_endpoint.py)

import json
import boto3
from flask import Flask
from flask_cors import CORS
from flask import make_response

WEBAPP = Flask(__name__)
CORS(WEBAPP)


@WEBAPP.route('/test_boto', methods=['GET'])
def handle_teste_boto():

    results = []
    ec2_res = boto3.resource('ec2')
    instances = ec2_res.instances.filter(Filters=[{'Name': 'instance-state-name', 'Values': ['running']}])

    for inst in instances:
        inst_dic = {'private_ip': inst.private_ip_address,
                    'instance_type': inst.instance_type,
                    'state': inst.state['Name']
                    }
        results.append(inst_dic)

    response_code = 200
    response = make_response(json.dumps(results, ensure_ascii=False), response_code)
    response.headers['Content-Type'] = 'application/json'
    return response

if __name__ == '__main__':
    WEBAPP.run(port=50000, host='0.0.0.0', debug=True)

运行 没有 Apache

时产生的输出
[
    {
        "state": "running",
        "private_ip": "172.31.56.153",
        "instance_type": "t2.micro"
    }
]

带有截断回溯的 Apache 日志

[Sat Jun 03 11:59:20.217312 2017] [wsgi:info] [pid 3094] [remote 192.168.0.115:50017] mod_wsgi (pid=3094, process='flask_test', application=''): Loading WSGI script '/var/www/siase/middleend/rest/cmd_server_wsgi.py'.
[Sat Jun 03 11:59:20.827295 2017] [wsgi:error] [pid 3094] [remote 192.168.0.115:50017] mod_wsgi (pid=3094): Exception occurred processing WSGI script '/var/www/siase/middleend/rest/cmd_server_wsgi.py'.
[Sat Jun 03 11:59:20.829915 2017] [wsgi:error] [pid 3094] [remote 192.168.0.115:50017] Traceback (most recent call last):
[Sat Jun 03 11:59:20.830014 2017] [wsgi:error] [pid 3094] [remote 192.168.0.115:50017]   File "/var/www/anaconda3/lib/python3.5/site-packages/flask/app.py", line 2000, in __call__
[Sat Jun 03 11:59:20.830017 2017] [wsgi:error] [pid 3094] [remote 192.168.0.115:50017]     return self.wsgi_app(environ, start_response)
[Sat Jun 03 11:59:20.830022 2017] [wsgi:error] [pid 3094] [remote 192.168.0.115:50017]   File "/var/www/anaconda3/lib/python3.5/site-packages/flask/app.py", line 1991, in wsgi_app
[Sat Jun 03 11:59:20.830024 2017] [wsgi:error] [pid 3094] [remote 192.168.0.115:50017]     response = self.make_response(self.handle_exception(e))
[Sat Jun 03 11:59:20.830027 2017] [wsgi:error] [pid 3094] [remote 192.168.0.115:50017]   File "/var/www/anaconda3/lib/python3.5/site-packages/flask_cors/extension.py", line 161, in wrapped_function
[Sat Jun 03 11:59:20.830029 2017] [wsgi:error] [pid 3094] [remote 192.168.0.115:50017]     return cors_after_request(app.make_response(f(*args, **kwargs)))

** (several lines) **

[Sat Jun 03 11:59:20.830194 2017] [wsgi:error] [pid 3094] [remote 192.168.0.115:50017]     body=body, headers=headers)
[Sat Jun 03 11:59:20.830197 2017] [wsgi:error] [pid 3094] [remote 192.168.0.115:50017]   File "/var/www/anaconda3/lib/python3.5/site-packages/botocore/vendored/requests/packages/urllib3/connectionpool.py", line 341, in _make_request
[Sat Jun 03 11:59:20.830199 2017] [wsgi:error] [pid 3094] [remote 192.168.0.115:50017]     self._validate_conn(conn)
[Sat Jun 03 11:59:20.830202 2017] [wsgi:error] [pid 3094] [remote 192.168.0.115:50017]   File "/var/www/anaconda3/lib/python3.5/site-packages/botocore/vendored/requests/packages/urllib3/connectionpool.py", line 761, in _validate_conn
[Sat Jun 03 11:59:20.830204 2017] [wsgi:error] [pid 3094] [remote 192.168.0.115:50017]     conn.connect()
[Sat Jun 03 11:59:20.830207 2017] [wsgi:error] [pid 3094] [remote 192.168.0.115:50017]   File "/var/www/anaconda3/lib/python3.5/site-packages/botocore/vendored/requests/packages/urllib3/connection.py", line 206, in connect
[Sat Jun 03 11:59:20.830209 2017] [wsgi:error] [pid 3094] [remote 192.168.0.115:50017]     resolved_cert_reqs = resolve_cert_reqs(self.cert_reqs)
[Sat Jun 03 11:59:20.830213 2017] [wsgi:error] [pid 3094] [remote 192.168.0.115:50017]   File "/var/www/anaconda3/lib/python3.5/site-packages/botocore/vendored/requests/packages/urllib3/util/ssl_.py", line 157, in resolve_cert_reqs
[Sat Jun 03 11:59:20.830216 2017] [wsgi:error] [pid 3094] [remote 192.168.0.115:50017]     res = getattr(ssl, candidate, None)
[Sat Jun 03 11:59:20.830230 2017] [wsgi:error] [pid 3094] [remote 192.168.0.115:50017] NameError: name 'ssl' is not defined

这是我的 wsgi 文件

# -*- coding: utf-8 -*-

import sys

APP_MODULE_PATH = '/var/www/siase/middleend'

if APP_MODULE_PATH not in sys.path:
    sys.path.insert(0, APP_MODULE_PATH)

from rest.cmd_server import WEBAPP as application
application.debug = True

这是我的 .conf 文件

<VirtualHost *:8080>

    ServerName localhost
    ServerAdmin administrator@localhost

    DocumentRoot /var/www/siase/middleend

    WSGIDaemonProcess flask_test user=studioapp group=www-data lang='en_US.UTF-8' locale='en_US.UTF-8' threads=20 processes=4 python-path=/var/www/anaconda3/lib/python3.5
    WSGIScriptAlias / /var/www/siase/middleend/rest/cmd_server_wsgi.py
    <Directory /var/www/siase/middleend>
        WSGIProcessGroup flask_test
        WSGIApplicationGroup %{GLOBAL}
        Require all granted
        Options -Indexes
    </Directory>

    <Directory "/">
        Options -Indexes
    </Directory>

    LogLevel info
    ErrorLog ${APACHE_LOG_DIR}/flask_test-error.log
    CustomLog ${APACHE_LOG_DIR}/flask_test-access.log combined

</VirtualHost>

下面是我目前使用的环境的一些细节:

Apache/2.4.7 (Ubuntu)
OpenSSL 1.0.1f
mod_wsgi4.5.5
Python 3.5.2 (Anaconda3 - 4.2.0)
烧瓶 0.11.1
Boto3 1.4.4

如果您要将 mod_ssl 模块加载到 Apache 中,您可能无法使其正常工作。问题是 Anaconda 一直在运送自己的 SSL 库,它们与操作系统 SSL 库不兼容。

Apache 在加载 mod_ssl 模块时会引入操作系统 SSL 库。然后在您的 Python 网络应用程序中,Anaconda 不能使用它自己的,而是继承由 Apache mod_ssl 库引入的 SSL 库。由于它们不兼容,Python 中的 ssl 模块设置失败,因此显示为未加载。

唯一的解决方案是使用 mod_wsgi-express 并将其置于 Apache 之后,Apache 仅充当代理。这样,Apache 和您的 Python 网络应用程序之间就有了适当的分离。