M
M
MartinX2016-05-11 02:25:43
Software design
MartinX, 2016-05-11 02:25:43

How can you architect a really big Flask application?

I'm developing a large Flask application and there was a problem in its architecture. In general, I liked the approach in https://github.com/sean-/flask-skeleton that you can use Blueprint (there are plenty of similar examples and guides).

However, the application is great in that it is not just divided into several files for convenience, but serves several sites (hosts / subdomains - will be set in the config) that have an intersection of functionality (therefore, there is a common code for this) and a common session is maintained between them user and the database itself with them (and some other data).

In general, the architecture is now built in such a way that there is a certain core where common models and classes for all sites are created, as well as a Flask application is created, the Flask-SQLAlchemy extension is connected. Support for host matching was also included and the indication of the host in the Blueprint was implemented. The functional blocks themselves are stored in individual packages, where Blueprints are created for this matter, forms, models are defined (they import the created object of the SQLAlchemy class from the extension from the core), views. In general, the idea is the same as in the specified skeleton.

It would seem that everything is fine, register Blueprints in the Flask application and rejoice. But the problem is that Blueprint actually just registers the same imported views under different routes in the routing table (it assumes registering one Blueprint many times - Flask allows this). And this is not even the root of the problem: the model in the functional block remains the same and works with the same data. In fact, at different addresses there will be the same thing, which nullifies the whole point in the application.

At first I tried to solve the problem with models, but I began to think: was the application architecture built correctly? Isn't it too much to demand complete isolation from Blueprint and python packages? Perhaps we need to move towards creating specific instances of models from the abstract one and slip it into the view through the DI pattern? Perhaps it’s worth it to resort to the application factory pattern right now and create a Flask application for each site (but then you need to pass the session and other commonalities between them)?

Briefly and on the fingers, then I would like to build an architecture where let there be site1.ru, site2.ru, site3.ru. User bases and registration are common, session too. There is a common code in the form of blocks, which let them implement the functionality of the same news, articles and forums. And the config would indicate that site1.ru needs news on the main page (prefix /), site2.ru needs two article directories (prefixes /articles_1/ and /articles_2/), site3.ru needs news (prefix /news/ ) and forum (/forum/ prefix). And, of course, these, so to speak, blocks of code must operate with different content.

Well, I'll answer some possible questions:

  • Flask was chosen because it is minimalistic and allows you to build applications flexibly (yes, the price for this is that you need to make bundles in places and build the architecture yourself. but I appreciate the flexibility, minimalism, power
  • Django was not chosen because it is more convenient for typical solutions. I don’t like everything how it works, I would have to rewrite and implement some things in the same way
  • Yes, my knowledge of Python is not perfect, but I like to dive into something new with the help of real projects, and not memorize tons of books before it or build another twitter tutorial world, where the described problems simply do not come up.
  • The internals of SQLAlchemy are not completely clear to me yet, but it begins to seem to me that it is not necessary to fight with it, but the jamb is simply allowed in the architecture, which is why everything turns out like this ...


PS I apologize for such a long footcloth, but I would like to solve the problem beautifully, since I have been struggling with it for some time now. And I would not want to decide by the collective farm like folding all the content into just one model (more precisely, a table, since the model is mapped onto it) - I would not want to. If there were no ORM, then in pure SQL it would be solved with simple prefixes for tables. But ORM, Python is still a new stack of technologies for me, which I would very much like to use already, and not sit in php4-style.

Answer the question

In order to leave comments, you need to log in

3 answer(s)
V
Vladimir, 2016-05-11
@vintello

just switch to Django. get less headaches

S
sim3x, 2016-05-12
@sim3x

If you want to build a large application, then you already immediately have a big problem
Share
You don’t have to have everything in one database and on one site
Make accounts on one domain - one application
And do everything else through deployment on a new domain
A about flask, I haven't seen success stories

A
asd111, 2016-05-11
@asd111

Dynamic table selection for the same model in django is usually solved something like this:

def get_model(db_table):
  class MyClassMetaclass(models.base.ModelBase):
    def __new__(cls, name, bases, attrs):
      name += db_table
      return models.base.ModelBase.__new__(cls, name, bases, attrs)

  class MyClass(models.Model):
    __metaclass__ = MyClassMetaclass

    class Meta:
      db_table = db_table

  return MyClass

my_model = get_model('29345794_table')
my_model.objects.filter( ...

The bottom line is that when creating a model, dynamically specify the name of the table. And everything else will work as usual. I think how to do it under sqlAlchemy you will figure it out on your own.

Didn't find what you were looking for?

Ask your question

Ask a Question

731 491 924 answers to any question