[python/asyncio] explicitly close client session via async context manager (#5621)

This commit is contained in:
Tomasz Prus 2020-03-25 15:59:27 +01:00 committed by GitHub
parent 928d065bbf
commit 625c734cfe
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
7 changed files with 58 additions and 22 deletions

View File

@ -76,13 +76,25 @@ class ApiClient(object):
self.user_agent = '{{#httpUserAgent}}{{{.}}}{{/httpUserAgent}}{{^httpUserAgent}}OpenAPI-Generator/{{{packageVersion}}}/python{{/httpUserAgent}}' self.user_agent = '{{#httpUserAgent}}{{{.}}}{{/httpUserAgent}}{{^httpUserAgent}}OpenAPI-Generator/{{{packageVersion}}}/python{{/httpUserAgent}}'
self.client_side_validation = configuration.client_side_validation self.client_side_validation = configuration.client_side_validation
{{#asyncio}}
async def __aenter__(self):
return self
async def __aexit__(self, exc_type, exc_value, traceback):
await self.close()
{{/asyncio}}
{{^asyncio}}
def __enter__(self): def __enter__(self):
return self return self
def __exit__(self, exc_type, exc_value, traceback): def __exit__(self, exc_type, exc_value, traceback):
self.close() self.close()
{{/asyncio}}
def close(self): {{#asyncio}}async {{/asyncio}}def close(self):
{{#asyncio}}
await self.rest_client.close()
{{/asyncio}}
if self._pool: if self._pool:
self._pool.close() self._pool.close()
self._pool.join() self._pool.join()

View File

@ -10,7 +10,6 @@ import ssl
import aiohttp import aiohttp
import certifi import certifi
import asyncio
# python 2 and python 3 compatibility library # python 2 and python 3 compatibility library
from six.moves.urllib.parse import urlencode from six.moves.urllib.parse import urlencode
@ -77,8 +76,8 @@ class RESTClientObject(object):
connector=connector connector=connector
) )
def __del__(self): async def close(self):
asyncio.ensure_future(self.pool_manager.close()) await self.pool_manager.close()
async def request(self, method, url, query_params=None, headers=None, async def request(self, method, url, query_params=None, headers=None,
body=None, post_params=None, _preload_content=True, body=None, post_params=None, _preload_content=True,

View File

@ -81,13 +81,14 @@ class ApiClient(object):
self.user_agent = 'OpenAPI-Generator/1.0.0/python' self.user_agent = 'OpenAPI-Generator/1.0.0/python'
self.client_side_validation = configuration.client_side_validation self.client_side_validation = configuration.client_side_validation
def __enter__(self): async def __aenter__(self):
return self return self
def __exit__(self, exc_type, exc_value, traceback): async def __aexit__(self, exc_type, exc_value, traceback):
self.close() await self.close()
def close(self): async def close(self):
await self.rest_client.close()
if self._pool: if self._pool:
self._pool.close() self._pool.close()
self._pool.join() self._pool.join()

View File

@ -18,7 +18,6 @@ import ssl
import aiohttp import aiohttp
import certifi import certifi
import asyncio
# python 2 and python 3 compatibility library # python 2 and python 3 compatibility library
from six.moves.urllib.parse import urlencode from six.moves.urllib.parse import urlencode
@ -85,8 +84,8 @@ class RESTClientObject(object):
connector=connector connector=connector
) )
def __del__(self): async def close(self):
asyncio.ensure_future(self.pool_manager.close()) await self.pool_manager.close()
async def request(self, method, url, query_params=None, headers=None, async def request(self, method, url, query_params=None, headers=None,
body=None, post_params=None, _preload_content=True, body=None, post_params=None, _preload_content=True,

View File

@ -0,0 +1,27 @@
# coding: utf-8
# flake8: noqa
import unittest
import weakref
from tests.util import async_test
import petstore_api
class TestApiClient(unittest.TestCase):
@async_test
async def test_context_manager_closes_client(self):
async with petstore_api.ApiClient() as client:
# thread pool
self.assertIsNotNone(client.pool)
pool_ref = weakref.ref(client._pool)
self.assertIsNotNone(pool_ref())
# pool_manager
self.assertFalse(client.rest_client.pool_manager.closed)
rest_pool_ref = client.rest_client.pool_manager
self.assertIsNone(pool_ref())
self.assertTrue(rest_pool_ref.closed)

View File

@ -18,7 +18,7 @@ import petstore_api
from petstore_api import Configuration from petstore_api import Configuration
from petstore_api.rest import ApiException from petstore_api.rest import ApiException
from .util import id_gen from .util import id_gen, async_test
import json import json
@ -27,15 +27,6 @@ import urllib3
HOST = 'http://localhost:80/v2' HOST = 'http://localhost:80/v2'
def async_test(f):
def wrapper(*args, **kwargs):
coro = asyncio.coroutine(f)
future = coro(*args, **kwargs)
loop = asyncio.get_event_loop()
loop.run_until_complete(future)
return wrapper
class TestPetApiTests(unittest.TestCase): class TestPetApiTests(unittest.TestCase):
def setUp(self): def setUp(self):

View File

@ -1,5 +1,6 @@
# flake8: noqa # flake8: noqa
import asyncio
import random import random
@ -8,4 +9,10 @@ def id_gen(bits=32):
return int(random.getrandbits(bits)) return int(random.getrandbits(bits))
def async_test(f):
def wrapper(*args, **kwargs):
coro = asyncio.coroutine(f)
future = coro(*args, **kwargs)
loop = asyncio.get_event_loop()
loop.run_until_complete(future)
return wrapper