2
votes

I'm trying to build an REST API that monitors the state of instances on AWS EC2 service. When I use my Flask application hosted on Apache I get an traceback informing that name 'ssl' is not defined.

To see what was wrong with my application I ran it on a standalone server (Flask only) using debug mode. For my surprise the application ran sucessfully.

My Flask application (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)

Output produced when running without Apache

[
    {
        "state": "running",
        "private_ip": "172.31.56.153",
        "instance_type": "t2.micro"
    }
]

Apache log with truncated traceback

[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

This is my wsgi file

# -*- 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

This is my .conf file

<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>

Here follows some details of the environment that I currently using:

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

1

1 Answers

1
votes

If you are loading the mod_ssl module into Apache you are likely not going to be able to get it working. The problem is that Anaconda has been shipping its own SSL libraries and they aren't compatible with the operating system SSL libraries.

What happens is that Apache when it loads the mod_ssl module pulls in the operating system SSL libraries. Then in your Python web application, Anaconda can't use its own and inherits the SSL libraries pulled in by Apache mod_ssl library instead. Because they aren't compatible, setup of the ssl module in Python fails so appears as not being loaded.

The only solution would be to use mod_wsgi-express and sit it behind Apache with Apache acting only as a proxy. That way there is a proper separation between Apache and your Python web application.