google-gemini / generative-ai-python

The official Python library for the Google Gemini API
https://pypi.org/project/google-generativeai/
Apache License 2.0
1.18k stars 226 forks source link

AttributeError: 'NoneType' object has no attribute 'POLLER' #207

Open abh31000 opened 4 months ago

abh31000 commented 4 months ago

Description of the bug:

This issue happens when I use the generate_content_async() method. Everything works perfectly, but at the end it raises that AttributeError: 'NoneType' object has no attribute 'POLLER'


Dummy code:

import asyncio
....

async def main():
   ....
   response = await model.generate_content_async(f"{prompt}")
   print(response.text)

if __name__ ==  "__main__":
   asyncio.run(main())


Traceback:

Traceback (most recent call last):
  File "src/python/grpcio/grpc/_cython/_cygrpc/aio/grpc_aio.pyx.pxi", line 110, in grpc._cython.cygrpc.shutdown_grpc_aio
  File "src/python/grpcio/grpc/_cython/_cygrpc/aio/grpc_aio.pyx.pxi", line 114, in grpc._cython.cygrpc.shutdown_grpc_aio
  File "src/python/grpcio/grpc/_cython/_cygrpc/aio/grpc_aio.pyx.pxi", line 78, in grpc._cython.cygrpc._actual_aio_shutdown
AttributeError: 'NoneType' object has no attribute 'POLLER'
Exception ignored in: 'grpc._cython.cygrpc.AioChannel.__dealloc__'
Traceback (most recent call last):
  File "src/python/grpcio/grpc/_cython/_cygrpc/aio/grpc_aio.pyx.pxi", line 110, in grpc._cython.cygrpc.shutdown_grpc_aio
  File "src/python/grpcio/grpc/_cython/_cygrpc/aio/grpc_aio.pyx.pxi", line 114, in grpc._cython.cygrpc.shutdown_grpc_aio
  File "src/python/grpcio/grpc/_cython/_cygrpc/aio/grpc_aio.pyx.pxi", line 78, in grpc._cython.cygrpc._actual_aio_shutdown
AttributeError: 'NoneType' object has no attribute 'POLLER'

Actual vs expected behavior:

No response

Any other information you'd like to share?

Python version: 3.11.4 Using the latest version of the lib

If it helps grpcio version: 1.60.1

TechAtlasDev commented 4 months ago

This appears to be a bug that is initiated by a tool used on Ubuntu systems called "apport" to collect application crash information, which is used for uncaught exceptions, when looking at the root of the bug I can see these comments:

def apport_excepthook(exc_type, exc_obj, exc_tb):
     '''Catch an uncaught exception and make a traceback.'''

     # create and save a problem report. Note that exceptions in this code
     # are bad, and we probably need a per-thread reentrancy guard to
     # prevent that happening. However, on Ubuntu there should never be
     # a reason for an exception here, other than [say] a read only var
     # or some such. So what we do is use a try - finally to ensure that
     # the original excepthook is invoked, and until we get bug reports
     # ignore the other issues.

     # import locally here so that there is no routine overhead in python
     # startup time - only when a traceback occurs will this trigger.

EDIT: but it seems to be an error that is linked to the asyncio library, because when I integrated the asynchronous function with pyrogram (without having the need to activate asynchronous functions with asyncio), that exception is not shown

noslouch commented 3 months ago

also seeing this whenever I run generate_content_async

cabralpinto commented 3 months ago

Also seeing it when I run generate_content_async, even on Windows.

Update: Fixed it by creating a new environment and reinstalling everything.

theo-alli commented 2 months ago

Also having this issue on macOS with generate_content_async. Creating a new environment hasn't fixed it. Using python 3.10.10 and grpcio 1.62.1

jmugan commented 3 weeks ago

I'm having it on Ubuntu as well. It even shows up if I wrap it in try-except

async def async_get_chat_response(chat: ChatSession, prompt: str):
    try:
        response = await chat.send_message_async(prompt)
        # because https://github.com/googleapis/python-aiplatform/issues/3129
        text = response.candidates[0].content.parts[0]._raw_part.text
    except AttributeError:
        pass # because https://github.com/google-gemini/generative-ai-python/issues/207
    return text
LTMullineux commented 2 weeks ago

I have had exactly this problem as well, it renders the async version useless. I needed an async version so used httpx and regex to just call the Rest API. Here's is an example based on the Entity Extraction JSON tutorial:

import json
import re

import httpx

URL = "https://generativelanguage.googleapis.com/v1beta/models/gemini-1.5-flash:generateContent"  # noqa: E501
API_KEY = "SUPERSECRETAPIKEY"

def create_prompt_payload(text: str) -> dict:
    prompt = f"""
    Given the text below, extract entities and their categories using the JSON schema:

    Entity = {{
        "name": str,
        "category": CategoryEnum[Person, Company, State, City]
    }}

    Return: list[Entity]

    {text}"""

    return {
        "contents": [{"parts": [{"text": prompt}]}],
        "generationConfig": {"temperature": 1.0},
    }

async def main():
    input_text = "John Johnson, the CEO of the Oil Inc. and Coal Inc. companies, has unveiled plans to build a new factory in Houston, Texas."  # noqa: E501
    payload = create_prompt_payload(input_text)
    headers = dict(
        content_type="application/json", response_mime_type="application/json"
    )

    async with httpx.AsyncClient(
        params=dict(key=API_KEY), headers=headers, timeout=60.0
    ) as client:
        response = await client.post(URL, json=payload)
        response.raise_for_status()

    response_payload = response.json()
    try:
        raw_result = response_payload["candidates"][0]["content"]["parts"][0]["text"]
        raw_json = re.search(r"```json(.*?)```", raw_result, re.DOTALL)
        json_match = raw_json.group(1)
        if json_match:
            result = json.loads(json_match.strip())
            print(json.dumps(result, indent=2))
        else:
            print("No JSON found in response")

    except (json.JSONDecodeError, KeyError, IndexError) as e:
        raise Exception("OPPSY!") from e

if __name__ == "__main__":
    import asyncio

    asyncio.run(main())

[
  {
    "name": "John Johnson",
    "category": "Person"
  },
  {
    "name": "Oil Inc.",
    "category": "Company"
  },
  {
    "name": "Coal Inc.",
    "category": "Company"
  },
  {
    "name": "Houston",
    "category": "City"
  },
  {
    "name": "Texas",
    "category": "State"
  }
]```