I'm setting up a Flask app on Heroku. Everything is working fine until I added static files. I'm using this:
from werkzeug import SharedDataMiddleware
app = Flask(__name__)
app.wsgi_app = SharedDataMiddleware(app.wsgi_app, {'/static': os.path.join(os.path.dirname(__file__), 'static') })
The first time I deploy the app, the appropriate files in the ./static will be available at herokuapp.com/static. But after that initial deploy, the files never change on Heroku. If I change the last line to:
app.wsgi_app = SharedDataMiddleware(app.wsgi_app, {'/assets': os.path.join(os.path.dirname(__file__), 'static') })
a new URL for the static files, herokuapp.com/assets, then I can see the updated files.
It seems like a mirror of the files gets stuck in the system. I've changed it four times and can access all of the URLs still.
SharedDataMiddleware defaults to sending Cache-Control and Expires HTTP headers, which means that your web browser may not even send a request to the server and just use the old files from cache. Try disabling the cache:
app.wsgi_app = SharedDataMiddleware(
app.wsgi_app,
{'/static': os.path.join(os.path.dirname(__file__), 'static')},
cache=False)
Flask does the same with static files. To disable it there:
app.config['SEND_FILE_MAX_AGE_DEFAULT'] = None
Related
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 use Flask as Web Application, to redirect http to https, I added such codes in app.py:
#app.before_request
def before_request():
if request.url.startswith('http://'):
url = request.url.replace('http://', 'https://', 1)
return redirect(url, code=301)
if __name__ == '__main__':
app.run()
and the gunicorn command in supervisor.conf is:
command=/home/MyToDo/venv/bin/gunicorn --certfile=/home/MyToDo/SSL/mytodo.vip.cer --keyfile=/home/MyToDo/SSL/mytodo.vip.key -w3 -b0.0.0.0:443 -b0.0.0.0:80 app:app
but when I visit the website, I still need to add "https://" in front the url, it didn't redirect automaticly. So how to make gunicorn redirect http to https, does using Nginx is the only way?
I had the same problem running Flask on Google App Engine Flexible environment with gunicorn. Solved by using werkzeug.contrib.fixers.ProxyFix of Werkzeug version 0.14.1.
from werkzeug.contrib.fixers import ProxyFix
app = Flask(__name__)
app.wsgi_app = ProxyFix(app.wsgi_app)
I had the same issues using Google App Engine and have spend too much time on this since all the answers including werkzeug.contrib.fixers.ProxyFix and the official docu's custom HTTPMethodsOverrideMiddleware or other custom solutions did not work for me.
I finally managed to solve this by configuring gunicorn using a config which sets:
secure_scheme_headers = {'X-FORWARDED-PROTO': 'https'} and forwarded_allow_ips = '*'
Additionally, for the ones wanting to serve static files and who are struggling with unwanted http redirects, adding handlers for each static directory in the .yaml configuration and avoiding nested sub-directories solved this issue.
Flask==2.1.3
gunicorn==20.1.0
I have a website that works fine on my 'production server' with the url being something akin to:
https://mymain.site.com
I have had my sys admins build a site out for development and that url is:
https://mymain.site.com/development
It is a different IP address, but I believe the URL is wrecking havoc on django routing. Mostly I notice it in the static section of it.
If I goto the development server settings and change the static url to:
/development/static/
instead of /static/ like it was on production
None of my static files are found. Since the development server is a VM copy the root on the server for static files is the same. So if I run with the /development/static as the dev url it fails to load resources. If I run on my development server with the url being /static/ I am 90% sure it is grabbing the static files from the production server (at a different ip/url). Not totally sure what the fix is here? I am loking for any kind of ideas.
I suspect if the url of my development server was something more akin to:
https://mymain.site.for.development/
then this would work right out of the box from the code copied from the VM just repointing a few things.
So what am I missing to get this to work with the right static files?
I use a CDN for my static file hosting and this is how I have my settings.py file setup:
STATIC_HOST = 'https://cdn.host.com' if not DEBUG else ''
STATIC_URL = STATIC_HOST + '/static/'
When I'm developing I'll set DEBUG = True and everything works as expected. I would imagine you would have to do something like this:
STATIC_HOST = 'https://mymain.site.com' if not DEBUG else 'https://mymain.site.com/development'
STATIC_URL = STATIC_HOST + '/static/'
See if something like that would work.
I'm relatively new to Angular 2, and I'm trying to build an app using the angular-cli system. This works and I can ng-serve and the application comes up. However, it seems like a huge pain in the ass to try and serve the application with anything other than the ng-serve system. In particular I'm trying to serve the application built with angular-cli with a Python Flask app. The amount of hoops I'm seemingly having to jump through trying to get this to work is making me crazy! I want to do this because I want to serve a REST API with the Python/Flask app that will respond to the HTTP services requests from the Angular 2 application.
Here are the relevant versions I'm using:
node - 6.2.2
npm - 2.9.5
angular 2 - rc.4
angular-cli - 1.0.0-beta.9
python - 2.7.5
flask - 0.10.1
How can I serve an Angular app while using Flask?
I've actually sort of solved the problem. I have a directory named "smoke" (short for smoke and mirrors ), and inside there I ran the angular-cli command:
ng new static
This created the angular-cli start out application in the static directory. Then I created this (simplified) Python Flask application:
import os
from flask import Flask, send_from_directory, redirect
from flask.ext.restful import Api
from gevent import monkey, pywsgi
monkey.patch_all()
def create_app():
app = Flask("press_controller")
# map the root folder to index.html
#app.route("/")
def home():
return redirect("/index.html")
#app.route("/<path:path>")
def root(path):
"""
This is the cheesy way I figured out to serve the Angular2 app created
by the angular-cli system. It essentially serves everything from
static/dist (the distribution directory created by angular-cli)
"""
return send_from_directory(os.path.join(os.getcwd(), "static/dist"), path)
return app
if __name__ == "__main__":
app = create_app()
server = pywsgi.WSGIServer(("0.0.0.0", 5000), app)
server.serve_forever()
else:
app = create_app()
This way I can navigate to http://localhost:5000 and the application will serve up the Angular app just like "ng serve" does. Now I can add in my REST API endpoints as I wanted and have Angular services access them to populate the application.
There's no requirement that Flask serves the frontend application.
Really all Flask would be doing with an Angular app is serving static files, something that is better handled by a web server like Nginx in production, or the framework's tools like ng-serve in development.
Meanwhile, Flask would act as the backend api server that your frontend app communicates with. Use request.get_json() and return jsonify(...) to get and respond with JSON data.
Run the two separately, they work together over HTTP only. This also simplifies working with backend vs. frontend developers: all they need to know about is the api to communicate between the two. However, since the frontend is being served on a different port than the backend, you'll need to set up Flask appropriately to allow CORS requests, for example with Flask-CORS.
Old question but I came across it when setting up my new project. I'm using a a more recent version of angular cli (7.3.1) and Flask (1.0.2) but the setup is pretty similar to yours. I should note that this is by no means the cleanest setup, and I'm sure the same could be achieved with webpack only, but I felt this way was a bit easier to follow (I've found webpack config can be a nightmare). My directory structure is as follows (after building):
client // this is my angular project
src
angular.json
server // this is my flask server
templates
index.html // generated from ng build
static
vendor.js // generated from ng build
pollyfills.js
...
Makefile
In angular.json, you'll want to point the build path to your flask server:
"build": {
"builder": "#angular-devkit/build-angular:browser",
"options": {
"outputPath": "../server/static",
"index": "src/index.html",
"main": "src/main.ts",
"polyfills": "src/polyfills.ts",
"tsConfig": "src/tsconfig.app.json",
"assets": [
"src/favicon.ico",
"src/assets"
],
"styles": [
"src/styles.scss"
],
"scripts": [],
"es5BrowserSupport": true
},
...
In my server, configure the static url:
app = Flask(__name__, static_url_path='')
And finally in the makefile, execute the build command, and copy the template file into the templates folder:
all:
cd client && ng build --prod;
mv server/static/index.html server/templates/ ;
.PHONY : all
Again, not the most elegant solution but pretty straight forward to get rolling with the angular cli (rather than getting the hands dirty with webpack).
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