WESLEY CHUN: Well, welcome back to "Serverless Migration
Station," where we show Google Cloud
users one specific migration they
can take to modernize their apps.
This is the video for module 1, focusing
on helping App Engine users to switch from webapp2 to Flask,
a popular web framework in the Python community.
Doing so opens the door to additional modernization
techniques.
Hi.
I'm Wesley from Google here to lead your journey, joined
by my colleague, Martin, and our little friend, Porter,
who will take you from point A to point B.
MARTIN OMANDER: Hey, Wes.
Happy to help.
But why are we focusing on webapp2?
I thought App Engine supported many web frameworks.
WESLEY CHUN: Yes, that is absolutely true, Martin.
While users can use other frameworks with App Engine,
webapp2 comes bundled with App Engine,
making it the default choice for many developers,
and unfortunately, not supported in Python 3.
By the way, if you've been using a framework that's not webapp,
you may actually be in better shape.
App Engine is now a more flexible platform.
So moving away from bundled services, like webapp2,
will make users' apps more portable.
Also, Flask has more users, it has more resources,
and is better supported.
Flask isn't the only option.
And generally, any WSGI-compliant framework
that does routing is supported.
MARTIN OMANDER: OK, so I get it for the web framework.
But what about all those App Engine bundled service APIs?
WESLEY CHUN: Well, have you heard of Cloud Datastore
and Cloud Tasks?
Well, they started out as App Engine Datastore and Task
Queues.
And since then, they've matured to becoming
their own standalone cloud products
where you'll find continuing new features and innovation.
We'll tackle those in other migration modules,
but this one focuses just on Flask.
MARTIN OMANDER: All right.
You said we're going to migrate a sample app to Flask.
What app?
WESLEY CHUN: Well, in the module 0 video,
we gave an overview of the baseline
app we're starting from.
So check it out if you missed it.
MARTIN OMANDER: OK, I'd like to follow what you're doing
to the code on my own computer.
Can you point me to the source code?
WESLEY CHUN: Sure thing, Martin.
Here's the link.
And by the way, the repo is maintained regularly,
unlike videos, so the code may be newer there.
Let's pause so all of you can go clone the repo
or download the zip file.
Got it?
Great.
Let's go to the computer now and start
migrating that module 0 code and turn it into the module 1 code.
Let's start from a good place.
Grab the module 0 code from the repo and deploy to App Engine.
If you've been around, you're probably
expecting to do an appcfg update.
There's a newer and more powerful CLI called gcloud
that comes with the Cloud SDK.
It gives you access to most Cloud tools,
instead of just one.
So to upload to App Engine, use gcloud app deploy.
What doesn't change is that your app
should be deployed and available around the world in less
than a minute.
Starting with the application file,
main.py, swap the Flask imports for webapp2s.
Next, while webapp2 is initialized
at the bottom with its routing table,
you can do it at the top with Flask.
Your app is more complex, but these basic changes
apply regardless.
Next, this app only has one route,
which goes to MainHandler.
Since we already know this, you can wipe the table.
But when migrating your app, don't delete it quite yet.
You'll probably have many more routes,
which you need to track.
So just comment it out for now once you get to this point.
There's no change to the way we access Datastore.
The data model and accompanying read/write calls stay as-is.
The handler represents the majority of the affected code.
webapp2 uses the handler classes and corresponding HTTP methods.
In Flask, a handler is just a route-decorated function,
like this.
Finally, both frameworks render the template in a similar way,
so you just switch to how Flask does it.
With that, you're done migrating the main application.
For this migration, app.yaml stays the same.
The index.html template file is identical to the original
with one minor, but notable, difference.
The Django-style templates that webapp2 uses automatically
executes callables, whereas the Jinja2 templating
system that Flask uses by default
requires users to explicitly add parentheses.
The datetime.ctime() call turns timestamps into human-readable
strings, and that's used in this app to show when visits
occurred.
Flask also organizes web templates in a templates folder
by default, so create it and move index.html into it before
or after your edit to the ctime() call.
Since Flask isn't bundled like webapp2,
you must add it to a list of required packages.
The base [INAUDIBLE] app didn't have any, so
create a brand new requirements.txt
file with just Flask.
If you're unfamiliar with the requirements.txt file,
check out its documentation.
For us, the current version is 1.12.
For a simple app, you probably don't need the version.
But in any case, the repo is maintained
while this video isn't, meaning you
may see a newer version there.
First-gen App Engine runtimes required developers
to explicitly bundle third-party packages.
For our app, it's Flask and its dependencies.
So run this pip install command to install them
to the lib folder before you test or deploy.
A side effect of bundling third-party packages
is that you need to tell App Engine where to find them.
So that's what appengine_config.py is
for, to tell the system to look in lib.
For your apps, you'll create this file in the same folder
as your application code, just like what
we've done with this sample.
The only other files in the repo are a README and .gcloudignore,
neither of which are critical.
But .gcloudignore is useful in preventing unnecessary files
to be uploaded.
And that's it.
MARTIN OMANDER: Hey, Wes, thanks for showing us
how to move to Flask.
Watching this video is great.
But is there a way for me to do that migration by hand,
on my own time, on that sample app
before migrating my own code?
WESLEY CHUN: Well, I'm glad you asked, Martin.
Yes.
In addition to this video, we have a corresponding Google
codelab.
Codelabs are free, online, self-paced, hands-on tutorials,
so you can do this same migration on your own time.
The repo links you to the codelab, the starting
module 0 code, as well as the finished module 1 code.
If you get stuck, you can always go back
to module 0 or compare your solution
to module 1 to see where you may have gotten off-course.
For your convenience, here are the docs
to both frameworks so that you can compare, and contrast,
and better understand the differences between them.
MARTIN OMANDER: Now that you've shown us
how to unlink part of our app from dedicated App Engine
libraries, like webapp2 framework, what's next, Wes?
WESLEY CHUN: Well the module 0 app used both webapp2
and the NDB library to talk to Datastore.
Now that we're done with the framework part,
we're going to be focused on moving from NDB to Cloud NDB,
so be sure to join us for that.
This is Wesley from Google Cloud on behalf of Martin and Porter.
Thanks for tuning in today, and we look forward to seeing you
at the next "Serverless Migration Station,"
as well as on other serverless expeditions.