Search code examples
pythonflaskflask-restful

How to run Python method only once, durning the program life cycle?


I have built a Python Flask REST API, which reacts to POST requests. Every time the endpoint is called, file from server is read. I was wondering is there any way for the file to be read in only once?

I would like to have it so that reading from file is done only once the program is launched. At the moment file is read in every time the "/test" endpoint is called.

This is an example of the controller:

@app.route('/test', methods=['POST'])
def test(data):
    file_content = Data.readFile()
    ...
    "Here do something with the file content and data"

Here is the content of Data.py:

def readFile():
    with open(os.getcwd() + '/csv_files/' + config.WORDS, encoding="utf-8-sig", mode='r') as f:
        csv_reader = csv.reader(f, delimiter=';')
        file_content = [row[0] for row in csv_reader]
    return file_content

I know that in Java Spring you can use @PostConstruct or @Configuration. Is there something similar in Python?


Solution

  • You can create a closure function for this.

    # Data.py
    def read_file():
        # the variable `read_file` is being modified inside the function
        # ignoring the global declaration will create a local variable read_file
        global read_file
    
        with open(os.getcwd() + '/csv_files/' + config.WORDS, encoding="utf-8-sig", mode='r') as f:
            csv_reader = csv.reader(f, delimiter=';')
            file_content = [row[0] for row in csv_reader]
    
        def inner():
            return file_content
    
        # read file is a global variable 
        # because it is declared as a function in the global scope
        # we are modifying it here and monkey patching it with `inner`
        # subsequent calls to `read_file` will inherently call `inner`
        read_file = inner
    
        # for the first time the function is called
        return file_content
    

    The first time you call read_file(), the file is opened and file_content is loaded into the variable and the variable read_file gets replaced by the inner function.
    For subsequent method calls, the value of file_content is simply returned by the inner function.