"event loop is already running" while trying to run `prodigy.serve`

I'm trying to use Prodigy via the Python API, but hitting an unexpected error. I'm just trying something basic, so let's say this is the command:

import prodigy
prodigy.serve("mark cat_images images --loader images --label CAT --view-id classification", port=8091)

I have a folder filled with images located in the .images directory. But when I run this cell in a notebook, I get the following error:

RuntimeError                              Traceback (most recent call last)
Input In [5], in <cell line: 1>()
----> 1 prodigy.serve("mark cat_images images --loader images --label CAT --view-id classification")

File ~/.pyenv/versions/3.9.13/envs/dev51/lib/python3.9/site-packages/prodigy/__init__.py:43, in serve(command, *recipe_args, **config)
     37     if not controller:
     38         msg.fail(
     39             f"Can't serve '{recipe_name}'. It doesn't seem to be a recipe "
     40             f"that requires the Prodigy server to be started.",
     41             exits=1,
     42         )
---> 43     server(controller, controller.config)
     44 else:
     45     # Backwards-compatibility: first arg used to be recipe name
     46     loaded_recipe = get_recipe(command)

File ~/.pyenv/versions/3.9.13/envs/dev51/lib/python3.9/site-packages/prodigy/app.py:549, in server(controller, config)
    540 msg.text(
    541     f"Starting the web server at http://{host}:{port} ...",
    542     "Open the app in your browser and start annotating!",
    543     icon="emoji",
    544     spaced=True,
    545 )
    547 # uvicorn doesn't seem to accept our log levels via getLogger, so we also
    548 # pass it in explicitly here
--> 549 uvicorn.run(
    550     app,
    551     host=host,
    552     port=int(port),
    553     log_level=get_log_level(),
    554     log_config=_uvicorn_log_config,
    555 )
    556 controller.save()

File ~/.pyenv/versions/3.9.13/envs/dev51/lib/python3.9/site-packages/uvicorn/main.py:386, in run(app, **kwargs)
    384     supervisor.run()
    385 else:
--> 386     server.run()

File ~/.pyenv/versions/3.9.13/envs/dev51/lib/python3.9/site-packages/uvicorn/server.py:49, in Server.run(self, sockets)
     47 self.config.setup_event_loop()
     48 loop = asyncio.get_event_loop()
---> 49 loop.run_until_complete(self.serve(sockets=sockets))

File ~/.pyenv/versions/3.9.13/lib/python3.9/asyncio/base_events.py:623, in BaseEventLoop.run_until_complete(self, future)
    612 """Run until the Future is done.
    614 If the argument is a coroutine, it is wrapped in a Task.
    620 Return the Future's result, or raise its exception.
    621 """
    622 self._check_closed()
--> 623 self._check_running()
    625 new_task = not futures.isfuture(future)
    626 future = tasks.ensure_future(future, loop=self)

File ~/.pyenv/versions/3.9.13/lib/python3.9/asyncio/base_events.py:583, in BaseEventLoop._check_running(self)
    581 def _check_running(self):
    582     if self.is_running():
--> 583         raise RuntimeError('This event loop is already running')
    584     if events._get_running_loop() is not None:
    585         raise RuntimeError(
    586             'Cannot run the event loop while another loop is running')

RuntimeError: This event loop is already running

I have no other Prodigy process running. I restarted my computer completely to be sure.

I started with this docs page and assumed I'd be able to get things working this way...

I fixed it myself. Turns out there's some issue with asyncio. The fix is to firstly pip install nest-asyncio and then run (somewhere else in the notebook):

import nest_asyncio

Now the prodigy.serve method works just as expected!

1 Like

Yeah, especially when you're running inside of Jupyter these async hiccups tend to occur.

Thanks for sharing the solution :blush:

1 Like