generative-ai-python
generative-ai-python copied to clipboard
AttributeError: 'NoneType' object has no attribute 'POLLER'
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
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
also seeing this whenever I run generate_content_async
Also seeing it when I run generate_content_async
, even on Windows.
Update: Fixed it by creating a new environment and reinstalling everything.
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
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
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"
}
]```
I notice the model
need to be inside the async function.
That is, the following works for me:
async def generate_content_async():
model = genai.GenerativeModel(model_name="gemini-1.5-flash")
result = await model.generate_content_async("hello")
return result.text
loop = asyncio.get_event_loop()
result = loop.run_until_complete(generate_content_async())
and the following will throw error:
model = genai.GenerativeModel(model_name="gemini-1.5-flash")
async def generate_content_async():
result = await model.generate_content_async("hello")
return result.text
loop = asyncio.get_event_loop()
result = loop.run_until_complete(generate_content_async())
I notice the
model
need to be inside the async function.That is, the following works for me:
async def generate_content_async(): model = genai.GenerativeModel(model_name="gemini-1.5-flash") result = await model.generate_content_async("hello") return result.text loop = asyncio.get_event_loop() result = loop.run_until_complete(generate_content_async())
and the following will throw error:
model = genai.GenerativeModel(model_name="gemini-1.5-flash") async def generate_content_async(): result = await model.generate_content_async("hello") return result.text loop = asyncio.get_event_loop() result = loop.run_until_complete(generate_content_async())
This fix worked for me