Unable to launch prodigy.serve in a Docker container

I have a FastAPI application which should start/stop a prodigy annotation server via endpoints. I'm using python's multiprocessing package to create a new process that calls prodigy.serve on a specific port. All this works great on Windows 10. However, when I build it as a Docker image and try using it, it fails when prodigy tries to run the uvicorn server with the following error:

File "/usr/local/lib/python3.8/site-packages/prodigy/__init__.py", line 43, in serve
    server(controller, controller.config)
  File "/usr/local/lib/python3.8/site-packages/prodigy/app.py", line 529, in server
    uvicorn.run(
  File "/usr/local/lib/python3.8/site-packages/uvicorn/main.py", line 362, in run
    server.run()
  File "/usr/local/lib/python3.8/site-packages/uvicorn/main.py", line 389, in run
    loop = asyncio.get_event_loop()
  File "/usr/local/lib/python3.8/asyncio/events.py", line 639, in get_event_loop
    raise RuntimeError('There is no current event loop in thread %r.'
RuntimeError: There is no current event loop in thread 'ThreadPoolExecutor-0_0'

Furthermore, I have configured the host to be 0.0.0.0 as suggested in other threads.
I'm using prodigy version 1.10.8.
I think this is exactly the same problem as one mentioned in this thread.

I was able to fix it by assigning the workers argument to 2 when starting my FastAPI app within Docker.

The issue here is that you're trying to serve prodigy in a thread, that is not the main thread. Only the main thread has an event loop running by default. You could have created a new event loop on that thread before calling the server function, e.g. asyncio.set_event_loop(uvloop.new_event_loop()). More info here.

I can't see how having 2 workers solved the issue. Maybe you changed the normal function into anasync function on the FastAPI application?

@Marcelo That's the only thing I changed - adding the workers argument to the Dockerfile CMD command. Keep in mind I am spawning a new Process using the multiprocessing library, as opposed to serving it in a thread. I think that's why creating a new event loop didn't work for me.