AppEngine: Migrating from Python 2.5 to Python 2.7 on Google App Engine in simple steps
I tried moving an old app on Google App Engine from Python 2.5 to Python 2.7. Google Developers has provided a nice writeup, with all the prerequisites. However, being a noob, I found it rather difficult.
The first problem being, main.app. In Python 2.5, the script is named after the filename. If you have a file called main.py which you want to be called to handle certain urls, you put the script name as main.py, under handlers in app.yaml.
In the Python 2.7 runtime, app engine wants you to use the dot notation to call the appropriate "WSGI application object". So app.yaml has main.app instaed of main.py.
And by main.app, you are referring to the app attribute of main.py file(i.e the module called "main")
I did not understand this at first, and changed the line in app.yaml to main.app and changed the name of the file main.py to main.app
ImportError: No module named main
On running the application dev_appserver, I got the following error
So, I renamed main.app(the incorrectly named file) back to main.py.
ImportError: module 'main' has no attribute app
I changed the rest of the app as per the instructions on the Migrating to Python 2.7 tutorial. And I ran the app using dev_appserver.py. This time, I got a different error.
If you see the old application code below,
Structure of the application.
app.yaml
main.py
New application (using webapp)
Webapp is deprecated in Python 2.7 under Google App Engine. But, if you want to stick with webapp for some more time, you can do so.
app.yaml
main.py
New application (with webapp2)
app.yaml remains the same. In main.py, we do not have to import run_wsgi_app.
app.yaml
main.py
Note: In the new app.yaml, the script is referred to as
Instead of main.application, you can call the script as main.app or main.whatever. Simply use the same name for the application object in your script file. i.e If you use main.app in app.yaml, change the line in main.py accordingly as follows.
I don't have a main.py, where should I make the changes to migrate to Python 2.7?
Go to your app folder and open the app.yaml file. In this, you may already be specifying a file named main.py or whatever_name.py to handle certain urls. In Python 2.5, the text in app.yaml looked as follows
If instead of main.py you have the following text
Then you should open the file named helloworld.py and edit it instead.
Do comment, if you spot errors in the code.
tl;dr
1. Open app.yaml, change as given in New application above
2. Open script file(main.py), change as given in New application above
3. Done!
Sources:
Code adapted from the following sources
1. Using the webapp Framework - Google App Engine
2. Migrating to Python 2.7 - Google App Engine
The first problem being, main.app. In Python 2.5, the script is named after the filename. If you have a file called main.py which you want to be called to handle certain urls, you put the script name as main.py, under handlers in app.yaml.
In the Python 2.7 runtime, app engine wants you to use the dot notation to call the appropriate "WSGI application object". So app.yaml has main.app instaed of main.py.
handlers: - url: /.* script: main.app
And by main.app, you are referring to the app attribute of main.py file(i.e the module called "main")
I did not understand this at first, and changed the line in app.yaml to main.app and changed the name of the file main.py to main.app
ImportError: No module named main
On running the application dev_appserver, I got the following error
ERROR wsgi.py:219] Traceback (most recent call last): File "wsgi.py", line 196, in Handle handler = _config_handle.add_wsgi_middleware(self._LoadHandler()) File "wsgi.py", line 255, in _LoadHandler handler = __import__(path[0]) ImportError: No module named main
So, I renamed main.app(the incorrectly named file) back to main.py.
ImportError: module 'main' has no attribute app
I changed the rest of the app as per the instructions on the Migrating to Python 2.7 tutorial. And I ran the app using dev_appserver.py. This time, I got a different error.
ImportError: has no attribute app
If you see the old application code below,
application = webapp.WSGIApplication( [('/', MainPage)], debug=True)The application object is called application instead of app. So, you could either rename application in main.py to app or refer to main.application in your app.yaml file. The old and new files are given below.
Structure of the application.
appname-root-folder -main.py -app.yaml -...Old application
app.yaml
application: appname version: 1 runtime: python api_version: 1 handlers: - url: /.* script: main.py
main.py
from google.appengine.ext import webapp from google.appengine.ext.webapp.util import run_wsgi_app class MainPage(webapp.RequestHandler): def get(self): self.response.headers['Content-Type'] = 'text/plain' self.response.out.write('Hello, webapp World!') application = webapp.WSGIApplication( [('/', MainPage)], debug=True) def main(): run_wsgi_app(application) if __name__ == "__main__": main()
New application (using webapp)
Webapp is deprecated in Python 2.7 under Google App Engine. But, if you want to stick with webapp for some more time, you can do so.
app.yaml
application: appname version: 1 runtime: python27 api_version: 1 threadsafe: true handlers: - url: /.* script: main.application
main.py
from google.appengine.ext import webapp from google.appengine.ext.webapp.util import run_wsgi_app class MainPage(webapp.RequestHandler): def get(self): self.response.headers['Content-Type'] = 'text/plain' self.response.out.write('Hello, webapp World!') application = webapp.WSGIApplication( [('/', MainPage)], debug=True)
New application (with webapp2)
app.yaml remains the same. In main.py, we do not have to import run_wsgi_app.
app.yaml
application: appname version: 1 runtime: python27 api_version: 1 threadsafe: true handlers: - url: /.* script: main.application
main.py
import webapp2 class MainPage(webapp2.RequestHandler): def get(self): self.response.headers['Content-Type'] = 'text/plain' self.response.out.write('Hello, webapp World!') application = webapp2.WSGIApplication( [('/', MainPage)], debug=True)
Note: In the new app.yaml, the script is referred to as
...
handlers: - url: /.* script: main.application
...
Instead of main.application, you can call the script as main.app or main.whatever. Simply use the same name for the application object in your script file. i.e If you use main.app in app.yaml, change the line in main.py accordingly as follows.
... app = webapp2.WSGIApplication( [('/', MainPage)], debug=True) ...
I don't have a main.py, where should I make the changes to migrate to Python 2.7?
Go to your app folder and open the app.yaml file. In this, you may already be specifying a file named main.py or whatever_name.py to handle certain urls. In Python 2.5, the text in app.yaml looked as follows
handlers: - url: /.* script: main.py
If instead of main.py you have the following text
handlers: - url: /.* script: helloworld.py
Then you should open the file named helloworld.py and edit it instead.
Do comment, if you spot errors in the code.
tl;dr
1. Open app.yaml, change as given in New application above
2. Open script file(main.py), change as given in New application above
3. Done!
Sources:
Code adapted from the following sources
1. Using the webapp Framework - Google App Engine
2. Migrating to Python 2.7 - Google App Engine
thanks, it solved my problem.
ReplyDelete