Skip to main content
 首页 » 编程设计

python之flask + Apache (mod_wsgi) + boto3 : name 'ssl' is not defined

2025年02月15日32lhb25

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

为了查看我的应用程序有什么问题,我使用 Debug模式在独立服务器(仅限 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_wsgi 4.5.5
Python 3.5.2 (Anaconda3 - 4.2.0)
flask 0.11.1
Boto3 1.4.4

请您参考如下方法:

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

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

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