I'm building a PWA in Django.
The serviceworker is located in
pwa->static->pwa->sw.js
Everthing gets loaded/cached and the serviceworker is running.
If in manifest.json "start_url": "/" or "start_url": "/pwa" is set, i get this serviceworker not found error, from the manifest, so it's not installable, but if I set it to "start_url": "." i can install my App but then I get:
Directory indexes are not allowed here.
Request Method: GET
Request URL: http://127.0.0.1:8000/static/pwa/
At app startup.
How can i overwrite or redirect this request to
http://127.0.0.1:8000/pwa/ ?
Django and service workers - serve "sw.js" at application's root url
The last entry solves my question.
Manifest, sw.js and index.html now in the template folder.
The assets in static.
Linking in sw.js
var filesToCache = ["/pwa", "/static/pwa/vue.js",...
Related
I have a Flask app integrating a Dash application.
My Flask application use Flask-Login to handle login, which is working well.
However I have a bug in my Dash application that only happens in production: my dash application shows files (images) located in a data folder. It needs serving file at URL such as http://127.0.0.1:5000/data/person1/person1_image.jpg or whatever the root URL is.
So what I did is I created a route for this such as:
#bp.route("/data/<path:filename>")
#login_required
def data_folder(filename):
"""Serve files located in person subfolder inside folder"""
return send_from_directory(current_app.config["DATA_FOLDER"], filename)
Which works "well" in local developpement. The first time I open the page the image don't show, but when I refresh it does.
But in production, no matter how many time I refresh the page the image doesn't show.
When I check the network tab of Firefox I get this:
302 https://my_domain.com/data/person1/person1_image.jpg
200 https://my_domain.com/login?next=/data/person1/person1_image.jpg
So it appears that when trying to fetch the ressource, it redirect me to the login page, while I'm already logged in ! (As the initial page is also login-protected and I am acessing it.)
Could this be a cookie thing ? In my config.py I have this:
SESSION_COOKIE_SAMESITE = "Lax"
SESSION_COOKIE_SECURE = "True"
Thanks for your help !
This is the full error we receive when running the flask application in the browser.
"Internal Server Error
The server encountered an internal error and was unable to complete your request. Either the server is overloaded or there is an error in the application."
I've done some research and have already attempted to link the folder with the
app = Flask(__name__, template_folder='/templates') assignment.
Here is my directory and debug logs. Any insight would be appreciated.
Directory
Logs
try it app = Flask(__name__, template_folder='templates')
Your code needs some changes. First of all, try using
render_template('prediction.html')
instead of
render_template('templates/prediction.html')
as Flasks already looks at templates folder (which in this case means that it will look for a folder 'templates' inside the folder 'templates')
If this doesn't work, try the same but when you declare the folder do it by:
app = Flask(__name__, template_folder='/templates')
(with '/' before templates)
and not your current
app = Flask(__name__, template_folder='templates')
If nothing of the above works, just the same solutions, without declaring template_folder at all, as by default Flask looks in the folder named 'templates'
I 've read answer [https://stackoverflow.com/a/20895594/305883] but did not help for me.
I have a flask app that can serve a template in localhost or debug at endpoint /path/<int:id>/, but in production with nginx it will fail with error 404.
Flask project has default structure:
app.py
index.html
/templates/mytemplate.html
/static/..
mytemplate.html will load resources from /static/ folder, with jinja syntax.
EDITED
Goal: I want the application to serve:
root / will serve index.html
/path/ will open 'myTemplate.html' and populate it with variables
(jinja); if possible I want static assets included in template (e.g
js, css, images) to be served by nginx;
/api/ will serve api rest.
In my local environment I am using flask server, not ningx, and three end-points are working as expected.
In production, I use flask and ningx.
Root and /api/ edges work; /path/ , used for templating in flask, does not and return error 404.
For setting up nginx I followed the steps in this tutorial:
[https://www.digitalocean.com/community/tutorials/how-to-serve-flask-applications-with-uwsgi-and-nginx-on-ubuntu-14-04]
The template in flask is served by:
#application.route('/path/<int:id>/')
def graph_template(id):
meta = {'og:image':'/url/image.jpg'}
try:
key = decode(id)[0]
except:
# todo replace with error 400
return jsonify({'error':'Something got wrong. ID not found'})
return render_template('mytemplate.html', meta=meta, id = id)
I am having difficulties in debugging and find the problem, making /path/ display the template.
nginx configuration
server {
listen 80;
# is this block to serve index on root only ?
# or will search for index files also in routes /path/ in ningx and/or flask?
root /var/www/mySite;
index index.html index.htm;
location /api {
# try_files $uri $uri/ /index.html;
include uwsgi_params;
uwsgi_pass unix:/var/www/mySite/myApp.sock;
# auth_basic "API Login";
# auth_basic_user_file /etc/nginx/pw_file;
# allow 127.0.0.1;
# allow XX.XX.XXX.XXX;
# deny all;
}
location /static {
alias /var/www/mySite/static;
}
}
I tried the following:
Included a proxy_pass:
location / {
proxy_pass http://127.0.0.1:8080;
}
result: cause error 502
Tried by changing port to :80
location / {
proxy_pass http://127.0.0.1:80;
}
result: error 404
Tried with uwsgi_pass socket at /path/ endpoint
location /path/ {
include uwsgi_params;
uwsgi_pass unix:/var/www/mySite/myApp.sock;
}
Result: This route does not exist http://example.com/path/
Which I don't understand because flask should serve the template here - at least not a misconfiguration error 502.
Answer at: [Python Flask server crashing on GET request to specific endpoint: shown two sockets for each endpoint - do I need to use such setup?
I m trying to document myself on what a socket is and using nginx documentation but sorry I m not that competent in it and I m moving a bit in darkness.
Could you help in debugging the problem?
YAII! I was able to find the answer myself:
adding this block in nginx worked out for serving templates from flask with nginx:
location /path/ {
include uwsgi_params;
uwsgi_pass unix:/var/www/mySite/myApp.sock;
}
where /path/ is the endpoint of the template.
I was receiving the message above because flask was actually handling the 404 error, due to I wrote my decorator to hit /path/<int:id> and handling 404 requests with:
#application.errorhandler(404)
def page_not_found(error):
return 'This route does not exist {}'.format(request.url), 404
However, I will be very grateful if someone could add some comments explaining how the routing between flask and nginx actually works, and a distinction between using a uwsgi_pass and proxy_pass (which I found in different tutorials), and the use of sockets (tutorial I followed).
As example, in this question [Python Flask server crashing on GET request to specific endpoint: the user use two sockets for each endpoint, and for me as beginner I thought it may have been the issue and it is not.
With this configuration, I understood flask will handle the .html template: does it handle also the resource in the template (js, css) or are they served by nginx (please see configuration above, all assets are in /static/ folder)
Would there be a better configuration to exploit ningx capabilities in serving flask templates ?
Comments most appreciated!
I assume your local env works without nginx, right? So, lets have a look:
In local environment, hitting /path/ (with no id) will return an error of url not found, which is ok. Instead in prod environment, nginx will search for /path/index.html - although I have not mentioned in flask decorator.
Have a look at line three of your nginx config. In there, you specified that nginx should look for index.html.
In local env, if I hit /path/id/ it works ok. In production env, it returns error 404, no such file or directory.
I assume, this is because you don't pass any traffic to your flask app. You need something along the lines of:
location / {
proxy_pass http://127.0.0.1:8080; #Change to match your environment
}
You're missing these (if not, please show your whole nginx config), so nginx will search for static files on your storage. However, these requests can't be served by static files, but instead your backend (aka your flask app) has to render and create these dynamically. For this to work, you have to send the traffic there.
I have not found an error due to failing with resources from /static/ folder (e.g. in permission); it looks like flask cannot load or be allowed to serve the templates.
Template file can be loaded by the browser at /mysite/templates/mytemplate.html Static folder permission is set on 403, but /static/js/file.js will be read.
Sorry, I don't get this. Could you elaborate?
I am using Cloud 9 IDE to build a website. My goal is to serve a static website from the site root '/index.html' and so on. The content in this site will be regenerated on a schedule (daily in this example). At the '/admin' and '/api' endpoints I want to serve a couple of flask apps.
Because this is being built on the Cloud 9 IDE, I do not have access to the proxy server configuration. I have to serve everything to one port using the HTML protocol. uWSGI is capable of doing exactly this. I am struggling with my configuration file though:
#uwsgi.ini
[uwsgi]
static-index = index.html
static-map2 = /=/home/ubuntu/workspace/generated-site
static-map2 = /static=/home/ubuntu/workspace/static-assets
mount = /admin=admin.py
mount = /api=api.py
manage-script-name = true
master = true
processes = 5
socket=0.0.0.0:8080
protocol=http
Requests to /admin and /api work as expected returning a result or 404 error.
Requests to / and /index.html both return generated-site/index.html as expected.
A request to /no_exist.html returns 404 Not Found as expected.
My problem is with the second static-map2. A request to /static/test.html came back 404 Not Found (I put an html file there to test).
static-map2 keep the path portion of the URL for its search so the request /static/test.html will be mapped to the file
/home/ubuntu/workspace/static-assets/static/test.html
You most probably want the simple static-map which strips the path from the URL before mapping to the file-system. So a request to /static/test.html will search for the file
/home/ubuntu/workspace/static-assets/test.html
My question is about how to serve multiple urls.py (like urls1.py, urls2.py and so on) files in a single Django project.
I am using Win7 x64, django 1.4.1, python 2.7.3 and as a server django dev-server tool.
I have decided to use a method which i found by google from
http://effbot.org/zone/django-multihost.htm
I have created a multihost.py file and put in to the django middleware folder:
C:\python27\Lib\site-packages\django\middleware\multihost.py
With the following code:
from django.conf import settings
from django.utils.cache import patch_vary_headers
class MultiHostMiddleware:
def process_request(self, request):
try:
host = request.META["HTTP_HOST"]
if host[-3:] == ":80":
host = host[:-3] # ignore default port number, if present
request.urlconf = settings.HOST_MIDDLEWARE_URLCONF_MAP[host]
except KeyError:
pass # use default urlconf (settings.ROOT_URLCONF)
def process_response(self, request, response):
if getattr(request, "urlconf", None):
patch_vary_headers(response, ('Host',))
return response
Also in my project setting.py file i have added a mapping dictionary like the link above shows:
# File: settings.py
HOST_MIDDLEWARE_URLCONF_MAP = {
"mysite1.com": "urls1",
#"mysite2.com": "urls2"
}
I did not yet implemented the error handling like described by the link above.
My hosts file includes the follwoing:
127.0.0.1 mysite1.com
Project structure is the following:
effbot django project folder:
+ effbot
--- settings.py
--- view.py
--- wsgi.py
--- urls.py
--- urls1.py
+ objex
--- models.py
--- views.py
+ static
--- css
--- images
There is no templates folder, because i dont serve html items from files, they are coming from databsse (i doubt that my problem is in this).
Now the problem is: when i go for the adress
mysite1.com
in my browser with django dev-server launched i get code 301 from the server. And browser shows "cannot display page" message.
Could you please explain me how to use mentioned method? I'm new to django and haven't done any real projects yet. Just have read the docs and launched a couple of sites at home to learn how it works.
I expect that urlconfs will be called in dependance from incoming
request.META["HTTP_HOST"]
The target is to serve different urlconfs for mysite1.com and mysite2.com
in a single django project.
I think this should to work some how.
Thank you for any feedback.
EDIT:
After some research attempts i found that i plugged my multyhost.py incorrectly in settings.
Fixed now. But the same result still.
Also i found out that my django dev-server tool is not reflecting anyhow that it handles any requests from the browser (IE9) except when i do "http://127.0.0.1".
May be i have to try some production server for my task, like nginx?
Your ROOT_URLCONF should be effbot.urls without .pyas you can see in the example in the documentation.
Also, HOST_MIDDLEWARE_URLCONF_MAP should reflect the ROOT_URLCONF so add `effbot. like this:
HOST_MIDDLEWARE_URLCONF_MAP = {
"mysite1.com": "effbot.urls1",
#"mysite2.com": "effbot.urls2"
}
One more thing, please try with another browser (Chrome, Firefox), sometimes I had problems accessing dev server with IE.