3
respostas

Estou obtendo um erro ao executar a aplicação via gradio após mudança para workflow

Tive que fazer a substituição do QueryPipeline pelo Workflow do LlamaIndex pois na nova versão esse módulo foi descontinuado. Porémao usar em conjunto com as funções do gradio, estou obtendo um erro. link do notebook: https://colab.research.google.com/drive/1oW6FeggVhjMVVbs9txtYZUgADe0Xq7FA?usp=sharing

3 respostas

Oi Mariana, tudo bem?

Executei o seu notebook e encontrei o seguinte erro:
ImportError: cannot import name 'Mistral' from 'mistralai' (unknown location)

Esse erro indica que uma parte do pacote llama-index-experimental está tentando importar a classe Mistral da biblioteca mistralai utilizando um caminho antigo. Em versões mais recentes do mistralai, essa classe foi reorganizada, o que gera um problema de incompatibilidade de versões. Isso acontece porque o llama-index-experimental está desatualizado e espera uma versão mais antiga do mistralai.

Para resolver, você pode ajustar a célula de instalação para garantir compatibilidade entre as bibliotecas, instalando versões adequadas:

!pip install llama-index llama-index-experimental llama-index-llms-groq mistralai -U -q
!pip install gradio fpdf nest_asyncio -q

Também deixo abaixo um notebook já ajustado e funcional como referência:

Espero que isso ajude.

Se surgir qualquer dúvida, fique à vontade para compartilhar no fórum. Abraços e bons estudos!

Caso este post tenha lhe ajudado, por favor, marcar como solucionado ✓. Bons estudos!

Na verdade, o erro ao qual me referia era outro.

Ao executar o código do gradio, após colocar um csv e fazer as perguntas sobre o arquivo aparece um erro, talvez na parte do assincronismo. Não entendo muito bem dessa parte e no código que você mandou o erro permanece:

erro: ERROR:    Exception in ASGI application
Traceback (most recent call last):
  File "/usr/local/lib/python3.12/dist-packages/uvicorn/protocols/http/httptools_impl.py", line 416, in run_asgi
    result = await app(  # type: ignore[func-returns-value]
             ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/usr/local/lib/python3.12/dist-packages/uvicorn/middleware/proxy_headers.py", line 60, in __call__
    return await self.app(scope, receive, send)
           ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/usr/local/lib/python3.12/dist-packages/fastapi/applications.py", line 1159, in __call__
    await super().__call__(scope, receive, send)
  File "/usr/local/lib/python3.12/dist-packages/starlette/applications.py", line 107, in __call__
    await self.middleware_stack(scope, receive, send)
  File "/usr/local/lib/python3.12/dist-packages/starlette/middleware/errors.py", line 186, in __call__
    raise exc
  File "/usr/local/lib/python3.12/dist-packages/starlette/middleware/errors.py", line 164, in __call__
    await self.app(scope, receive, _send)
  File "/usr/local/lib/python3.12/dist-packages/gradio/brotli_middleware.py", line 74, in __call__
    return await self.app(scope, receive, send)
           ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/usr/local/lib/python3.12/dist-packages/gradio/route_utils.py", line 882, in __call__
    await self.app(scope, receive, send)
  File "/usr/local/lib/python3.12/dist-packages/starlette/middleware/exceptions.py", line 63, in __call__
    await wrap_app_handling_exceptions(self.app, conn)(scope, receive, send)
  File "/usr/local/lib/python3.12/dist-packages/starlette/_exception_handler.py", line 53, in wrapped_app
    raise exc
  File "/usr/local/lib/python3.12/dist-packages/starlette/_exception_handler.py", line 42, in wrapped_app
    await app(scope, receive, sender)
  File "/usr/local/lib/python3.12/dist-packages/fastapi/middleware/asyncexitstack.py", line 18, in __call__
    await self.app(scope, receive, send)
  File "/usr/local/lib/python3.12/dist-packages/starlette/routing.py", line 716, in __call__
    await self.middleware_stack(scope, receive, send)
  File "/usr/local/lib/python3.12/dist-packages/starlette/routing.py", line 736, in app
    await route.handle(scope, receive, send)
  File "/usr/local/lib/python3.12/dist-packages/starlette/routing.py", line 290, in handle
    await self.app(scope, receive, send)
  File "/usr/local/lib/python3.12/dist-packages/fastapi/routing.py", line 134, in app
    await wrap_app_handling_exceptions(app, request)(scope, receive, send)
  File "/usr/local/lib/python3.12/dist-packages/starlette/_exception_handler.py", line 53, in wrapped_app
    raise exc
  File "/usr/local/lib/python3.12/dist-packages/starlette/_exception_handler.py", line 42, in wrapped_app
    await app(scope, receive, sender)
  File "/usr/local/lib/python3.12/dist-packages/fastapi/routing.py", line 120, in app
    response = await f(request)
               ^^^^^^^^^^^^^^^^
  File "/usr/local/lib/python3.12/dist-packages/fastapi/routing.py", line 674, in app
    raw_response = await run_endpoint_function(
                   ^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/usr/local/lib/python3.12/dist-packages/fastapi/routing.py", line 328, in run_endpoint_function
    return await dependant.call(**values)
           ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/usr/local/lib/python3.12/dist-packages/gradio/routes.py", line 1671, in get_upload_progress
    await asyncio.wait_for(
  File "/usr/lib/python3.12/asyncio/tasks.py", line 520, in wait_for
    return await fut
           ^^^^^^^^^
  File "/usr/local/lib/python3.12/dist-packages/gradio/route_utils.py", line 528, in is_tracked
    return await self._signals[upload_id].wait()
           ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/usr/lib/python3.12/asyncio/locks.py", line 209, in wait
    fut = self._get_loop().create_future()
          ^^^^^^^^^^^^^^^^
  File "/usr/lib/python3.12/asyncio/mixins.py", line 20, in _get_loop
    raise RuntimeError(f'{self!r} is bound to a different event loop')
RuntimeError: <asyncio.locks.Event object at 0x7d2bc154e960 [unset]> is bound to a different event loop

Insira aqui a descrição dessa imagem para ajudar na acessibilidade

Olá Marianna! Tudo bem?

Analisei os dois notebooks que você enviou. O erro:

RuntimeError: <asyncio.locks.Event object ...> is bound to a different event loop

estava acontecendo porque o Gradio (Uvicorn) e o seu código estavam trabalhando com event loops diferentes do asyncio. Isso é um problema clássico quando misturamos Jupyter/Colab + Gradio + chamadas assíncronas.

Para resolver esse problema, realizei as seguintes mudanças:

1. Remoção completa dos shims complicados

  • Excluí a função _ensure_asyncio_run_loop_factory_shim()
  • Excluí todo o bloco que redefinia asyncio.run antes da interface Gradio

2. Aplicação limpa e única do nest_asyncio
No início da célula principal:

import nest_asyncio
nest_asyncio.apply()
gr.close_all()   # evita conflitos de porta ao reiniciar o Gradio

3. Execução assíncrona direta no Gradio
No seu código original:

def executar_consulta_gradio(pergunta: str, df_estado):
    ...
    resposta = pipeline.run(pergunta)   # ← causava o erro

Na versão corrigida:

async def executar_consulta_gradio(pergunta: str, df_estado):
    if df_estado is None or not (pergunta and str(pergunta).strip()):
        return "Nenhum arquivo carregado ou pergunta vazia."

    # Instanciamos o Workflow diretamente
    workflow = PandasWorkflow(api_key=api_key)

    ev = ConsultaStartEvent(
        query=pergunta,
        df=df_estado,
        debug_prompts=False
    )

    resultado = await workflow.run(start_event=ev)   # ← await direto
    return resultado["resposta_final"]

E tornei a função chamada pelo botão também assíncrona:

async def processar_pergunta(pergunta, df_estado):
    return await executar_consulta_gradio(pergunta, df_estado)

4. Substituição do PandasInstructionParser por eval() controlado
No método executar_codigo do PandasWorkflow:

Antes:

parser = PandasInstructionParser(ev.df)
resultado = parser.parse(ev.pandas_code)

Depois (mais estável no Gradio):

df = ev.df
try:
    resultado = eval(ev.pandas_code, {"__builtins__": {}}, {"df": df})
except Exception as e:
    ...

Resumo das correções principais:

  • Removidos todos os monkey-patches de asyncio.run
  • nest_asyncio.apply() aplicado apenas uma vez, de forma simples
  • Mudança para chamada async/await direta dentro do Gradio
  • Substituição do PandasInstructionParser por eval seguro

Com essas alterações o erro desapareceu completamente e a interface Gradio está funcionando normalmente.

Vou te explicar quais eram os principais problemas no seu notebook original.

Problemas identificados no seu código:

  1. Monkey-patches duplicados e conflitantes do asyncio.run
    Seu notebook tinha duas tentativas diferentes de corrigir o comportamento do asyncio.run (uma dentro da definição do workflow e outra antes da parte do Gradio). Esses patches interferiam entre si e faziam com que objetos internos do asyncio (como Event) ficassem vinculados a loops diferentes.

  2. Chamada síncrona do workflow dentro do Gradio
    Você estava usando pipeline.run(), que internamente chama asyncio.run(). Como o Gradio já roda dentro de seu próprio event loop, isso gerava o conflito.

  3. Uso do PandasInstructionParser
    Esse parser depende de signal.SIGALRM, que não funciona corretamente quando o código é executado fora da thread principal (comportamento comum no Gradio).


Abaixo deixo o link do notebook corrigido. Você pode fazer uma cópia e continuar o seu projeto:

🔗 Notebook Corrigido – Pandas Workflow + Gradio

Qualquer dúvida sobre alguma mudança, é só perguntar.

Caso este post tenha lhe ajudado, por favor, marcar como solucionado ✓. Bons Estudos!