I'm writing a service with 2 blueprints(auth & business), each of the blueprint is located in its own package, I need to share some images, scripts and styles accross the Blueprints.
When placing the flash.js
and favicon.png
in the appropriate folder(styles, images or scripts) in the root static folder is not being fetched when deployed to GCP, while running the app locally the files are being routed properly.
What is the appropriate way to share common static files across blueprints when deploying to GAE?
The Blueprints are defined as follow:
auth_bp = Blueprint(
'auth',
__name__,
template_folder='templates',
static_folder='static',
static_url_path='/auth/static/'
)
business_bp = Blueprint(
'business',
__name__,
template_folder='templates',
static_folder='static',
static_url_path='/business/static/'
)
The package structure:
├── app
│ ├── __init__.py
│ ├── auth
│ │ ├── __init__.py
│ │ ├── blueprint.py
│ │ ├── constants.py
│ │ ├── forms.py
│ │ ├── static
│ │ │ ├── images
│ │ │ │ └── favicon.png
│ │ │ ├── scripts
│ │ │ │ ├── captcha.js
│ │ │ │ ├── login.js
│ │ │ │ └── reset-password.js
│ │ │ └── styles
│ │ │ └── main.css
│ │ ├── templates
│ │ │ ├── base-auth.html
│ │ │ ├── login.html
│ │ │ ├── reset-password.html
│ │ │ └── reset-request.html
│ │ └── utilities.py
│ ├── business
│ │ ├── __init__.py
│ │ ├── blueprint.py
│ │ ├── static
│ │ └── templates
│ ├── classes
│ │ ├── __init__.py
│ │ └── system_user.py
│ ├── config.py
│ ├── static
│ │ ├── images
│ │ ├── scripts
│ │ │ └── flash.js
│ │ └── styles
│ ├── templates
│ │ └── _macros.html
│ └── utilities
│ ├── __init__.py
│ └── utilities.py
├── app.yaml
├── deployer.sh
├── main.py
└── requirements.txt
app.yaml:
runtime: python311
default_expiration: "2h"
handlers:
- url: /static
static_dir: static
- url: /.*
script: auto
secure: always
This would be a sample on how I want to use the shared files:
<head>
...
<link rel="apple-touch-icon" href="{{ url_for('static', filename = 'images/favicon.png') }}" />
<link rel="icon" sizes="192x192" href="{{ url_for('static', filename = 'images/favicon.png') }}" type="image/png" />
<script src="{{ url_for('auth.static', filename = 'scripts/captcha.js') }}" defer></script>
<script src="{{ url_for('static', filename = 'scripts/flash.js') }}" defer></script>
...
</head>
The favicon.png
I want to use it accross the application, along with the flash.js
while the captcha.js
, I want it only on the auth
Blueprint.
Locally, this setup is working fine, is when I deploy to GAE that doesn't work anymore as expected(the shared static files return 404 and the endpoint is not created), so my guess is that my app.yaml
needs fine tuning, but can't find a resource to lead my in the right direction.
UPDATE I
I removed the static
declaration from app.yaml
and at least the script flash.js
worked as expected when deploying.
However I tested the auth
blueprint and current_app
static_folder
and static_url_path
when deployed with and without the static
declaration on the app.yaml
file and in both cases is the same, but the resources are missing when the declaration is on de yaml file.
In both cases only the auth/static
is available on the developer console under sources
in Chrome.
app.yaml
with the static
declaration
app.yaml
without the static
declaration
To move on, removed the files and hosted them on a Storage Bucket.
UPDATE II
When checking the source in the rendered webpage the path created by url_for
seemed correct static/scripts/flash.js
for the scripts and static/images/favicon.png
for the images, but the favicon was nowhere to be found(404) while the script was available only when I removed the static
declaration from the app.yaml
.
I created a dummy project to try to reproduce your issue.
Below is the project folder structure (project is called common_static_files
and I have 2 sub apps called app_1
and app_2
The blueprint definition in app_1
app_1_handlers = Blueprint("app_1_handlers", __name__,
template_folder="templates",
static_folder='static',
static_url_path='/app_1/static/')
The contents of app.yaml
file
# This handles static files under the app_2 folder
- url: /app_2/static
static_dir: common_static_files/app_2/static
# This handles static files under the app_1 folder
- url: /app_1/static
static_dir: common_static_files/app_1/static
# This handles static files in the common static folder (in the root of the project)
- url: /static
static_dir: common_static_files/static/
The contents of app_1.htm
under the templates folder in app_1
folder
Notice how the package name is used for the static handler for app_1
<head>
<link href="{{ url_for('app_1_handlers.static', filename = 'css/app_1.css') }}" rel="stylesheet">
</head>
<body >
<div style="font-size: 3em; margin-top: 20px;">{{message}} </div>
<div style="margin-top:20px;">
<img src="{{ url_for('static', filename = 'images/question.png') }}" />
</div>
</body>
The output when the page is loaded
a) The css file with a black background and white text color is under app_1 > static > css > app_1.css
b) The image (screenshot of the stackoverflow question) is in the common static folder