Flask: Using multiple packages in one app - python

I'm just getting started with flask and I've hit a snag. I'm trying to write a small blog to get used to the framework so I made two packages, an "auth" and "posts". I read through the Large Applications section in the Flask docs.
My directory looks like this.
>/root
>>run.py
>>/posts
>>>____init____.py
>>>views.py
>>>/templates
>>>/static
>>/auth
>>>____init____.py
>>>views.py
>>>/templates
>>>/static
the run.py looks like this:
from flask import Flask
from auth import auth_app
from posts import posts_app
auth_app.run()
posts_app.run()
/posts/__init__.py and /auth/__init__.py look like this:
from flask import Flask
auth_app = Flask(__name__)
import auth.views
and the views.py look like this:
from auth import auth_app
#auth_app.route('/auth/')
def index():
return "hello auth!"
But whenever I run the server, only the localhost/auth/ is available, and everything else gives a 404, som I'm assuming that the posts app isnt being run.
Can anyone help?

Your auth_app.run() method blocks your program from continuing to run. This is why the the posts_apps app doesn't get run. The entire process of serving up pages happens within Flask's run() method. Therefore, you can conclude that you can't run two Flask apps in the same process.
If you wish to split up your application into two like this, the recommended way is to use blueprints. Rather than creating two apps (auth and posts), you create two blueprints. You then create one application like so...
from flask import Flask
from auth import auth_blueprint
from posts import post_blueprint
app = Flask(__name__)
app.register_blueprint(auth_blueprint)
app.register_blueprint(post_blueprint)
app.run()

Though it seems as though Mark's approach using blueprints fits your project well, if you want to use separate applications for each package you should look into werkzeug.wsgi.DispatcherMiddleware.
A single process cannot run a second app after you run the first (like in your question), but that's not a problem with DispatcherMiddleware. You can use it to define a main application as well as others based on URL prefixes.
The example on the docs distinguishes between two applications --frontend and backend-- which are run depending on the URL the user requests.
If you want to learn more, read Matt Wright's "How I Structure My Flask Applications" and look at Overholt, his sample project. He decides to use two apps: one for the main website (the frontend) and another for the API, and he creates the distinction between the two based on the URL prefix. From his code*:
from werkzeug.serving import run_simple
from werkzeug.wsgi import DispatcherMiddleware
from overholt import api, frontend
application = DispatcherMiddleware(frontend.create_app(), {
'/api': api.create_app()
})
if __name__ == "__main__":
run_simple('0.0.0.0', 5000, application, use_reloader=True, use_debugger=True)
This way, he creates two applications wherein each has its defined set of views, configurations, etc. and is able to run them from the same Python interpreter process.
*Note that run_simple() is only meant to be used for development --not production.

Related

Is it possible to get flask app url without request context?

It's a URL shortener app. The app structure is like following:
App structure
In forms.py, I have custom validators: validate_url() and validate_short_url()
that use APP_URL; APP_URL = "localhost:5000/"
I'm fine with that running locally, but there is a lot of cases app domain can change:
Running through docker image;
Hosting (e.g. on Heroku);
Changing the port value;
So every time I run this flask app differently I have to change the value of APP_URL, which isn't the best practice
All in all, I want to use something like flask.Request.url_root to avoid manual writing again and again
When I just try to use flask.request I get the following traceback:
RuntimeError: Working outside of request context.
This typically means that you attempted to use functionality that needed
an active HTTP request. Consult the documentation on testing for
information about how to avoid this problem.
forms.py is posted here
The app is already hosted on Heroku, here is the link: https://qysqa.herokuapp.com/
The solution was to use flask.request inside custom validators (validate_url() and validate_short_url()) where app context gets passed

Is it possible to integrate a graphic interface into a web page in my flask app?

I'm creating a web app with flask, this app works with a graphic interactive interface with user.
The user gives input data and the program displays results and some graphs.
My interface works as I wanted,
The question is:
How can I make the interface as one of my web pages and not an executable window that appears separately?
I hope it's clear.
import Main #file containing the graphic interface code
from flask import Flask,request, render_template
from time import localtime, sleep
app = Flask(__name__)
#app.route('/interface')
def web():
M=Main.Generale() #instantiated my class
return render_template('web.html',M=M)
if __name__ == '__main__':
app.run(debug=True)
No, you can't integrate a Tk/Tkinter GUI into a web page. (Not without some very significant advanced magic รก la Emscripten, anyway.)
You'll have to look into web frontend programming (JavaScript) to reimplement the UI you have if you want it to be used over the web.
You're much better off creating an interface with something like React that makes request to your Flask backend. You can build the React project and serve the static files from Flask.
See this question

Accessing flask context outside the main class

I'm new to python, therefore I believe solution might be quick one. I've spent hours, but couldn't make it work.
I need to access app outside main class.
Package structure below:
app/
app.py
another_class.py
In app.py:
app = Flask(__name__)
In another_class.py:
from flask import current_app as app
app.config['test_key']
Of course I receive error
RuntimeError: Working outside of application context.
This typically means that you attempted to use functionality that needed
to interface with the current application object in some way. To solve
this, set up an application context with app.app_context(). See the
documentation for more information.
I've tried running it in block of
with app.app_context:
but it didn't seem to work.
What do I do wrong?
Your problem is right here.
I need to access app outside main class
And you are trying to solve it the wrong way. current_app is useful to use features that are originally used externally. Typically, a use case would be to simulate routes, but offline.
What you want to do, is have a file that will "manage" your application, such as manage.py for instance. Then, another file app.py that will contain the configuration of your application.
In your manage.py file, you will import app in order to run it. And if you then need to access to your app object, you can import app from your another file. Basically, the app object you're instantiating in the app.py acts like a pointer, and the other files importing the app will also be affected by the change you make in another file to this object app.
Your tree should look like this.
your_api/
app.py # Instantiate the app object.
manage.py # Import the app.py package to run it.
another_file.py # If this file imports app.py and modifies the app object
# inside, the changes will also affect the object imported by manage.py.

Flask application with multiple views, how does 'flask run' work in this case?

So I'm coming from the world of spring mvc, and so far Flask has been great.
I've got multiple views/controllers in different python files(this could easily be the wrong approach if so please tell me).
And i want to use the flask command 'run' to try out my controller with postman, is there anyway i can call run on multiple python files at once? it's just this command that has me confused:
export FLASK_APP=hello.py
In each controller I also have this line:
app = FLASK(name)
is this require?
I've looked into flask blueprints but they seem to be about sharing functionality which I dont really require, would love to know if they were the way forward.
Multiple file is not possible but all the multiple files share the single app = Flask(__name__) right ? You can use this app to start the flask run.
file1.py => app = Flask(__name__)
file2.py => from file import app
file3.py => from file import app
export FLASK_APP=file1.py
flask run

Flask : define a route to explore files and folders like SimpleHTTPSever does

I have done a simple Flask application which goal is to generate some output XML files.
I have all my applicative routes properly defined, ajax calls and so forth.
The application works fine and I'm happy with it.
What I am missing is a way to easily serve and browse the result files and folders.
This is what SimpleHTTPServer would do when run against the folder where the results files are stored.
I would like to achieve something similar via Flask (not to have a dedicated web server running on another port just for this mere purpose).
I know that Flask is based on BaseHTTPServer just like SimpleHTTPServer is, and I'm afraid that the file system browsing capability is part of the SimpleHTTPServer layer.
Is it possible ?
If not natively supported, is there a Flask plugin which could help ?
Flask AutoIndex does exactly what you're looking for:
import os.path
from flask import Flask
from flask.ext.autoindex import AutoIndex
app = Flask(__name__)
AutoIndex(app, browse_root=os.path.curdir)
if __name__ == '__main__':
app.run()

Categories