multiple file handlers in google app engine - google-app-engine

I want to have multiple pages in google-app engine (python 2.7) and the followoing is my directory structure:
root contains: pujaweb.py (the main script), index.html, stylesheets(folder), port(folder)...
now my second script for the page is in the port folder and i want to configure my index.html such that it links to that page. I have tried a lot of stuff but somehow it does not work and always shows 404 page not found error and the command line says that PujaPort module does not exist (pujaport being the app handler for the second page).
the following is my app.yaml file code:
application: thepujabhalerao
version: 1
runtime: python27
api_version: 1
threadsafe: true
handlers:
- url: /images
static_dir: images
- url: /stylesheets
static_dir: stylesheets
- url: /port
script: pujaport.app
- url: /.*
script: pujaweb.app
libraries:
- name: jinja2
version: latest
this is my main handler (pujaweb.py)
import cgi
import webapp2
import jinja2
import os
from google.appengine.api import xmpp
from google.appengine.ext import db
jinja_environment = jinja2.Environment(
loader=jinja2.FileSystemLoader(os.path.dirname(__file__)))
class MainPage(webapp2.RequestHandler):
def get(self):
template_values = {}
template = jinja_environment.get_template('index.html')
self.response.out.write(template.render(template_values))
app = webapp2.WSGIApplication([('/', MainPage)],
debug=True)
and the href in the index filer looks like this:
P
and finally this is the second page handler pujaport.py:
import cgi
import webapp2
import jinja2
import os
from google.appengine.api import xmpp
from google.appengine.ext import db
jinja_environment = jinja2.Environment(
loader=jinja2.FileSystemLoader(os.path.dirname(__file__)))
class PujaPort(webapp2.RequestHandler):
def get(self):
self.response.out.write("In handler")
app = webapp2.WSGIApplication([('/port', PujaPort)],
debug=True)
I know its a minor glitch somewhere but please help me out as after being on it for too long i maybe missing the obvious.

If you insist on using that folder structure, you'll need to make the port directory into a package by adding an __init__.py file to it (which can be empty), and reference the app as port.pujaport.app, its fully qualified name.

Related

Google App Engine - Flask Application Bypassing Standard Google Auth on Devserver

I am new to Flask and I am trying to organize my code as a large application for deployment on Google App Engine. I am using Flask-Classy to help organize my application into logical packages.
The application runs on the dev server just fine with one exception. When I set login: required or login: admin in my app.yaml (see app.yaml below), the application appears to skip over the mock Google Login page and automatically signs in as 'test#example.com'.
Normally, I would expect to see the standard Google mock authentication form (below) when login:required or login: admin is set in the app.yaml. However, when I point the browser to the '/' or any other uri, I am directed right to the respective page without authenticating via this form.
I am not sure what I am missing/doing wrong. I am not getting any type of errors.
Below, I have included my application's structure and most of the pertinent code to see if anyone might be able to point out anything I am doing wrong here.
/flask_app
/flask_app
/mod_one
/__init__.py
/forms.py
/views.py
/models.py
/mod_two
/__init__.py
/forms.py
/views.py
/models.py
/static
/css
...
/templates
/index.html
...
/__init__.py
/settings.py
/urls.py
/lib
/app.yaml
/appengine_config.py
/main.py
app.yaml
application: flask-app
version: 1
runtime: python27
api_version: 1
threadsafe: yes
default_expiration: "30d"
builtins:
- deferred: on
- admin_redirect: on
handlers:
- url: /css
static_dir: flask_app/static/css
- url: /admin/.*
script: main.app
login: admin
- url: /.*
script: main.app
login: required
appengine_config.py
import sys
import os.path
sys.path.insert(0, os.path.join(os.path.dirname(__file__), 'lib'))
main.py
from flask_app import app
app = app
flask_app/init.py
import os
from flask import Flask
from flask_bootstrap import Bootstrap
from werkzeug.debug import DebuggedApplication
app = Flask(__name__)
if os.getenv('FLASK_CONF') == 'TEST':
app.config.from_object('flask_app.settings.Testing')
elif 'SERVER_SOFTWARE' in os.environ and os.environ['SERVER_SOFTWARE'].startswith('Dev'):
# Development settings
app.config.from_object('flask_app.settings.Development')
app.wsgi_app = DebuggedApplication(app.wsgi_app, evalex=True)
else:
app.config.from_object('flask_app.settings.Production')
# Instantiate Flask-Bootstrap.
Bootstrap(app)
import urls
flask_app/urls.py
from flask import render_template
from flask_app import app
#app.route('/')
def index():
params = {
'page_title': 'Home'
}
return render_template('index.html', **params)
#app.route('/contact')
def contact():
params = {
'page_title': 'Contact'
}
return render_template('contact.html', **params)
#app.route('/about')
def about():
params = {
'page_title': 'About'
}
return render_template('about.html', **params)
# Error handlers
# Handle 404 errors
#app.errorhandler(404)
def page_not_found(e):
return render_template('404.html'), 404
# Handle 500 errors
#app.errorhandler(500)
def server_error(e):
return render_template('500.html'), 500
# Register Flask Classy Classes
import mod_one.views as mod_one
import mod_two.views as mod_two
mod_one.OneView.register(app)
mod_two.TwoView.register(app)
As #Greg pointed out in a comment to the question, I was already 'logged in' to the dev_appserver (which threw me off since I never saw the mock login page) so authentication was happening using the default 'test#example.com' user.
Once I went to /_ah/login I was able to access the mock login page and proceed as usual from there.

Using Google App Engine how do I open an html page?

Using Google App Engine I hope to learn some very basic knowledge with this question. I want to be able to open an index.html page that is placed in a folder when I open the application.
I generated a new application using 'Google App Engine Launcher'
I slightly modified the app.yaml and it now looks like the following...
application: helloworld
version: 1
runtime: python27
api_version: 1
threadsafe: yes
handlers:
- url: /favicon\.ico
static_files: favicon.ico
upload: favicon\.ico
- url: /templates
static_dir: templates
- url: .*
script: main.app
libraries:
- name: webapp2
version: "2.5.2"
I also have a added a directory called 'templates'.
In the directory I placed a file called 'index.html'.
<html>
<header><title>This is title</title></header>
<body>
Hello world cls
</body>
</html>
My main.py hasn't been modified so it looks like
#!/usr/bin/env python
#
import webapp2
class MainHandler(webapp2.RequestHandler):
def get(self):
self.response.write('Hello world!')
app = webapp2.WSGIApplication([
('/', MainHandler)
], debug=True)
Any ideas on what I need to do or change to find success?
Regards,
Chris
>
My code has changed in a big way because of a comment from Gwyn
I now have the standard Django template code from link (https://console.developers.google.com/start/appengine)
Gwyn eventually the index.html file will be something a little more than a static page so a direct URL that you described won't work. You did teach me though and that will come in handy as I progress. I want to bring in some Polymer code once I get the basics figured out here...
So if anyone can help me feed up a hello world from within a 'templates' folder using an index.html page from a standard django codeset generated from the Google Developers Console then your answer would be very much appreciated here.
Regards,
Chris
First, to use HTML, do you need a template engine, in app engine you can use this EZT, Cheetah, ClearSilver, Quixote, Django, and Jinja2 but for simplicity, you can modify your code to send the html directly
import webapp2
class MainPage(webapp2.RequestHandler):
def get(self):
self.response.headers['Content-Type'] = 'text/plain'
self.response.write('<html><header><title>This is title</title></header><body>Hello world cls</body></html>')
application = webapp2.WSGIApplication([
('/', MainPage),
], debug=True)
But as Gwyn Howell says, for more complicated stuff you must use a template engine
I wanted to update this so if anyone else is struggling they may find success also...
I want to thank both of Gwyn Howell and Kristian Damian. I used both of your comments to come up with an answer for anyone else that has the same question.
I went to clarify that I am using the downloaded Python SDK for Google App Engine
I made a sample python project using File|Create New Application - Python 2.7
I ran the project to make sure it was working without any of my changes
I then decided I would use 'Jinja2' for my template engine
I made a 'templates' folder and placed my 'about_v2.html' file in it
I modified the 'app.yaml' code to read
application: helloworld
version: 2
runtime: python27
api_version: 1
threadsafe: yes
handlers:
- url: /favicon\.ico
static_files: favicon.ico
upload: favicon\.ico
- url: .*
script: main.app
libraries:
- name: webapp2
version: latest
- name: jinja2
version: latest
I modified the 'main.py' code to read
import os
import webapp2
import jinja2
env = jinja2.Environment(
loader=jinja2.FileSystemLoader(os.path.join(os.path.dirname(__file__),
'templates')))
class MainHandler(webapp2.RequestHandler):
def get(self):
self.response.write('Hello world! About.<br />')
class AboutPage_v2(webapp2.RequestHandler):
def get(self):
template_values = {
}
template = env.get_template('about_v2.html')
self.response.out.write(template.render(template_values))
app = webapp2.WSGIApplication([
('/', MainHandler),
('/about_v2.html', AboutPage_v2)],
debug=True)
I then ran the project on my local machine and was able to get to the url
I hope this answer helps someone else.

Google App Engine import NLTK error

I am trying to import NLTK library in Google App Engine it gives error, I created another module "testx.py" and this module works without error but I dont know why NLTK does not work.
My code
nltk_test.py
import webapp2
import path_changer
import testx
import nltk
class MainPage(webapp2.RequestHandler):
def get(self):
#self.response.headers['Content-Type'] = 'text/plain'
self.response.write("TEST")
class nltkTestPage(webapp2.RequestHandler):
def get(self):
text = nltk.word_tokenize("And now for something completely different")
self.response.write(testx.test("Hellooooo"))
application = webapp2.WSGIApplication([
('/', MainPage), ('/nltk', nltkTestPage),
], debug=True)
testx.py code
def test(txt):
return len(txt)
path_changer.py code
import os
import sys
sys.path.insert(0, os.path.join(os.path.dirname(__file__), 'nltk'))
sys.path.insert(1, os.path.join(os.path.dirname(__file__), 'new'))
app.yaml
application: nltkforappengine
version: 0-1
runtime: python27
api_version: 1
threadsafe: true
handlers:
- url: /.*
script: nltk_test.application
- url: /nltk.*
script: nltk_test.application
libraries:
- name: numpy
version: "1.6.1"
This code works fine When I comment the import nltk and nltk related code, I think NLTK is not imported, please help me to sort out this problem, thanks
Where do you have nltk installed?
GAE libraries need to be available in your app folder. If you have nltk elsewhere in your pythonpath it won't work.

Google AppEngine Tutorial, difference between code snippets

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.)

URL with trailing slash in Google App Engine

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

Resources