I have a Google App working and I would like to make it run 2 python files instead of one. Here's my original handlers part of my app.yaml
handlers:
- url: /.*
script: enwebXML.app
Then I wanted to make it run 2 different python files but it just does whatever the first one is doing so it just ignores the seconde file.
handlers:
- url: /.*
script: enwebXML.app
- url: /.*
script: frwebXML.app
I just think that since it's the same url it doesn't go through the second one, I tried to change the urls to 2 sub urls but no chance it doesn't work for some reason, here's the urls I tried with:
-url: /en/.*
-url: /fr/.*
Since it doesn't work I would like to know if there's something I can do like:
handlers:
- url: /.*
script: enwebXML.app
script: frwebXML.app
The app.yaml pattern url routing works on a 1st match basis: whichever pattern matches first wins and the respective script is invoked - as you observed.
So you need 2 different routing patterns to route requests to 2 different scripts. You were on the right track:
handlers:
- url: /en/.*
script: enwebXML.app
- url: /fr/.*
script: frwebXML.app
Of course, you'll need to update accordingly the app handler mapping patterns in each of the scripts. Something like this:
in enwebXML.app change /some_path to /en/some_path
in frwebXML.app change /some_path to /fr/some_path
Related
There are already a lot of post dealing with this issue but I wasn't able to find a solution to my problem. I am using the Google App Engine Launcher to create a small web application using python. I need to display a picture (/images/chartname.png) on my page. I am using the following line of html code <img width=150 src="/images/chartname.png"> but the picture does not show up. Additionally when I open http://localhost:8080/images I get an error 404.
Here's the content of my .yaml file:
application: app
version: 1
runtime: python27
api_version: 1
threadsafe: false
handlers:
- url: /.*
script: app.my_app
- url: /images
static_dir: images
I don't understand why the picture doesn't show up and why http://localhost:8080/images returns an error 404.
I've tried the suggestion in this post: Google App Engine add image to page with static folder but it didn't do it for me.
Try reordering the handlers:
- url: /images
static_dir: images
- url: /.*
script: app.my_app
Patterns are evaluated in the order they appear in the app.yaml file, from top to bottom. The first mapping whose pattern matches the URL is the one used to handle the request.
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.
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
When I control different type of pages, I move my code to another python file. But this way has disadvantage : each time I want to change url hander, I must comback to main.py to config bottom lines about url handler. for example :
app = webapp2.WSGIApplication([('/', MainPage),
('/thanks',ThanksHandler),
('/unit2/signup',Signup),
('/unit2/successful', LoginSuccess)], debug=True)
I try to config handler in app.yaml to prevent dis advantage.
I add file blog.py in same directory and in this file, I have Blog class. And here is my blog.py file:
class Blog(BaseHandler):
def get(self):
self.response.out.write("Hello")
app = webapp2.WSGIApplication([('/blog', Blog)], debug=True)
Here is original file:
> handlers:
> - url: /favicon\.ico static_files: favicon.ico upload: favicon\.ico
- url: /.* script: main.app
and this new file app.yaml:
handlers:
- url: /favicon\.ico static_files: favicon.ico upload: favicon\.ico
- url: /blog/.* script: blog.app
- url: /.* script: main.app
But when I goto: localhost:port/blog : 404: resource not found.
Please help me.
Thanks :)
The /blog/.* url specification from the yaml file does not match the url specification from the blog.py file (/blog). In particular the fact that /blog/.* requires the url to have a slash after blog. If for example you use just /blog in both places it will work. Or you can use /blog/.* in both places.
The url specifiers are matched in the order in which they appear in the yaml file therefore in this particular case /blog/.* will not match on /blog but will match on the last (catch all really) /.* specifier and therefore main.py handler will be loaded and fail to match (no pattern in the call WSGIApplication constructor inside main.py).
Hope this helps.
-Silviu
I am new at this and am planning to move my stuff from a paid web service to GAE (nothing dynamic just static pages). Believe me I have spent countless hours trying to make this work but am at an impasse whereby I achieve one result at the exclusion of another and visa versa.
I am sure it is a simple answer and that I am violating some basic principles. What I want is that the app engine page (mygaeid.appspot.com) delivers a static landing page such that other pages are available with the addition of a suffix e.g. mygaeid.appspot.com/oranges.html mygaeid.appspot.com/grapes.html etc.
I am unable to achieve this such that I either am able to get the other pages when I add the suffix e.g. mygaeid.appspot.com/apples.html; mygaeid.appspot.com/oranges.html but not the landing page OR with a slightly different yaml the landing page (mygaeid.appspot.com) works but there is no access to the other pages (mygaeid.appspot.com/oranges.html etc) that have a suffix.
The py file (abcdefg.py) is below and is common to the two different yamls that follow:
import os
from google.appengine.ext import webapp
from google.appengine.ext.webapp import util
from google.appengine.ext.webapp import template
class MainHandler(webapp.RequestHandler):
def get (self, q):
if q is None:
q = 'htmdir/apples.html'
path = os.path.join (os.path.dirname (__file__), q)
self.response.headers ['Content-Type'] = 'text/html'
self.response.out.write (template.render (path, {}))
def main ():
application = webapp.WSGIApplication ([('/(.*html)?', MainHandler)], debug=True)
util.run_wsgi_app (application)
if __name__ == '__main__':
main ()
Using the following yaml the landing page (mygaeid.appspot.com) works perfectly (delivering the content of apples.html), but I cannot access the page if I add a suffix e.g. mygaeid.appspot.com/apples.html or mygaeid.appspot.com/static/htmdir/apples.html etc, as soon as I add the suffix it does not work. In the directory (htmdir) I have placed apples.html along with other html pages e.g. oranges.html etc and I cannot access any of them with this yaml.
application: mygaeid
version: 1
runtime: python
api_version: 1
handlers:
- url: /(.*\.(html))
static_files: static/htmdir/\1
upload: static/htmdir/(.*\.(html))
- url: /css
static_dir: css
- url: /js
static_dir: js
- url: /images
static_dir: images
- url: .*
script: abcdefg.py
If I modify the yaml as follows then the landing page (mygaeid.appspot.com) does not work but when I add the suffixes then it works perfectly e.g. mygaeid.appspot.com/apples.html; mygaeid.appspot.com/oranges.html etc deliver the appropriate pages:
- url: /(.*\.(html))
static_files: htmdir/\1
upload: htmdir/(.*\.(html))
Finally if I dispense with the directories altogether and using the same abcdefg.py (without the directory) the following very simple yaml actually delivers the results I want but is very unruly as all the files are stuffed in the root directory.
application: mygaeid
version: 1
runtime: python
api_version: 1
handlers:
- url: /(.*\.(png|js|css))
static_files: \1
upload: (.*\.(png|js|css))
- url: .*
script: abcedfg.py
any help would be much appreciated on figuring this out.
thanks
thanks wooble and thanks dave I went back yet again and carefully read the logs Wooble's solution works but I needed to put the htmdir (that contains the html) inside a directory called static. GAE is a great (and free) solution for static websites
your help and feedback is very much appreciated
SiteDirectory
-mygaeid
-static
-htmdir
-js
-css
-images
app.yaml
index.yaml
(py file was removed)
If you declare files as static in app.yaml, they are not available to your application's handlers.
However, if they're really static, using the django template engine to "render" them is kind of silly; just add mappings in app.yaml to display the static files, including one to display apples.html for /:
application: mygaeid
version: 1
runtime: python
api_version: 1
handlers:
- url: /(.*\.html)
static_files: static/htmdir/\1
upload: static/htmdir/.*\.html
- url: /css
static_dir: css
- url: /js
static_dir: js
- url: /images
static_dir: images
- url: /
static_files: static/htmdir/apples.html
upload: static/htmdir/apples\.html
(no python files needed)
Woobie has the right answer. Let me phrase it differently.
When you put .html in static_files, they're served by separate services that are dedicated to serving static content. Your app will not be able to see those files. The app can only see files that are resources.
Django templates must be resources, not static files. Otherwise, the application can't see them, and the template.render(path, ... will fail.
A next step to getting your problem solved is (if you haven't done so aleady) is to update your post to show your current app.yaml, and also to show us what's being reported up in the application's logs.
There are technical reasons why it works this way
The app.yaml config functions in a very simple top->bottom procedural manner.
Matching happens in the following order:
1. - url: /(.*\.(html))
static_files: static/htmdir/\1
upload: static/htmdir/(.*\.(html))
2. - url: /css
static_dir: css
3. - url: /js
static_dir: js
4. - url: /images
static_dir: images
5. - url: .*
script: abcdefg.py
To put it simply, if the file has a .html suffix it gets matched in step 1 and reroutes that request from mygaeid.appspot.com/.html to mygaeid.appspot.com/htmdir/.html. The *.html handler in step 5 never gets hit because all *.html routes are already spoken for.
In addition -- as the answers have already covered -- directories marked as static will not be available locally to your app handlers. I'll try to address the technical reasons why.
app.yaml acts as a configuration file for GAE's reverse proxy. Static files only change when they're uploaded so they're ideal for caching. By immediately pushing the static files to a cache server when they're deployed, GAE increases loading performance and removes unnecessary load from the app servers.
There's a good reason that static requests are counted separately and cost less than regular app requests. Every time you request a static file you're essentially pulling fetching the file from GAE's CDN. If you were to only fetch static files, then your server would have no reason to spool up in the first place.
The obvious downside to that approach is that those files don't physically exist on the same server as your app so you can't fetch or upload them directly in your app.
Note: Also following what other answers have covered. Don't mark your template folder as static. When your app goes to load the template -- instead of grabbing it from an adjacent directory -- it'll have to send out a web request and fetch the file from a remote location. Obviously, fetching a remote file instead of a local file is going to increase load time and latency.