The context here is a kind of "resource pump" webapp, a common enough migration of early static web sites, during the mid-web-2.0-era (say 2008), to Python 2 with WSGI on Google App Engine. The simple python program does very little, allowing the app.yaml file to define the work, serving folders full of static files.
So, how do we move these sites to App Engine with Python 3.8 and Flask 2?
Here's an ordered checklist, that is, a set of instructions with ordered dependencies.
That's also typical of unfolding sequences in software, but in the latter, there tends to be more creativity and judgment involved ... and the steps are not instructions ... instead they're helpful issues to consider at that moment.
Most of the steps below simply need to happen, in that order. So they are instructions.
There's only one somewhat creative step here (5) ... yet it highlights the point where more steps might be written and inserted, to serve a wider range of migrations.
I assume this is a directory with git source control.
If so:
git commit -a -m 'starting migration from python 2.7'
If not:
git init
git add app.yaml
git commit -a -m 'starting source control'
mkdir templates
mv index.html templates
and git add templates/index.html
add requirements.txt
and git add requirements.txt
add main.py (if there's a route table in the WSGI version, move the routes to flask. This is the one creative task. It's kind of a stub: this is where all the creative tasks in a sequence would go, to serve a greater range of programs.)
and git add main.py
change the app.yaml head
change the app.yaml tail
and git commit -m 'first python 3.8 changes'
(if it makes sense, set up the local test environment)
(if it makes sense, run gunicorn & test) Note that gunicorn does not use app.yaml, so your mileage may vary, in using this local test environment. If you don't need to debug the server-side python, see deployment test steps 12-14
(if you created a virtual environment, add the <project env> directory (see below) to .gcloudignore)
gcloud app deploy --project <migrating site> --no-promote
Go to (cloud console->app engine -> versions), find the new version, launch and test
Is the test good? Select the new version and click “migrate traffic”.
If you want to setup a local test environment (again, useful if there's more server code to test):
virtualenv -p python3.8.2 <project env>
source ./<project env>/bin/activate
pip install -r requirements.txt
(or
pip install gunicorn
pip install flask
pip install google-cloud-datastore
pip list
)
gunicorn -b :8080 main:app
(test in browser at localhost:8080)
^c
deactivate
old app.yaml head:
runtime: python27
api_version: 1
threadsafe: false
new app.yaml head:
runtime: python38
app_engine_apis: true
old app.yaml tail:
- url: /.*
script: <migrating site>.app
secure: always
redirect_http_response_code: 301
new app.yaml tail:
- url: /.*
script: auto
secure: always
redirect_http_response_code: 301
new requirements.txt:
Flask==2.2.2
google-cloud-datastore==2.7.0
appengine-python-standard>=1.0.0
google-auth==2.17.1
google-auth-oauthlib==1.0.0
google-auth-httplib2==0.1.0
werkzeug==2.2.2
And here's the one creative step in this checklist's sequence: migrating the route table. It's only a stub for further creative-and-judged unfolding steps, if one is migrating server-side application logic:
new main.py:
from flask import Flask, render_template, request
app = Flask(__name__)
@app.route('/')
@app.route('/endpoin_one')
@app.route('/endpoint_two')
def root():
# NB: index.html must be in /templates
return render_template('index.html')
if __name__ == '__main__':
app.run()
old <migrating site>.py:
# universal index.html delivery
# in python27 as a service
# on Google App Engine
import cgi
import os
import webapp2
from google.appengine.ext.webapp import template
from google.appengine.api import users
class MainPage(webapp2.RequestHandler):
def get(self):
template_values = {
}
path = os.path.join(os.path.dirname(__file__), 'index.html')
self.response.out.write(template.render(path, template_values))
app = webapp2.WSGIApplication(
[('/', MainPage)
,('/endpoint_one',MainPage)
,('/endpoint_two',MainPage)
],
debug=True)
No comments:
Post a Comment