Skip to content

Commit

Permalink
[python/asyncio] explicitly close client session via async context ma…
Browse files Browse the repository at this point in the history
…nager
  • Loading branch information
tomplus committed Mar 18, 2020
1 parent fc9d458 commit 884d0e8
Show file tree
Hide file tree
Showing 7 changed files with 58 additions and 22 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -76,13 +76,25 @@ class ApiClient(object):
self.user_agent = '{{#httpUserAgent}}{{{.}}}{{/httpUserAgent}}{{^httpUserAgent}}OpenAPI-Generator/{{{packageVersion}}}/python{{/httpUserAgent}}'
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):
return self

def __exit__(self, exc_type, exc_value, traceback):
self.close()
{{/asyncio}}

def close(self):
{{#asyncio}}async {{/asyncio}}def close(self):
{{#asyncio}}
await self.rest_client.close()
{{/asyncio}}
if self._pool:
self._pool.close()
self._pool.join()
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,6 @@ import ssl

import aiohttp
import certifi
import asyncio
# python 2 and python 3 compatibility library
from six.moves.urllib.parse import urlencode

Expand Down Expand Up @@ -77,8 +76,8 @@ class RESTClientObject(object):
connector=connector
)

def __del__(self):
asyncio.ensure_future(self.pool_manager.close())
async def close(self):
await self.pool_manager.close()

async def request(self, method, url, query_params=None, headers=None,
body=None, post_params=None, _preload_content=True,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -81,13 +81,14 @@ def __init__(self, configuration=None, header_name=None, header_value=None,
self.user_agent = 'OpenAPI-Generator/1.0.0/python'
self.client_side_validation = configuration.client_side_validation

def __enter__(self):
async def __aenter__(self):
return self

def __exit__(self, exc_type, exc_value, traceback):
self.close()
async def __aexit__(self, exc_type, exc_value, traceback):
await self.close()

def close(self):
async def close(self):
await self.rest_client.close()
if self._pool:
self._pool.close()
self._pool.join()
Expand Down
5 changes: 2 additions & 3 deletions samples/client/petstore/python-asyncio/petstore_api/rest.py
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,6 @@

import aiohttp
import certifi
import asyncio
# python 2 and python 3 compatibility library
from six.moves.urllib.parse import urlencode

Expand Down Expand Up @@ -85,8 +84,8 @@ def __init__(self, configuration, pools_size=4, maxsize=None):
connector=connector
)

def __del__(self):
asyncio.ensure_future(self.pool_manager.close())
async def close(self):
await self.pool_manager.close()

async def request(self, method, url, query_params=None, headers=None,
body=None, post_params=None, _preload_content=True,
Expand Down
27 changes: 27 additions & 0 deletions samples/client/petstore/python-asyncio/tests/test_api_client.py
Original file line number Diff line number Diff line change
@@ -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)
11 changes: 1 addition & 10 deletions samples/client/petstore/python-asyncio/tests/test_pet_api.py
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@
from petstore_api import Configuration
from petstore_api.rest import ApiException

from .util import id_gen
from .util import id_gen, async_test

import json

Expand All @@ -27,15 +27,6 @@
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):

def setUp(self):
Expand Down
9 changes: 8 additions & 1 deletion samples/client/petstore/python-asyncio/tests/util.py
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
# flake8: noqa

import asyncio
import random


Expand All @@ -8,4 +9,10 @@ def id_gen(bits=32):
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

0 comments on commit 884d0e8

Please sign in to comment.