[TangerineSDR] Production server for flask

Rob Wiesler robert.wiesler at case.edu
Sat Dec 14 19:11:21 EST 2019


On Sat, Dec 14, 2019 at 22:58:17 +0000, Engelke, Bill wrote:
> I have been using flask to show the web pages & control everything for
> TangerineSDR. It works great when using it from a browser running
> directly on the Odroid.
>
> However, there is a use case where the user might like to show these
> pages & control the system from his/her desktop.  For flask to work
> with any IP other than 127.0.0.1, it requires a production server,
> which in turn seems to require running in a virtual environment...
> some considerable complexity.  Typical example:
> https://www.digitalocean.com/community/tutorials/how-to-serve-flask-applications-with-uswgi-and-nginx-on-ubuntu-18-04
>
> ...here we see the need to install a variety of additional things,
> where we clearly need to minimize the number of packages &
> configurations.
>
> Do you (or anyone else on this email distribution) have any
> recommended course of action here?

The simple answer is to use Waitress as the web server, like the
tutorial I thought you were following recommends [0] (so I'm a little
confused by your question).  Just install the Debian/Ubuntu
"python3-waitress" package instead where it tells you to use pip, and
use your own package name instead of "flaskr".

[0] https://flask.palletsprojects.com/en/1.1.x/tutorial/deploy/#run-with-a-production-server

I went through a small subset of this tutorial very quickly to make sure
my instructions were correct.  If you have any problems, please share
your code with me (via a git repo hosted somewhere).  Here's my simple
layout:

	.
	├── README
	└── tangerinesdr
	    ├── __init__.py
	    └── webapp
	        └── __init__.py

tangerinesdr/__init__.py is empty.
tangerinesdr/webapp/__init__.py is the simple Hello World file from very
early in the tutorial:

	from flask import Flask
	
	app = Flask(__name__)
	
	@app.route('/')
	def hello_world():
		return "Hello, world!"

>From the directory in which the tree above is rooted, I can serve this
with the following command:

	sudo waitress-serve --port=80 --url-scheme=http tangerinesdr.webapp:app

Later steps in the tutorial tell you to create a `create_app' function
instead of leaving a bare Flask app instance at the global level (which
is not reentrant).  Here's tangerinesdr/webapp/__init__.py with that
change:

	from flask import Flask
	from os import makedirs

	def create_app(test_config=None):
		# create and configure the app
		app = Flask(__name__, instance_relative_config=True)
		app.config.from_mapping(
			SECRET_KEY='dev',
			DATABASE='/'.join((app.instance_path, 'tangerinesdr.webapp.sqlite'))
		)

		if test_config is None:
			# load the instance config, if it exists, when not testing
			app.config.from_pyfile('config.py', silent=True)
		else:
			# load the test config if passed in
			app.config.from_mapping(test_config)

		# ensure the instance folder exists
		try:
			makedirs(app.instance_path)
		except OSError:
			pass

		# a simple page that says hello
		@app.route('/')
		def hello():
			return "Hello, World!"

		return app

In this case, create_app is now a function that creates a Flask app
instance, so you have to tell Waitress to call it instead of treating it
as an app directly:

	sudo waitress-serve --port=80 --url-scheme=http --call tangerinesdr.webapp:create_app

Of course, you'll want to do the other things the tutorial says to do
before production.  In particular, the SECRET_KEY needs to be set
correctly, which I have not done.



More information about the TangerineSDR mailing list