227

I am pretty new to this whole MV* client-side framework frenzy. It doesn't have to be AngularJS, but I picked it because it feels more natural to me than either Knockout, Ember or Backbone. Anyway what is the workflow like? Do people start with developing a client-side application in AngularJS and then hooking up the back-end to it?

Or the other way around by first building the back-end in Django, Flask, Rails and then attaching an AngularJS app to it? Is there a "right" way of doing it, or is it just a personal preference in the end?

I am also not sure whether to structure my project according to the Flask or AngularJS? community practices.

For example, Flask's minitwit app is structured like so:

minitwit
|-- minitwit.py
|-- static
   |-- css, js, images, etc...
`-- templates
   |-- html files and base layout

AngularJS tutorial app is structured like this:

angular-phonecat
|-- app
    `-- css
    `-- img
    `-- js
    `-- lib
    `-- partials
    `-- index.html
|-- scripts
 `-- node.js server and test server files

I could picture a Flask app by itself, and it's fairly easy to see AngularJS app like ToDo List by itself but when it comes to using both of these technologies I don't understand how they work together. It almost seems like I don't need a server-side web-framework when you already have AngularJS, a simple Python web server will suffice. In the AngularJS to-do app for example they use MongoLab to talk to the database using Restful API. There was no need having a web framework on the back-end.

Maybe I am just awfully confused, and AngularJS is nothing more than a fancy jQuery library so I should use just like I would use jQuery in my Flask projects (assuming I change the AngularJS template syntax to something that doesn't conflict with Jinja2). I hope my questions make some sense. I mainly work on the back-end and this client-side framework is an unknown territory for me.

Graham
  • 7,431
  • 18
  • 59
  • 84
Sahat Yalkabov
  • 32,654
  • 43
  • 110
  • 175

6 Answers6

170

I would start out by organizing the Flask app in the standard structure as follows:

app
|-- app.py
|-- static
    |-- css
    |-- img
    |-- js
|-- templates

And as btford mentioned, if you are doing an Angular app, you'll want to focus on using Angular client-side templates and stay away from server-side templates. Using render_template('index.html') will cause Flask to interpret your angular templates as jinja templates, so they won't render correctly. Instead, you'll want to do the following:

@app.route("/")
def index():
    return send_file('templates/index.html')

Note that using send_file() means that the files will be cached, so you might want to use make_response() instead, at least for development:

    return make_response(open('templates/index.html').read())

Afterwards, build out the AngularJS part of your app, modifying the app structure so that it looks like this:

app
|-- app.py
|-- static
    |-- css
    |-- img
    |-- js
        |-- app.js, controllers.js, etc.
    |-- lib
        |-- angular
            |-- angular.js, etc.
    |-- partials
|-- templates
    |-- index.html

Make sure your index.html includes AngularJS, as well as any other files:

<script src="static/lib/angular/angular.js"></script>

At this point, you haven't yet constructed your RESTful API, so you can have your js controllers return predefined sample data (only a temporary setup). When you're ready, implement the RESTful API and hook it up to your angular app with angular-resource.js.

EDIT: I put together an app template that, though a little more complex that what I've described above, illustrates how one could build an app with AngularJS + Flask, complete with communication between AngularJS and a simple Flask API. Here it is if you want to check it out: https://github.com/rxl/angular-flask

Ryan Shea
  • 4,252
  • 4
  • 32
  • 32
  • 1
    I came across this issue: the file's context wasn't preserved when I attempted to serve the index.html statically. I got around this by prepending my static file with `app.root_path`. Otherwise, this is pretty spot on. – Makoto Sep 28 '13 at 20:32
  • Can you explain more about "Note that using send_file() means that the files will be cached, so you might want to use make_response() instead, at least for development"? Thanks – nam Jan 08 '14 at 17:56
  • How do you manage builds, such as using grunt with this approach ? – Saad Farooq May 13 '14 at 17:35
  • 1
    @nam, i think what he means is that if you're making small changes in your js etc while debugging, you won't see the effect in the browser because send_file caches files being served with a timeout = SEND_FILE_MAX_AGE_DEFAULT. there are ways to override this but it's much simpler to just use make_response until you're ready for deployment. – ars-longa-vita-brevis Jun 21 '14 at 17:19
  • @SaadFarooq I don't cover grunt here because it complicates things quite a bit. If you're ready to use something like Grunt, then it makes sense to have a separate repo for the front-end code, then bundle everything together, copy-paste it into the Flask repo or push it to a CDN, and reference it from index.html. – Ryan Shea Jun 21 '14 at 22:36
  • what about templates that you want to include with ng-include? should those be in static templates, or some other place? – zidarsk8 Jun 22 '14 at 13:41
  • Angular templates are known as partials. If you're ng-include'ing any templates, I'd put them in that folder. – Ryan Shea Jun 22 '14 at 19:57
  • What's the benefit of serving the angular html files with flask instead of directly through the server? – TheOne Jan 20 '15 at 19:15
  • what do you mean "Using render_template('index.html') will cause Flask to interpret your angular templates as jinja templates, so they won't render correctly."? Are your referring to how angular and jinja2 share the curly braces? I believe jinja2 can be configured to use syntax. I understand why you wouldnt want to use it at all. But i'n not sure why i should stay away from using render_template. – Drew Verlee Apr 07 '15 at 22:03
  • Also, can you explain how "make_response" compares to "send_static_file"? I have seen them both used to achieve similar results. – Drew Verlee Apr 08 '15 at 00:21
  • You could use render_template if you want. Just wrap any Angular content in {% raw %}{% endraw %} and Flask won't render that bit. – ChrisE Nov 13 '16 at 20:02
38

You can start on either end.

You are right that you probably don't need a full server-side framework with AngularJS. It's typically better to serve static HTML/CSS/JavaScript files, and provide a RESTful API for the back end for the client to consume. One thing that you should probably avoid is mixing server-side templates with AngularJS client-side templates.

If you want to use Flask to serve your files (might be overkill, but you can use it nonetheless) you would copy the contents of "app" from "angular-phonecat" into the "static" folder of "minitwit."

AngularJS is more targeted at AJAX-like applications, whereas flask gives you the ability to do both the older-style web apps as well as create RESTful APIs. There are advantages and disadvantages to each approach, so it really depends what you want to do. If you give me some insights, I might be able to make further recommendations.

btford
  • 5,631
  • 2
  • 29
  • 26
  • 26
    +1 - but I wouldn't say that Flask is targeted at older-style web apps - it provides all the helpers you **need** to use it as a web API backend too ;-) There is also [Flask-Restless](http://flask-restless.readthedocs.org/en/latest/) if you want to be able to generate a JSON-serving API for your web app really easily using [Flask-SQLAlchemy](http://packages.python.org/Flask-SQLAlchemy/) - just FYI :-) – Sean Vieira Jul 18 '12 at 15:09
  • Good point! I'm not especially familiar with Flask; thanks for providing some expertise on the subject. – btford Jul 18 '12 at 19:11
  • 3
    also check out our tutorial which shows how to build crud apps with angular and all of the tooling we provide: http://docs.angularjs.org/tutorial – Igor Minar Jul 24 '12 at 19:46
  • 2
    To me, it seems fair to put the "app" folder from "angular-phonecat" to the static folder. But I think the index.html file should be put into the minitwit templates folder. The css and img folders should be moved to "static". – Nezo Jan 24 '13 at 17:12
22

This official Jetbrains PyCharm video by John Lindquist (angular.js and jetbrains guru) is a nice starting point as it shows the interplay of webservice, database and angular.js within flask.

He builds a pinterest clone with flask, sqlalchemy, flask-restless and angular.js in less than 25 minutes.

Enjoy: http://www.youtube.com/watch?v=2geC50roans

Bijan
  • 25,559
  • 8
  • 79
  • 71
17

edit: The new Angular2 style guide suggests a similar, if not the same structure in much more detail.

The answer below target large scale projects. I have spend quite some time thinking and experimenting with several approaches so I can combine some server side framework (Flask with App Engine in my case) for back-end functionality along with a client side framework like Angular. Both answers are very good, but I would like to suggest a slightly different approach which (in my mind at least) scales in a more human way.

When you are implementing a TODO example, things are quite straight forward. When you start adding functionality though and small nice details for user experience improvement, its not difficult to get lost in chaos of styles, javascript etc..

My application started to grow quite big, so I had to take a step back and rethink. Initially an approach like suggested above would work, by having all the styles together and all JavaScript together, but its not modular and not easily maintainable.

What if we organized the client code per feature and not per file type:

app
|-- server
    |-- controllers
        |-- app.py
    |-- models
        |-- model.py
    |-- templates
        |-- index.html
|-- static
    |-- img
    |-- client
        |-- app.js
        |-- main_style.css
        |-- foo_feature
            |-- controller.js
            |-- directive.js
            |-- service.js
            |-- style.css
            |-- html_file.tpl.html
        |-- bar_feature
            |-- controller.js
            |-- directive.js
            |-- service.js
            |-- style.css
            |-- html_file.tpl.html
    |-- lib
        |-- jquery.js
        |-- angular.js
        |-- ...

and so on.

If we build it like this, we can wrap every directory of ours in an angular module. And we have split our files in a nice way that we don't have to go through irrelevant code when we are working with a specific feature.

A task runner like Grunt properly configured, will be able to find and concatenate and compile your files without much hassle.

topless
  • 8,069
  • 11
  • 57
  • 86
1

Another option is to completely separate the two.

project
|-- server
|-- client

Files related to flask goes under the server folder and files related to angularjs goes under the client folder. This way, it will be easier to change the backend or front-end. For example, you might want to switch from Flask to Django or AngularJS to ReactJS in the future.

Bhargav Rao
  • 50,140
  • 28
  • 121
  • 140
John Kenn
  • 1,607
  • 2
  • 18
  • 31
0

I think it is important to determine at what end you want to do most of your data processing - front end or back end.
If it's front end, then go with the angular workflow, which means your flask app will function as more of an api where an extension like flask-restful will come end.

But if like me, you are doing most work on the backend, then go with the flask structure and only plug angular ( or in my case vue.js) to build the front end (when neccessary)

Kudehinbu Oluwaponle
  • 1,045
  • 11
  • 11