librelist archives

« back to archive

import blueprints dynamically?

import blueprints dynamically?

From:
Malphas Wats
Date:
2012-10-06 @ 11:30
Hi,

  I think this is more a python question than a flask question, but
it's not something I've needed to do yet for anything else!

I'm building a flask app that simply provides login management and
that's it. I then want to extend the app with different features, such
as a blog tool, bookmark tool and so on, but each feature I add I want
to build as a blueprint that just relies on the top-level app to
provide the account management stuff.

I'd like to be able to just drop each blueprint module into a
'Blueprints' folder, restart the frontend (or maybe even without
having to restart?) and have it automatically detect the new
blueprint, import the python code and list it in the menu.

How can I import python modules variably? without having to hard-code
the imports?

Thank you
-Malphas

Re: [flask] import blueprints dynamically?

From:
Jeffrey Tratner
Date:
2012-10-06 @ 11:54
I thought this looked interesting, so I wrote up a code snippet.

I saved this to a Gist on Github, which might be easier to work with:
https://gist.github.com/3844721

(but I also copy/pasted it here if you don't want to click the link :P)

The key to the snippet is using the "imp" module (
http://docs.python.org/library/imp.html) to dynamically import files, then
using getattr to get the
actual blueprint from the file and finally registering it on the app.  I'm
surprised, it actually turned out not
to be that difficult.  The key issue is that you need to have a standard
naming scheme for blueprints (for example,
the code expects every file to have an attribute called "the_blueprint",
but you can pass whatever blueprint name
to register blueprints).

import os


PATH = os.getcwd()

BLUEPRINT = 'the_blueprint'



def import_file(path, name=None):

    """ imports a file with given name and path """

    # use the imp module to do actual imports

    import imp

    name = name or os.path.split(path)[-1].replace(".", "_")

    fp, pathname, description = imp.find_module(path)

    return imp.load_module(name, fp, pathname, description)


def register_blueprints(app, files, blueprint_attribute):

    """ registers the blueprints from a given set of files on the given app """

    imported_modules = [import_file(file) for file in files]

    for module in imported_modules:

        app.register(getattr(module, blueprint_attribute))


if __name__ == "__main__":

   # get the files that end in py in the folder

   filelist = [file for file in os.listdir(PATH) if file.endswith ".py"]

   from my_app import app

   register_blueprints(app, filelist, BLUEPRINT)




On Sat, Oct 6, 2012 at 7:30 AM, Malphas Wats <malphas@subdimension.co.uk>wrote:

> Hi,
>
>   I think this is more a python question than a flask question, but
> it's not something I've needed to do yet for anything else!
>
> I'm building a flask app that simply provides login management and
> that's it. I then want to extend the app with different features, such
> as a blog tool, bookmark tool and so on, but each feature I add I want
> to build as a blueprint that just relies on the top-level app to
> provide the account management stuff.
>
> I'd like to be able to just drop each blueprint module into a
> 'Blueprints' folder, restart the frontend (or maybe even without
> having to restart?) and have it automatically detect the new
> blueprint, import the python code and list it in the menu.
>
> How can I import python modules variably? without having to hard-code
> the imports?
>
> Thank you
> -Malphas
>

Re: [flask] import blueprints dynamically?

From:
Malphas Wats
Date:
2012-10-06 @ 18:37
OK, so I've been working on this for a few hours now and I can't get it to work.

I have the code online here:
  https://github.com/MalphasWats/flask-blueprint-loader

for the moment, I've hard-coded the blueprint that I want to load. If
I run it, I get:
    ImportError: No frozen submodule named blueprints.very_simple_page

if I change line 17 of dashboard.py to remove the path parameter:
    fp, pathname, description = imp.find_module('very_simple_page')

and move very_simple_page.py into the root of the project directory
(same folder as startDevServer.py) it works, but I can't work out how
to make it import stuff in the blueprints directory.

I did also test it with the simple_page package, as long as
__init__.py imports the blueprint, it works (when the package
directory is in the root, but not when it is in the blueprints
directory).

I've moved the blueprints directory all over the place to no effect.

If anyone has a bit of spare time, I'd really appreciate it if you
could take a look at it. I always struggle with the import path, it
just doesn't quite fit in my brain properly.

in answer to your question Amirouche, yes you can register blueprints
on a running app, but as I understand it, you can't unregister them
(would require the app to be restarted).

Thanks
-Malphas

On Sat, Oct 6, 2012 at 12:54 PM, Jeffrey Tratner <jtratner@gmail.com> wrote:
> I thought this looked interesting, so I wrote up a code snippet.
>

Re: [flask] import blueprints dynamically?

From:
Smartboy
Date:
2012-10-06 @ 18:44
I already have a solution working for this in one of my projects which may
help you. It's located in ScoringServer/utils.py (function named
load_plugins) with an example of it being used to load blueprints in
ScoringServer/views.py. The project's url:
https://github.com/smartboyathome/Cheshire-Engine

Alex Abbott

On Sat, Oct 6, 2012 at 11:37 AM, Malphas Wats <malphas@subdimension.co.uk>wrote:

> OK, so I've been working on this for a few hours now and I can't get it to
> work.
>
> I have the code online here:
>   https://github.com/MalphasWats/flask-blueprint-loader
>
> for the moment, I've hard-coded the blueprint that I want to load. If
> I run it, I get:
>     ImportError: No frozen submodule named blueprints.very_simple_page
>
> if I change line 17 of dashboard.py to remove the path parameter:
>     fp, pathname, description = imp.find_module('very_simple_page')
>
> and move very_simple_page.py into the root of the project directory
> (same folder as startDevServer.py) it works, but I can't work out how
> to make it import stuff in the blueprints directory.
>
> I did also test it with the simple_page package, as long as
> __init__.py imports the blueprint, it works (when the package
> directory is in the root, but not when it is in the blueprints
> directory).
>
> I've moved the blueprints directory all over the place to no effect.
>
> If anyone has a bit of spare time, I'd really appreciate it if you
> could take a look at it. I always struggle with the import path, it
> just doesn't quite fit in my brain properly.
>
> in answer to your question Amirouche, yes you can register blueprints
> on a running app, but as I understand it, you can't unregister them
> (would require the app to be restarted).
>
> Thanks
> -Malphas
>
> On Sat, Oct 6, 2012 at 12:54 PM, Jeffrey Tratner <jtratner@gmail.com>
> wrote:
> > I thought this looked interesting, so I wrote up a code snippet.
> >
>

Re: [flask] import blueprints dynamically?

From:
Malphas Wats
Date:
2012-10-06 @ 20:04
This is brilliant, thank you! It seems the only thing I was doing
wrong was that I was passing the path as a simple string, rather than
a list:
    fp, pathname, description = imp.find_module('very_simple_page',
'blueprints')

should be:
    fp, pathname, description = imp.find_module('very_simple_page',
['blueprints'])

Your solution is really nice, thanks!
-Malphas

On Sat, Oct 6, 2012 at 7:44 PM, Smartboy <smartboyathome@gmail.com> wrote:
> I already have a solution working for this in one of my projects which may
> help you. It's located in ScoringServer/utils.py (function named
> load_plugins) with an example of it being used to load blueprints in
> ScoringServer/views.py. The project's url:
> https://github.com/smartboyathome/Cheshire-Engine
>
> Alex Abbott

Re: [flask] import blueprints dynamically?

From:
Jeremy Sandell
Date:
2012-10-06 @ 19:03
On Sat, Oct 6, 2012 at 2:37 PM, Malphas Wats <malphas@subdimension.co.uk>wrote:

> OK, so I've been working on this for a few hours now and I can't get it to
> work.
>
> I have the code online here:
>   https://github.com/MalphasWats/flask-blueprint-loader
>
> for the moment, I've hard-coded the blueprint that I want to load. If
> I run it, I get:
>     ImportError: No frozen submodule named blueprints.very_simple_page
>
> if I change line 17 of dashboard.py to remove the path parameter:
>     fp, pathname, description = imp.find_module('very_simple_page')
>
> and move very_simple_page.py into the root of the project directory
> (same folder as startDevServer.py) it works, but I can't work out how
> to make it import stuff in the blueprints directory.
>
> I did also test it with the simple_page package, as long as
> __init__.py imports the blueprint, it works (when the package
> directory is in the root, but not when it is in the blueprints
> directory).
>
> I've moved the blueprints directory all over the place to no effect.
>
> If anyone has a bit of spare time, I'd really appreciate it if you
> could take a look at it. I always struggle with the import path, it
> just doesn't quite fit in my brain properly.
>
> in answer to your question Amirouche, yes you can register blueprints
> on a running app, but as I understand it, you can't unregister them
> (would require the app to be restarted).
>
> Thanks
> -Malphas
>
>
Pretty busy right now, but this is a problem I solved a year or so ago
using "werkzeug.utils.find_modules" and "werkzeug.utils.import_string"

When I have more time I'll see about posting the snippet as a gist.

HTH,
Jeremy Sandell

Re: [flask] import blueprints dynamically?

From:
Jeffrey Tratner
Date:
2012-10-06 @ 19:12
I'll try and take a look at it later. Can you post trace backs or minimal
working examples so I can play around with it? You might also try just
using __import__ directly (e.g.__import__(somestr).blueprint)
On Oct 6, 2012 2:40 PM, "Malphas Wats" <malphas@subdimension.co.uk> wrote:

> OK, so I've been working on this for a few hours now and I can't get it to
> work.
>
> I have the code online here:
>   https://github.com/MalphasWats/flask-blueprint-loader
>
> for the moment, I've hard-coded the blueprint that I want to load. If
> I run it, I get:
>     ImportError: No frozen submodule named blueprints.very_simple_page
>
> if I change line 17 of dashboard.py to remove the path parameter:
>     fp, pathname, description = imp.find_module('very_simple_page')
>
> and move very_simple_page.py into the root of the project directory
> (same folder as startDevServer.py) it works, but I can't work out how
> to make it import stuff in the blueprints directory.
>
> I did also test it with the simple_page package, as long as
> __init__.py imports the blueprint, it works (when the package
> directory is in the root, but not when it is in the blueprints
> directory).
>
> I've moved the blueprints directory all over the place to no effect.
>
> If anyone has a bit of spare time, I'd really appreciate it if you
> could take a look at it. I always struggle with the import path, it
> just doesn't quite fit in my brain properly.
>
> in answer to your question Amirouche, yes you can register blueprints
> on a running app, but as I understand it, you can't unregister them
> (would require the app to be restarted).
>
> Thanks
> -Malphas
>
> On Sat, Oct 6, 2012 at 12:54 PM, Jeffrey Tratner <jtratner@gmail.com>
> wrote:
> > I thought this looked interesting, so I wrote up a code snippet.
> >
>

Re: [flask] import blueprints dynamically?

From:
Amirouche Boubekki
Date:
2012-10-06 @ 16:25
Héllo,

Thanks for the trick Jeffrey I did not know the imp module, it's a rather
useful module.

Just one question, is it possible to register blueprints or new urls on a
running application ?


Thanks,


Amirouche

2012/10/6 Jeffrey Tratner <jtratner@gmail.com>

> I thought this looked interesting, so I wrote up a code snippet.
>
> I saved this to a Gist on Github, which might be easier to work with:
> https://gist.github.com/3844721
>
> (but I also copy/pasted it here if you don't want to click the link :P)
>
> The key to the snippet is using the "imp" module (
> http://docs.python.org/library/imp.html) to dynamically import files,
> then using getattr to get the
> actual blueprint from the file and finally registering it on the app.  I'm
> surprised, it actually turned out not
> to be that difficult.  The key issue is that you need to have a standard
> naming scheme for blueprints (for example,
> the code expects every file to have an attribute called "the_blueprint",
> but you can pass whatever blueprint name
> to register blueprints).
>
> import os
>
>
>
>
> PATH = os.getcwd()
>
>
>
> BLUEPRINT = 'the_blueprint'
>
>
>
>
>
> def import_file(path, name=None):
>
>
>
>     """ imports a file with given name and path """
>
>
>
>     # use the imp module to do actual imports
>
>
>
>     import imp
>
>
>
>     name = name or os.path.split(path)[-1].replace(".", "_")
>
>
>
>     fp, pathname, description = imp.find_module(path)
>
>
>
>     return imp.load_module(name, fp, pathname, description)
>
>
>
>
> def register_blueprints(app, files, blueprint_attribute):
>
>
>
>     """ registers the blueprints from a given set of files on the given app """
>
>
>
>     imported_modules = [import_file(file) for file in files]
>
>
>
>     for module in imported_modules:
>
>
>
>         app.register(getattr(module, blueprint_attribute))
>
>
>
>
> if __name__ == "__main__":
>
>
>
>    # get the files that end in py in the folder
>
>
>
>    filelist = [file for file in os.listdir(PATH) if file.endswith ".py"]
>
>
>
>    from my_app import app
>
>
>
>    register_blueprints(app, filelist, BLUEPRINT)
>
>
>
>
>
>
> On Sat, Oct 6, 2012 at 7:30 AM, Malphas Wats <malphas@subdimension.co.uk>wrote:
>
>> Hi,
>>
>>   I think this is more a python question than a flask question, but
>> it's not something I've needed to do yet for anything else!
>>
>> I'm building a flask app that simply provides login management and
>> that's it. I then want to extend the app with different features, such
>> as a blog tool, bookmark tool and so on, but each feature I add I want
>> to build as a blueprint that just relies on the top-level app to
>> provide the account management stuff.
>>
>> I'd like to be able to just drop each blueprint module into a
>> 'Blueprints' folder, restart the frontend (or maybe even without
>> having to restart?) and have it automatically detect the new
>> blueprint, import the python code and list it in the menu.
>>
>> How can I import python modules variably? without having to hard-code
>> the imports?
>>
>> Thank you
>> -Malphas
>>
>
>

Re: import blueprints dynamically?

From:
Malphas Wats
Date:
2012-10-06 @ 13:55
This is awesome, thank you! I haven't come across the imp module. From
looking at your Gist (I've not had a chance to test it yet), I realise I
said module rather than package (I still get these confused in my head). I
assume importing a package is as easy as just looking at the directories in
that Blueprint directory, rather than filtering for .py files? I'd have to
make sure there is a common module in any blueprint package?

Thank you for this, I will have a play around with it when I get back to my
computer!

On Saturday, October 6, 2012, Jeffrey Tratner wrote:

> I thought this looked interesting, so I wrote up a code snippet.
>
> I saved this to a Gist on Github, which might be easier to work with:
> https://gist.github.com/3844721
>
> (but I also copy/pasted it here if you don't want to click the link :P)
>
> The key to the snippet is using the "imp" module (
> http://docs.python.org/library/imp.html) to dynamically import files,
> then using getattr to get the
> actual blueprint from the file and finally registering it on the app.
>


> On Sat, Oct 6, 2012 at 7:30 AM, Malphas Wats 
<malphas@subdimension.co.uk<javascript:_e({}, 'cvml', 
'malphas@subdimension.co.uk');>
> > wrote:
>
>> Hi,
>>
>>   I think this is more a python question than a flask question, but
>> it's not something I've needed to do yet for anything else!
>>
>> I'm building a flask app that simply provides login management and
>> that's it. I then want to extend the app with different features, such
>> as a blog tool, bookmark tool and so on, but each feature I add I want
>> to build as a blueprint that just relies on the top-level app to
>> provide the account management stuff.
>>
>> I'd like to be able to just drop each blueprint module into a
>> 'Blueprints' folder, restart the frontend (or maybe even without
>> having to restart?) and have it automatically detect the new
>> blueprint, import the python code and list it in the menu.
>>
>> How can I import python modules variably? without having to hard-code
>> the imports?
>>
>> Thank you
>> -Malphas
>>
>
>

Re: [flask] Re: import blueprints dynamically?

From:
Jeffrey Tratner
Date:
2012-10-06 @ 14:02
The method should be the same (import using imp, then use getattr to get
the object you want) but I'm guessing you have to do something different
with imp to do it. Alternatively you could alter import_file to check if a
passed path is a directory or file and do the right import that way
On Oct 6, 2012 9:59 AM, "Malphas Wats" <malphas@subdimension.co.uk> wrote:

> This is awesome, thank you! I haven't come across the imp module. From
> looking at your Gist (I've not had a chance to test it yet), I realise I
> said module rather than package (I still get these confused in my head). I
> assume importing a package is as easy as just looking at the directories in
> that Blueprint directory, rather than filtering for .py files? I'd have to
> make sure there is a common module in any blueprint package?
>
> Thank you for this, I will have a play around with it when I get back to
> my computer!
>
> On Saturday, October 6, 2012, Jeffrey Tratner wrote:
>
>> I thought this looked interesting, so I wrote up a code snippet.
>>
>> I saved this to a Gist on Github, which might be easier to work with:
>> https://gist.github.com/3844721
>>
>> (but I also copy/pasted it here if you don't want to click the link :P)
>>
>> The key to the snippet is using the "imp" module (
>> http://docs.python.org/library/imp.html) to dynamically import files,
>> then using getattr to get the
>> actual blueprint from the file and finally registering it on the app.
>>
>
>
>> On Sat, Oct 6, 2012 at 7:30 AM, Malphas Wats <malphas@subdimension.co.uk>wrote:
>>
>>> Hi,
>>>
>>>   I think this is more a python question than a flask question, but
>>> it's not something I've needed to do yet for anything else!
>>>
>>> I'm building a flask app that simply provides login management and
>>> that's it. I then want to extend the app with different features, such
>>> as a blog tool, bookmark tool and so on, but each feature I add I want
>>> to build as a blueprint that just relies on the top-level app to
>>> provide the account management stuff.
>>>
>>> I'd like to be able to just drop each blueprint module into a
>>> 'Blueprints' folder, restart the frontend (or maybe even without
>>> having to restart?) and have it automatically detect the new
>>> blueprint, import the python code and list it in the menu.
>>>
>>> How can I import python modules variably? without having to hard-code
>>> the imports?
>>>
>>> Thank you
>>> -Malphas
>>>
>>
>>

Re: import blueprints dynamically?

From:
Malphas Wats
Date:
2012-10-06 @ 14:12
That's cool, I shall experiment!

Thank you

On Saturday, October 6, 2012, Jeffrey Tratner wrote:

> The method should be the same (import using imp, then use getattr to get
> the object you want) but I'm guessing you have to do something different
> with imp to do it. Alternatively you could alter import_file to check if a
> passed path is a directory or file and do the right import that way
>
>