2

I'm researching Sanic as we're looking for alternatives to our flask-based rest services. I'm intriguied by the async nature of sanic, but I know that we'll bump into a lot of code that simply won't support async (we use a ton of boto3 and also some ORMs on top of DynamoDB for example, none of which support awaiting).

So: I need to find the cleanest way of being able to run synchronous code inside an async framework like Sanic. In python 3.7 there's the asyncio.create_task call which I'm finding interesting.

Wondering if this would be a possible way to go:

main.py:

#default boilerplate sanic code excluded for brevity
from app_logic import AppLogic

@app.route("/")
async def test(request):
    task = await asyncio.create_task(AppLogic.sync_request('https://stuff.com'))
    return json({"hello": "world", 'status_code': task.status_code})

app_logic.py:

import requests

class AppLogic(object):
    @staticmethod
    async def sync_request(url='https://myurl.com'):
        #Some non-async library/code thingy
        print('requesting the thing')
        return requests.get(url)

This seems to work, and the the returned task object is a regular requests response.

However, I have no idea if this is "safe" - eg I'm not sure how I can investigate the event loop and verify that it's not blocking in any way. I'm sure there's also other reasons for this approach being completely dumb, so lay them on me :-)

Trondh
  • 3,221
  • 1
  • 25
  • 34
  • What is a "non-async coroutine"? – wim Dec 04 '18 at 18:33
  • tried to clarify – Trondh Dec 04 '18 at 18:36
  • In case you're still looking for an answer, yes using `requests` will block the event loop as the `requests` library isn't async. You'll need to use an async http library, like [`aiohttp`](https://github.com/aio-libs/aiohttp). An example can be seen in [this file on github](https://github.com/jackfischer/sanic/blob/5171cdd305ffde7ebf1e4d23b886489d038795b8/examples/aiohttp_example.py#L25-L29). – xyres Jan 22 '19 at 12:32
  • thanks @xyres. My question was rather: What can I do when there is no async option available to me? (requests was just used as an example of a non-async library) – Trondh Jan 28 '19 at 19:25
  • @Trondh Oh, in that case, if you're doing some networking related task, you can write an async version yourself. If it's a CPU heavy task, then the only option is to run it in a separate thread or process. – xyres Jan 28 '19 at 20:17
  • Possible duplicate of [How to use asyncio with existing blocking library?](https://stackoverflow.com/questions/41063331/how-to-use-asyncio-with-existing-blocking-library) – MarkReedZ Feb 12 '19 at 03:41
  • This is a duplicate of https://stackoverflow.com/q/41063331/9638646 . You can run your blocking code in threads using a ThreadPoolExecutor. – MarkReedZ Feb 12 '19 at 03:42
  • nice, thanks for that. – Trondh Feb 12 '19 at 22:07

0 Answers0