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

前端 未结 3 507
后悔当初
后悔当初 2021-01-05 15:30

Does anyone know how to serve an Angular single page application using Flask?

I\'m having trouble serving the default route, \'/\', which should load index.html and

相关标签:
3条回答
  • 2021-01-05 15:55

    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
    /venv
    server.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.

    0 讨论(0)
  • 2021-01-05 16:11

    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.html
    static/ # 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
    
    0 讨论(0)
  • 2021-01-05 16:13

    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_directory
    
    app = 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
    
    0 讨论(0)
提交回复
热议问题