dimanche 10 octobre 2021

How to use context object pattern in Flask?

Introduction

I have a flask app in which whenever a request comes there are some values in headers which needs to be extracted and stored in variables and are being used all across the code base to fetch configs etc.

So currently what I am doing is setting those values in request context and passing them around:

#urls.py
@app.before_request
def before_request_handler():
    request.a = request.headers.get("A")
    request.b = request.headers.get("B")
    request.c = request.headers.get("C")
    request.d = request.headers.get("D")
    request.cache = PaymentAerospikeCache()

#views.py
class ViewA(BaseView):
    s_a = ServiceA(a=request.a,b=request.b)
    s_a.do_one_thing()
    s_a.do_another_thing(request.c, request.d) 

#service_a.py
class ServiceA():
    def __init__(self, a, b):
        self.a = a
        self.b = b
        self.a_conf = self.get_conf(a)
        self.b_conf = self.get_conf(b)
    
    def do_one_thing():
        # do something using a and b conf
    
    def do_another_thing(c, d):
        x = ServiceB(self.a, self.b, c)
        x.do_somthing(d)

class ServiceB():
    def __init__(self, a, b, c):
        self.a = a
        self.b = b
        self.c = c
    def do_something(c, d):
        ServiceC(self.a, self.b, c).do_something_else()
        ServiceD(self.a, self.b, d).do_something_else()
        

Problem Statement

So basically there's a lot of passing down of variables which are actually part of the request. I tried using flask's request level context here but the problem is I also have crons and qworkers which are using these classes and they can't use a request level context. 1 possible solution is I use

#qworker.py/cron.py
with app.test_request_context():
    # set the values in context and call services and their methods.
 

But this doesn't seem right to me personally as this is not a test request context. Is there any otherway to handle this scenario?

Aucun commentaire:

Enregistrer un commentaire