msgraph-sdk-python
msgraph-sdk-python copied to clipboard
RuntimeError: Event loop is closed while using Pytest
Describe the bug
When running multiple tests that are using GraphServiceClient every second test is failing with "RuntimeError: Event loop is closed". When changing scope of test to "module" tests are working properly.
Expected behavior
GraphServiceClient can be used in pytest tests with test scope=="function".
How to reproduce
import pytest
from azure.identity import AzureCliCredential
from msgraph import GraphServiceClient
@pytest.mark.asyncio()
async def test_1():
with AzureCliCredential() as credential:
client = GraphServiceClient(credential)
me = await client.me.get()
@pytest.mark.asyncio()
async def test_2():
with AzureCliCredential() as credential:
client = GraphServiceClient(credential)
me = await client.me.get()
SDK Version
1.4.0
Latest version known to work for scenario above?
Tried 1.0.0. Issue still exists.
Known Workarounds
No response
Debug output
Click to expand log
platform darwin -- Python 3.9.6, pytest-8.2.2, pluggy-1.5.0
rootdir: /Users/marcin/Desktop/msgraphbug/pythonProject
plugins: time-machine-2.14.2, asyncio-0.23.7, anyio-4.4.0
asyncio: mode=strict
collected 2 items
test.py .F [100%]
============================================================================ FAILURES ============================================================================
_____________________________________________________________________________ test_2 _____________________________________________________________________________
@pytest.mark.asyncio()
async def test_2():
with AzureCliCredential() as credential:
client = GraphServiceClient(credential)
> me = await client.me.get()
test.py:15:
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _
.venv/lib/python3.9/site-packages/msgraph/generated/users/item/user_item_request_builder.py:160: in get
return await self.request_adapter.send_async(request_info, User, error_mapping)
.venv/lib/python3.9/site-packages/kiota_http/httpx_request_adapter.py:178: in send_async
response = await self.get_http_response_message(request_info, parent_span)
.venv/lib/python3.9/site-packages/kiota_http/httpx_request_adapter.py:530: in get_http_response_message
resp = await self._http_client.send(request)
.venv/lib/python3.9/site-packages/httpx/_client.py:1661: in send
response = await self._send_handling_auth(
.venv/lib/python3.9/site-packages/httpx/_client.py:1689: in _send_handling_auth
response = await self._send_handling_redirects(
.venv/lib/python3.9/site-packages/httpx/_client.py:1726: in _send_handling_redirects
response = await self._send_single_request(request)
.venv/lib/python3.9/site-packages/httpx/_client.py:1763: in _send_single_request
response = await transport.handle_async_request(request)
.venv/lib/python3.9/site-packages/msgraph_core/middleware/async_graph_transport.py:21: in handle_async_request
response = await self.pipeline.send(request)
.venv/lib/python3.9/site-packages/kiota_http/middleware/middleware.py:38: in send
return await self._first_middleware.send(request, self._transport)
.venv/lib/python3.9/site-packages/kiota_http/middleware/redirect_handler.py:77: in send
response = await super().send(request, transport)
.venv/lib/python3.9/site-packages/kiota_http/middleware/middleware.py:65: in send
return await self.next.send(request, transport)
.venv/lib/python3.9/site-packages/kiota_http/middleware/retry_handler.py:84: in send
response = await super().send(request, transport)
.venv/lib/python3.9/site-packages/kiota_http/middleware/middleware.py:65: in send
return await self.next.send(request, transport)
.venv/lib/python3.9/site-packages/kiota_http/middleware/parameters_name_decoding_handler.py:62: in send
response = await super().send(request, transport)
.venv/lib/python3.9/site-packages/kiota_http/middleware/middleware.py:65: in send
return await self.next.send(request, transport)
.venv/lib/python3.9/site-packages/kiota_http/middleware/url_replace_handler.py:44: in send
response = await super().send(request, transport)
.venv/lib/python3.9/site-packages/kiota_http/middleware/middleware.py:65: in send
return await self.next.send(request, transport)
.venv/lib/python3.9/site-packages/kiota_http/middleware/user_agent_handler.py:30: in send
return await super().send(request, transport)
.venv/lib/python3.9/site-packages/kiota_http/middleware/middleware.py:65: in send
return await self.next.send(request, transport)
.venv/lib/python3.9/site-packages/kiota_http/middleware/headers_inspection_handler.py:54: in send
response = await super().send(request, transport)
.venv/lib/python3.9/site-packages/kiota_http/middleware/middleware.py:65: in send
return await self.next.send(request, transport)
.venv/lib/python3.9/site-packages/msgraph_core/middleware/telemetry.py:48: in send
response = await super().send(request, transport)
.venv/lib/python3.9/site-packages/kiota_http/middleware/middleware.py:62: in send
response = await transport.handle_async_request(request)
.venv/lib/python3.9/site-packages/msgraph_core/middleware/async_graph_transport.py:24: in handle_async_request
response = await self.transport.handle_async_request(request)
.venv/lib/python3.9/site-packages/httpx/_transports/default.py:373: in handle_async_request
resp = await self._pool.handle_async_request(req)
.venv/lib/python3.9/site-packages/httpcore/_async/connection_pool.py:216: in handle_async_request
raise exc from None
.venv/lib/python3.9/site-packages/httpcore/_async/connection_pool.py:196: in handle_async_request
response = await connection.handle_async_request(
.venv/lib/python3.9/site-packages/httpcore/_async/connection.py:101: in handle_async_request
return await self._connection.handle_async_request(request)
.venv/lib/python3.9/site-packages/httpcore/_async/http2.py:185: in handle_async_request
raise exc
.venv/lib/python3.9/site-packages/httpcore/_async/http2.py:148: in handle_async_request
status, headers = await self._receive_response(
.venv/lib/python3.9/site-packages/httpcore/_async/http2.py:292: in _receive_response
event = await self._receive_stream_event(request, stream_id)
.venv/lib/python3.9/site-packages/httpcore/_async/http2.py:333: in _receive_stream_event
await self._receive_events(request, stream_id)
.venv/lib/python3.9/site-packages/httpcore/_async/http2.py:361: in _receive_events
events = await self._read_incoming_data(request)
.venv/lib/python3.9/site-packages/httpcore/_async/http2.py:452: in _read_incoming_data
raise exc
.venv/lib/python3.9/site-packages/httpcore/_async/http2.py:438: in _read_incoming_data
data = await self._network_stream.read(self.READ_NUM_BYTES, timeout)
.venv/lib/python3.9/site-packages/httpcore/_backends/anyio.py:35: in read
return await self._stream.receive(max_bytes=max_bytes)
.venv/lib/python3.9/site-packages/anyio/streams/tls.py:205: in receive
data = await self._call_sslobject_method(self._ssl_object.read, max_bytes)
.venv/lib/python3.9/site-packages/anyio/streams/tls.py:147: in _call_sslobject_method
data = await self.transport_stream.receive()
.venv/lib/python3.9/site-packages/anyio/_backends/_asyncio.py:1141: in receive
self._transport.resume_reading()
/Library/Developer/CommandLineTools/Library/Frameworks/Python3.framework/Versions/3.9/lib/python3.9/asyncio/selector_events.py:808: in resume_reading
self._add_reader(self._sock_fd, self._read_ready)
/Library/Developer/CommandLineTools/Library/Frameworks/Python3.framework/Versions/3.9/lib/python3.9/asyncio/selector_events.py:754: in _add_reader
self._loop._add_reader(fd, callback, *args)
/Library/Developer/CommandLineTools/Library/Frameworks/Python3.framework/Versions/3.9/lib/python3.9/asyncio/selector_events.py:258: in _add_reader
self._check_closed()
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _
self = <_UnixSelectorEventLoop running=False closed=True debug=False>
def _check_closed(self):
if self._closed:
> raise RuntimeError('Event loop is closed')
E RuntimeError: Event loop is closed
/Library/Developer/CommandLineTools/Library/Frameworks/Python3.framework/Versions/3.9/lib/python3.9/asyncio/base_events.py:510: RuntimeError
======================================================================== warnings summary ========================================================================
.venv/lib/python3.9/site-packages/urllib3/__init__.py:35
/Users/marcin/Desktop/msgraphbug/pythonProject/.venv/lib/python3.9/site-packages/urllib3/__init__.py:35: NotOpenSSLWarning: urllib3 v2 only supports OpenSSL 1.1.1+, currently the 'ssl' module is compiled with 'LibreSSL 2.8.3'. See: https://github.com/urllib3/urllib3/issues/3020
warnings.warn(
test.py::test_1
/Users/marcin/Desktop/msgraphbug/pythonProject/.venv/lib/python3.9/site-packages/kiota_abstractions/default_query_parameters.py:23: DeprecationWarning: GetQueryParameters is deprecated. Use QueryParameters instead.
warn("GetQueryParameters is deprecated. Use QueryParameters instead.", DeprecationWarning)
test.py::test_1
/Users/marcin/Desktop/msgraphbug/pythonProject/.venv/lib/python3.9/site-packages/msgraph/generated/users/item/user_item_request_builder.py:910: DeprecationWarning: This class is deprecated. Please use the generic RequestConfiguration class generated by the generator.
warn("This class is deprecated. Please use the generic RequestConfiguration class generated by the generator.", DeprecationWarning)
test.py::test_1
/Users/marcin/Desktop/msgraphbug/pythonProject/.venv/lib/python3.9/site-packages/msgraph/generated/users/item/user_item_request_builder.py:943: DeprecationWarning: This class is deprecated. Please use the generic RequestConfiguration class generated by the generator.
warn("This class is deprecated. Please use the generic RequestConfiguration class generated by the generator.", DeprecationWarning)
test.py::test_1
/Users/marcin/Desktop/msgraphbug/pythonProject/.venv/lib/python3.9/site-packages/msgraph/generated/users/item/user_item_request_builder.py:950: DeprecationWarning: This class is deprecated. Please use the generic RequestConfiguration class generated by the generator.
warn("This class is deprecated. Please use the generic RequestConfiguration class generated by the generator.", DeprecationWarning)
-- Docs: https://docs.pytest.org/en/stable/how-to/capture-warnings.html
==================================================================== short test summary info =====================================================================
FAILED test.py::test_2 - RuntimeError: Event loop is closed
============================================================ 1 failed, 1 passed, 5 warnings in 2.13s =============================================================
Configuration
- OS: macOS 14.1.1
- Architecture: ARM
Other information
In my opinion it is connected to GraphRequestAdapter and GraphClientFactory.create_with_default_middleware - After I've modified client parameters to be None by default and then creating clients if needed within the function body it started working properly.
An option for non-async API calls would be highly appreciated.