Python (Flask) serving Angular project's index.html file Python (Flask) serving Angular project's index.html file flask flask

Python (Flask) serving Angular project's index.html file


To simplify the setup, consider using Angular CLI to place all of the files in a distribution directory during the build process, i.e., by specifying the outputPath in angular.json. You can use the angular.json assets section to move your Python files during the build.

angular.json

"your-project": {  "root": "your-project-directory",  "sourceRoot": "your-project-directory/src",  "projectType": "application",  "architect": {    "build": {    "builder": "@angular-devkit/build-angular:browser",    "options": {      "outputPath": "dist",      "index": "your-project-directory/src/index.html",      "main": "your-project-directory/src/main.ts",      ...      "assets": [        {          "glob": "**/*",          "input": "your-project-directory/src/assets/",          "output": "assets"        },        {          "glob": "**/*",          "input": "your-project-directory/src/python/",          "output": "."        }



In the top level of the dist directory, place your main.py with the basic Flask setup along with index.html. Note the static_proxy to ensure that supporting files are served.

main.py

from flask import Flask, send_from_directoryapp = Flask(__name__)@app.route('/<path:path>', methods=['GET'])def static_proxy(path):  return send_from_directory('./', path)@app.route('/')def root():  return send_from_directory('./', 'index.html')if __name__ == '__main__':  # This is used when running locally only. When deploying use a webserver process   # such as Gunicorn to serve the app.  app.run(host='127.0.0.1', port=8080, debug=True)@app.errorhandler(500)def server_error(e):  return 'An internal error occurred [main.py] %s' % e, 500


This is an old question but accepted answer did not work for me. So here is my solution that works with angular routing:


My folder structure:

/angular    /src    angular.json    ... angular project files/public    index.html    ... angular build files/venvserver.py

In my angular.json I changed outputPath to achive above structure:

"outputPath": "../public"

And in server.py:

import os.path@app.route("/custom-endpoint")def custom_endpoint_handler():    return jsonify(myKey="myValue")# Serving static files@app.route('/', defaults={'path': ''})@app.route('/<string:path>')@app.route('/<path:path>')def static_proxy(path):    if os.path.isfile('public/' + path):        # If request is made for a file by angular for example main.js        # condition will be true, file will be served from the public directory        return send_from_directory('public', path)    else:        # Otherwise index.html will be served,        # angular router will handle the rest        return app.send_static_file("index.html")

Footnote: I am new to flask. So any improvements or fixes if there are any errors are welcomed.


As mentioned in Flask docs:

Just create a folder called static in your package or next to your module and it will be available at /static on the application.

So, if you use the template in:

templates/dist/templates/index.htmlstatic/ # set static folder there

Or, depending how you have your application sorted:

templates/dist/static/ # set static folder there

Have a look at how they sort the application in the docs:

/application.py/templates    /hello.html

or if you use module folders:

/application    /__init__.py    /templates        /hello.html