Accessing flask context outside the main class - python

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.

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

flask API calls scheduling with cron jobs

I have a function which calls several API's and updates the database upon being called. I want to schedule the function to run daily at specific time.
Already tried flask_apscheduler and APScheduler which gives this error:
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.
Any leads on this will be helpful.
You should:
Post the code where you define your flask application.
Specify how you try to access the app.
How you're calling the APIs.
Whether those APIs are 3rd party or part of your blueprint.
However, this is probably a context issue. I have come across a similar one with SQLAlchemy before.
You will need to somehow get access to your app, either by using app_context or by importing current_app from Flask and accessing the config.
Assuming you imported the app where your function is used, try this:
with app.app_context():
# call your function here
Refer to this document for more information: Flask Documentation
Another approach you can try, is passing your app configurations through a config class object.
You can define the jobs you want to schedule and pass a reference to your function inside.
Check this example from flask-apscheduler repository on GitHub.

How to execute code automatically after manage.py runserver

I need to read a csv file just after running server. It can't be done in any view because it need to be preload to execute all views, so I need to do it immediately after "manage.py runserver". Is there any file where I can write the code that I need to execute in first place?
Code put in settings.py file may run when Django application as #salman-arshad suggested, but it is not the best way of doing it. It could be problematic or even dangerous according to the context of what you are running.
The first problem is code will run twice when the application starts. Django uses the settings.py file many times during startup and running. Just put print('Hello world') at the end of the settings.py file and you will see it printed twice. It means the code ran twice. Secondly, the settings.py file does not serve the purpose of running arbitrary code. It is dedicated to your project settings. Thirdly if you try to import anything from within the application in settings.py and use it (for instance a Model), it would cause errors. Because Django's internal app registry is not ready yet.
So the best place for running this type of code is in the ready hook of the AppConfig class. In any Django application, there is an apps.py file that defines a configuration class. You can override the ready function in it. This function will run only once when you start the application like this. Say you have an app named app_name
class AppNameConfig(AppConfig):
name = 'app_name'
def ready(self):
pass
# write your startup code here you can import application code here
#from app_name.models import MyModel
then put the following line in that app's __init__.py file
default_app_config = 'app_name.apps.AppNameConfig'
Now, this code will run at every startup without problems.
Just add that script in settings.py file. Because settings.py file of those files which are executed prior to views.py file

Web API in Flask

I want to use Flask to create a web API for my application, but have some problems to make my flask app aware of my other objects.
I want to use Flask in order to be able to interact with my application through http requests. So the whole flask application in my case is just an external API, and relies on a core application.
Let's imagine that my flask application will have to perform database
calls.
To manage database calls in my application, I use a single object that connects to the db ans implements some kind of Queue.
That means my core application running in the background has a reference to my db object in order to make db calls.
This is done by giving a reference to my queue object to this core application.
Now I want to be able to perform actions on the db using a flask application too.
What is the correct way to pass a reference to this Queue object to my Flask application?
If I define all my objects at module level, I have no way to interact with them afterwards, do I?
All the example of Flask applications use Flask as the core of their system and define everything in their app on module level. How do I make Flask just a part of my app?
I'm not sure what you mean by
If I define all my objects at module level, I have no way to interact with them afterwards, do I?
But no, you don't have to define your objects at the module level - that's true of your Flask instance, blueprints and any object which you provide. For example you can create an AppBuilder class that makes and configures Flask instances.
For some interactions context locals are a very handy tool as well.
If you can clarify the issue I'll try to expand my answer.

Flask: Using multiple packages in one app

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.

Categories