A Python module to use the Tesla Motors Owner API for monitoring and controlling Tesla vehicles, Powerwall batteries, and solar panels remotely
—
Quality
Pending
Does it follow best practices?
Impact
Pending
No eval scenarios have been run
Core authentication functionality using Tesla's OAuth 2 Single Sign-On service with support for multiple authentication methods, token caching, and automatic token refresh capabilities.
Creates and manages the main Tesla API session with OAuth 2 authentication, supporting various configuration options for proxy, timeout, caching, and custom authentication methods.
class Tesla(OAuth2Session):
def __init__(self, email, verify=True, proxy=None, retry=0, timeout=10,
user_agent=None, authenticator=None, cache_file='cache.json',
cache_loader=None, cache_dumper=None, sso_base_url=None,
code_verifier=None, app_user_agent=None, **kwargs):
"""
Initialize Tesla API session.
Parameters:
- email (str): SSO identity (required)
- verify (bool): Verify SSL certificate (default: True)
- proxy (str): URL of proxy server (optional)
- retry (int or Retry): Number of connection retries or Retry instance (default: 0)
- timeout (int): Connect/read timeout in seconds (default: 10)
- user_agent (str): The User-Agent string (optional)
- authenticator (callable): Function with one argument (authorization URL) that returns redirected URL (optional)
- cache_file (str): Path to cache file used by default loader and dumper (default: 'cache.json')
- cache_loader (callable): Function that returns the cache dict (optional)
- cache_dumper (callable): Function with one argument (cache dict) (optional)
- sso_base_url (str): URL of SSO service, use 'https://auth.tesla.cn/' for China region (optional)
- code_verifier (str): PKCE code verifier string (optional)
- app_user_agent (str): X-Tesla-User-Agent string (optional)
- **kwargs: Extra keyword arguments for OAuth2Session constructor
"""Methods for obtaining, refreshing, and managing OAuth 2 tokens with automatic persistence and refresh capabilities.
def fetch_token(self, token_url='oauth2/v3/token', **kwargs):
"""
Sign into Tesla's SSO service using Authorization Code grant with PKCE extension.
Parameters:
- token_url (str): Token endpoint URL (default: 'oauth2/v3/token')
- authorization_response (str): Authorization response URL (optional)
- code_verifier (str): Code verifier cryptographic random string (optional)
Returns:
dict: The token dictionary
Raises:
CustomOAuth2Error: On authentication errors
"""
def refresh_token(self, token_url='oauth2/v3/token', **kwargs):
"""
Refresh Tesla's SSO token.
Parameters:
- token_url (str): The token endpoint (default: 'oauth2/v3/token')
- refresh_token (str): The refresh_token to use (optional)
Returns:
dict: The refreshed token dictionary
Raises:
ValueError: If refresh_token is not set and not authorized
ServerError: On server errors
"""Session lifecycle management including logout and connection handling.
def logout(self, sign_out=False):
"""
Remove token from cache, return logout URL, and optionally log out using default browser.
Parameters:
- sign_out (bool): Sign out using system's default web browser (default: False)
Returns:
str or None: Logout URL or None if not authorized
"""
def close(self):
"""
Remove all adapters on close.
"""Generate authorization URLs for manual authentication flows with PKCE support.
def authorization_url(self, url='oauth2/v3/authorize', code_verifier=None, **kwargs):
"""
Form an authorization URL with PKCE extension for Tesla's SSO service.
Parameters:
- url (str): Authorization endpoint url (default: 'oauth2/v3/authorize')
- code_verifier (str): PKCE code verifier string (optional)
- state (str): A state string for CSRF protection (optional)
Returns:
str or None: Authorization URL or None if already authorized
"""
@staticmethod
def new_code_verifier():
"""
Generate code verifier for PKCE as per RFC 7636 section 4.1.
Returns:
bytes: Code verifier
"""Core API request functionality with endpoint name support and path variable substitution.
def api(self, name, path_vars=None, **kwargs):
"""
Convenience method to perform API request for given endpoint name with keyword arguments as parameters.
Parameters:
- name (str): Endpoint name from endpoints.json
- path_vars (dict): Path variables for URI substitution (optional)
- **kwargs: Parameters for the API call
Returns:
JsonDict or str: API response
Raises:
ValueError: On unknown endpoint name or missing path variables
"""
def request(self, method, url, serialize=True, **kwargs):
"""
Perform API request with relative URL support, serialization and error message handling.
Parameters:
- method (str): HTTP method to use
- url (str): URL to send (relative or absolute)
- serialize (bool): (de)serialize request/response body (default: True)
- withhold_token (bool): Perform unauthenticated request (optional)
- params (dict): URL parameters to append to the URL (optional)
- data: The body to attach to the request (optional)
- json: JSON for the body to attach to the request (optional)
Returns:
JsonDict or str or requests.Response: Response based on serialize parameter
Raises:
HTTPError: When an error occurs
"""Methods to retrieve lists of Tesla products associated with the account.
def vehicle_list(self):
"""
Returns a list of Vehicle objects.
Returns:
list[Vehicle]: List of Vehicle objects
"""
def battery_list(self):
"""
Returns a list of Battery objects.
Returns:
list[Battery]: List of Battery objects
"""
def solar_list(self):
"""
Returns a list of SolarPanel objects.
Returns:
list[SolarPanel]: List of SolarPanel objects
"""Session properties for token and URL management.
@property
def expires_at(self):
"""
Returns unix time when token needs refreshing.
Returns:
int or None: Unix timestamp of token expiration
"""
@property
def auto_refresh_url(self):
"""
Returns refresh token endpoint URL for auto-renewal access token.
Returns:
str or None: Refresh token endpoint URL
"""
@auto_refresh_url.setter
def auto_refresh_url(self, url):
"""
Sets refresh token endpoint URL for auto-renewal of access token.
Parameters:
- url (str): Refresh token endpoint URL
"""import teslapy
# Basic authentication with email
tesla = teslapy.Tesla('elon@tesla.com')
if not tesla.authorized:
tesla.fetch_token() # Opens browser for authentication
# Use context manager for automatic cleanup
with teslapy.Tesla('elon@tesla.com') as tesla:
vehicles = tesla.vehicle_list()import teslapy
def custom_auth(url):
print(f"Open this URL to authenticate: {url}")
return input("Enter the redirected URL: ")
tesla = teslapy.Tesla('elon@tesla.com', authenticator=custom_auth)
if not tesla.authorized:
tesla.fetch_token()import teslapy
# First stage - generate URLs
tesla = teslapy.Tesla('elon@tesla.com')
if not tesla.authorized:
state = tesla.new_state()
code_verifier = tesla.new_code_verifier()
auth_url = tesla.authorization_url(state=state, code_verifier=code_verifier)
print(f"Open: {auth_url}")
tesla.close()
# Second stage - complete authentication
tesla = teslapy.Tesla('elon@tesla.com', state=state, code_verifier=code_verifier)
if not tesla.authorized:
auth_response = input('Enter URL after authentication: ')
tesla.fetch_token(authorization_response=auth_response)import teslapy
with teslapy.Tesla('elon@tesla.com') as tesla:
if not tesla.authorized:
refresh_token = input('Enter SSO refresh token: ')
tesla.refresh_token(refresh_token=refresh_token)
vehicles = tesla.vehicle_list()import json
import sqlite3
import teslapy
def db_load():
con = sqlite3.connect('cache.db')
cur = con.cursor()
cache = {}
try:
for row in cur.execute('select * from teslapy'):
cache[row[0]] = json.loads(row[1])
except sqlite3.OperationalError:
pass
con.close()
return cache
def db_dump(cache):
con = sqlite3.connect('cache.db')
con.execute('create table if not exists teslapy (email text primary key, data json)')
for email, data in cache.items():
con.execute('replace into teslapy values (?, ?)', [email, json.dumps(data)])
con.commit()
con.close()
with teslapy.Tesla('elon@tesla.com', cache_loader=db_load, cache_dumper=db_dump) as tesla:
tesla.fetch_token()import teslapy
try:
tesla = teslapy.Tesla('elon@tesla.com')
vehicles = tesla.vehicle_list()
except teslapy.HTTPError as e:
print(f"HTTP Error: {e}")
except ValueError as e:
print(f"Configuration Error: {e}")Install with Tessl CLI
npx tessl i tessl/pypi-teslapy