1

Every time I request flask API I want to get incremented value. But I am always getting the same value because series() object is getting created again and again.

I have already made flask API and generator function.


    @app.route('/eRxBot/Increment', methods=['POST','GET'])
    def Gen():
       gen =series()
       val =str(next(gen))
       print(val)
       res = Response(val)
       return res


    def series():
        for i in range(1,999):
            yield i

Output:

1 2 3

and so on increment with every API call.

  • It seems that you does not know what is restful, see this: https://stackoverflow.com/questions/671118/what-exactly-is-restful-programming – Waket Zheng Apr 17 '19 at 07:57
  • If you're trying to increment with every API call it wont happen, cause state is not stored across calls. If you wanna pull something like that off, maybe use something like session, but still it seems like a very bad practice when it comes to principles of REST. What is it that you're actually trying to accomplish? – Shuvojit Apr 17 '19 at 07:58

1 Answers1

3

The issue you are seeing is that you are creating a new instance of the series generator for every HTTP request. By moving the instance of the generator outside the view function it will increment with each request.

State however won't be stored across restarts of the app or synchronised between multiple processes which would need a backing data store.

Here is a working version and an example of using Redis to back the value generation instead of a local generator. EDIT: For the additional question, the series now resets daily for the generator based example.

from flask import Flask, Response
from flask_redis import FlaskRedis
import datetime

app = Flask(__name__)
redis_store = FlaskRedis(app)
redis_key = "my_incr"


def series():
    for i in range(1, 999):
        yield i


def make_get_or_rotate_series():
    today = datetime.date.today()
    current_series = series()

    def get_or_rotate_series(current_day=None):
        nonlocal today, current_series
        current_day = current_day if current_day else datetime.date.today()

        if today != current_day:
            today = current_day
            current_series = series()

        return current_series
    return get_or_rotate_series


get_series = make_get_or_rotate_series()


@app.route('/eRxBot/Increment', methods=['POST', 'GET'])
def gen():
    val = str(next(get_series()))
    print(val)
    res = Response(val)
    return res


@app.route('/eRxBot/Increment-Redis', methods=['POST', 'GET'])
def gen_redis():
    val = redis_store.incr(redis_key)
    res = Response(str(val))
    return res


if __name__ == "__main__":
    # tests
    test_get_series = make_get_or_rotate_series()
    assert next(test_get_series()) == 1
    assert next(test_get_series()) == 2
    tomorrow = datetime.date.today() + datetime.timedelta(days=1)
    assert next(test_get_series(tomorrow)) == 1
    assert next(test_get_series(tomorrow)) == 2

    app.run()


Steve McCartney
  • 181
  • 1
  • 3