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.
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
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
Other information
In my opinion it is connected to
GraphRequestAdapter
andGraphClientFactory.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.