Hey everyone,
I’ve been struggling with this situation for a while and I have no idea how to approach it. I’ve tried all the localized fixes I could think of and I have no idea what the right way would be.
The situation
I am writing a web application with Django. It’s pretty much exclusively sync, but some dependencies use async under the hood, specifically playwright (which we use for testing) and procrastinate (a postgres-backed job queuing system).
Given that we’re not really doing async, I reached for the projects’ respective sync apis, which leads to a call graph kinda like this:
pytest
-> fixture setup
-> playwright is started
-> test case
-> production code
-> procrastinate, e.g. to queue an email to send later
-> ...more test cases
-> fixture teardown
-> playwright shuts down
So far so good, but it turns out that both sync apis start an event loop internally, causing RuntimeError: You cannot use AsyncToSync in the same thread as an async event loop - just await the async function directly.
I could use pytest-asyncio
to get an event loop at the test case level (in the above figure), which would cover the whole execution scope, but my sync production code is between the event loop and the calls into procrastinate.
Async → sync → async callchains don’t seem to be a thing and nest_asyncio
, which is the only approach I found people going for, seems like it will be a bad choice to bet on.
Any guidance on how to tackle this problem would be appreciated. Do we really have to asyncify the whole call chain?