0
votes

I read http://bottlepy.org/docs/dev/tutorial_app.html#server-setup

and running Apache + Bottle + Python

and Bottle + Apache + WSGI + Sessions

and I would like to know if one can run asynchronous rest api calls to bottle on mod_wsgi server to a py function that does not return anything(its a backend logic) and is non blocking - so I looked up gevent but i am haven't found a solution where you can run mod_wsgi with gevents.

Is there any solution to async calls to run on apache server using mod_wsgi or any other alternative?

UPDATE as per andreans' answer below;

I ran a simple myip address return with bottle + celery. so one has to run a celery as @celery.task and then run(host='localhost', port=8080, debug=True)? does it require to start celery worker on terminal as well? never used celery before [runnin locally] also running bottle with decorator @route(/something) works but app.route doesnt where app = Bottle() possibly due to some .wsgi file error?

1
you could use celery, define your tasks, and run them asynchronously from request handler function, it won't block so the handler func returns immediately, but your client app will have to check back periodically to see if a result is available.andrean
@andrean what if i have to just recv the request from client app and store it in the db after processing over it? but the user should continue the usual interaction on his browser? should something be returned then?user2290820

1 Answers

1
votes

Sorry, can't fit into the comment box. Every request must get a response eventually (or fail/time out). If you really don't need to return any data to the client, send back just an empty response with a status code. If the processing of the request takes time, it should run asynchronously, and that's where celery comes in. So a blocking implementation of your request handler:

def request_processor_long_running_blocking_func(request_data):
    # process request data, which takes a lot of time
    # result is probably written into db
    pass

def request_handler_func(request):
    request_processor_long_running_blocking_func(request.data)
    return HttpResponse(status=200)

If I understood correctly this is what you're trying to avoid, by making the request_processor_long_running_blocking_func run asynchronously, so the request_handler_func won't block. This would be solved with celery like this:

from celery.task import task

@task
def request_processor_long_running_blocking_func(request_data):
    # the task decorator wraps your blocking function, with celery's Task class 
    # which has a delay method available for you to call, which will run your function
    # asynchronously on one of your celery background worker processes
    pass

def request_handler_func(request):
    request_processor_long_running_blocking_func.delay(request.data)
    # calling the function with delay won't block, it returns immediately
    # and your response is sent back instantly
    return HttpResponse(status=200)

One more thing, send these task requests with ajax, so your web interface won't be reloaded or anything, so the user can continue using your app after sending the request