I have been learning flask/ python from this tutorial http://blog.miguelgrinberg.com/post/the-flask-mega-tutorial-part-i-hello-world
This blog is pretty good and it explain very well. In the first tutorial, if you notice,
he asks us to create a init.py file, a views.py file and a main run.py file.
root
/microblog
/apps
/__init__.py
views.py
I created the two files. He asks us to create a run.py file and put it in the root file. then
chmod a+x run.py
./run.py
It says the file does not exist.
If I,
python run.py
It says App module not defined.
I cannot figure out the problem, I put the run.py file in all the files, it doesnt not work what so ever.
I will also include the code so that it would be easier to answer instead of going to the above link
init.py
from flask import Flask
app = Flask(__name__)
from app import views
views.py
from app import app
#app.route('/')
#app.route('/index')
def index():
return 'Hello world'
run.py
#!flask/bin/python
from app import app
app.run(debug = True)
My questions:
Where should I put the run.py file?
Why are we creating different files? Why cant all of them be in one
full file?
init.py -->
he is importing flask which is normal. then assigning app =
(name). why is that? Then why is he importing views from apps?
views.py -->
from app import app? is app an existing module here or the one we
just created? what does #app.route('/') or
#app.route('/index')do?
Can some one put the code together and explain it?
It says App module not defined
You misspelled package name: you have apps in your directory tree and you try to import app
Where should I put the run.py file?
Anywhere you want as long app is in PYTHONPATH. Or you can put it inside microblog directory.
he is importing flask which is normal. then assigning app = (name). why is that?
# Create reference to flask WSGI application object
app = Flask(__name__)
Why? Because you need application to run. See official docs: Flask object
Then why is he importing views from apps?
from app import views
means: From package named app import module named views
Naming convention could be probably different but if you don't see the difference you should probably spend more learning python basics before starting with more sophisticated stuff.
from app import app? is app an existing module here or the one we just created? what > does #app.route('/') or #app.route('/index')do?
#app.route('/')
def index():
return 'Hello world'
Short answer: if app receives request for url '/' responds using function foo
For more see official docs: add_url_rule and URL Route Registrations
Update
Why are we creating different files? Why cant all of them be in one full file?
Actually nothing stops you from putting everything inside one file but most of the time it is really bad idea. If you ask about reasoning in this specific example it is mostly about separating modules that have different responsibilities.
Related
I have been following the flask mega tutorial form Miguel grinberg and the very first "Hello World!" program is confusing me.
More specifically it is the import of the routes module from the init.py module that is confusing me.
Below is the init.py file:
#__init__.py file:
from flask import Flask
app = Flask(__name__)
from app import routes
# above line is the source of confusion.
Below is the routes.py file
from app import app
#app.route('/')
#app.route('/index')
def index():
return "Hello, world!"
Now if I understand correctly, app is an object of class Flask. when we do "from app import app" in routes.py, I understand that we are importing the app object created in init.py file.
The code then follows is registering a route for this object.
So my question is why do we need to import this routes module in init.py?
I mean in routes module, the app object has been imported and a route has been registered on it. So this should reflect on the app object created in init.py. So why do we need to import it?
I know that it does not work if we remove the import routes statement. But want to know why.
Edit: Though I have a programming background, I am new to python. So it might be misunderstanding on how python files are executed when projects are executed. Also I think this has to do something with python being an interpreted language.
When you import anything in python, it actually runs the entire file that you are importing. The __init__.py file does not have any information about the routes so by importing it you are essentially providing that information to the app object. In addition, this routes file is never directly ran so that is the only way the views are actually created.
Hope this helps!
My flask application currently consists of a single test.py file with multiple routes and the main() route defined. Is there some way I could create a test2.py file that contains routes that were not handled in test.py?
#app.route('/somepath')
def somehandler():
# Handler code here
I am concerned that there are too many routes in test.py and would like to make it such that I can run python test.py, which will also pick up the routes on test.py as if it were part of the same file. What changes to I have to make in test.py and/or include in test2.py to get this to work?
You can use the usual Python package structure to divide your App into multiple modules, see the Flask docs.
However,
Flask uses a concept of blueprints for making application components and supporting common patterns within an application or across applications.
You can create a sub-component of your app as a Blueprint in a separate file:
simple_page = Blueprint('simple_page', __name__, template_folder='templates')
#simple_page.route('/<page>')
def show(page):
# stuff
And then use it in the main part:
from yourapplication.simple_page import simple_page
app = Flask(__name__)
app.register_blueprint(simple_page)
Blueprints can also bundle specific resources: templates or static files. Please refer to the Flask docs for all the details.
You can use simple trick which is import flask app variable from main inside another file, like:
test_routes.py
from __main__ import app
#app.route('/test', methods=['GET'])
def test():
return 'it works!'
and in your main files, where you declared flask app, import test-routes, like:
app.py
from flask import Flask, request, abort
app = Flask(__name__)
# import declared routes
import test_routes
It works from my side.
This task can be accomplished without blueprints and tricky imports using Centralized URL Map
app.py
import views
from flask import Flask
app = Flask(__name__)
app.add_url_rule('/', view_func=views.index)
app.add_url_rule('/other', view_func=views.other)
if __name__ == '__main__':
app.run(debug=True, use_reloader=True)
views.py
from flask import render_template
def index():
return render_template('index.html')
def other():
return render_template('other.html')
I would like to recommend flask-empty at GitHub.
It provides an easy way to understand Blueprints, multiple views and extensions.
If you need split blueprint to separate files you can use snippet:
# app.py
from blueprint_module import blueprint
app = Flask(__name__)
app.register_blueprint(blueprint)
# blueprint_module\__init__.py
from flask import Blueprint
blueprint = Blueprint('my_blueprint', __name__)
from . import page
# blueprint_module\page.py
from . import blueprint
#blueprint.route("/url", methods=['GET'])
def hello():
return 'hello world'
Dividing the app into blueprints is a great idea. However, if this isn't enough, and if you want to then divide the Blueprint itself into multiple py files, this is also possible using the regular Python module import system, and then looping through all the routes that get imported from the other files.
I created a Gist with the code for doing this:
https://gist.github.com/Jaza/61f879f577bc9d06029e
As far as I'm aware, this is the only feasible way to divide up a Blueprint at the moment. It's not possible to create "sub-blueprints" in Flask, although there's an issue open with a lot of discussion about this:
https://github.com/mitsuhiko/flask/issues/593
Also, even if it were possible (and it's probably do-able using some of the snippets from that issue thread), sub-blueprints may be too restrictive for your use case anyway - e.g. if you don't want all the routes in a sub-module to have the same URL sub-prefix.
This question already has answers here:
Why do circular imports seemingly work further up in the call stack but then raise an ImportError further down?
(9 answers)
Closed 6 years ago.
I learn from Larger Applications.In this document, It says: "all the view functions (the ones with a route() decorator on top) have to be imported in the init.py file. Not the object itself, but the module it is in."
I don't know why should when I do this: from . import views,It succeed.Though from views import * can also work well.
I organize these file like this:
myapplication/
runner.py
myflask/
__init__.py
views.py
templates/
static/
...
runner.py:
from testFlask import app
app.run()
myflask/__init__.py:
from flask import Flask
app = Flask(__name__)
from . import views # why this can work????
myflask/views.py:
from . import app
#app.route('/')
def index():
return 'Hello World!'
and I run it:
$ cd myapplication
$ python runner.py
It's OK to run this Flask app. However I want to know why from . import views can solve this circle import problem in flask? And why the doc says: Not the object itself, but the module it is in????
However,when I do like this:
#some_dir/
# application.py
# views.py
#application.py
from flask import Flask
app = Flask(__name__)
import views # it doesn't work
# from views import * # it works
app.run()
#views.py
from application import app
#app.route('/')
def index():
return 'Hello World!'
#run it
$ python application.py
It doesn't work.
It is a circular import. But in your case, the variable that might have been problematic (app) has already been defined in the imported script, so the import just causes the first "app" instance to be overwritten by the imported "app" instance. Which has no practical effect.
For details about this circular import situation, please read this post.
If you want to follow the pattern for a large flask application, you should look into blueprints and application factories.
It's not the specific command that solves the problem, but the order of the commands.
The trick is that you import the views after you created the app variable in your main script, so when the view script imports the main script the variable is already defined.
If you would try to import the views above declaring the app variable it would not work because it would cause an import loop and could not find the app variable.
Your project structure defines how the import would work best.
Here's an example of "A bit larger type of application" where you can use blueprints that defines a collection of views, templates, static files and other elements that can be applied to an application:
https://github.com/pallets/flask-website/tree/master/flask_website
Kind regards
So I'm trying to graduate from the single file application and organize my flask app for scalability. However, I can't even get past running the server... I tried duplicating exact stackoverflow questions that have had similar troubles before, but no luck, i.e. Structure Flask-Restful API to use SQLAlchemy, python flask-restful cannot get app access in resource class.
I got a regular flask app to work following this structure: http://flask.pocoo.org/docs/0.10/patterns/packages/, however, I have a restful extension that I'm trying to structure, and it's not working.
The error I am getting is:
from yourapplication.resources.foo import Foo
ImportError: No module named resources.foo
My directory structure is:
/myapp
runserver.py
/venv
/yourapplication
init.py
api.py
/resources
foo.py
In runserver.py, I have:
from yourapplication import app
app.run(debug=True)
For init.py, I have:
from flask import Flask
app = Flask(__name__)
import yourapplication.api
lastly, for foo.py, I have:
from flask_restful import Resource
class Foo(Resource):
def get(self):
pass
def post(self):
pass
It's so simple, yet I can't get it to work. I followed, http://flask.pocoo.org/docs/0.10/patterns/packages/, and it works for a regular flask app, but not yet found luck structuring restful extension flask apps, which is what I'm dealing with. Please help guys!
My project structure is like below
run.py
lib/
mysite/
conf/
__init__.py (flask app)
settings.py
pages/
templates/
index.html
views.py
__init__.py
This is mysite.conf.__init__
from flask import Flask
app = Flask(__name__)
app.debug = True
My idea is to now import app to every other module to use it to create views. Here in this case there is a module pages.
In pages.views I have some code like
from flask import render_template
from mysite.conf import app
#app.route('/')
def index():
return render_template('index.html')
The index.html is placed in pages/templates
When I run this app from run.py which is like below
from mysite.conf import app
app.run()
I'm getting template not found error.
How to fix it? and why is this happening!
I'm basically a django guy, and facing a lot of inconvenience with importing the wsgi object every time to create a view in every module! It kinda feels crazy -- Which in a way encourages circular imports. Is there any way to avoid this?
Flask expects the templates directory to be in the same folder as the module in which it is created; it is looking for mysite/conf/templates, not mysite/pages/templates.
You'll need to tell Flask to look elsewhere instead:
app = Flask(__name__, template_folder='../pages/templates')
This works as the path is resolved relative to the current module path.
You cannot have per-module template directories, not without using blueprints. A common pattern is to use subdirectories of the templates folder instead to partition your templates. You'd use templates/pages/index.html, loaded with render_template('pages/index.html'), etc.
The alternative is to use a Blueprint instance per sub-module; you can give each blueprint a separate template folder, used for all views registered to that blueprint instance. Do note that all routes in a blueprint do have to start with a common prefix unique to that blueprint (which can be empty).
I ran in to this problem as well being brand new to Flask.
The solution for my situation was to create an __init__.py file in the main app directory so as to turn app/ in to a module since, as Martijn Pieters pointed out, flask expects templates to be in the main module directory by default. And to restate from his answer, you can reassign the default directory when instantiating the Flask class, e.g. Flask(__name__, template_folder=any/relative/path/from/app/dir/or/absolute/path/youd/like)
A simple directory structure should therefore look like this:
app/
run.py
templates/
sample_template.html
__init__.py # <---- This was the missing file in my case.
... where app.py might look like this:
from flask import Flask, render_template
app = Flask(__name__) # or e.g. Flask(__name__, template_folder='../otherdir')
#app.route("/")
def home():
return "Hello world"
#app.route("/hello/again")
def hello_again():
return render_template("hello_again.html")
if __name__ == "__main__":
app.run()
I'm pretty sure you made a mistaking spelling "template" on main folder. Just rename it
or:
do something like this (template_folder = 'the name of the folder your file belongs to')
from flask import Blueprint
from flask import render_template
views = Blueprint('views',__name__,template_folder='tamplate')
#views.route('/')
def home():
return render_template("home.html")