I am trying to access configuration value from my Flask application object outside view function. As I understand from official docs, we can access Flask app instance thats currently running with the help of proxy object called current_app, we can import it with command: from flask import current_app. I need to access config value outside view function. I am using third party API to send sms from my application. I wrote code for this in another separate module and need to access config values in order to initialize custom objects of this third party library.
Here is the code snippets that I wrote inside my module:
from third_party_api import Configuration
from flask import current_app
configuration = Configuration()
configuration.username = current_app.config['third_party_api_username']
configuration.password = current_app.config['third_party_api_password']
Here is the snapshot of RuntimeError I get:
As I understand, we can access current_app config object inside view function without any problem. I dont want to access config value directly from configuration file or class. I read the docs, but it didnt help.
Solved by moving this piece of code to inside the function which is called inside another view function:
configuration = Configuration()
configuration.username = current_app.config['third_party_api_username']
configuration.password = current_app.config['third_party_api_password']
Related
Working on flask app (factory structure), that has quite heavy background order processing with its own config defined in app/orders/parser_config class MyCustomConfig.
I need to access some configuration from this class inside models.py, but got circular import error. Decided to import and inherit MyCustomConfig in application config.py:
from app.orders.parser_config import MyCustomConfig
...
class Config(MyCustomConfig):
...
Which works fine, however I can't find information whether current_app.config is sent with each request? I can access variables from MyCustomConfig inside template with {{ config.VARIABLE_INSIDE_MYCUSTOMCONFIG }} as shown in this question answers. Does this mean jinja pulls directly from server when rendering, or is this within request context?
Related question does not answer this.
Question in short: does flask config size impact client load time on each request?
Given a flask application, how would you extract all the view functions that end up rendering the results of the requests sent to it?
The reason I ask is because I'm using a flask extension called flask_apispec which requires you to call it with every single function you wish to end up on in the swagger spec and documentation.
The answer was a field named view_functions on the flask application itself.
To produce the api documentation I then ended up iterating over that dictionary:
for key, view in app.view_functions.items():
if key.startswith('api'):
docs.register(view, endpoint=key)
I didn't get it clearly from Flask docs. Also, I can see similar stackoverflow questions but I still didn't get my answer, hence asking.
I have a flask application served using gunicorn+gevent. Gunicorn worker process, on start, creates a Flask application. Then it imports some files that setup a few global things, like a udp connection to a statsd server, etc. The setup needs to be done only once i.e. on worker process start and not with every client request. The setup code in the imported files needs access to config variables.
I know that while serving a request I can use the current_app proxy, but not outside a request.
One way can be: put Flask app creation code in a separate file and include it wherever you need access to config.
Ex:
file: mywsgi.py
from flask import Flask
application = Flask(__name__)
application.config.from_pyfile('myconfig.cfg')
file: mygunicornapp.py
from mywsgi import application
import file1
import file2
# import more files
file: file1.py
from mywsgi import application
# use the application config to setup something
file: file2.py
from mywsgi import application
# use the application config to setup something
Is this the preferred way?
Flask doc says I can create application context explicitly.
Can I push application context, just after creating my flask app, and never pop it. So that the application context is always there as long as my process runs and the current_app proxy will be available application wide even when no request being served?
Ex:
from flask import Flask
application = Flask(__name__)
application.config.from_pyfile('myconfig.cfg')
application.app_context().push()
Now I should be able to use the current_app proxy anywhere in my code. Thoughts, please!
== Update ==
The files file1.py, file2.py etc are imported for adding routes to the application. They provide the functions that handle my api requests. So the file mygunicornapp.py looks more like:
file: mygunicornapp.py
from mywsgi import application
from file1 import API1
#application.route("/api1")
def handle_api1():
return API1.handler()
from file2 import API2
#application.route("/api2")
def handle_api2():
return API2.handler()
# many more routes
Now file1 imports many other files and they, in turn, import many more files. Any of these imported files may need access to a config parameter that I have set on the application object. The question is: How do I make the application object available to all these files? Do you suggest that I pass the application object to each file?
Is it possible to just delay adding routes? I mean set routes after current_app context local is available. That means the files will be imported after current_app is available. I tried adding routes to the current_app context local in 'before_first_request' callback. The problem with that is, the very first request returns 404. Subsequent returns give a correct response.
Why don't you make functions in file1 and file2, and pass the argument app into them? Then you can call these functions in your setup code in mywsgi.py, using as an argument the app object you just created.
This should work much better than some of the other things you suggested. The different files importing each other is close to a circular import. Pushing an app context is also something that leaves you likely to end up with difficult to understand bugs.
If you create the object app in one file and import it from that file everywhere, you basically have a global variable (using a namespace). This is going to cause problem when you want to test your app setup code, or create more than one version of your app for another reason. There is also the issue that you won't be able to import any of file1, file2 without creating an app object. While testing these, or possibly re-using some of that code outside of Flask, this will be a pain.
It's much better to create the app object once and pass it around. Having a function which returns the newly created app, which can be imported and called from anywhere, is a common way of organizing a flask app. This file is often called factory.py. It makes it easier to create zero, one or more copies of the app, rather than making it more difficult.
I am new to Flask, i have three sections in config.py file
say
class Config(object):
DEBUG = False
TESTING = False
DATABASE_URI = 'sqlite://:memory:'
class ProductionConfig(Config):
DATABASE_URI = 'mysql://user#localhost/foo'
class DevelopmentConfig(Config):
DEBUG = True
class TestingConfig(Config):
TESTING = True
And as per documentation we can pass one the config at a time and run the app so the app will run for the passed config settings only.
I am looking changing the config based on url pattern,
so say if url is:
http://127.0.0.1:8080/api/app/hello should use app.config.from_object(ProductionConfig)
http://127.0.0.1:8080/api/app_dev/hello should use app.config.from_object(DevelopmentConfig)
http://127.0.0.1:8080/api/app_test/hello should use app.config.from_object(TestingConfig)
Is it possible while running app i want to change config based on url pattern so that i dont have to run multiple instance of app at time.
Please guide me how can i catch the url pattern in middleware to change configuration file.
It sounds like what you might be looking for is application dispatching, where each app is the same except for the configuration file that is loaded.
here is a solution for a very similar issue, except it uses subdomain dispatching rather than URL dispatching as you have requested.
The basic concept should apply, and taking this together with the examples in the first link should give you a good start for developing code that suits your needs.
You can do this inside a route endpoint
app.config['DEBUG'] = True
but it affects the whole app object. So when you GET /api/app_dev/hello and then /api/app/whatever; you are still using app_dev config.
In config file you can set API
_PATH. and in blueprint you need to set this parameter for required APIs
I have a factory-object which I'd like to make available to certain views in Django. The factory does not change the any state, it only creates instances. Instead of instantiating the factory in each view I'd like to create one instance and register it on server-startup.
Is this possible in Django and if so how? Otherwise what is the Pythonic/Djangonic way to do it?
It's enough to put the code in one of the files imported by Django on startup, such as:
settings.py
myapp/__init__.py where myapp is an app in INSTALLED_APPS setting var
myapp/models.py where myapp is an app in INSTALLED_APPS setting var
Your code doesn't have to go in the actual file above, you could put it in a separate file as long as you import that from one of the files above.