Skip to content

Comments

feat: add rate limit tracking and public API#148

Open
banter240 wants to merge 3 commits intoerwindouna:mainfrom
banter240:fix/request-improvements
Open

feat: add rate limit tracking and public API#148
banter240 wants to merge 3 commits intoerwindouna:mainfrom
banter240:fix/request-improvements

Conversation

@banter240
Copy link

Essential improvements for production use:

Rate Limit Support (NEW):

  • Add: Store response headers from API calls
  • Add: Parse RateLimit headers per IETF draft spec
  • Add: rate_limit property returning (limit, remaining) tuple
  • Add: last_headers property for debugging
  • Change: Use context manager to access headers before consuming body

Public API (NEW - enables extensions):

  • Add: session property (get aiohttp ClientSession)
  • Add: home_id property (get home ID)
  • Add: access_token property (get OAuth token)
  • Add: refresh_auth() public method (refresh token)

Model Fixes:

  • Fix: ZoneState null nextTimeBlock handling (API sometimes returns null)

Breaking Changes: None (only additions and one critical bug fix)

All changes are backward compatible. Existing code works unchanged.

Enables Home Assistant integrations to:

  • Track API quota usage (rate_limit property)
  • Build extensions without private attribute access (public API)
  • Handle edge cases in API responses (ZoneState fix)

@erwindouna erwindouna added the enhancement Enhancement of the code, not introducing new features label Feb 23, 2026
Copy link
Owner

@erwindouna erwindouna left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks for contributing, here an initial review. :)

@banter240 banter240 force-pushed the fix/request-improvements branch from e6e3c02 to b46987b Compare February 23, 2026 17:35
Essential improvements for production use.

Rate Limit Support:
- Store response headers from API calls
- Parse RateLimit headers per IETF draft spec
- rate_limit property returning (limit, remaining) tuple
- last_headers property for debugging

Public API (enables extensions):
- session property (get aiohttp ClientSession)
- home_id property (get home ID)
- access_token property (get OAuth token)
- refresh_auth() public method (refresh token)

Model Fixes:
- ZoneState null nextTimeBlock handling (API sometimes returns null)

Breaking Changes: None (only additions and bug fixes)
All changes are backward compatible.
@banter240 banter240 force-pushed the fix/request-improvements branch from b46987b to 2b4e258 Compare February 23, 2026 17:36
Copy link
Owner

@erwindouna erwindouna left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Making solid progress. tadoasync is heavily tested. Would you mind including/updating tests, that way we can ensure we're releasing a solid package. :)

Comment on lines +149 to +166
@property
def session(self) -> ClientSession:
"""Return the aiohttp session."""
return self._ensure_session()

@property
def home_id(self) -> int | None:
"""Return the home ID."""
return self._home_id

@property
def access_token(self) -> str | None:
"""Return the OAuth access token."""
return self._access_token

async def refresh_auth(self) -> None:
"""Refresh the OAuth token."""
await self._refresh_auth()
Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Not be too nitpicky, but we never exposed these before. I suppose this is from your other work? The refresh auth is something I might have doubts on, since the business logic should be that it checks per request if a refresh is needed.

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yeah, you're right, this is from my TadoHijack integration.
I need these for TadoX API support. The new Tado X hardware uses a completely separate API at hops.tado.com that's not covered by tadoasync's existing methods. I have to make direct HTTP requests to that API while reusing tadoasync's session and auth:

In TadoXApi class

await self._tado._refresh_auth()  # Refresh before our external request
headers = {"Authorization": f"Bearer {self._tado._access_token}"}
url = f"https://hops.tado.com/homes/{self._tado._home_id}/rooms"
async with self._tado._ensure_session().request(...) as response:
    return await response.json()

Since we're making requests to an external API (outside of tadoasync's _request() flow), we need manual access to the session, auth token, and refresh logic. Currently we're accessing _refresh_auth(), _access_token, _home_id, and _ensure_session() as private attributes, which is why we'd like to see them public.

The refresh_auth() method is needed because we're bypassing tadoasync's normal request flow entirely - we need to manually refresh before our own external API calls.

Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I see, that supports the hybrid solution, right?

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yes, exactly. Once we manage to integrate native Tado X support directly into tadoasync, we can refactor this and maybe make them private again. But for now, while I have to handle the Tado X API externally alongside tadoasync (the hybrid approach), it's much safer to have these exposed publicly rather than relying on private _ members.

Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Makes sense, I can accept that change.

@erwindouna
Copy link
Owner

So I think, the only thing left are updating the tests. :)

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

enhancement Enhancement of the code, not introducing new features

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants