Using GAE Webapp2 with classes in more than one file - python

I'm having problems with Webapp2. When I put handlers for URLs that point to different python files in the app.yaml I get the following error:
ERROR 2012-10-06 16:44:57,759 wsgi.py:203]
Traceback (most recent call last):
File "/Applications/GoogleAppEngineLauncher.app/Contents/Resources/GoogleAppEngine-default.bundle/Contents/Resources/google_appengine/google/appengine/runtime/wsgi.py", line 195, in Handle
handler = _config_handle.add_wsgi_middleware(self._LoadHandler())
File "/Applications/GoogleAppEngineLauncher.app/Contents/Resources/GoogleAppEngine-default.bundle/Contents/Resources/google_appengine/google/appengine/runtime/wsgi.py", line 250, in _LoadHandler
__import__(cumulative_path)
ImportError: No module named application
My app.yaml:
application: [[app's name]]
version: 1
runtime: python27
api_version: 1
threadsafe: yes
inbound_services:
- mail
handlers:
- url: /send
script: email.application
- url: /_ah/mail/update#sitdown-standup.appspotmail.com.*
script: email.application
- url: /.*
script: SDSUmodels.application
libraries:
- name: webapp2
version: "2.5.1"
SDSUmodels.py ends with:
application = webapp2.WSGIApplication([('/info', MakeBasicInfo)],
debug=True)`
and email.py ends with:
application = webapp2.WSGIApplication([('/request', Request_update),
('/send', Send_report),
(Receive_email.mapping())],
debug=True)`
When I remove these lines
- url: /send
script: email.application
from app.yaml, the error stops, but this leaves me without a way to point a URL towards a particular file.
I can see some alternative ways of handling this in this question but I was wondering why this approach isn't working. I've done this previously with the old webapp version in a different project and it's worked – details below.
app.yaml:
application: [[other app's name]]
version: 1
runtime: python
api_version: 1
handlers:
- url: /stylesheets
static_dir: stylesheets
- url: /twitter
script: twitter.py
- url: /_ah/mail/kindle#shelvdtracker.appspotmail.com.*
script: kindle.py
- url: /.*
script: web.py
inbound_services:
- mail
twitter.py ends with:
application = webapp.WSGIApplication(
[('/twitter', Process_new_DM)],
debug=True)
def main():
run_wsgi_app(application)
if __name__ == "__main__":
main()

There is a standard library named email as well; it is being loaded before your local module is being found.
Rename the module to something else and it'll work.

Related

Google App Engine URL Handler Error While Running

This is my app.yml file
application: hello
version: 1
runtime: python27
api_version: 1
threadsafe: false
handlers:
- url: /.*
script: hello.py
The hello.py is located at the same directory as the app.yml file.
When I run the app I get this error:
google.appengine.api.yaml_errors.EventError: Unknown url handler type.
<URLMap
secure=default
static_files=None
application_readable=None
auth_fail_action=redirect
require_matching_file=None
static_dir=None
redirect_http_response_code=None
http_headers=None
url=/.*
script=None
upload=None
api_endpoint=None
expiration=None
position=None
login=optional
mime_type=None
>
in "C:\Users\***\Desktop\app\app.yaml", line 8, column 1
2016-03-01 11:36:12 (Process exited with code 1)
I thought it was spacing that was the issue so I added two spaces after script but I am still getting the same error.
You need to change the definition of your handler in app.yaml to:
application: hello
version: 1
runtime: python27
api_version: 1
threadsafe: false
handlers:
- url: /.*
script: hello.app
Pay close attention to the script: property. It should be pointing to your WSGIApplication, which for the example above is defined within the app variable.

Constantly being unable to deploy app on app engine

Using google app engine launcher, I can't seem to deploy my app due to this:
email=martinchua99#gmail.com', '--passin', 'update', 'C:\Users\admin\Desktop\school work\customtinywebdb']"
Usage: appcfg.py [options] update | [file, ...]
appcfg.py: error: Error parsing C:\Users\admin\Desktop\school work\customtinywebdb\app.yaml: mapping values are not allowed here
in "C:\Users\admin\Desktop\school work\customtinywebdb\app.yaml", line 1, column 24.
2014-11-25 19:46:48 (Process exited with code 2)
This is my yaml file,whats wrong with it?
application: camel-cars: 1
runtime: python
api_version: 1
handlers:
- url: /images
static_dir: images
url: .*
script: main.py
Yaml files are sensitive to white spaces. Also you are missing key words and new lines. Give this a try:
application: camel-cars
version: 1
runtime: python27
api_version: 1
threadsafe: false
handlers:
- url: /images
static_dir: images
- url: .*
script: main.py

webapp2 routing can't route to handler - error 404

For a blog project, I'm trying to set different webapp2 handlers for different urls. One of them is the "permalink" url of a post (accessed by post id). Another one is the url for deleting said post. When I try to go to such url, I get a blank page, and the AppEngineLauncher console says:
INFO 2014-01-20 08:08:42,574 module.py:612] default: "GET /del/5066549580791808 HTTP/1.1" 404 -
This is the code for the handlers part of my program:
application = webapp2.WSGIApplication([ ('/newpost', NewPost), #works OK
('/([0-9]+)', PermaLink), #works OK
('/del/([0-9]+)', Delete), #won't work!!!
('/', Front)], debug=True) #works OK
If somebody has some clue about this I'd appreciate it. I've been looking for a solution but the fact that I get no error message and it doesn't seem (to me at least) to make any sense makes it so much harder.
EDIT:
The app.yaml file:
application: blogapp
version: 1
runtime: python27
api_version: 1
threadsafe: true
handlers:
- url: /.*
static_dir: static
- url: /.*
script: base.application
libraries:
- name: jinja2
version: latest
The Delete class is trivial code for testing, such as:
class Delete(Base): #Base is my base RequestHandler
def get(self, s):
self.response.write(s)
I even tried matching the urls '/del/([0-9]+)' to the same PermaLink class, and still doesn't work.
Nevermind, it's solved. I tidied up the yaml file and everything works correctly now.
application: blogapp
version: 1
runtime: python27
api_version: 1
threadsafe: true
handlers:
- url: /static
static_dir: static
- url: (/.*)*
script: base.application
libraries:
- name: jinja2
version: latest

GAE: 404 error on creating a new script

I'm using Google App Engine with Python environment.
I have my main code in the main.py file. I want to create a new .py file for a different page.
I created the .py file, added the path to the yaml file. But I still get a '404 Error, resource not found'.
Here is my yaml file
application: myapp
version: 1
runtime: python27
api_version: 1
threadsafe: yes
handlers:
- url: .*
script: main.app
- url: /hello
script: hello.app
libraries:
- name: webapp2
version: "2.5.2"
When the user goes to exampleurl.com/hello I want the hello.py file to be executed.
Here's the current content of hello.py
import webapp2
class HeyPage(webapp2.RequestHandler):
def get(self):
self.response.headers['Content-Type'] = 'text/html'
self.response.out.write('Hello, All!')
app = webapp2.WSGIApplication([('/hello', HeyPage)],
debug=True)
Here is the log:
INFO 2014-01-10 06:15:31,150 module.py:617] default: "GET /hello HTTP/1.1" 404 154
You should list your handlers from most specific to least specific. Your handler:
- url: .*
script: main.app
basically says that main.app should handle every url. Since it is the first in the list, main.py will try to handle every request regardless of the handlers that follow it in app.yaml. Change it to:
handlers:
- url: /hello
script: hello.app
- url: .*
script: main.app
And all should work.
As far as I can remember, GAE matches a URL with the patterns in handlers from top to down. .* matches with any URL and as it is the first pattern in the handlers section, it call main.app instead of your hello.app. You should place .* pattern at the end of the handlers section so that any URL that doesn't match with any of your previously defined URL patterns get handled by main.app.
So, modify your handlers section as:
application: myapp
version: 1
runtime: python27
api_version: 1
threadsafe: yes
handlers:
- url: /hello
script: hello.app
- url: .*
script: main.app
libraries:
- name: webapp2
version: "2.5.2"

Python ImportError: No module named main in Google app engine project

I have the following app.yaml file
application: gtryapp
version: 1
runtime: python27
api_version: 1
threadsafe: yes
handlers:
- url: /images/(.*\.(gif|png|jpg))
static_files: static/img/\1
upload: static/img/(.*\.(gif|png|jpg))
- url: /css/(.*\.css)
mime_type: text/css
static_files: static/css/\1
upload: static/css/(.*\.css)
- url: /js/(.*\.js)
mime_type: text/javascript
static_files: static/js/\1
upload: static/js/(.*\.js)
- url: /(.*\.html)
mime_type: text/html
static_files: static/\1
upload: static/(.*\.html)
- url: .*
script: main.app
libraries:
- name: webapp2
version: "2.5.2"
And the file app.py:
import webapp2
class MainPage(webapp2.RequestHandler):
def get(self):
if self.request.url.endswith('/'):
path = '%sindex.html'%self.request.url
else:
path = '%s/index.html'%self.request.url
self.redirect(path)
application = webapp2.WSGIApplication([('/.*', MainPage)],
debug=True)
The files that I should deploy are just html files or js or images, I get the following error after compiling the app:
raise ImportError('%s has no attribute %s' % (handler, name))
ImportError: has no attribute app
Solved: I had to call "app" not "application" !
app = webapp2.WSGIApplication([('/.*', MainPage)],
debug=True)
You've called the file index.py, not main.py. Either rename it, or use index.app in the yaml.
The issue you are having is that your app.yaml file doesn't properly describe your code. Here is the offending bit:
- url: .*
script: main.app
This says that all URLs that were not matched by some previous entry should be handled by the app object of the main module, which should be a WSGI application object (see the WSGI standard).
This doesn't work because your code is set up differently. Your primary module is in index.py (the index module) and its interface with the server is via the CGI standard (though WSGI is used internally).
So, you need to change something. It could either be the app.yaml description of the app, or it could be the organization of your code.
Making your code work as a CGI-style program is easy. Just change app.yaml to point to index.py as the script. The .py part in this case is the file extension, and the file will be run as a script.
If instead you want to go with the newer, WSGI-compatible style (which is probably the best option), the documentation suggests the following format:
import webapp2
class MainPage(webapp2.RequestHandler):
def get(self):
self.response.headers['Content-Type'] = 'text/plain'
self.response.out.write('Hello, webapp World!')
app = webapp2.WSGIApplication([('/', MainPage)])
Your code is almost like this already. To make it work, get rid of your main function and if __name__ == "__main__" boilerplate. Replace it with:
app = webapp.WSGIApplication([('/.*', IndexHandler)],
debug=False)
This creates an app object at the top level of your module. Now, either rename your index.py file to main.py, or change app.yaml to point to index.app. The .app part of this is different this time. Rather than a file extension, it represents Python member access (in this case, accessing a global variable in a module).

Categories