Python2 to Python3 on App Engine

With Python 2.7 at end of life, my hosting on Google App Engine (GAE) needs to migrate. This is not trivial:

  • webapp2 is replaced with WSGI.
  • The local development server is gone.
  • No more free caching.
  • All String database fields are indexed now.
  • Database image support is gone.

For me, the caching is of particular concern, because I was relying on that to smooth out db access. Hitting the db is fine, but if it happens a lot repeatedly, server side caching is what prevents exceeding db quotas. My reason for hosting on GAE was to put a free app out there, grow it past demo level with a handful of users, then get funding when the model is proved. Having the app already deployed on world class scalable infrastructure with zero technical impediments to growth was a selling point. Now it’s looking increasingly like it might not be worth it.

Porting a simple app

To check out the porting process, I converted a simple Python 2.7 webapp2 back-end with no database. Redoing my 4 API endpoints to Python 3.7 WSGI using the Flask framework was fairly painless, and an improvement. Running it locally was also not too hard, but it took me a few days to accept the idea that what I would be running locally would be completely separate from what I was running on GAE. I finally bit the bullet and installed nginx and gunicorn, connecting them and setting up the config to emulate my app.yaml declarations.

The general approach of moving utilities out of GAE in favor of standard Python modules makes a lot of sense, but is not always smooth. For example, moving from google.appengine.api urlfetch to urllib is straightforward, but a connection that had been working smoothly for years suddenly stopped because the default User-Agent: Python-urllib/3.7 appears to be persona non grata most places on the web. Of course where you are calling from can also make a difference, so this is always a question, but it’s indicative of the danger of equivalence assumptions for libraries when converting code.

Aside from that annoying issue, migrating my site was smooth, the code ended up a lot cleaner, and the result generally inspired confidence. If your database needs are minimal to non-existant, GAE is a solid option.

Porting with data

My other apps that I need to port store data. Most of the modules base their data access on google.appengine.ext db.Model, while making significant use of google.appengine.api for both images and memcache. I need to jump forward all the way to cloud NDB, and probably convert my existing data. I will need some other way to deal with images. I will need to write a cache interface to preserve all the time invested in logically solid server side caching, while not actually caching anything anymore. Then hope everything works without blowing quota in short order.

Daunting.

Given the magnitude of changes, I think my path forward is to migrate everything to an alternative host, leaving the existing site alone until the new one is ready. After switching, I can explore switching back.

Conclusions

When I first started this conversion process, it took me a while to find out what the path was going to be, and what changes affect viability. I put the summary list together in case it helps anyone else in a similar position.

When porting, I’m going to try factor my data handling so it only makes use of the highly constrained access provided by app engine. I’d like the option to move back, if the platform is viable.

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out /  Change )

Google photo

You are commenting using your Google account. Log Out /  Change )

Twitter picture

You are commenting using your Twitter account. Log Out /  Change )

Facebook photo

You are commenting using your Facebook account. Log Out /  Change )

Connecting to %s


%d bloggers like this: