def create_async_httpx_client( hass: HomeAssistant, verify_ssl: bool = True, auto_cleanup: bool = True, **kwargs: Any, ) -> httpx.AsyncClient: """Create a new httpx.AsyncClient with kwargs, i.e. for cookies. If auto_cleanup is False, the client will be automatically closed on homeassistant_stop. This method must be run in the event loop. """ client = HassHttpXAsyncClient( verify=verify_ssl, headers={USER_AGENT: SERVER_SOFTWARE}, **kwargs, ) original_aclose = client.aclose client.aclose = warn_use( # type: ignore client.aclose, "closes the Home Assistant httpx client") if auto_cleanup: _async_register_async_client_shutdown(hass, client, original_aclose) return client
def async_create_clientsession( hass: HomeAssistantType, verify_ssl: bool = True, auto_cleanup: bool = True, **kwargs: Any, ) -> aiohttp.ClientSession: """Create a new ClientSession with kwargs, i.e. for cookies. If auto_cleanup is False, you need to call detach() after the session returned is no longer used. Default is True, the session will be automatically detached on homeassistant_stop. This method must be run in the event loop. """ connector = _async_get_connector(hass, verify_ssl) clientsession = aiohttp.ClientSession( connector=connector, headers={USER_AGENT: SERVER_SOFTWARE}, **kwargs, ) clientsession.close = warn_use( # type: ignore clientsession.close, "closes the Home Assistant aiohttp session") if auto_cleanup: _async_register_clientsession_shutdown(hass, clientsession) return clientsession
def _async_create_clientsession( hass: HomeAssistant, verify_ssl: bool = True, auto_cleanup_method: Callable[[HomeAssistant, aiohttp.ClientSession], None] | None = None, **kwargs: Any, ) -> aiohttp.ClientSession: """Create a new ClientSession with kwargs, i.e. for cookies.""" clientsession = aiohttp.ClientSession( connector=_async_get_connector(hass, verify_ssl), **kwargs, ) # Prevent packages accidentally overriding our default headers # It's important that we identify as Home Assistant # If a package requires a different user agent, override it by passing a headers # dictionary to the request method. # pylint: disable=protected-access clientsession._default_headers = MappingProxyType( {USER_AGENT: SERVER_SOFTWARE}) # type: ignore clientsession.close = warn_use(clientsession.close, WARN_CLOSE_MSG) # type: ignore if auto_cleanup_method: auto_cleanup_method(hass, clientsession) return clientsession
def new_event_loop(self) -> asyncio.AbstractEventLoop: """Get the event loop.""" loop: asyncio.AbstractEventLoop = super().new_event_loop() loop.set_exception_handler(_async_loop_exception_handler) if self.debug: loop.set_debug(True) executor = InterruptibleThreadPoolExecutor( thread_name_prefix="SyncWorker", max_workers=MAX_EXECUTOR_WORKERS) loop.set_default_executor(executor) loop.set_default_executor = warn_use( # type: ignore loop.set_default_executor, "sets default executor on the event loop") return loop
def _async_create_clientsession( hass: HomeAssistant, verify_ssl: bool = True, auto_cleanup_method: Callable[[HomeAssistant, aiohttp.ClientSession], None] | None = None, **kwargs: Any, ) -> aiohttp.ClientSession: """Create a new ClientSession with kwargs, i.e. for cookies.""" clientsession = aiohttp.ClientSession( connector=_async_get_connector(hass, verify_ssl), headers={USER_AGENT: SERVER_SOFTWARE}, **kwargs, ) clientsession.close = warn_use(clientsession.close, WARN_CLOSE_MSG) # type: ignore if auto_cleanup_method: auto_cleanup_method(hass, clientsession) return clientsession
def new_event_loop(self) -> asyncio.AbstractEventLoop: """Get the event loop.""" loop: asyncio.AbstractEventLoop = super().new_event_loop() loop.set_exception_handler(_async_loop_exception_handler) if self.debug: loop.set_debug(True) executor = ThreadPoolExecutor( thread_name_prefix="SyncWorker", max_workers=MAX_EXECUTOR_WORKERS ) loop.set_default_executor(executor) loop.set_default_executor = warn_use( # type: ignore loop.set_default_executor, "sets default executor on the event loop" ) # Python 3.9+ if hasattr(loop, "shutdown_default_executor"): return loop # Copied from Python 3.9 source def _do_shutdown(future: asyncio.Future) -> None: try: executor.shutdown(wait=True) loop.call_soon_threadsafe(future.set_result, None) except Exception as ex: # pylint: disable=broad-except loop.call_soon_threadsafe(future.set_exception, ex) async def shutdown_default_executor() -> None: """Schedule the shutdown of the default executor.""" future = loop.create_future() thread = threading.Thread(target=_do_shutdown, args=(future,)) thread.start() try: await future finally: thread.join() setattr(loop, "shutdown_default_executor", shutdown_default_executor) return loop
def new_event_loop(self) -> asyncio.AbstractEventLoop: """Get the event loop.""" loop: asyncio.AbstractEventLoop = super().new_event_loop() loop.set_exception_handler(_async_loop_exception_handler) if self.debug: loop.set_debug(True) executor = ThreadPoolExecutor(thread_name_prefix="SyncWorker", max_workers=MAX_EXECUTOR_WORKERS) loop.set_default_executor(executor) loop.set_default_executor = warn_use( # type: ignore loop.set_default_executor, "sets default executor on the event loop") # Shut down executor when we shut down loop orig_close = loop.close def close() -> None: executor.shutdown(wait=True) orig_close() loop.close = close # type: ignore return loop