Giter Club home page Giter Club logo

Comments (17)

mlowijs avatar mlowijs commented on June 6, 2024

Hi! I didn't release a new version yet to PyPI, let me do that right now.

from tesla_api.

mlowijs avatar mlowijs commented on June 6, 2024

I just released version 2.0.0 to PyPI, which should be available soon. Let me know if you still have problems after updating!

from tesla_api.

tyddynonn avatar tyddynonn commented on June 6, 2024

Thanks for the speedy response - all downloaded OK.

Just need to upgrade to Python 3.8 now to get asyncio.run working ;-)

from tesla_api.

tyddynonn avatar tyddynonn commented on June 6, 2024

So Python 3.8 installed & working, now I get a different error when passing in a token string as a parameter to TeslaApiClient - I'm passing in the OAuth token string.

File "/usr/local/lib/python3.8/site-packages/tesla_api/init.py", line 67, in authenticate
expiry_time = timedelta(seconds=self.token['expires_in'])
TypeError: string indices must be integers

It looks like from line 65 of init.py that the object saves self.token as the complete response from authentication rather than just the token value - which would account for this error.

Is this the intention? It would mean re-authenticating for every session, or finding a way to create/save a complete token dict to pass in on the next invocation.

Ideally I'd like to save the OAuth token outside my code (env variable?) and just pass that in when I instantiate TeslaApiClient. Does this make sense?

from tesla_api.

mlowijs avatar mlowijs commented on June 6, 2024

Hi there! I think we made a little oversight here. The token parameter should be set to a Token dict, looking like:

{
  "access_token": "AN_ACCESS_TOKEN",
  "refresh_token": "A_REFRESH_TOKEN",
  "expires_in": 123567,
  "created_at": "2020-01-01T00:00:00"
}

You could probably make it work for once by setting the token parameter to:

{
  "access_token": "",
  "refresh_token": "A_VALID_REFRESH_TOKEN_HERE",
  "expires_in": 0,
  "created_at": "2020-01-01T00:00:00"
}

and then making an API call to refresh the token and after that grabbing the token property from the TeslaApiClient.

Or use your username and password one time and then grab the token property from the TeslaApiClient!

from tesla_api.

tyddynonn avatar tyddynonn commented on June 6, 2024

Thanks again, I can work with this. Just need the token to be publicly accessible from the client - at the moment it always returns null. As you can probably tell, I'm new to Python - more a C# & Javascript person..

from tesla_api.

mlowijs avatar mlowijs commented on June 6, 2024

Hey, I'm more of a C# person myself, so I understand you 😉. The token property should be publically accessible from the client:

async def main():
  client = TeslaApiClient("[email protected]", "[email protected]")
  await client.list_vehicles()
  print(client.token)

Works on my machine with the 2.0.1 package.

from tesla_api.

tyddynonn avatar tyddynonn commented on June 6, 2024

from tesla_api.

Dreamsorcerer avatar Dreamsorcerer commented on June 6, 2024

I plan to add some features around this, and some documentation to show how to use this properly.

But, as demonstrated above, you need to use the client first (e.g. client.list_vehicles()) before the token is retrieved and saved to that attribute.
After that you should be able to access client.token and get a dict object.

To save/restore with the token, I've been using json.dump() to store the token, and then loading it back with json.load() to be passed into a file.

A fuller example would therefore be something like:

async def main():
  email = password = token = None
  try:
    token = json.load(open("token_file"))
  except OSError:
    email = input()
    password = input()
  client = TeslaApiClient(email, password, token)
  await client.list_vehicles()

  # If successful, save token.
  json.dump(client.token, open("token_file", "w"))

from tesla_api.

tyddynonn avatar tyddynonn commented on June 6, 2024

from tesla_api.

mlowijs avatar mlowijs commented on June 6, 2024

@Dreamsorcerer We should probably make it so that you can pass in a refresh token and let the client request a fresh token for us, what do you think??

from tesla_api.

tyddynonn avatar tyddynonn commented on June 6, 2024

from tesla_api.

mlowijs avatar mlowijs commented on June 6, 2024

@tyddynonn The client already does that; it checks whether your access token has expired and will request a new one using the refresh token. I'm proposing to let you pass just the refresh token into the TeslaApiClient, instead of the full dictionary. Or perhaps we should support both a refresh token or the full dict.

from tesla_api.

Dreamsorcerer avatar Dreamsorcerer commented on June 6, 2024

I'm not sure I see the use case..
If you want to restore from a token, it's more efficient to use the full token which appears to be valid for 45 days. In what case would you only want to save the refresh token?

I'm currently waiting for my token to expire so I can test out the refresh stuff. I find it rather odd that you would be able to fetch a new API token, after it had expired (at which point you are no longer authenticated to use the service).

from tesla_api.

tyddynonn avatar tyddynonn commented on June 6, 2024

I'm easy with just using the full dict. The main reason is to avoid embedding username/pw details anywhere...

from tesla_api.

Dreamsorcerer avatar Dreamsorcerer commented on June 6, 2024

@tyddynonn The next release will have some changes to this. It handles the JSON, so you should now just pass in the string format. There is also a callback you should pass into the constructor to save the token. So, that previous example will now look more like this:

def save_token(token):
    open("token_file", "w").write(token)

async def main():
  email = password = token = None
  try:
    token = open("token_file").read()
  except OSError:
    email = input()
    password = input()
  client = TeslaApiClient(email, password, token, on_new_token=save_token)

The callback means you don't need to worry about when the token is available. But, more importantly, it will allow you to automatically save any new tokens (from a refresh), so you don't end up with an invalid/expired token.

from tesla_api.

Dreamsorcerer avatar Dreamsorcerer commented on June 6, 2024

README has been updated with the current best practices on master (will need a new release for pip).

from tesla_api.

Related Issues (19)

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.