Import client everywhere

This is an example of how to write one file to import a signed in client in every other file.

 1"""
 2A basic example for a dedicated file to import a signed in client everywhere else. For example in Cogs of discord bots.
 3To use the client in any other file use the following code:
 4```py
 5from import_client import abstractClient
 6coc_client = await abstractClient.get_client()
 7```
 8or
 9```py
10from import_client import abstractClient
11coc_client = await abstractClient.client
12```
13
14"""
15import asyncio
16import logging
17from typing import AsyncGenerator
18
19import coc
20from coc import Client
21
22# logging
23logging.basicConfig(level=logging.INFO)
24logger = logging.getLogger("coc.http")
25logger.setLevel(logging.DEBUG)
26
27
28class AbstractClient:
29	"""Class holding the async generator used to get the client and login on demand"""
30
31	def __init__(self):
32		# Pass credentials here or use a venv etc. to avoid hard coding them
33		self.__async_gen = self.__yield_client()  # create the async generator
34
35	async def __yield_client(self) -> AsyncGenerator[coc.Client, None]:
36		"""Get the async generator which always yields the client"""
37
38		async with coc.Client(loop=asyncio.get_event_loop_policy().get_event_loop()) as client:
39			await client.login("EMAIL", "PASSWORD")  # be aware that hard coding credentials is bad practice!
40			while True:
41				try:
42					yield client
43				except GeneratorExit:
44					break
45
46	async def get_client(self) -> Client:
47		"""Get the actual logged in client"""
48		if not hasattr(self, '__async_gen') and not hasattr(self, '_AbstractClient__async_gen'):
49			self.__async_gen = self.__yield_client()  # create async generator if needed
50		coc_client = await self.__async_gen.__anext__()
51		return coc_client
52
53	@property
54	async def client(self) -> Client:
55		"""Get the actual logged in client"""
56		if not hasattr(self, '__async_gen') and not hasattr(self, '_AbstractClient__async_gen'):
57			self.__async_gen = self.__yield_client()  # create async generator if needed
58		coc_client = await self.__async_gen.__anext__()
59		return coc_client
60
61	async def shutdown(self):
62		"""Log out and close the ClientSession"""
63		await self.__async_gen.aclose()
64
65
66abstractClient = AbstractClient()