Forums

really basic app organization questions for Flask/Angular/other JS

Hi all, I have a lot of basic app organization questions. These are not specific to PythonAnywhere.

Using Flask. I'm not sure I'm making a single page application. In some sense I have various "apps" on different pages handled within different app.route sections. Question 1 - is that a reasonable organization for a small app? For example, in one page I upload some data and in another page, I massage this data, and in a third page, I (as a user) can download the new data. Of course, it can be more complicated. Now for some more super basic questions:

  1. I want to use Flask with Angular or some other framework. Reading elsewhere it seems like my Python Flask could just serve up REST APIs, and that is probably smarter. However, I plan to start with having Flask do the routing, then on my separate pages, I'll use Angular as a controller for that specific screen.

  2. What is a good/best way for all my top nav and side nav stuff. Should I have a template include other templates and if so what is a good way to keep all that organized? Further to that, if I create a button to do some change to my data, then I want to show my change on the right, should I basically use the same template but put my content on the right in a table column? Frames?

Edit since posting: mainly using Angular partials for this and various CSS things. No longer a question.

  1. What else should I think about when combining Flask and some kind of JS framework? Is it silly not to think REST APIs? Note that I obviously do not want to use node.js (or else I wouldn't be using PythonAnywhere). There are various Python libraries like pandas I want to use so it seems cleaner to use Flask or maybe Django.

Thanks for any answers. I realize this is kind of a big post.

Edit: got most of my questions above answered. Have more detailed questions below (most of which I seem to be figuring out eventually). These aren't really Python or PythonAnywhere questions, more general app, but appreciate all the comments!

Hmm, those are very broad questions, and I suspect a lot of them are quite subjective -- different people like to construct their sites differently.

The way we're building new stuff on PythonAnywhere isn't that different to what you're describing, though. Our website server code is Django (though it could equally well be Flask). Some of our pages are rendered as Django templates. Others, where we want something to change without moving to a new page, use React (again, we could probably equally well use Angular, though in our evaluation of different JS frameworks we decided we preferred React -- that's very subjective, though). The React code communicates with the server using a REST framework.

It all works pretty well.

The only specific thing I'd recommend is in relation to point 2, where you're asking about using templates versus frames for the nav stuff. There I'd definitely say that templates are the way to go. Using frames means that the URL in the browser's URL bar will stay the same when people are viewing different things (because the contents of frames have changed), which can lead to confusion -- especially if people use bookmarks or if they link to specific pages on your site from elsewhere.

Thanks so much for your answer, Giles. I realize it's very subjective and searching around, people call the JavaScript issue "Framework Hell". That said, I suppose I shouldn't mind having a choice between frameworks or tools many people love. If React makes it easy to change just a small portion of a page, maybe that is for me. I read that React is for the "view" portion only. Hmm. Seems like a good idea for what I'm trying to learn to do. I'll have to read up a lot more. I don't necessarily want to do "microservices" with Flask but it seems like many people believe this is smarter, more maintainable, etc. so thinking maybe Flask for API + React may be good and straightforward. Thanks.

Appreciate if anyone else would like to provide some opinions or experienced stories, too.

Re: JavaScript frameworks -- absolutely! If you haven't read it already, this article about what it's like to learn JavaScript in 2016 might be amusing...

Oh boy. Hahaha! That is really what this feels like. Love the Python 3 punchline at the end, too.

Read up on the Jinja2 documentation. A lot can be handled with templates.

http://jinja.pocoo.org/docs/2.9/

Please don't ask too many questions of me. I am still learning Flask & Jinja myself.

And I read the Javascript in 2016. Now my head is spinning.

Thanks. Perhaps as a partial result of reading that article, I decided to try some Angular first. Very easy to get started. However, I'm already running into a conflict because Angular wants to do routing and Flask also wants to do routing. Any tips to get this right? I set up Flask to route /angular to use a template that has my Angular app code. In that code, it has a router for some other routing, for example /about - but it is going to partially load an about.html template. I wonder if there is some conflict between the Flask routing and the Angular routing.

I assume this is all possible on PythonAnywhere and I've just got something set up wrong, but appreciate it if anyone has already done this and can provide a hint. Thanks.

Edit: already figured out how to do this. I think I can mix a small amount of Flask routing for some things I want to do with Flask, especially REST API to return bits of data, then mostly Angular for "SPA" routing to show bits of data coming back from my Flask processing. Any intermediate to advanced tips appreciated. What do I need to watch out for in using some Flask routing (esp for API) vs. some Angular routing?

I solved the template issue for now. Flask serves certain routes and Angular covers others. However, I am stuck on using controllers for only a portion of my app. I guess I probably just don't understand how to separate the root scope from a more specific section. Going to check around some more. I want to use Flask-Excel for a csv upload, then return some json to a table controlled with Angular inside a partial. If you happen to be reading this and know exactly what I'm talking about, appreciate any tips.

i thought angular does "routing" in that it knows say to hit this url when you need xyz resource. But the server side response is still all done by flask.

yes it does routing in a similar way to flask. the setup i'm still sorting out is roughly:

  • flask routes index.html which calls the main angular js file
  • that angular file routes angular style urls
  • in an angular partial, I use flask-excel to upload a csv using a post
  • normally the python code I use can do something like pandas.to_html() to send back html (I'll switch it to json).
  • I don't think I can do that the flask way because angular likely needs to do another http get to get the results.
  • so I suppose when I post to python, I'll generate the result and have to hold it (in memory? on disk?) to be ready for the angular to do the get.

anybody happen to know?

I think there is likely some kind of callback function in Angular, right? So I can do this:

  • send post of csv to Python for processing
  • Angular function will wait for and expect json to come back, rather than issue another http get and expect the Flask code to process and make the data available from a url (seems inefficient)

it depends how long it takes to do the calculations. if it's <30s, then you could just respond to the initial csv upload request with the result. then angular could take that and display it. i believe this is what you are describing.

if it takes significantly longer, then you would have to get angular to get the results (eg: by hitting an endpoint every 1min say, or just by refreshing the page). And you could store/cache the results in say the database (again, depending on what/how big the result is)

thanks, bfg. hmm, that is a really good point. I assume for the former (short case), there is some kind of callback waiting thing. I just don't know how to do that just yet. Will get back to this in a few days or a week. For the latter case, that seems reasonable.

Hi all, I got my very basic case working. My angular routing is separate from my Flask routing. Essentially: Flask has various routes:

  • a
  • b
  • c

Inside one of these routes is an Angular single page app, so as if inside a there are more routes so content can load dynamically without reloading the whole page:

  • a
  • a#/1
  • a#/2
  • a#/3 Inside one of these pages is a table that is generated dynamically from another site/url that returns some simple JSON. So on to the next part.

I want that JSON to be dynamic based on user manipulations that use Python on the server side. This Python should then send back JSON. I don't want to have a static URL. I want to hand some dynamic URL, possibly with some state info, back to my Angular controller. The Angular controller will then offer to the user to do another step and this process will repeat.

How should I best do that in a really clean, scalable way? Any advice? Edit: basically use the Angular Promises as a callback type of function?

if you mean that between http requests, the server is supposed to save state/remember previous calculations, then that's not really something i would suggest to do. (ie. you want to be relatively stateless between http requests).

it sounds like you are describing something like:

from the webpage, you tell the server to load xyz file, then server responds with, "ok, executed this code". then you tell server to manipulate xyz in abc way, then server responds with "ok, executed that code and here is the result" etc. and you take that result and do more stuff to it, and potentially reference stuff/variables previously executed/stored.

webapps aren't the best way to do this / you are going to end up creating something super complicated.

yeah unfortunately though http is stateless, I want to do this complicated app as a webapp. hmm. in way over my head but it is fascinating...

I have a question in production do we have to do the commancd npm run serve to start angulars server as well? I think thats what has kept me from getting angular 2 typescript up and going in a small project on pythonanywhere.com is if my django server will run both or if i need to do the npm run serve as well thanks any information would be appreciated thanks guys

npm run serve will not work on PythonAnywhere. If you need TypeScript you will have to pre-compile it into plain JavaScript and deliver it through your web app.

gotcha thats what threw me off was not sure if we needed angulars server to make it work but if pythonanywhere takes care of it then thats one less thing to worry about :)

and Precompile? I thought typescript did that for us

Maybe? I don't know. It depends on how you've set up your toolchain, I guess.

I'm using flask as a backend. the organization of flask for api rest that I used is based on this tutorial which also uses flask migration to show a model for api rest.

The JS code I store it on the static folder, but it was previous "compiled". Then my index.html includes the JS in the static folder. The js code uses the flask api rest backend.

That sounds like a good setup! Is it working well?

Hey all, getting back to this topic after working on something else for a while. Still have some really basic noob questions.

I am uploading csv and do a manipulation with pandas. I want to send back some json to angular. I can have an angular partial load some json but I'm hardcoding my column names for now. What is a good way to deal with my column names (unknown in advance) dynamically? Thanks for any hints.

Edit: I think doing something like this answer may be a good way to go? https://stackoverflow.com/questions/27851484/angularjs-dynamic-table-with-unknown-number-of-columns

P.S. this looks really interesting but I think that will be a step 2 or later for me: http://ui-grid.info/docs/#/tutorial/207_importing_data

The answer in the Stack Overflow post looks pretty good to me.

Thanks for the 2nd opinion! After some modifications to fit my specific controller, I got it working and now I think I will know how to send back JSON I can show, regardless of number of columns.

My next question after that is going to be about how to select a specific column in my UI to send info back to my Python code.

For example, columns in cols is used in my ng-repeat to show each one in my table. However, I'll want to show a name of a column in the UI and then send my Python code this specific column info and do something with it. This is again conceptually easy, but I really find js (and angularjs) code to be weird. Any tips from anyone appreciated. I'll probably find an example sooner or later, though.

Another question (still searching stackoverflow, etc.) that is probably super basic.

How do I submit a post using angular framework, wait for response, then redirect to another page (partial)?

i think it's something like $http.post, and then on success, $location.path('/new/path')

if you search on stack overflow you will find something like this

Thanks, conrad. Conceptually that seems straightforward enough. I am a little baffled by angular syntax, so kind of going back and doing a bunch of catch-up reading first.

So I found this nice snippet in the pandas doc.

    >>> df.to_json(orient='table')
'{"schema": {"fields": [{"name": "index", "type": "string"},
                        {"name": "col 1", "type": "string"},
                        {"name": "col 2", "type": "string"}],
             "primaryKey": "index",
             "pandas_version": "0.20.0"},
  "data": [{"index": "row 1", "col 1": "a", "col 2": "b"},
           {"index": "row 2", "col 1": "c", "col 2": "d"}]}'

My angularjs is currently set up to process json that looks like a nested dictionary with "records" as the only key for the outer dict and a list of dicts as column/value pairs. It works. I don't know how to insert the name "records" as the outer key. I'm returning json that looks like a list of dicts instead. Trying to figure that out. Edit: figured that out already.

However wondering if I should scrap that and switch to table orientation instead. Is there much benefit to having a much more well defined schema and data section in the returned json? I guess there is, but right now my json which is raw rows and cols is already parsed.