1

I'm working on a flask app which continuously keeps checking for new messages from an AWS SQS queue and receives them. For this specific I've written a function which can be triggered by an endpoint. - /start. For simplicity, in the code, I haven't posted all the logic for receiving messages from SQS queue. Just printing datetime and waiting for 3 seconds.

How do I make this endpoint to be hit as soon as the flask server is up and ready to serve the requests?

Is there any decorator or something to make this possible?

quque_services.py:

from datetime import datetime
import time
def receive_messages():
    print(datetime.now())
    time.sleep(3)

__init__.py:

from flask import Flask, request, jsonify
from app.workload.services.queue_services import receive_messages

def create_app(**kwargs):
    app = Flask(__name__, **kwargs)

    @app.route('/start')
    def queue_receiver():
        while True:
            receive_messages()

    return app

wsgi.py:

from app import create_app

application = create_app()

if __name__ == "__main__":
    application.run()
Underoos
  • 4,708
  • 8
  • 42
  • 85
  • Do you really need a Flask app then? Sounds to me like if you just call `receive_messages` in your `main` block, it will work without the need to have a HTTP server. – frankie567 Sep 30 '19 at 07:16
  • I also need to serve APIs for managing this `receive_messages` functionality based on the endpoints that are hit. – Underoos Sep 30 '19 at 07:24
  • 2
    The problem here is that the `while` loop will block the HTTP server. IMO, this should be two separate apps (the Flask app that will accept HTTP requests to post new messages, and another one that is dedicated to receive and process messages). If you don't want to do this, maybe you can start a subprocess like described here: https://stackoverflow.com/questions/28800614/run-while-loop-concurrently-with-flask-server – frankie567 Sep 30 '19 at 07:29
  • I'm ok with HTTP server being blocked for that request. I just need to hit it after the server start. For now I need to hit the endpoint manually. And the `datetime` is being printed. And other APIs are being served without any blocking as the `datetime` is being printed on console. – Underoos Sep 30 '19 at 07:52
  • 1
    Would this not be better as a [celery](http://www.celeryproject.org/) app along side the http server? I agree with @frankie567 that it's a strange design construct to have a continuous loop like that on an end point of an API - why not just run the process separately to the flask component? – elembie Oct 01 '19 at 03:29
  • Hello. Were you able to solve this? – Javier Lopez Tomas May 24 '22 at 10:28

1 Answers1

1

You can use the flask test client to send requests to an application after it has been created. I've simplified your code into a single self contained script below that demonstrates this.

from flask import Flask

def create_app(**kwargs):
    app = Flask(__name__, **kwargs)

    @app.route('/start')
    def queue_receiver():
        print("***Endpoint hit***")
        return ""

    return app

application = create_app()

if __name__ == "__main__":
    application.test_client().get('/start')
    print("***Starting server***")
    application.run()

If this is not working for your code then I suspect that it is because you are never returning from your /start endpoint. I had assumed that you were breaking out of your while True loop when all of the messages were processed but had not included the code for brevity. If this is not the case then it will probably be necessary to split the application into a separate client and server as previously suggested in the comments.

EAW
  • 628
  • 6
  • 10