Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
38 changes: 23 additions & 15 deletions franklinwh/client.py
Original file line number Diff line number Diff line change
Expand Up @@ -295,27 +295,32 @@ class GatewayOfflineException(Exception):
class TokenFetcher:
"""Fetches and refreshes authentication tokens for FranklinWH API."""

def __init__(self, username: str, password: str) -> None:
def __init__(self, username: str, password: str, **kwargs) -> None:
"""Initialize the TokenFetcher with the provided username and password."""
self.username = username
self.password = password
self.session = kwargs.get("session")
self.info: dict | None = None

async def get_token(self):
"""Fetch a new authentication token using the stored credentials.

Store the intermediate account information in self.info.
"""
self.info = await TokenFetcher._login(self.username, self.password)
self.info = await TokenFetcher._login(
self.username, self.password, self.session or httpx.AsyncClient(http2=True)
)
return self.info["token"]

@staticmethod
async def login(username: str, password: str):
"""Log in to the FranklinWH API and retrieve an authentication token."""
return (await TokenFetcher._login(username, password))["token"]
return (
await TokenFetcher._login(username, password, httpx.AsyncClient(http2=True))
)["token"]

@staticmethod
async def _login(username: str, password: str) -> dict:
async def _login(username: str, password: str, session: httpx.AsyncClient) -> dict:
"""Log in to the FranklinWH API and retrieve account information."""
url = (
DEFAULT_URL_BASE + "hes-gateway/terminal/initialize/appUserOrInstallerLogin"
Expand All @@ -326,8 +331,7 @@ async def _login(username: str, password: str) -> dict:
"lang": "en_US",
"type": 1,
}
async with httpx.AsyncClient(http2=True) as client:
res = await client.post(url, data=form, timeout=10)
res = await session.post(url, data=form, timeout=10)
res.raise_for_status()
js = res.json()

Expand All @@ -353,15 +357,24 @@ class Client:
"""Client for interacting with FranklinWH gateway API."""

def __init__(
self, fetcher: TokenFetcher, gateway: str, url_base: str = DEFAULT_URL_BASE
self,
fetcher: TokenFetcher,
gateway: str,
url_base: str = DEFAULT_URL_BASE,
**kwargs,
) -> None:
"""Initialize the Client with the provided TokenFetcher, gateway ID, and optional URL base."""
self.fetcher = fetcher
self.gateway = gateway
self.url_base = url_base
self.token = ""
self.snno = 0
self.session = httpx.AsyncClient(http2=True)
# avoid even creating a new AsyncClient unless required
self.session = (
httpx.AsyncClient(http2=True)
if "session" not in kwargs
else kwargs["session"]
)

# to enable detailed logging add this to configuration.yaml:
# logger:
Expand Down Expand Up @@ -398,13 +411,8 @@ async def debug_response(response: httpx.Response):
return response

self.logger = logger
self.session = httpx.AsyncClient(
http2=True,
event_hooks={
"request": [debug_request],
"response": [debug_response],
},
)
self.session.event_hooks["request"].append(debug_request)
self.session.event_hooks["response"].append(debug_response)

# TODO(richo) Setup timeouts and deal with them gracefully.
async def _post(self, url, payload, params: dict | None = None):
Expand Down
2 changes: 1 addition & 1 deletion pyproject.toml
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ build-backend = "hatchling.build"

[project]
name = "franklinwh"
version = "1.0.0"
version = "1.1.0"
authors = [
{ name="Richo Butts", email="richo@psych0tik.net" },
]
Expand Down