Close aiohttp responses (#4624)
* Close aiohttp responses * Update generic.py
This commit is contained in:
parent
b1ef5042f9
commit
e5504b39ec
6 changed files with 98 additions and 56 deletions
|
@ -97,8 +97,7 @@ class GenericCamera(Camera):
|
|||
def fetch():
|
||||
"""Read image from a URL."""
|
||||
try:
|
||||
kwargs = {'timeout': 10, 'auth': self._auth}
|
||||
response = requests.get(url, **kwargs)
|
||||
response = requests.get(url, timeout=10, auth=self._auth)
|
||||
return response.content
|
||||
except requests.exceptions.RequestException as error:
|
||||
_LOGGER.error('Error getting camera image: %s', error)
|
||||
|
@ -108,13 +107,13 @@ class GenericCamera(Camera):
|
|||
None, fetch)
|
||||
# async
|
||||
else:
|
||||
response = None
|
||||
try:
|
||||
websession = async_get_clientsession(self.hass)
|
||||
with async_timeout.timeout(10, loop=self.hass.loop):
|
||||
response = yield from websession.get(
|
||||
url, auth=self._auth)
|
||||
self._last_image = yield from response.read()
|
||||
yield from response.release()
|
||||
except asyncio.TimeoutError:
|
||||
_LOGGER.error('Timeout getting camera image')
|
||||
return self._last_image
|
||||
|
@ -122,6 +121,9 @@ class GenericCamera(Camera):
|
|||
aiohttp.errors.ClientDisconnectedError) as err:
|
||||
_LOGGER.error('Error getting new camera image: %s', err)
|
||||
return self._last_image
|
||||
finally:
|
||||
if response is not None:
|
||||
self.hass.async_add_job(response.release())
|
||||
|
||||
self._last_url = url
|
||||
return self._last_image
|
||||
|
|
|
@ -103,28 +103,31 @@ class MjpegCamera(Camera):
|
|||
|
||||
# connect to stream
|
||||
websession = async_get_clientsession(self.hass)
|
||||
stream = None
|
||||
response = None
|
||||
try:
|
||||
with async_timeout.timeout(10, loop=self.hass.loop):
|
||||
stream = yield from websession.get(
|
||||
self._mjpeg_url,
|
||||
auth=self._auth
|
||||
)
|
||||
except asyncio.TimeoutError:
|
||||
raise HTTPGatewayTimeout()
|
||||
stream = yield from websession.get(self._mjpeg_url,
|
||||
auth=self._auth)
|
||||
|
||||
response = web.StreamResponse()
|
||||
response.content_type = stream.headers.get(CONTENT_TYPE_HEADER)
|
||||
|
||||
yield from response.prepare(request)
|
||||
|
||||
try:
|
||||
while True:
|
||||
data = yield from stream.content.read(102400)
|
||||
if not data:
|
||||
break
|
||||
response.write(data)
|
||||
|
||||
except asyncio.TimeoutError:
|
||||
raise HTTPGatewayTimeout()
|
||||
|
||||
finally:
|
||||
if stream is not None:
|
||||
self.hass.async_add_job(stream.release())
|
||||
if response is not None:
|
||||
yield from response.write_eof()
|
||||
|
||||
@property
|
||||
|
|
|
@ -73,15 +73,13 @@ def async_setup_platform(hass, config, async_add_devices, discovery_info=None):
|
|||
'version': '1',
|
||||
'query': 'SYNO.'
|
||||
}
|
||||
query_req = None
|
||||
try:
|
||||
with async_timeout.timeout(TIMEOUT, loop=hass.loop):
|
||||
query_req = yield from websession_init.get(
|
||||
syno_api_url,
|
||||
params=query_payload
|
||||
)
|
||||
except (asyncio.TimeoutError, aiohttp.errors.ClientError):
|
||||
_LOGGER.exception("Error on %s", syno_api_url)
|
||||
return False
|
||||
|
||||
query_resp = yield from query_req.json()
|
||||
auth_path = query_resp['data'][AUTH_API]['path']
|
||||
|
@ -89,7 +87,12 @@ def async_setup_platform(hass, config, async_add_devices, discovery_info=None):
|
|||
camera_path = query_resp['data'][CAMERA_API]['path']
|
||||
streaming_path = query_resp['data'][STREAMING_API]['path']
|
||||
|
||||
# cleanup
|
||||
except (asyncio.TimeoutError, aiohttp.errors.ClientError):
|
||||
_LOGGER.exception("Error on %s", syno_api_url)
|
||||
return False
|
||||
|
||||
finally:
|
||||
if query_req is not None:
|
||||
yield from query_req.release()
|
||||
|
||||
# Authticate to NAS to get a session id
|
||||
|
@ -166,21 +169,24 @@ def get_session_id(hass, websession, username, password, login_url):
|
|||
'session': 'SurveillanceStation',
|
||||
'format': 'sid'
|
||||
}
|
||||
auth_req = None
|
||||
try:
|
||||
with async_timeout.timeout(TIMEOUT, loop=hass.loop):
|
||||
auth_req = yield from websession.get(
|
||||
login_url,
|
||||
params=auth_payload
|
||||
)
|
||||
auth_resp = yield from auth_req.json()
|
||||
return auth_resp['data']['sid']
|
||||
|
||||
except (asyncio.TimeoutError, aiohttp.errors.ClientError):
|
||||
_LOGGER.exception("Error on %s", login_url)
|
||||
return False
|
||||
|
||||
auth_resp = yield from auth_req.json()
|
||||
finally:
|
||||
if auth_req is not None:
|
||||
yield from auth_req.release()
|
||||
|
||||
return auth_resp['data']['sid']
|
||||
|
||||
|
||||
class SynologyCamera(Camera):
|
||||
"""An implementation of a Synology NAS based IP camera."""
|
||||
|
@ -247,29 +253,33 @@ class SynologyCamera(Camera):
|
|||
'cameraId': self._camera_id,
|
||||
'format': 'mjpeg'
|
||||
}
|
||||
stream = None
|
||||
response = None
|
||||
try:
|
||||
with async_timeout.timeout(TIMEOUT, loop=self.hass.loop):
|
||||
stream = yield from self._websession.get(
|
||||
streaming_url,
|
||||
params=streaming_payload
|
||||
)
|
||||
except (asyncio.TimeoutError, aiohttp.errors.ClientError):
|
||||
_LOGGER.exception("Error on %s", streaming_url)
|
||||
raise HTTPGatewayTimeout()
|
||||
|
||||
response = web.StreamResponse()
|
||||
response.content_type = stream.headers.get(CONTENT_TYPE_HEADER)
|
||||
|
||||
yield from response.prepare(request)
|
||||
|
||||
try:
|
||||
while True:
|
||||
data = yield from stream.content.read(102400)
|
||||
if not data:
|
||||
break
|
||||
response.write(data)
|
||||
|
||||
except (asyncio.TimeoutError, aiohttp.errors.ClientError):
|
||||
_LOGGER.exception("Error on %s", streaming_url)
|
||||
raise HTTPGatewayTimeout()
|
||||
|
||||
finally:
|
||||
if stream is not None:
|
||||
self.hass.async_add_job(stream.release())
|
||||
if response is not None:
|
||||
yield from response.write_eof()
|
||||
|
||||
@property
|
||||
|
|
|
@ -722,18 +722,25 @@ def _async_fetch_image(hass, url):
|
|||
return cache_images[url]
|
||||
|
||||
content, content_type = (None, None)
|
||||
try:
|
||||
websession = async_get_clientsession(hass)
|
||||
response = None
|
||||
try:
|
||||
with async_timeout.timeout(10, loop=hass.loop):
|
||||
response = yield from websession.get(url)
|
||||
if response.status == 200:
|
||||
content = yield from response.read()
|
||||
content_type = response.headers.get(CONTENT_TYPE_HEADER)
|
||||
yield from response.release()
|
||||
|
||||
except asyncio.TimeoutError:
|
||||
pass
|
||||
|
||||
if content:
|
||||
finally:
|
||||
if response is not None:
|
||||
yield from response.release()
|
||||
|
||||
if not content:
|
||||
return (None, None)
|
||||
|
||||
cache_images[url] = (content, content_type)
|
||||
cache_urls.append(url)
|
||||
|
||||
|
|
|
@ -155,6 +155,7 @@ class YrData(object):
|
|||
nxt)
|
||||
|
||||
if self._nextrun is None or dt_util.utcnow() >= self._nextrun:
|
||||
resp = None
|
||||
try:
|
||||
websession = async_get_clientsession(self.hass)
|
||||
with async_timeout.timeout(10, loop=self.hass.loop):
|
||||
|
@ -163,12 +164,16 @@ class YrData(object):
|
|||
try_again('{} returned {}'.format(self._url, resp.status))
|
||||
return
|
||||
text = yield from resp.text()
|
||||
self.hass.async_add_job(resp.release())
|
||||
|
||||
except (asyncio.TimeoutError, aiohttp.errors.ClientError,
|
||||
aiohttp.errors.ClientDisconnectedError) as err:
|
||||
try_again(err)
|
||||
return
|
||||
|
||||
finally:
|
||||
if resp is not None:
|
||||
self.hass.async_add_job(resp.release())
|
||||
|
||||
try:
|
||||
import xmltodict
|
||||
self.data = xmltodict.parse(text)['weatherdata']
|
||||
|
|
|
@ -34,6 +34,7 @@ def async_setup_platform(hass, config, async_add_devices, discovery_info=None):
|
|||
password = config.get(CONF_PASSWORD)
|
||||
websession = async_get_clientsession(hass)
|
||||
|
||||
response = None
|
||||
try:
|
||||
with async_timeout.timeout(TIMEOUT, loop=hass.loop):
|
||||
response = yield from websession.post(
|
||||
|
@ -47,6 +48,9 @@ def async_setup_platform(hass, config, async_add_devices, discovery_info=None):
|
|||
aiohttp.errors.ClientDisconnectedError) as error:
|
||||
_LOGGER.error("Failed authentication API call: %s", error)
|
||||
return False
|
||||
finally:
|
||||
if response is not None:
|
||||
yield from response.close()
|
||||
|
||||
try:
|
||||
token = data['data']['token']
|
||||
|
@ -54,6 +58,7 @@ def async_setup_platform(hass, config, async_add_devices, discovery_info=None):
|
|||
_LOGGER.error("No token. Check username and password")
|
||||
return False
|
||||
|
||||
response = None
|
||||
try:
|
||||
with async_timeout.timeout(TIMEOUT, loop=hass.loop):
|
||||
response = yield from websession.get(
|
||||
|
@ -65,6 +70,9 @@ def async_setup_platform(hass, config, async_add_devices, discovery_info=None):
|
|||
aiohttp.errors.ClientDisconnectedError) as error:
|
||||
_LOGGER.error("Failed getting devices: %s", error)
|
||||
return False
|
||||
finally:
|
||||
if response is not None:
|
||||
yield from response.close()
|
||||
|
||||
yield from async_add_devices(
|
||||
HookSmartHome(
|
||||
|
@ -102,6 +110,7 @@ class HookSmartHome(SwitchDevice):
|
|||
@asyncio.coroutine
|
||||
def _send(self, url):
|
||||
"""Send the url to the Hook API."""
|
||||
response = None
|
||||
try:
|
||||
_LOGGER.debug("Sending: %s", url)
|
||||
websession = async_get_clientsession(self.hass)
|
||||
|
@ -109,11 +118,17 @@ class HookSmartHome(SwitchDevice):
|
|||
response = yield from websession.get(
|
||||
url, params={"token": self._token})
|
||||
data = yield from response.json()
|
||||
|
||||
except (asyncio.TimeoutError,
|
||||
aiohttp.errors.ClientError,
|
||||
aiohttp.errors.ClientDisconnectedError) as error:
|
||||
_LOGGER.error("Failed setting state: %s", error)
|
||||
return False
|
||||
|
||||
finally:
|
||||
if response is not None:
|
||||
yield from response.close()
|
||||
|
||||
_LOGGER.debug("Got: %s", data)
|
||||
return data['return_value'] == '1'
|
||||
|
||||
|
|
Loading…
Add table
Reference in a new issue