Flask: Attribute Value None - python

Here are my code blocks:
Below one is overriding Flask Blueprint and adding attribute config which copies the app's config.
# Overriding Flask Blueprint
from flask import Blueprint
class CustomBlueprint(Blueprint):
def __init__(self, name, import_name):
super().__init__(name, import_name)
self.config = None
self.guard = None
def register(self, app, options, first_registration=False):
self.config = app.config
self.guard = app.guard
print(self.guard) # Works Fine
print(self.config) # Works Fine
super(CustomBlueprint, self).register(app, options, first_registration)
Below one is using that class.
from src.SHARED.overriden.blueprint import CustomBlueprint
from .guard import module_guard
example = CustomBlueprint('EXAMPLE', __name__)
print(example.config) # Here is the problem: It prints None
#example.route('/')
#module_guard
def hello_example():
return "Example is Working !!"
And I tried one another way also, using #property, getter, and setter. But that gives an error, Attribute Error: Can't add Attribute
I want to access/print the app.config, what should I do ??

you need app.app_context().push() in your app.py

You can access app.config on your Blueprints using current_app.config.
from flask import Blueprint, current_app
from .guard import module_guard
example = Blueprint('EXAMPLE', __name__)
# Want to access current_app here e.g print(current_app.config)
#example.route('/')
#module_guard
def hello_example():
return '{}'.format(current_app.config.get('ENV'))
https://flask.palletsprojects.com/en/1.1.x/api/#flask.current_app

Related

generating flask route from class method

i am trying to generate Flask route using a basic DI i.e mapping methods as route handlers, i am a total beginner at Flask so mind my basic skills
class myClass():
def __init__(self):
self.dbConnObj = DbToolsMySql('someconnection', 'slave')
self.dbConnObj.connect()
self.blueprint = Blueprint('myClass', __name__)
self.blueprint.add_url_rule('/my_method', view_func=self.my_method)
def my_method(self, event):
retun "hello"
and then in my handler file
from flask import Flask
from flask_restful import Api, Resource
from src.app.services.myClassimport myClass
app = Flask(__name__)
app.register_blueprint(myClass.blueprint)
if __name__ == "main":
app.run()
Quite simple ehh???? but not working... i am getting following message
Not Found The requested URL was not found on the server. If you
entered the URL manually please check your spelling and try again.
typically you add routes to the Flask app with decorators like so:
app = Flask(__name__)
#app.route('/some-endpoint')
def some_endpoint_handler():
# do something
pass
Or you can add without a decorator like so:
def some_endpoint_handler():
# do something
pass
app = Flask(__name__)
app.route('/some-endpoint', methods=['GET'])(some_endpoint_handler)
So in your scenario, you can pass the app.route call to your myClass object and set the route like this:
class myClass():
def __init__(self, router):
self.dbConnObj = DbToolsMySql('someconnection', 'slave')
self.dbConnObj.connect()
self.blueprint = Blueprint('myClass', __name__)
#self.blueprint.add_url_rule('/my_method', view_func=self.my_method)
router('/my_method', ['GET'])(self.my_method)
def my_method(self, event):
retun "hello"
myObj = myClass( app.route )
or, invert the dependency:
app = Flask(__name__)
#app.route(myClass.blueprint.some_endpoint_string)
def some_endpoint_handler():
myClass.blueprint.call_some_endpoint_handler()
pass
if __name__ == "main":
app.run()

RuntimeError: No application found.This only happens when I query from db

I am creating a Python Object that all static data in the db. I would like to have one instance of this across the Application that I can access by using an "import" variable. In the code, I have multiple DB queries happening but as soon as I use "country.query.all()" I get the runtime error.
I have tried using with app.app_context() only to be greeted to "Error: ImportError: cannot import name 'api' from 'App.api.routes'
Edit: I am using blue prints this is why you will see App.api.routes
getinfo.py
def create():
class Country:
def __init__(self,id, name,iso):
self.id= id
self.name = name
self.iso = iso
self.providers = get_providers_by_id(id)
class Provider:
def __init__(self, id, name):
self.id = id
self.name = name
self.products = get_product_by_id(id)
b = []
countries = country.query.all()
for row in countries:
b.append(Country(row.id, row.name,row.iso))
return b
items = create()
routes.py
From App.getinfo import items
Error: RuntimeError: No application found. Either work inside a view function or push an application context. countries = country.query.all()
getinfo.py (changes to try to fix)
app = create_app()
with app.app_context():
items= create()
Error: ImportError: cannot import name 'api' from 'App.api.routes'
I am hoping to not get this issue and to have the option to use the variable "items" as an instance in my routes.
Edit #2: Tried using current_app
getinfo.py (Try to fix #2)
from flask import current_app
with current_app.app_context():
test = create()
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.
There is no such terms App.api.routes from your shared code, so we can't help you here. Just do a full search on the project path and fix the import error.
You were right on using the application context, however better use current_app instead of re-creating an new app:
from flask import current_app

Why doesn't flask session object need to be instantiated?

Reading the documentation I understand that flask defines a class flask.session.
The thing that confuses me is that when people use it they don't instantiate an object of the session class, but use session directly, as in the following code:
from flask import Flask, session
app = Flask(__name__)
#app.route('/')
def index():
session['key'] = 'value'
I don't understand why the code shouldn't look something like this instead:
from flask import Flask, session
app = Flask(__name__)
s = session() # so s is an instance of the flask.session class
#app.route('/')
def index():
s['key'] = 'value'
I am also wondering if this has anything to do with session being a proxy, as it says in the documentation. I read the 'Notes on Proxies' but couldn't understand much.
Awesome question.
It gets initialized in flasks globals.py
https://github.com/pallets/flask/blob/master/flask/globals.py
session = LocalProxy(partial(_lookup_req_object, 'session'))
So when you import from flask you import from its package __init__.py which pulls session from globals.py and initializes it. You grab a reference to that when you directly import it.
I should clarify that session itself is not a class. It’s an instance of the LocalProxy class, which is a proxy to the request context.

Extending Flask class as main App

I'm learning Flask and am a bit confused about how to structure my code. So I tried to extend Flask main class as follows:
from flask import Flask, ...
class App(Flask):
def __init__(self, import_name, *args, **kwargs):
super(App, self).__init__(import_name, *args, **kwargs)
Note that I am aware of that this may be a completely wrong approach.
So that when I want to start the app I do:
app = App(__name__)
if __name__ == '__main__':
app.run()
This way I can order my methods and routes in the class, but the problem is when using self-decorators:
#route('/')
def home(self, context=None):
context = context or dict()
return render_template('home.html', **context)
Which raises an error as unresolved reference 'route'. I guess this is not the way I should be structuring the app. How should I do it instead or how do I get the error fixed?
Doing this doesn't make sense. You would subclass Flask to change its internal behavior, not to define your routes as class methods.
Instead, you're looking for blueprints and the app factory pattern. Blueprints divide your views into groups without requiring an app, and the factory creates and sets up the app only when called.
my_app/users/__init__.py
from flask import Blueprint
bp = Blueprint('users', __name__, url_prefix='/users')
my_app/users/views.py
from flask import render_template
from my_app.users import bp
#bp.route('/')
def index():
return render_template('users/index.html')
my_app/__init__.py
def create_app():
app = Flask(__name__)
# set up the app here
# for example, register a blueprint
from my_app.users import bp
app.register_blueprint(bp)
return app
run.py
from my_app import create_app
app = create_app()
Run the dev server with:
FLASK_APP=run.py
FLASK_DEBUG=True
flask run
If you need access to the app in a view, use current_app, just like request gives access to the request in the view.
from flask import current_app
from itsdangerous import URLSafeSerializer
#bp.route('/token')
def token():
s = URLSafeSerializer(current_app.secret_key)
return s.dumps('secret')
If you really want to define routes as methods of a Flask subclass, you'll need to use self.add_url_rule in __init__ rather than decorating each route locally.
class MyFlask(Flask):
def __init__(self, *args, **kwargs):
super().__init__(*args, **kwargs)
self.add_url_rule('/', view_func=self.index)
def index(self):
return render_template('index.html')
The reason route (and self) won't work is because it's an instance method, but you don't have an instance when you're defining the class.

Is it possible to import flask configuration values in modules without circular import?

I'm using Flask with Blueprints to get a skeleton for my website and I'm having a problem using configuration classes deep in my application.
Here's some dummy code that explains how I've set everything up:
websiteconfig.py
class Config(object):
pass
class ProductionConfig(Config):
DEBUG = False
class DevelopmentConfig(Config):
DEBUG = True
website/__ init __.py:
# Some app code and config loading
app = Flask('website')
app.config.from_object('websiteconfig.DevelopmentConfig')
# Import some random blueprint
from website import users
app.register_blueprint(users.api)
# This works:
# print app.config['DEBUG']
website/users/__ init __.py:
from flask import Blueprint
from website.users.models import test
api = Blueprint('users', __name__, url_prefix='/users')
# This works:
# print api.config['DEBUG']
# From models
print test()
website/users/models.py:
# How can I reach the config variables here?
def test():
# I want config['DEBUG'] here
How can I reach the configuration variables stored in the class I load in app.py deep inside the users package?
Is a circular import like from website import app (inside models.py) an accepted solution?
If not, is there some simple solution I've missed?
I believe you can use flask's current_app idiom for that.
http://flask.pocoo.org/docs/api/#flask.current_app
from flask import current_app
def test():
return current_app.config.get('some_config_value')

Categories