zabuldon / teslajsonpy

Apache License 2.0
56 stars 62 forks source link

Can't login with just email and password #389

Open amthorn opened 1 year ago

amthorn commented 1 year ago

I'm trying to run the following script using teslajsonpy 3.7.0

import asyncio, teslajsonpy
client = teslajsonpy.Controller(email='<my_email_address>', password='<my_password>')
asyncio.run(client.connect())

I get the following error:

Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
  File "/Users/avathorn/.pyenv/versions/3.8.9/lib/python3.8/asyncio/runners.py", line 44, in run
    return loop.run_until_complete(main)
  File "/Users/avathorn/.pyenv/versions/3.8.9/lib/python3.8/asyncio/base_events.py", line 616, in run_until_complete
    return future.result()
  File "/Users/avathorn/.pyenv/versions/3.8.9/lib/python3.8/site-packages/teslajsonpy/controller.py", line 196, in connect
    self._product_list = await self.get_product_list()
  File "/Users/avathorn/.pyenv/versions/3.8.9/lib/python3.8/site-packages/teslajsonpy/controller.py", line 290, in get_product_list
    return (await self.api("PRODUCT_LIST"))["response"]
  File "/Users/avathorn/.pyenv/versions/3.8.9/lib/python3.8/site-packages/teslajsonpy/controller.py", line 1320, in api
    return await self.__post_with_retries("", method=method, data=kwargs, url=uri)
  File "/Users/avathorn/.pyenv/versions/3.8.9/lib/python3.8/site-packages/tenacity/_asyncio.py", line 86, in async_wrapped
    return await fn(*args, **kwargs)
  File "/Users/avathorn/.pyenv/versions/3.8.9/lib/python3.8/site-packages/tenacity/_asyncio.py", line 48, in __call__
    do = self.iter(retry_state=retry_state)
  File "/Users/avathorn/.pyenv/versions/3.8.9/lib/python3.8/site-packages/tenacity/__init__.py", line 362, in iter
    raise retry_exc.reraise()
  File "/Users/avathorn/.pyenv/versions/3.8.9/lib/python3.8/site-packages/tenacity/__init__.py", line 195, in reraise
    raise self.last_attempt.result()
  File "/Users/avathorn/.pyenv/versions/3.8.9/lib/python3.8/concurrent/futures/_base.py", line 437, in result
    return self.__get_result()
  File "/Users/avathorn/.pyenv/versions/3.8.9/lib/python3.8/concurrent/futures/_base.py", line 389, in __get_result
    raise self._exception
  File "/Users/avathorn/.pyenv/versions/3.8.9/lib/python3.8/site-packages/tenacity/_asyncio.py", line 51, in __call__
    result = await fn(*args, **kwargs)
  File "/Users/avathorn/.pyenv/versions/3.8.9/lib/python3.8/site-packages/teslajsonpy/controller.py", line 1330, in __post_with_retries
    return await self.__connection.post(command, method=method, data=data, url=url)
  File "/Users/avathorn/.pyenv/versions/3.8.9/lib/python3.8/site-packages/teslajsonpy/connection.py", line 110, in post
    self.code = await self.get_authorization_code(
  File "/Users/avathorn/.pyenv/versions/3.8.9/lib/python3.8/site-packages/teslajsonpy/connection.py", line 489, in get_authorization_code
    raise IncompleteCredentials("Unable to login with credentials")
teslajsonpy.exceptions.IncompleteCredentials

Am i missing something obvious? Or does this api not support logging in without an access token/refresh token?

alandtse commented 1 year ago

That email/pass path is unfortunately not maintained anymore after Tesla started requiring the refresh token. This library is primarily used for home assistant, so all support right now is for the implementation here: https://github.com/alandtse/tesla/blob/dev/custom_components/tesla_custom/config_flow.py#L178-L188

I believe we were seeing Tesla require javascript to generate tokens so it became a losing game for us to do it in python (although I think some other implementations eventually figured out a way). If you look at the HA component, you'll see we just require the refresh token and user name now. The README will point to various apps that can generate it.

I wouldn't be against PRs to try to bring that functionality back in for non Home assistant use.

amthorn commented 1 year ago

@alandtse hey thanks, I did try to implement this myself a few weeks back but wasn't able to get the access or refresh token because I was seeing that the Tesla login page has a captcha unless the exact right user-agent (among other headers) are set and I don't know what they are.

That said, i'm also using this for HA, but as a decoupled async rest service since i'm not running HA in supervisor mode so can't add integrations (i'm running on a raspberry pi zero so i don't know that i have enough compute/memory to handle all the docker containers, It starts to boot loop after about 3, been meaning to upgrade but haven't yet).

That said, maybe i'll try again. If i get anything working i'll be happy to submit a PR. But in the meantime i've just supplied the refresh token. I worry that it will expire every X days and break my home automation but that's something i'll deal with when it happens. Do you know how long refresh tokens are good for?

alandtse commented 1 year ago

I believe it's 45 days. That said custom integrations don't need to run in a separate docker. They run in the same as core but are loaded from the config/custom_components directory. You're thinking about add-ons. I'd suggest you use hacs and install the custom component so you don't need to basically rewrite the component from scratch.

amthorn commented 1 year ago

cool thanks:)

I did also try to reverse engineer the browser's web calls to implement the change, hit the same error i did before with captcha's and 403 errors. I haven't found any implementation in open source that uses just username and password. Everything I can find uses the refresh token. Are you aware of any functioning implementations?

alandtse commented 1 year ago

Not in python. There may be some in nodejs. Most people report issues with the API at timdorr's github. You may find something in his discussions or issues. https://github.com/timdorr/tesla-api/issues/431