question-mark
Stuck on an issue?

Lightrun Answers was designed to reduce the constant googling that comes with debugging 3rd party libraries. It collects links to all the places you might be looking at while hunting down a tough bug.

And, if you’re still stuck at the end, we’re happy to hop on a call to see how we can help out.

[QUESTION] Storing object instances in the app context

See original GitHub issue

Description

In Flask, I’ve found this to be a common pattern to do something like this:

run_app.py

from api.factory import create_app

app = create_app()

api/factory.py

from flask import Flask, current_app
import redis
import config
from api.resources.basic import basic

def create_app():
    """Create the app."""
    app = Flask(__name__)
    app.config.from_object(config.ProductionConfig)
    app.redis = redis.Redis(host=app.config["REDIS_HOST"], port=app.config["REDIS_PORT"])
    app.register_blueprint(basic, url_prefix="/api/v1")

api/resources/basic.py

from flask import current_app
from flask import Blueprint
from webargs import fields
from webargs.flaskparser import use_args

mod = Blueprint('basic', __name__)
write_args = {"value": fields.Str(required=True)}

@mod.route('/<str:key>', methods=['POST'])
@use_args(write_args, key)
def create_resource(args, key):
   """POST resource to redis."""
   current_app.redis.set(key, args["value"])
   current_app.logger.info("inserted value into redis")
   return {key: args["value"]}, 201

@mod.route('/<str:key>', methods=['GET'])
def retrieve_resource(key):
   """GET value from redis."""
   return {key: current_app.redis.get(key)}, 200

Is it possible to have a ‘global’ app context where you can put objects shared across request contexts, where you would access objects that you don’t want to keep reinstantiating because it might be expensive and because of the convenience and how it makes it easier to reason about where ‘objects’ live. Like current_app.redis, or current_app.logger, or current_app.kafka_producer. I read about Depends, and saw the examples provided for how to deal with dependencies / resources but I didn’t see something like the above.

Might be a bad practice, but it’s worked well for me so far.

Issue Analytics

  • State:closed
  • Created 5 years ago
  • Reactions:20
  • Comments:15 (6 by maintainers)

github_iconTop GitHub Comments

44reactions
vgavrocommented, Dec 15, 2020

@ebarlas you’re 100% right. The way FastAPI documentation proposing app configuration assuming you have global variables for use with (angular-style inspired)? dependency injection, and in big projects it will be a huge mess, but MORE important - it’s complex to write reusable modules for different apps. Other frameworks trying to solve this in different way, happily FastAPI is based on starlette - and there is request.state and request.app.state variables. Pseudo-code for proper application configuration will look something like this, use this factory in tests to override settings without ugly hacks like documentation suggests.

create_app(**config):
  config.set_default('debug', true)
  config.set_default('db_url', 'sqlite://:memory:')
  app = FastAPI(app)
  app.state.config = config
  setup_database(app)  # reads app.state.config, register middleware for request.state.db_session
  setup_redis(app)  # something similar
  return app
11reactions
ebarlascommented, Sep 23, 2020

@tiangolo, I’m working with a colleague on a FastAPI application and we’re having a discussion about the merits of global module variables vs. passed dependencies. I’ve been advocating dependency passing as a way to modularize an application, govern access, facilitate testing, etc. For example, I’ve been advocating that a database repository object should be passed as a dependency of some kind and should not be a globally accessible module variable.

We noticed this issue and your comment about globals on 2019/3/17. I’m hoping you’ll weigh in again since we’re looking to the broader Python community for guidance on this question. Are global module variables considered idiomatic Python? Are the pitfalls of globals less applicable here? Can you think of FastAPI reference applications that heavily use module globals as a way to distribute dependencies like caches, database repositories, etc?

Read more comments on GitHub >

github_iconTop Results From Across the Web

Store Objects in ApplicationContext - android - Stack Overflow
I am using the following code. Accounts.create(getApplicationContext()) will be called once to store the accounts instance. Is that possible( ...
Read more >
Creating and Saving Managed Objects - Apple Developer
The context tracks changes to and relationships between objects. As shown in this example, the NSEntityDescription class has a class method ...
Read more >
Chapter 3. Beans, BeanFactory and the ApplicationContext
The BeanFactory provides an advanced configuration mechanism capable of managing beans (objects) of any nature, using potentially any kind of storage ...
Read more >
The Application Context — Flask Documentation (2.2.x)
Storing Data​​ The application context is a good place to store common data during a request or CLI command. Flask provides the g...
Read more >
Classes and Objects in Java - GeeksforGeeks
In real-time, we need different objects of a class in different methods. Creating a number of references for storing them is not a...
Read more >

github_iconTop Related Medium Post

No results found

github_iconTop Related StackOverflow Question

No results found

github_iconTroubleshoot Live Code

Lightrun enables developers to add logs, metrics and snapshots to live code - no restarts or redeploys required.
Start Free

github_iconTop Related Reddit Thread

No results found

github_iconTop Related Hackernoon Post

No results found

github_iconTop Related Tweet

No results found

github_iconTop Related Dev.to Post

No results found

github_iconTop Related Hashnode Post

No results found