watchforstock / evohome-client

Python client to access the Evohome web service
Apache License 2.0
88 stars 52 forks source link

asyncio version of evohomeclient2 #96

Closed zxdavb closed 5 years ago

zxdavb commented 5 years ago

Re: #52 - I have a working (but not fully tested) asyncio version of evomeclient2 at https://github.com/zxdavb/evohome-client/tree/master/evohomeclient3

It is the same as evohomeclient2, with only the minimal changes needed to swap to aiohttp from requests.

I'd be happy to submit as a PR, but wanted to check how you'd best like it packaged?

FYI, here is an example of the new code:

        async with self._session.post(
            url, data=payload, headers=HEADER_BASIC_AUTH,
        ) as response:
            try:
                response_text = await response.text()
                response.raise_for_status()

            except aiohttp.ClientResponseError:
                msg = "Unable to obtain an Access Token"
                if response_text:  # if there is a message, then raise with it
                    msg = msg + ", hint: " + response_text
                raise AuthenticationError(msg)

        try:  # the access token _should_ be valid...
            response_json = response.json()
    ....
        except KeyError:

... and here is the corresponding non-async version:

        response = requests.post(url, data=payload, headers=HEADER_BASIC_AUTH)
        try:
            response.raise_for_status()

        except requests.HTTPError:
            msg = "Unable to obtain an Access Token"
            if response.text:  # if there is a message, then raise with it
                msg = msg + ", hint: " + response.text
            raise AuthenticationError(msg)

        try:  # the access token _should_ be valid...
            response_json = response.json()
    ....
        except KeyError:
watchforstock commented 5 years ago

Thanks for this. The short answer is I'm not sure! I've not worked with the asyncio stuff before, or used packages that have. I think I probably agree with your preferred option of a different repo unless there's a well established pattern that others have used for other python packages.

If we do go with the separate repo, it presumably makes sense to host it under your github account. I'm obviously more than happy to make sure there are links from github and docs to the other repo to make sure people can find it.

zxdavb commented 5 years ago

OK, I'll implement as a separate github repo, and a separate pypi package. The plan will be to make minimal changes, and certainly keep as close as possible to the existing docs:

Old way:

    try:  # this invokes client._login
        client = self.client = evohomeclient3.EvohomeClient(
            self.params[CONF_USERNAME],
            self.params[CONF_PASSWORD],
            refresh_token=refresh_token,
            access_token=access_token,
            access_token_expires=access_token_expires
        )
    except (
        requests.exceptions.RequestException,
        evohomeclient2.AuthenticationError,
    ) as err:
        if not _handle_exception(err):
            return False
    finally:
        self.config = client.installation_info[loc_idx][GWS][0][TCS][0]

New way (add client.login() because you can't do asyncio in __init__()):

    client = self.client = evohomeclient3.EvohomeClient(
        self.params[CONF_USERNAME],
        self.params[CONF_PASSWORD],
        refresh_token=refresh_token,
        access_token=access_token,
        access_token_expires=access_token_expires,
        debug=True
    )
    try:
        await client.login()
    except (
        aiohttp.ClientResponseError,
        evohomeclient2.AuthenticationError,
    ) as err:
        if not _handle_exception(err):
            return False
    finally:
        self.config = client.installation_info[loc_idx][GWS][0][TCS][0]
zxdavb commented 5 years ago

OK, evohome-async is up, and is based upon your 0.3.3.

evohomeclient2 is (fully?) ported, but evohomeclient1 is not yet ported.

I'd be pleased to give you write access to the github repo and/or pypi package if you wish.