The url "/web" does not match any handlers - python

I've been trying to do a simple webapp on appengine, but I got an issue with handlers.
This is my code:
My app.yaml file:
application: test-app
version: 1
runtime: python27
api_version: 1
threadsafe: true
handlers:
- url: /web/.*
script: AppWebInterface.application
My AppWebInterface.py file:
import webapp2
class MainPage(webapp2.RequestHandler):
def get(self):
self.response.headers['Content-Type'] = 'text/plain'
self.response.write('Hello, World!')
application = webapp2.WSGIApplication([
('/', MainPage),
], debug=True)
When I run the dev_server and visit localhost:8080/web , I get this error:
The url "/web" does not match any handlers.

I see two problems, one masking the other.
First, /web/.* will match /web/, /web/foo, but not /web. There are a few approaches. One is to use
- url: /web.*
But this will also match /webelos. Many that's not a problem for you, because the next step will catch it.
The next problem is that, having passed /web/foo through to the application, there's nothing mapping that url pattern to a class. The WSGIAppliction is set up to handle /, though no such URL will make it to the app given the handler in app.yaml.
If you're stuck getting started, try changing the handler in app.yaml to - url: /. Get something simple working, then add handlers from there.

It is because your pattern only match url which contains /web/ (need to have a '/' after /weg)
modify the pattern and see the result.
handlers:
- url: /web.*
script: AppWebInterface.application

Related

Setting multiple handlers with Python App Engine

I just cannot seem to get multiple handlers working. I'm using Google App Engine with Python. The base URL returns "Hello world!", as expected, but I keep getting a 404 error when I try to visit "/girl".
As far as I can tell I'm doing exactly what is specified in the docs:
https://cloud.google.com/appengine/docs/python/config/appconfig
And in this similar question:
YAML file url and script in GAE python
and yet trying all variants I can think of on these models does not resolve my 404 problem. I am a beginner and don't really understand how the app.yaml file works, thus I'm pretty sure that I'm not specifying the handlers correctly. But I don't know how to fix it.
app.yaml
application: multiapp
version: 1
runtime: python27
api_version: 1
threadsafe: yes
handlers:
- url: ./girl/.*
script: girl.app
- url: .*
script: main.app
libraries:
- name: webapp2
version: "2.5.2"
main.py
import webapp2
class MainHandler(webapp2.RequestHandler):
def get(self):
self.response.write('Hello world!')
app = webapp2.WSGIApplication([
('/', MainHandler)
], debug=True)
girl.py
import webapp2
class MainHandler(webapp2.RequestHandler):
def get(self):
self.response.write('Hey girl!')
app = webapp2.WSGIApplication([
('/',MainHandler),
('/girl/', MainHandler)
], debug=True)
Added: Different organization of the project could definitely avoid having to solve this problem, but I would also like to know why setting these multiple handlers isn't working to begin with.
I know this is an old thread, and that you sort of got your answer, but I want to give a better explanation of what was happening, as I have just found the answer to your fundamental question: How to split handlers into different files?
The key problem is that you are working with regular expressions, both when you declare your WSGIApplication
app = webapp2.WSGIApplication([
('/', MainHandler),
('/girl/', GirlHandler)
], debug=True)
and in your yaml file
handlers:
- url: ./girl/.*
script: girl.app
- url: .*
script: main.app
The path in your yaml url: regex must be the full path from your webapp domain. So if your domain is localhost:8080 then in your yaml file yo should add the url from localhost:8080 onwards. If you type url: /girl/.*
you're asking the browser to match domain+regex: localhost:8080/girl/.*
This means:
match this part exactly: localhost:8080/girl/
match any characters that follow the first part (as that's what ".*"
means in a regex)
So the following yaml statement:
handlers:
- url: /girl/.*
script: girl.app
means that for any url of the form domain/girl/ anything (or nothing) use the the app variable in girl.py file app = webapp2.WSGIApplication(...)
The first implication of this, is there is no purpose in writing a handler for a url that girl.py will never handle, such as when you coded:
girl.py
import webapp2
class MainHandler(webapp2.RequestHandler):
def get(self):
self.response.write('Hey girl!')
app = webapp2.WSGIApplication([
('/',MainHandler),
], debug=True)
You will never use this main handler, as it will only 'activate' when you browse for domain/, but you said in your yaml file that you only wanted girl.py to handler urls of the form domain/girl/something. It's a contradiction
This means that for your setup to work, in girl.py you should only write handlers for urls that match the regex in your yaml. in this case, any regex that is also accepted by /girl/.*.
As a sidenote, if you wanted your girlHandler to work on either domain/girl and domain/girl/ you should use this regex in your yaml file:
handlers:
- url: ./girl(?:/.*)?
script: girl.app
- url: .*
script: main.app
as this makes the /.* part optional
Hope this helps anyone reaching this question, as an insight of how webapp2 calls each handler depending on the url given
You should bundle all your routes together in one file, and have different handlers for different routes.
main.py
import webapp2
class MainHandler(webapp2.RequestHandler):
def get(self):
self.response.write('Hello world!')
class GirlHandler(webapp2.RequestHandler):
def get(self):
self.response.write('Hey Girl!')
app = webapp2.WSGIApplication([
('/', MainHandler),
('/girl/', GirlHandler)
], debug=True)
then in your app.yaml you only have to link to main.app
application: multiapp
version: 1
runtime: python27
api_version: 1
threadsafe: yes
handlers:
- url: .*
script: main.app
libraries:
- name: webapp2
version: "2.5.2"
You don't need multiple webapp2.WSGIApplication instances.
You could have central routing while keeping handlers in separate files with something along these lines in main.py:
app = webapp2.WSGIApplication([
('/girl/.*', "girl.MainHandler")
('/.*', MainHandler),
], debug=True)
Another possibility of running largely independent "apps" while still be able to share some info across them (like authentication) would be to make them modules of the main app. While offering more flexibility in the long run they do have a non-neglijible learning curve (and docs aren't always up2date for them)
Organizational issues aside, the reason this wasn't working was that I didn't include a trailing slash.
"/girl" (no slash) returns 404;
"/girl/" (with slash) renders the page.
Also the lines in app.yaml should be:
handlers:
- url: /girl/.*
script: girl.app

Why is my url in the following google appengine (python) yaml config file not recognized?

I have the following config file for my google appengine app in python:
application: testapp-94974206
version: 1
runtime: python27
api_version: 1
threadsafe: true
handlers:
- url: /helloworld
script: helloworld.application
- url: /
script: helloworld.application
when calling the url with no prefix (/) I get my "helloworld" app called, while when calling with /helloworld I get a 404 not found error page. What is wrong with the declaration of "/helloworld" above?
My question is actually close to another one that has been already answered here.
It turns out that the /helloworld url is actually well routed by the appengine, but then the culprit is the WSGI router that parses the whole absolute URL and not just the one relative to /helloworld, as I thought it would.

GAE app.yaml Script Handling for scripts in subdirectories (python)

I am setting up a new GAE project, and I can't get my scripts in sub-directories to work.
EDIT: If I go to localhost:8080/testing_desc.html I don't any errors, just a blank page (view-source is blank, too). Scripts in my root dir work normally. There is a __init__.py in both the root and sub-dir.
Python script example ("/testing/testing_desc.py"):
import webapp2 as webapp
class DescTstPage(webapp.RequestHandler):
def get(self):
html = 'This should work.'
self.response.out.write(html)
app = webapp.WSGIApplication([('/.*', DescTstPage)], debug=True)
app.yaml:
application: blah
version: blah
runtime: python27
api_version: 1
default_expiration: "5d 12h"
threadsafe: false
libraries:
- name: webapp2
version: latest
handlers:
- url: / <-- This one works
script: main.app
- url: /index.html <-- This does NOT work (??)
script: main.app
- url: /(.*?)_desc.html <-- Also does NOT work
script: \1/\1_desc.app
#file not found
- url: /.*
script: file_not_found.app
I have also tried a simpler version of the yaml:
-url: /testing_desc.html
script: /testing/testing_desc.app
When you use WSGI Pyhon27 this will work. Use a dot for the seperator :
-url: /testing_desc.html
script: /testing.testing_desc.app
You are passing a list of routes to your WSGIApplicaiton call. Those routes must match whatever URL is being handled.
('/', DescTstPage) just matches the '/' URL to your handler. /.* matches all routes.
What routes are you setting in testing/testing_desc.app? They must match /testing_desc.html.
To get my scripts working in sub-dir, I changed the app.yaml and /testing/testing_desc.py to this:
app.yaml:
- url: /testing.html
script: testing/testing_desc.py
/testing/testing_desc.py:
app = webapp.WSGIApplication([('/.*', DescTstPage),], debug=True)
def main():
run_wsgi_app(app)
if __name__ == '__main__':
main()
ATM I do not understand how to make the routing work with sub-dir, so I will use this.
The answer is here:
How can i use script in sub folders on gae?
Its not explicitly stated, but in the answer you must change /foo/ to /foo in the WSGIApplication call, which maps to www.bar.com/foo. If you want to map to www.bar.com/foo.html you need to change /foo to /foo.* in the WSGIApplication call AND the url handler in app.yaml to - url: /foo\.html

Is there any difference between splitting application in app.yaml or webapp2 URI router

Consider the two following scenarios:
There are two url handlers in app.yaml
handlers:
- url: /main
script: main.app1
- url: /secondary
script: secondary.app2
and URI router in main.py
app1 = webapp2.WSGIApplication([('/main', MainHandler)])
and another in secondary.py
app2 = webapp2.WSGIApplication([('/secondary', SecondaryHandler)])
vs
There is one url handler in app.yaml
handlers:
- url: /.*
script: main.app
and the URI router decides the handler
app = webapp2.WSGIApplication([
('/main', MainHandler),
('/secondary', SecondaryHandler)
])
Is there any difference in how the App Engine imports the two scenarios? If all requests are for MainHandler, does the App Engine import the files associated with SecondaryHandler at all in the first scenario or does an instance always import each handler when it is first initialized?
Obviously these are different ways to partition the application logically, but I'm asking if there are any associated performance considerations.
You can use a lazy handler in webapp2 to optimize loading and use a single app.
See this link : https://webapp2.readthedocs.io/en/latest/guide/routing.html#lazy-handlers

First iussue about GAE

I'm approaching to Google App Engine.
I want to implement some handlers, but I get a "Oops! This link appears to be broken." error for each of them:
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()
if I used a simple print function (i.e. print "2gf"), all would work perfectly.
This is my app.yaml file:
application: sample-app
version: 1
runtime: python
api_version: 1
handlers:
- url: /aaa/aaa
script: helloworld.py
- url: /bbb/bbb
script: helloworld2.py
Suggestions?
Your code is old, and the yaml file is pointing the python scripts/apps at the wrong urls. Try the code below:
import webapp2
class HomePageHandler(webapp2.RequestHandler):
def get(self):
self.response.headers['Content-Type'] = 'text/plain'
self.response.write('Hello appengine!')
app = webapp2.WSGIApplication([('/', MainPage)],
debug=True)
And the app.yaml file should contain something like this:
application: helloworld
version: 1
runtime: python27
api_version: 1
threadsafe: true
handlers:
- url: /.*
script: helloworld.py
Also, go through the following App Engine python tutorial. It explains the main concepts of coding for App Engine really well. It helped me greatly when I got started.
In your app.yaml you do not have any routing instructions for /. Therefore when you hit a URL that does not match one of those already in your YAML, your app doesn't know what to do and shows you that error. In order to fix that you need to provide a 'default' handler for anything else that isn't specified in your app.yaml. As mentioned by #Tkingovr (+1 to him), you want to point the default (/.*) to your script. Add that handler at the bottom of your app.yaml and point it to your main script. However I agree with #Tkingovr - switching over to 2.7 now (when you're first learning) will make things easier in the long run :)

Categories

Resources