Your problem is that put_nowait() under the hood is trying to wake up all pending tasks. But asyncio doesn't handle the situation when this method is called from a synchronous function outside the event loop. So your event loop doesn't get a notification from an external thread to wake up - it doesn't wake up.
I don't recommend using run_coroutine_threadsafe() because it will make your external thread dependent on the event loop: it will be blocked until the event loop executes your coroutine. If you use call_soon_threadsafe(), the queue will actually update only after the event loop has handled your callback. This leaves the only reasonable solution, which is to use a queue that is both async-aware and thread-aware.
I don't know what the status of Janus is right now. It hasn't actually been updated in 3 years. I even created an issue about it. So I want to offer you my package, which is called aiologic.
from aiologic import SimpleQueue
queue = SimpleQueue()
queue.green_put(42) # sync
await queue.async_get() # async
Unlike janus.Queue, it never creates additional threads to notify an external thread.