Try changing ('/', MainHandler)
to (r'/.*', MainHandler)
(the r
just indicates it is a raw string). The problem is that you don't currently have any handlers for anything other than your root /
, so requests with other parameters (such as http://localhost:8080/hello
) have no matching handler and therefore it is unknown how to handle it. Changing the handler to /.*
means that all requests (regardless of what comes after the root) should be routed to your MainHandler
.
As for the app.yaml
handlers and the handlers in your *.py
file, think of the app.yaml
as the high-level director. It gets a request and simply determines where to send it (am I getting a request for a static Javascript file? CSS? Picture? Or is this a request that should serve a page, etc.?). In the case such as yours above, you want it to serve a particular page when hitting any URL that is not /favicon
(so /.*
), so what it does is takes any request to /.*
and routes it to main.app
, which is in your main.py
file (I'm ignoring helloworld.app
for now, mainly because in your situation you don't necessarily need it).
It is then that the more granular handling happens - main.app
receives the original request, and then it looks for a specific handler to execute the code. When we change your handlers to r'/.*'
, it matches anything that comes in (so /
, /hello
, /helloworld
, etc.), and it executes the corresponding class MainHandler
, in this case).