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.
Related
This should be really easy but I am having trouble.
My main.py looks like this:
import webapp2
import urllib2
from google.appengine.api import images
from google.appengine.ext import db
class MainHandler(webapp2.RequestHandler):
def get(self):
self.response.write("hello worldd")
#********????*********
app = webapp2.WSGIApplication([
('/', MainHandler)
], debug=True)
Where I have commented #********????********* can I place some html headers <html><head><body><img src> etc? When I do this it breaks.
My app.yaml looks like this:
application: myprojectnamehere
version: 1
runtime: python27
api_version: 1
threadsafe: yes
handlers:
- url: /favicon\.ico
static_files: favicon.ico
upload: favicon\.ico
- url: .*
script: main.app
- url: /images
static_dir: images
libraries:
- name: webapp2
version: "2.5.2"
My image is stored in a directory called 'images', in the same project folder as main.py.
Is this automatically uploaded to the server when I hit 'deploy'?
I have found some "clues" on google's website such as this about general images, and this about dynamic images, but I am still having trouble with this. Can you help bring me up to speed? I would like eventually to show an image that is a custom button, detect a mouse click on the image, and change the image as a result.
Any guidance would be great. What I am trying to do should be pretty simple but it's turning out to be much harder than I expected. From basic searches in the documentation I am finding clues but none seem to be pointing in a clear exact direction for what I need to be using to display a simple image on my app engine webpage.
Next I will familiarize myself with something called the GWT API, based on a clue I found here.
I'm trying to upload JPEG images to my Google App Engine website; these images will then be referenced within HTML pages of my website.
I've placed my images in a directory /img in the root directory of my GAE project and configured by app.yaml file according to the official docs (https://developers.google.com/appengine/docs/python/gettingstartedpython27/staticfiles) as follows:
handlers:
- url: /img
static_dir: img
- url: /javascript
static_dir: javascript
- url: /.*
script: main.application
However, every time I try to access an image at mywebsite.appspot.com/img/testImg.jpg, I get a 404 Failed to Load Resource error -- even though I have a testImg.jpg file in my /img directory.
I placed a dummy text file in my /img directory and could successfully retrieve and display mywebsite.appspot.com/img/test.txt, so I'm not sure why my images are uploading. I've looked over the Google App Engine guide many times and can't find any answers... my app.yaml file looks exactly like what their example has.
I trying to learn web application development. I'm currently using Google App Engine to create apps. I was experimenting with showing images on my site but the site just shows the alternate text.
The first time I tried this I didn't know about static files. Once I fixed that problem the request line for the image showed: '"GET /images/pic.jpg HTTP/1.1" 200 -'. When I ran dev_appserver it showed a warning saying I needed the python module "PIL" to do imaging. Once I downloaded and installed that the warning disappeared but it still won't load the picture! The request line still shows that it found the image. But all the site displays is the alternate text!
Anyway, here's the code for the app.yaml and script:
(note: I'm using the code for python 2.5)
-----------app.yaml------------
application: mysite
version: 1
runtime: python
api_version: 1
handlers:
- url: /.*
script: myscript.py
- url: /images
static_dir: images
---------- script -----------
template = """
<body>
<br>
<br>
<img src="/images/pic.jpg" alt="Clone Pic" width="100", height="70"/><br>
</body>
"""
print "Content-Type: text/html"
print template
Here's what my application directory looks like:
Root
app.yaml
script.py
images
pic.jpg
I recently found out that even if I change the name of the images directory in my script
<img src="/foo/pic.jpg...)
the request line still says its OK
"GET /foo/pic.jpg HTTP/1.1" 200 -
Anybody know what's going on?
The order of your handlers matter. /.* matches every URI, hence you typically want that at the end. Try the following ...
handlers:
- url: /images
static_dir: images
- url: /.*
script: myscript.py
Also, make sure your image files are under the directory images as you specified in static_dir.
Hope this helps.
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.
I am unable to display images in pages created using Google App Engine(Python).
My app.yaml file has :
- url: /images
static_dir: images
And the python file has:
self.response.out.write("""<img src = '/images/title.gif' />""")
The image still does not display in the page.
Thanks
I would test:
Do you see http://yourapp.appspot.com/images/title.gif?
Are you sure that images folder is on your app root?
Title.gif is a "working" image?
I would recommend you to use a static folder to store your static contents organized in subfolders:
Root
static
images
stylesheets
javascripts
app.yaml
and Mapping a url /images like this.
- url: /images
static_dir: static/images
mime_type: image/png
mime_type: image/png is optional; if not specified, the MIME type for a file will be derived from the file's filename extension.
I encountered a similar problem. The solution was ultimately very simple. You need to try to reposition the url handler for the static directory before the apphandler for the main.app
like this:
handlers:
url: /favicon\.ico static_files: favicon.ico upload: favicon\.ico
url: /photos static_dir: photos
url: .* script: main.app
This annoyed me for like 45 min before I found the solution on google.
Is there a directory called 'images' in your app's root directory? What does it contain? What do you get if you attempt to fetch the file directly?
The reason may be about upper/lower case difference between systems. Windows is not upper/lower sensitive, but Linux is. Supposing your actual file name is Title.GIF. It works if it is written as title.gif on a Windows machine (Your Local machine), but does not work on a Linux server (Google App Server).
One possible reason for this to happen is if you do not provide space between - url and if you do not restart your server. It will show 404 that time. If you restart your server then you will encounter the error in app.yaml. This is one very common mistake that people commit. Because the way you have done it seems that it should work fine.