how to get static URL inside GAE app - google-app-engine

my app.yaml:
handlers:
- url: /static
static_dir: static
- url: /.*
script: main.app
is there a way, inside my webapp2 code, to get the absolute URL of the /static route?

When you define routes in your application you can compute an uri. See: http://webapp-improved.appspot.com/guide/routing.html#building-uris
With this information and your knowledge of the app.yaml you can compute the uri for the static url.
In your main.app you add a dummy route definition for static. It will only be used to build the uri and it will never be used for routing.
Modified example from the webapp2 docs :
app = webapp2.WSGIApplication([
webapp2.Route('/', handler='HomeHandler', name='home'),
webapp2.Route('/static', handler=HomeHandler, name='static'), # never used for routing
])

no there is no way to query, loop or find out what is in a folder that was uploaded as static.
but the static files do not change as long as you wont deploy the app with new static files.
you need to keep of the static files and compose those absolute urls yourself

Related

React app giving 404 error when deployed to GCP

I have deployed my react app to GCP's App engine. It successfully deploys and the landing page is accessible. However none of the routes work. All the routes are giving '404' error.
I am pretty sure its the app.yaml configuration that has issue. Help please!
app.yaml
runtime: nodejs10
handlers:
- url: /
static_files: build/index.html
upload: build/index.html
- url: /
static_dir: build
The issue is that you are using both static_files and static_dir to your / url.
You need to either use static_files or static_dir.
From the description of your question it looks like you want to use static_dir to match everything that is inside the directory after the url: /.
As stated in the documentation:
static_dir: The path to the directory containing the static files, from the application root directory. Everything after the end of the matched url pattern is appended to static_dir to form the full path to the requested file.
static_files: A static file pattern handler associates a URL pattern with paths to static files uploaded with the application. The URL pattern regular expression can define regular expression groupings to be used in the construction of the file path. You can use this instead of static_dir to map to specific files in a directory structure without mapping the entire directory.

Login not asked by appengine with login required

I'm using Google AppEngine to deploy a webapp and I've set my app.yaml like this:
handlers:
- url: /assets
static_dir: dist/assets
- url: /dist
static_dir: dist
- url: /.*
script: app.server.main.app
secure: always
login: required
When I open my app in Chrome Incognito mode, Flask handles the call to / and serve the file index.html (no direct access to this file, which is not even in /assets nor /dist) and then all my static resources are served (the CSS, JS present in index.html), and so some AJAX requests are performed too. Those AJAX requests will fail because of the login: required in the yaml.
The error I get in the console:
XMLHttpRequest cannot load
https://www.google.com/a/XXXXX/ServiceLogin?service=ah&passive=t…inue%3Dhttps://YYYYYY.appspot.com/gettoken.
No 'Access-Control-Allow-Origin' header is present on the requested
resource. Origin
'https://YYYYYY.appspot.com' is
therefore not allowed access.
Why are those resources served in a first time ? Accessing '/' of my app should require the login first, and then serve them.
[edit] My first post was unclear about how index.html is accessed
The reason your static files are served is due to the fact that they do not require login. Please note that login is only required for /.* pattern and has no effect on other patterns, and
Patterns are evaluated in the order they appear in the app.yaml file, from top to bottom.
(see https://cloud.google.com/appengine/docs/standard/python/config/appref#handlers)
The following configuration, although not tested, should require login before serving the static files.
handlers:
- url: /assets
static_dir: dist/assets
login: required
- url: /dist
static_dir: dist
login: required
- url: /.*
script: app.server.main.app
secure: always
login: required

Google App Engine URL Routing with App.Yaml for Static resource and Script

I am busy migrating a app into the GAE. I used to utilize timthumb.php to resize images on demand from within a static img folder. From the same folder I used to serve static images aswel.
eg: example.com/img/image_name.jpg
example.com/img/timbthumb.php?src=example.com/img/image_name.jpg&w=50&h=50
etc.
I am not using timbthump.php anymore, I have re-written it to serve images via CloudStorageTools.php api, and I do not want to go through all code to rewrite the image paths.
Now, on my local environment the google app engine is serving both versions of images, static and dynamic via timbthumb.php.
On the live environment GAE only serves static or dynamic, I cannot build URL handlers to serve both.
The timbthumb.php images are throwing a 404 error with both handlers.
My app.yaml
application: my-app
version: 1
runtime: php55
api_version: 1
threadsafe: yes
handlers:
- url: /favicon\.ico
static_files: favicon.ico
upload: favicon\.ico
- url: /css
static_dir: dir/css
#timbthumb.php images
- url: /img/(.+\.php)$
script: dir/img/timbthumb.php
#static images
- url: /img
static_dir: dir/img
#all other php files
- url: /.*
script: dir/index.php
My Question, how can I make GAE route static images via example.com/img/ and the timthumb.php script located at example.com/img/timbthumb.php in my app.yaml?
Thanks
According to the documentation you can't serve a script from a static directory:
A static directory handler makes it easy to serve the entire contents
of a directory as static files. Each file is served using the MIME
type that corresponds with its filename extension unless overridden by
the directory's mime_type setting. All of the files in the given
directory are uploaded as static files, and none of them can be run
as scripts.
The fact that it appears to be running in the development server is just another reflection of the fact that the development server is just an approximation of GAE, but not really GAE.
If your image paths naming allows it you could use static_files routing rules instead of a static_dir one:
A static file pattern handler associates a URL pattern with paths to
static files uploaded with the application. The URL pattern regular
expression can define regular expression groupings to be used in the
construction of the file path. You can use this instead of
static_dir to map to specific files in a directory structure without
mapping the entire directory.

App Engine can't find static files

I'm using webapp2 and python 2.7 on my app engine application. However, I'm having a problem with the url on app.yaml.
I have my static files inside a static/ directory, in the root of my path. So inside of static/ I have static/scripts/MyScript.js
When I set app.yaml like:
application: myapp
version: 1
runtime: python27
threadsafe: true
api_version: 1
handlers:
- url: /.*
script: myapp.app
- url: /static
static_dir: static
libraries:
- name: webapp2
version: latest
In my HTML code, the js is called like:
<script src="static/scripts/Fuel.js"></script>
But, the file is not loaded, and I get a 404 error. (This problem happens also for .css files.)
However if I change the first url in app.yaml to:
handlers:
- url: /
script: myapp.app
The static files are loaded, but when I try calling the routes url in my app, like an url I call in a form to save some data on server, this route is not found and I also get a 404 error.
Here is my routing code in myapp.py file.
app = webapp2.WSGIApplication(
[('/', MainHandler),
('/save', SaveData),],
debug=True)
So if I try to access myapp.appspot.com/save, it returns me a 404 error, saying:
The requested URL /save was not found on this server.
Any ideas? If you need more information about it, just ask on the comments.
Thanks.
Put your catch all url /.* at the bottom since this is evaluated in order. Meaning it never pass after that.
handlers:
- url: /static
static_dir: static
- url: /.*
script: myapp.app

GAE: How to upload files to be accessed by the application?

Update: I found the problem. My static rule for HTML files still matched the templates even though they were in a subdirectory. After changing the rule to not match them anymore, the files could be accessed by the application.
I'm creating a Google AppEngine application. I'm using the Go language but I'm not sure that's relevant. I want to use a template with a separate template file. So the application must read the template file. Locally this works but after uploading the app to GAE, I get "no such file or directory" when calling template.ParseFiles().
So I'm thinking that somehow I must indicate that the template files are application files so that they get uploaded in the right way. I thought maybe my template files were uploaded as static files because of this in my app.yaml
- url: /(.*\.html)
static_files: \1
upload: .*\.html
So I moved them to their own directory. But that didn't make a difference. I tried adding an upload directive for my script rule in app.yaml like this:
- url: /.*
script: _go_app
upload: templates/.*
But that didn't seem to be allowed. So can anyone tell me how do I access the template files (or any data files) from my GAE application?
Thanks!
All files in your project directory are automatically uploaded.
If your app needs to access them (this is your case as you are working with templates) you can't mark them as static. This is why the first solution fails.
The second attempt, does not work either as upload is not a member of an url description.
In your case, just deploy your app and the files will be automatically uploaded and available to your app (you may need to get the basepath of your project to construct the full path to the template).
The files are automatically uploaded, assuming they're not in a static_dir or static_files directory. See the Skipping Files section in the App Engine documentation. App Engine treats such directories and files as static resources, and static resources are served separately from the application.
Static resources are not normally accessible from application code. If you must put your templates in the same directory as your other static resources, you can use the application_readable setting to make such resources accessible to your app as well.
But as you note, you can put your templates in a place within your app that isn't mapped to a static resource path; that's probably the right thing to do.
Check the different options for the app.yaml at [1]. You can check the static_dir and static_files options. I’m sharing a sample that is able to download static files. These files are in the static folder adn test folder. I share my app.yaml:
runtime: python27
api_version: 1
threadsafe: yes
handlers:
- url: .*
script: main.app
- url: /test
static_dir: test
application_readable: true
- url: /(.*\.(gif|png|jpg))$
static_files: static/\1
upload: static/.*\.(gif|png|jpg)$
application_readable: true
And the main.py:
…
import webapp2
...
class Download(webapp2.RequestHandler):
def get(self):
imageName = self.request.get('img-name')
self.response.headers['Content-Disposition'] = str('attachment; filename=' + imageName)
f = None
try:
f = open('static/' + imageName, 'r')
self.response.out.write(f.read())
except:
self.response.out.write('Jon Wayne')
class Test(webapp2.RequestHandler):
def get(self):
imageName = self.request.get('tst-name')
self.response.headers['Content-Disposition'] = str('attachment; filename=' + imageName)
f = None
try:
f = open('test/' + imageName, 'r')
self.response.out.write(f.read())
except:
self.response.out.write('Jon Test')
app = webapp2.WSGIApplication([
('/download', Download),
('/tst', Test)
], debug=True)
I have two images: fib2.png and fib1.jpeg
Then in the Test folder I have two files fib2.tst and fib1.tst.
Web is the domain name.
https://web.com/download?img-name=fib2.png
https://web.com/download?img-name=fib1.jpeg
https://web.com/tst?tst-name=fib2.tst
https://web.com/tst?tst-name=fib1.tst
Hope this helps!
[1] https://cloud.google.com/appengine/docs/standard/go/config/appref#handlers_element

Resources