ScottMcC ScottMcC - 2 months ago 18
Python Question

Azure Flask Deployment - WSGI Interface

I'm currently working through the book Flask Web Development, Developing Web Applications with Python and am currently having some issues determining where I should place the WSGI interface so that I can deploy it to an Azure Web Service. For reference I'm currently at Chapter 7 and a copy of this code that I'm currently working through can be found at https://github.com/miguelgrinberg/flasky/tree/7a

To try and work out where the problem is I've created a test Azure Cloud Service with Flask in Visual Studio which runs perfectly in the Azure Emulator. The following code is a copy of the app.py file.

"""
This script runs the application using a development server.
It contains the definition of routes and views for the application.
"""

from flask import Flask
app = Flask(__name__)

# Make the WSGI interface available at the top level so wfastcgi can get it.
wsgi_app = app.wsgi_app

@app.route('/')
def hello():
"""Renders a sample page."""
return "Hello World!"

if __name__ == '__main__':
import os
HOST = os.environ.get('SERVER_HOST', 'localhost')
try:
PORT = int(os.environ.get('SERVER_PORT', '5555'))
except ValueError:
PORT = 5555
app.run(HOST, PORT)


The key line here is the declaration of the wsgi_app attribute which is picked up by wfastcgi. However when I try to insert this into the following code (manage.py for reference) and change it slightly to run with the test project settings

#!/usr/bin/env python
import os
from app import create_app, db
from app.models import User, Role
from flask.ext.script import Manager, Shell
from flask.ext.migrate import Migrate, MigrateCommand

app = create_app(os.getenv('FLASK_CONFIG') or 'default')
manager = Manager(app)
migrate = Migrate(app, db)


def make_shell_context():
return dict(app=app, db=db, User=User, Role=Role)
manager.add_command("shell", Shell(make_context=make_shell_context))
manager.add_command('db', MigrateCommand)


@manager.command
def test():
"""Run the unit tests."""
import unittest
tests = unittest.TestLoader().discover('tests')
unittest.TextTestRunner(verbosity=2).run(tests)

# Make the WSGI interface available at the top level so wfastcgi can get it.
wsgi_app = app.wsgi_app

if __name__ == '__main__':
HOST = os.environ.get('SERVER_HOST', 'localhost')
try:
PORT = int(os.environ.get('SERVER_PORT', '5555'))
except ValueError:
PORT = 5555
app.run(HOST, PORT)


I receive the following error when I try to run it inside of an Azure Emulator.

AttributeError: 'module' object has no attribute 'wsgi_app'


I suspect that I'm not putting the wsgi_app variable in the correct location but I can't figure out exactly where I should put it.

Any help would be greatly appreciative.

Answer

After a bit of troubling shooting I was able to find a solution to my problem but was unfortunately unable to isolate exactly what went wrong.

Basically I went through the process of rebuilding my test project from scratch in VS2015 (Python -> Azure Cloud Service -> Flask Web Role) and was somehow this time able to get a working solution using the 7a test project with it running in the Azure Emulator followed by successfully publishing it as an Azure Web App.

I believe my problem could have resulted from one of the following issues:

  • The requirements.txt file was most likely not up to date. Note that when you run the Azure Simulator it checks the requirements.txt file and updates/installs any libraries that you don't currently have installed in your python environment automatically (without a prompt).
  • I possibly didn't have the ConfigureCloudService.ps1 or ps.cmd file in the bin folder in the Flask Worker Role Project. (It's also worthwhile reading through the Readme.mht file if you run into any problems)
  • I also changed the base of the manage.py file to:

    if __name__ == '__main__':
        app.run()
    

Which may have helped as well.

I hope this helps out anyone else who may run into a similar issue.