amartinez
amartinez

Reputation: 179

API serving up old responses in flask

I'm calling a Flask api, run by gunicorn and which is served out by nginx all on a linux box viretal env

When I use curl or postman to test I get 1 of 4 responses randomly each time I run - but mostly response 2 below

Here's my flask api py file. I'm new to this so excuse any errors:

app = Flask(__name__)
now = datetime.now()
timestamp=str(now.strftime("%Y-%m-%d %H:%M"))

# assignes route for POSTING JSON requests
@app.route('/api/v1.0/my-api', methods=['POST'])
#@requires_auth
def runscope():
    if request.method == 'POST':
        in_json = request.json
    in_json["api_datetime"] = timestamp
    json_to_file(in_json)
        return timestamp + "New msg log file success!" 


# assigns route for the default GET request
@app.route('/')
def index():
    return 'test on the index'  


if __name__ == "__main__":
    app.debug = True
    application.run()

# function to drop request data to file
def json_to_file(runscope_json):
    with open('data/data.json', 'a') as outfile:
            json.dump(runscope_json, outfile, indent=2)

So when I run the test below several times in a row

curl -H "Content-Type: application/json" -X POST -d '{"username":"xyz","password":"xyz"}' http://localhost:8000/api/v1.0/my-api

I get either 1. Response: "New msg log file success!" with the json getting to the file i specified

OR

  1. Response: "log file success!" which was in an old version of the python code above! The data gets to the file but without the timestamp as the old code didn't have it

OR

  1. "Not Found The requested URL was not found on the server. If you entered the URL manually please check your spelling and try again."

OR

  1. { "message": "Authenticate." } which is a response I had in another OLD version of the code!

Note: I do a "gunicorn my-api:app" and a nginx restart if I changed the code, making sure to manually delete the .pyc file first

Can anyone help out? Wheres it getting the old code responses from? Why is it intermittent, giving me the expected new code response only sometimes?

Upvotes: 0

Views: 1857

Answers (2)

Gregory R.
Gregory R.

Reputation: 1945

use Flask-Caching https://flask-caching.readthedocs.io/en/latest/

pip install Flask-Caching

Set Up

Cache is managed through a Cache instance:

from flask import Flask
from flask_caching import Cache

config = {
    "DEBUG": True,          # some Flask specific configs
    "CACHE_TYPE": "simple", # Flask-Caching related configs
    "CACHE_DEFAULT_TIMEOUT": 300
}
app = Flask(__name__)
# tell Flask to use the above defined config
app.config.from_mapping(config)
cache = Cache(app)

Caching View Functions

To cache view functions you will use the cached() decorator. This decorator will use request.path by default for the cache_key:

@app.route("/")
@cache.cached(timeout=50)
def index():
    return render_template('index.html')

Upvotes: 0

errata
errata

Reputation: 6041

Did you try to add cache-related headers to your responses? Something like:

# example code
@app.route('/api/v1.0/my-api', methods=['POST'])
def runscope():
    response.headers['Cache-Control'] = 'no-cache, no-store, must-revalidate'
    response.headers['Pragma'] = 'no-cache'
    # rest of the code...

for a specific Flask route...

Or if you want to disable cache for all requests:

# example code
@app.after_request
def add_header(response):
    response.cache_control.max_age = 60
    if 'Cache-Control' not in response.headers:
        response.headers['Cache-Control'] = 'no-store'
    return response

Upvotes: 2

Related Questions