Angular 4 frontend with python flask backend how to render simple index page

10,927

Solution 1

Since I had this same problem, I hope this answer will help someone looking for it again.

  1. First create your angular application and build it. (You will get all the required js files and index.html file inside the 'dist' folder.
  2. Create your python + flask web app with required end points.

    from flask import Flask,render_template
    app = Flask(__name__)
    
    @app.route("/")
    def hello():
        return render_template('index.html')
    
    if __name__ == "__main__":
        app.run()
    
  3. Create a folder 'templates' inside your python app root folder.

  4. Copy your index.html file from the angular dist folder to newly created 'templates' folder.

  5. Create a another folder call 'static' inside your python app root folder

  6. Then copy all the other static files( JS files and CSS files ) to this new folder.

  7. Update your index.html file static file urls like this.

      <script type="text/javascript" src="/static/inline.bundle.js"></script>
    

Flask look static files inside '/root_folder/static' folder and update url relative to this structure.

Done. Now your app will serve on localhost:5000 and angular app will served. Final folder structure will like this,

    /pythondApplication
        |-server.py
        |-templates
        |     -index.html
        |-static
        |     -js files and css files 

Since this is my first answer in stackoverflow,If there is a thing to be corrected, feel free to mention it.

Solution 2

I don't think that it's possible to access Angular 'dist' directory via a REST API. Any routing should be done on the client-side with Angular, and Flask should handle your end-points.

In terms of building your REST API, I'd recommend something like this:

from flask import Flask, jsonify

app = Flask(__name__)

tasks = [
    {
        'id': 1,
        'title': u'Buy groceries',
        'description': u'Milk, Cheese, Pizza, Fruit, Tylenol', 
        'done': False
    },
    {
        'id': 2,
        'title': u'Learn Python',
        'description': u'Need to find a good Python tutorial on the web', 
        'done': False
    }
]

@app.route('/todo/api/v1.0/tasks', methods=['GET'])
def get_tasks():
    return jsonify({'tasks': tasks})

if __name__ == '__main__':
    app.run(debug=True)

This is from a very helpful tutorial on building a basic REST API in Flask.

This will then plug in very nicely to your client-side in Angular:

getInfo() {
 return  this.http.get(
   'http://myapi/id')
   .map((res: Response) => res.json());

}

Share:
10,927
George C.
Author by

George C.

Nothing special to see but you can find something interesting here

Updated on July 04, 2022

Comments

  • George C.
    George C. almost 2 years

    Hello Python community I am angular and node.js developer and I want to try Python as backend of my server because I am new to python I want to ask you how to target the dist folder that contains all HTML and CSS and js files from the angular 4 apps in flask python server

    Because my app is SPA application I have set routes inside angular routing component

    When I run about or any other route I get this string message './dist/index.html' And I know I return string message but I want to tell the flask whatever route the user type on URL let the angular to render the page because inside my angular app I have set this pages and is work

    any help how to start with flask and angular to build simple REST API

    Now I have this file structure

    python-angular4-app
                      |___ dist
                      |      |___ index.html
                      |      |___ style.css
                      |      |___ inline.js
                      |      |___ polyfill.js
                      |      |___ vendor.js
                      |      |___ favicon.ico
                      |      |___ assets
                      |
                      |___ server.py
    

    My server.py have this content

    from flask import Flask
    
    app = Flask(__name__, )
    
    @app.route('/')
    def main():
        return './dist/index.html'
    
    
    @app.route('/about')
    def about():
        return './dist/index.html'
    
    
    @app.route('/contact')
    def contact():
        return './dist/index.html'
    
    if __name__ == "__main__":
        app.run(debug=True)
    

    Best regards George35mk thnx for your help

  • George C.
    George C. over 6 years
    Thank you Gerand but what about the index.html, The python can render html files ??
  • George C.
    George C. over 6 years
    can you teel mee how to render the index.html when the user hits "/" and if the user hit "about i want to render again the index.html" all this is not work
  • DariusFontaine
    DariusFontaine over 6 years
    You need to use the "render_template()" method. So it would be something like : 'return render_template("index.html")'
  • DariusFontaine
    DariusFontaine over 6 years
    Also worth mentioning that 'render_template' needs to be imported from 'flask'. Hope this helps! :)
  • George C.
    George C. over 6 years
    my index is inside "dist/index.html I need to call this every time the user types" for example localhost:5000/about
  • George C.
    George C. over 6 years
    i get this error jinja2.exceptions.TemplateNotFound: index.html
  • DariusFontaine
    DariusFontaine over 6 years
    Have you tried 'render_template("dist/index.html")'? Apologies, I may have misinterpreted what you are trying to do.
  • George C.
    George C. over 6 years
    i have try 100 difrient combinations but i canot render the pages
  • George C.
    George C. over 6 years
    i have this error jinja2.exceptions.TemplateNotFound jinja2.exceptions.TemplateNotFound: dist/index.html
  • DariusFontaine
    DariusFontaine over 6 years
    Could you try placing all of your templates into a directory called "templates"? I just remembered that Flask automatically looks for a folder called that
  • George C.
    George C. over 6 years
    i rename the dist folder to templates
  • DariusFontaine
    DariusFontaine over 6 years
    So are you still getting a jinja2.exception? If not, is your index.html formatted correctly? By that I mean is it formatted for Angular or does it use Jinja contemplating, or is it just plain html?
  • George C.
    George C. over 6 years
    it is angular 4 app this files works perfect in node.js
  • George C.
    George C. over 6 years
    but in python is very hard no videos on youtube how to make angular 4 app with python
  • George C.
    George C. over 6 years
    With node.js i target the folder that contains all the index and css files and thats it
  • George C.
    George C. over 6 years
    i add the app.routes(**) and now angular take the route controls
  • DariusFontaine
    DariusFontaine over 6 years
    Hi George, you seem to be trying to render templates which are structured for Angular. As I said in my original answer, these would need to be handled on the client-side, as Python does not recognize the structure of your templates. However if you want to use Flask to actually render html templates, they need to be formatted using either plain html, or Jinja: jinja.pocoo.org/docs/2.9. Your Angular most likely works with Node because Angular compiles TypeScript to JavaScript, but we unfortunately we have to jump through some hoops to gain the full benefits of Python ;)
  • George C.
    George C. over 6 years
    When i run ng build --prod i compile the code in pure javascript there is no typescript in the code aftter i run this command take that dist folder and run it what ever backend language you want java asp.net node.js all can read .html file css and javascript the problem i facing is if the user tytpe localhost/ i want to sent the index.html from that dist folder if the user type localhost/pdashboard i the python to sent again the index.html file becaus i have SPA aplication i dont need templates and if the user type localhost/api/user i want only json response
  • Orestis Zekai
    Orestis Zekai over 4 years
    Very nice and detailed guide. But how do I specify the paths for the icons located in the /assets/img folder