I'm learning developing in Google App Engine.
This is one of the code from the tutorial, http://code.google.com/appengine/docs/python/gettingstarted/usingwebapp.html
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()
I've almost identical code. I sometime get warning:
WARNING 2011-06-30 13:10:44,443 init.py:851] You are using the default Django version (0.96). The default Django version will change in an App Engine release in the near future. Please call use_library() to explicitly select a Django version. For more information see http://code.google.com/appengine/docs/python/tools/libraries.html#Django
Can anyone please re factor the above code with use_library(). I'm not sure how to start and where to use use_library and what to do with webapp.
Thanks in advance.
The above code should not require you to call use_library directly.
If you create a new file in the root directory of your application named appengine_config.py and add the following line to it:
# Make webapp.template use django 1.2
webapp_django_version = '1.2'
try putting this code on top of your module :
import os
from google.appengine.dist import use_library
use_library('django', '1.2')
In the current version this is even simpler as third-party libraries are now specified in app.yaml
libraries:
- name: django
version: "1.2"
You can also use webapp2 that includes Django’s templating engine.
import webapp2
from google.appengine.ext.webapp2 import template
Related
I downloaded the experimental version of PyCrypto (pycrypto-2.7a1.tar.gz). I have copied the "Crypto" directory (extracted from pycrypto-2.7a1.tar.gz) to my project folder.
In app.yaml file:
libraries:
- name: pycrypto
version: 2.7 # latest
I get error (at the time of deployment) if I try to give version as 2.7a1 or 2.7 for PyCrypto in app.yaml:
appcfg.py: error: Error parsing C:\gaurav\coding\python\x\x\app.yaml: pycrypto version "2.7" is not supported, use one of: "2.3", "2.6" or "latest" ("latest" recommended for development only)
in "C:\gaurav\coding\python\x\x\app.yaml", line 73, column 1.
How do I provide the correct PyCrypto version in app.yaml ?
You use the app.yaml file to tell App Engine which libraries and versions you want to use only for those Third-party libraries available at the platform.
In your case, you want to use a version of the library that is not available, so you can't use that method to configure it.
Instead of that, you can upload to App Engine the libraries you want to use by following the method outlined in this other question:
To download the library and unzipped inside your GAE application directory. In this example, the destination directory is called pycrypto26.
To include the path to that library with something like
import sys
import os
sys.path.insert(0, os.path.join(os.path.dirname(__file__), 'pycrypto26/lib'))
To import the relevant modules
import Crypto
from Crypto.Hash import SHA256, SHA512
A full working example is
import webapp2
import logging
import sys
import os
sys.path.insert(0, os.path.join(os.path.dirname(__file__), 'pycrypto26/lib'))
import Crypto
from Crypto.Hash import SHA256, SHA512
class MainPage(webapp2.RequestHandler):
def get(self):
logging.info("Running PyCrypto with version %s" % Crypto.__version__)
self.response.write('<html><body>')
self.response.write( SHA256.new('abcd').hexdigest() + "<br>" )
self.response.write( SHA512.new('abcd').hexdigest() + "<br>")
self.response.write('</body></html>')
application = webapp2.WSGIApplication([
('/', MainPage),
], debug=True)
I use the following code to use webapp2
import webapp2
from webapp2_extras import i18n, jinja2
class Test(webapp2.RequestHandler):
#webapp2.cached_property
def jinja2(self):
# Returns a Jinja2 renderer cached in the app registry.
return jinja2.get_jinja2(app=self.app)
def render(self, _template, **context):
# Renders a template and writes the result to the response.
rv = self.jinja2.render_template(_template, **context)
self.response.write(rv)
def get(self):
self.render('index2.html')
app = webapp2.WSGIApplication([('/',Test)], debug=False)
app.run()
To be simple, we just make index2.html is full of 1000 test
If you run it, you will find that the Google App Engine Launcher log windows is full of test.
It's rather terrible when you are debugging a real website.
But I find that if index2.html contains just few words like 10 test. The test will not appear in logging window.
Any solution?
It looks like you are running two separate instances of your application.
The first is running through the development server, the second is actually running and outputting to the terminal. You can see this by adding a log output to your application. You can see that when you go to your site, the log is written two twice.
You can fix this by removing the line:
app.run()
This is not necessary when running on App Engine. Your app.yaml file references the app directly:
handlers:
- url: .*
script: guestbook.app # Notice the .app here.
I'm trying to run the following test ile
from google import appengine
from google.appengine.ext import testbed
from google.appengine.ext import ndb
import unittest
import passwordproperty
class MyTestCase(unittest.TestCase):
def setUp(self):
self.tb = testbed.Testbed()
self.tb.setup_env()
self.tb.activate()
self.tb.init_datastore_v3_stub()
def tearDown(self):
self.tb.deactivate()
... tests ...
if __name__ == '__main__':
unittest.main()
But when I try to run this file, I get the following error:
google.appengine.tools.devappserver2.wsgi_server.BindError: Unable to bind localhost:8080
So it looked like something was almready using port 8080, so I ran lsof -i :8080, which came up empty, and navigating to localhost without a port also doesn't give me anything. What's going on?
In the run/debug configuration create project of "python tests" and set the values like working directory , class (class name of the test class) and it will work
can anyone tell me please the difference between these two code snippets:
1.
import webapp2
from google.appengine.api import users
class MainPage(webapp2.RequestHandler):
def get(self):
user = users.get_current_user()
if user:
self.response.headers['Content-Type'] = 'text/plain'
self.response.out.write('Hello, ' + user.nickname())
else:
self.redirect(users.create_login_url(self.request.uri))
app = webapp2.WSGIApplication([('/', MainPage)],
debug=True)
2.
import webapp2
from google.appengine.api import users
class MainPage(webapp2.RequestHandler):
def get(self):
user = users.get_current_user()
if user:
self.response.headers['Content-Type'] = 'text/plain'
self.response.out.write('Hello, ' + user.nickname())
else:
self.redirect(users.create_login_url(self.request.uri))
app = webapp2.WSGIApplication([('/', MainPage)],
debug=True)
The thing is that i'm trying to go over Google AppEngine introduction material and whenever i try to type the code myself, something's different and it doesn't work. And whenever i just copy it from their website, it works, although it looks identical.
Checked the coding in the View panel, it's same, ANSI (i'm using Notepad++).
Tried to play with indentation as well and it didn't made any difference.
Any comments would be appreciated.
Thank you.
You should always start your Pyhton code with these 3 lines:
#!/usr/bin/python
# -*- coding: utf-8 -*-
from __future__ import unicode_literals
And your editor should encode in utf-8. Do not use ANSI.
The last line is optional, but I recommend it, to stay away from encoding problems. There are a few exceptions. So if you use unicode literals, you have to change the line with the headers:
import webapp2
from google.appengine.api import users
class MainPage(webapp2.RequestHandler):
def get(self):
user = users.get_current_user()
if user:
self.response.headers['Content-Type'.encode()] = 'text/plain'.encode()
self.response.out.write('Hello, ' + user.nickname())
else:
self.redirect(users.create_login_url(self.request.uri))
app = webapp2.WSGIApplication([('/', MainPage)],
debug=True)
And your app.yaml should look like:
application: helloworld
version: 1
runtime: python27
api_version: 1
threadsafe: false
handlers:
- url: /.*
script: helloworld.app
libraries:
- name: webapp2
version: latest
But Notepad++ is not a good development environment for app engine. You need a good Python IDE. I recommend Eclipse with PyDev. To setup, use this totorial see this question: Debug google app engine project line by line
And if you are a total newbie? go to this great web development course using google app engine : http://www.udacity.com/overview/Course/cs253/CourseRev/apr2012
Found a problem, it was indentation thing.
You can read about this here and here
There's difference whether you are using "space" or "tab" to indent and it can cause problems,
also problems can occur from settings in your program (in my case in Sublime Text's setting of "Tab" indent,it can be set to 4 or 8 etc.)
This is my app.yaml:
- url: /about|/about/.*
script: about.py
This is my `about.py':
application = webapp.WSGIApplication([(r'^/about$', AboutPage),
(r'^/about/$', Redirect),
(r'.*', ErrorPage)],
debug = True)
I want to redirect all requests for /about/ to /about. I'd like all other requests to be sent to the error page.
It works in the development server on localhost, but I cannot access /about/ after I deployed the app on GAE - it just shows an empty page.
I adjusted the order of URL patterns in app.yaml.
It works now on GAE.
If you don't want trailing slashes for GET requests anywhere in your application, you can implement a global redirect at the top of your app.yaml. Note that POST requests will NOT redirect, but this is ok (for me anyway) because users don't generally hand-write POST URLs.
app.yaml:
application: whatever
version: 1
api_version: 1
runtime: python
handlers:
- url: .+/
script: slashmurderer.py
slashmurderer.py
from google.appengine.ext import webapp
from google.appengine.ext.webapp.util import run_wsgi_app
class SlashMurdererApp(webapp.RequestHandler):
def get(self, url):
self.redirect(url)
application = webapp.WSGIApplication(
[('(.*)/$', SlashMurdererApp)]
)
def main():
run_wsgi_app(application)
I see that this question has already been answered, but I ran into the same problem and wanted to see if there was a "lazier" solution.
If you're using the Python 2.7 runtime, then the webapp2 library is available, and I believe the following will work:
import webapp2
from webapp2_extras.routes import Redirect Route
class MainHandler(webapp2.RequestHandler):
def get(self):
self.response.out.write("This is my first StackOverflow post")
app = webapp2.WSGIApplication([
RedirectRoute('/', MainHandler, name='main', strict_slash=True),
('/someurl', OtherHandler),
])
strict_slash=True means that if the client doesn't supply the slash it will be redirected to the url with the slash (to match the first argument).
You can combine the special Route classes from webapp2_extras with normal (regex, handler) tuples as shown above. The "name" parameter is required for the constructor for RedirectRoute. More details here: webapp2_extras documentation for RedirectRoute