tesla-fleet-api 0.5.6__py3-none-any.whl → 0.5.8__py3-none-any.whl

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -9,3 +9,18 @@ from .partner import Partner
9
9
  from .user import User
10
10
  from .vehicle import Vehicle
11
11
  from .vehiclespecific import VehicleSpecific
12
+
13
+
14
+ __all__ = [
15
+ "TeslaFleetApi",
16
+ "TeslaFleetOAuth",
17
+ "Teslemetry",
18
+ "Tessie",
19
+ "Charging",
20
+ "Energy",
21
+ "EnergySpecific",
22
+ "Partner",
23
+ "User",
24
+ "Vehicle",
25
+ "VehicleSpecific",
26
+ ]
tesla_fleet_api/const.py CHANGED
@@ -3,7 +3,7 @@
3
3
  from enum import Enum
4
4
  import logging
5
5
 
6
- VERSION = "0.5.6"
6
+ VERSION = "0.5.8"
7
7
  LOGGER = logging.getLogger(__package__)
8
8
  SERVERS = {
9
9
  "na": "https://fleet-api.prd.na.vn.cloud.tesla.com",
tesla_fleet_api/energy.py CHANGED
@@ -91,7 +91,7 @@ class Energy:
91
91
  self,
92
92
  energy_site_id: int,
93
93
  disallow_charge_from_grid_with_solar_installed: bool | None = None,
94
- customer_preferred_export_rule: EnergyExportMode|str | None = None,
94
+ customer_preferred_export_rule: EnergyExportMode | str | None = None,
95
95
  ) -> dict[str, Any]:
96
96
  """Allow/disallow charging from the grid and exporting energy to the grid."""
97
97
  return await self._request(
@@ -114,6 +114,7 @@ class Forbidden(TeslaFleetError):
114
114
 
115
115
  message = "Access to this resource is not authorized, developers should check required Scope."
116
116
  status = 403
117
+ key = "Unauthorized missing scopes"
117
118
 
118
119
 
119
120
  class UnsupportedVehicle(TeslaFleetError):
@@ -15,7 +15,7 @@ from .vehicle import Vehicle
15
15
  class TeslaFleetApi:
16
16
  """Class describing the Tesla Fleet API."""
17
17
 
18
- server: str
18
+ server: str | None = None
19
19
  session: aiohttp.ClientSession
20
20
  headers: dict[str, str]
21
21
  raise_for_status: bool
@@ -23,7 +23,7 @@ class TeslaFleetApi:
23
23
  def __init__(
24
24
  self,
25
25
  session: aiohttp.ClientSession,
26
- access_token: str,
26
+ access_token: str | None = None,
27
27
  region: str | None = None,
28
28
  server: str | None = None,
29
29
  raise_for_status: bool = True,
@@ -38,9 +38,10 @@ class TeslaFleetApi:
38
38
  self.session = session
39
39
  self.access_token = access_token
40
40
 
41
- if region and not server and region not in SERVERS:
42
- raise ValueError(f"Region must be one of {', '.join(SERVERS.keys())}")
43
- self.server = server or SERVERS.get(region)
41
+ if region is not None:
42
+ if not server and region not in SERVERS:
43
+ raise ValueError(f"Region must be one of {', '.join(SERVERS.keys())}")
44
+ self.server = server or SERVERS.get(region)
44
45
  self.raise_for_status = raise_for_status
45
46
 
46
47
  LOGGER.debug("Using server %s", self.server)
@@ -61,7 +62,8 @@ class TeslaFleetApi:
61
62
  for server in SERVERS.values():
62
63
  self.server = server
63
64
  try:
64
- response = await (self.user.region()).get("response")
65
+ region_response = await self.user.region()
66
+ response = region_response.get("response")
65
67
  if response:
66
68
  self.server = response["fleet_api_base_url"]
67
69
  LOGGER.debug("Using server %s", self.server)
@@ -74,9 +76,9 @@ class TeslaFleetApi:
74
76
  self,
75
77
  method: Method,
76
78
  path: str,
77
- params: dict[str:Any] | None = None,
78
- json: dict[str:Any] | None = None,
79
- ):
79
+ params: dict[str, Any] | None = None,
80
+ json: dict[str, Any] | None = None,
81
+ ) -> dict[str, Any] | str:
80
82
  """Send a request to the Tesla Fleet API."""
81
83
 
82
84
  if not self.server:
@@ -125,7 +127,7 @@ class TeslaFleetApi:
125
127
  LOGGER.debug("Response Text: %s", data)
126
128
  return data
127
129
 
128
- async def status(self):
130
+ async def status(self) -> str:
129
131
  """This endpoint returns the string "ok" if the API is operating normally. No HTTP headers are required."""
130
132
  if not self.server:
131
133
  raise ValueError("Server was not set at init. Call find_server() first.")
@@ -42,7 +42,9 @@ class TeslaFleetOAuth(TeslaFleetApi):
42
42
  """Get the login URL."""
43
43
  return f"https://auth.tesla.com/oauth2/v3/authorize?response_type=code&client_id={self.client_id}&redirect_uri={redirect_uri}&scope={' '.join(scopes)}&state={state}"
44
44
 
45
- async def get_refresh_token(self, client_secret: str, code: str, redirect_uri: str):
45
+ async def get_refresh_token(
46
+ self, client_secret: str, code: str, redirect_uri: str
47
+ ) -> None:
46
48
  """Get the refresh token."""
47
49
  async with self.session.post(
48
50
  "https://auth.tesla.com/oauth2/v3/token",
@@ -63,13 +65,13 @@ class TeslaFleetOAuth(TeslaFleetApi):
63
65
  region = code.split("_")[0].lower()
64
66
  self.server = SERVERS.get(region)
65
67
 
66
- async def check_access_token(self) -> str | None:
68
+ async def check_access_token(self) -> dict[str, Any] | None:
67
69
  """Get the access token."""
68
70
  if self.access_token and self.expires > time.time():
69
- return
71
+ return None
70
72
  return await self.refresh_access_token()
71
73
 
72
- async def refresh_access_token(self) -> str:
74
+ async def refresh_access_token(self) -> dict[str, Any]:
73
75
  """Refresh the access token."""
74
76
  if not self.refresh_token:
75
77
  raise ValueError("Refresh token is missing")
@@ -93,9 +95,9 @@ class TeslaFleetOAuth(TeslaFleetApi):
93
95
  self,
94
96
  method: Method,
95
97
  path: str,
96
- params: dict | None = None,
97
- data: dict | None = None,
98
- ):
98
+ params: dict[str, Any] | None = None,
99
+ data: dict[str, Any] | None = None,
100
+ ) -> str | dict[str, Any]:
99
101
  """Send a request to the Tesla Fleet API."""
100
102
  await self.check_access_token()
101
103
  return await super()._request(method, path, params, data)
@@ -52,7 +52,8 @@ class Teslemetry(TeslaFleetApi):
52
52
  LOGGER.debug("Using server %s", self.server)
53
53
  return resp
54
54
 
55
- async def find_server(self):
55
+ # TODO: type this properly, it probably should return something
56
+ async def find_server(self) -> None:
56
57
  """Find the server URL for the Tesla Fleet API."""
57
58
  await self.metadata(True)
58
59
 
@@ -60,9 +61,9 @@ class Teslemetry(TeslaFleetApi):
60
61
  self,
61
62
  method: Method,
62
63
  path: str,
63
- params: dict[str:Any] | None = None,
64
- json: dict[str:Any] | None = None,
65
- ):
64
+ params: dict[str, Any] | None = None,
65
+ json: dict[str, Any] | None = None,
66
+ ) -> str | dict[str, Any]:
66
67
  """Send a request to the Teslemetry API."""
67
68
  async with rate_limit:
68
69
  return await super()._request(method, path, params, json)
tesla_fleet_api/tessie.py CHANGED
@@ -2,7 +2,6 @@ import aiohttp
2
2
  from typing import Any
3
3
  from .teslafleetapi import TeslaFleetApi
4
4
  from .const import Method
5
- from .vehiclespecific import VehicleSpecific
6
5
 
7
6
 
8
7
  class Tessie(TeslaFleetApi):
@@ -23,7 +22,7 @@ class Tessie(TeslaFleetApi):
23
22
  energy_scope=False,
24
23
  )
25
24
 
26
- async def find_server(self):
25
+ async def find_server(self) -> str:
27
26
  """Find the server URL for the Tesla Fleet API."""
28
27
  raise NotImplementedError("Do not use this function for Tessie.")
29
28
 
@@ -24,6 +24,10 @@ class Vehicle:
24
24
  def specific(self, vehicle_tag: str | int) -> VehicleSpecific:
25
25
  """Creates a class for each vehicle."""
26
26
  return VehicleSpecific(self, vehicle_tag)
27
+
28
+ def pre2021(self, vin: str) -> bool:
29
+ """Checks if a vehicle is pre-2021."""
30
+ return vin[9] <= "L"
27
31
 
28
32
  async def actuate_trunk(
29
33
  self, vehicle_tag: str | int, which_trunk: Trunk | str
@@ -567,7 +571,7 @@ class Vehicle:
567
571
  lon: float | None = None,
568
572
  ) -> dict[str, Any]:
569
573
  """Turns on HomeLink (used to open and close garage doors)."""
570
- data = {}
574
+ data: dict[str, str | float] = {}
571
575
  if token:
572
576
  data["token"] = token
573
577
  if lat and lon:
@@ -742,12 +746,11 @@ class Vehicle:
742
746
  endpoints: List[VehicleDataEndpoint] | List[str] | None = None,
743
747
  ) -> dict[str, Any]:
744
748
  """Makes a live call to the vehicle. This may return cached data if the vehicle is offline. For vehicles running firmware versions 2023.38+, location_data is required to fetch vehicle location. This will result in a location sharing icon to show on the vehicle UI."""
745
- if isinstance(endpoints, list):
746
- endpoints = ";".join(endpoints)
749
+ endpoint_payload = ";".join(endpoints) if endpoints else None
747
750
  return await self._request(
748
751
  Method.GET,
749
752
  f"api/1/vehicles/{vehicle_tag}/vehicle_data",
750
- {"endpoints": endpoints},
753
+ {"endpoints": endpoint_payload},
751
754
  )
752
755
 
753
756
  async def vehicle_subscriptions(
@@ -13,10 +13,15 @@ from .const import (
13
13
  class VehicleSpecific:
14
14
  """Class describing the Tesla Fleet API vehicle endpoints and commands for a specific vehicle."""
15
15
 
16
- def __init__(self, parent, vin: str | None = None):
16
+ def __init__(self, parent, vin: str | int | None = None):
17
17
  self._parent = parent
18
18
  self.vin = vin
19
19
 
20
+
21
+ def pre2021(self) -> bool:
22
+ """Checks if a vehicle is pre-2021."""
23
+ return self._parent.pre2021(self.vin)
24
+
20
25
  async def actuate_trunk(self, which_trunk: Trunk | str) -> dict[str, Any]:
21
26
  """Controls the front or rear trunk."""
22
27
  return await self._parent.actuate_trunk(self.vin, which_trunk)
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.1
2
2
  Name: tesla_fleet_api
3
- Version: 0.5.6
3
+ Version: 0.5.8
4
4
  Summary: Tesla Fleet API library for Python
5
5
  Home-page: https://github.com/Teslemetry/tesla_fleet_api
6
6
  Author: Brett Adams
@@ -0,0 +1,19 @@
1
+ tesla_fleet_api/__init__.py,sha256=0MON9vh3AShIiX16FZ6NU3yZ7kyXFh5GxA0rY8CzVRM,584
2
+ tesla_fleet_api/charging.py,sha256=N_mc8axrXj3iduqLj_jCt4Vx86tHqe3xqQT4R1R7HvU,1689
3
+ tesla_fleet_api/const.py,sha256=Iw-pOe1Bg2vU4uk0SQ1Nf6YiXy0ndXMZ0SWl1T27znQ,9277
4
+ tesla_fleet_api/energy.py,sha256=kE-HDupzhgatIsizJoer1MAALP-wH6jjjGliiRQN0Os,5285
5
+ tesla_fleet_api/energyspecific.py,sha256=kICxdeDoWR9JHlgjHvnmjJ1ErLOWJT8bCSESoXo9axU,3732
6
+ tesla_fleet_api/exceptions.py,sha256=Wh9roGPYB9oBGgEEfxMDay5A7RkPy8JFKloKPStGQ2Y,9211
7
+ tesla_fleet_api/partner.py,sha256=1vIBUaxKLIfqcC0X6VXZN0dMAzj_CLNPUMjA6QVqZ1k,1223
8
+ tesla_fleet_api/teslafleetapi.py,sha256=3-gGx-RxOD92Ul0lNCEsCwVBsYunKsO2Sr5rYH0YtIg,5070
9
+ tesla_fleet_api/teslafleetoauth.py,sha256=FfLnuqZMxF2HsZ5miLNtm3pRwKDoQKi2GD-oXgKxZgA,3594
10
+ tesla_fleet_api/teslemetry.py,sha256=XOqm7SaakooJSNXEasJI_tRoCIyiFCD6n_PCx9U_D9g,2107
11
+ tesla_fleet_api/tessie.py,sha256=ZttWuDdQOuTFO4k-BMq7fXKP3Nb4Dsxk3gFJprHHsco,2214
12
+ tesla_fleet_api/user.py,sha256=TZE2oh-n5zrhKXmGRuiNL9voKVODD7rBhGE_IObYVGA,1179
13
+ tesla_fleet_api/vehicle.py,sha256=3MF8KN3BjY2dQxmu6-hrrVxrXxI8iQF-rBS8v89ruUw,32835
14
+ tesla_fleet_api/vehiclespecific.py,sha256=Weadm-IU9vsL5JCwXilaz3Yrwxb1iZdsdmGxuUHMxMA,21493
15
+ tesla_fleet_api-0.5.8.dist-info/LICENSE,sha256=xx0jnfkXJvxRnG63LTGOxlggYnIysveWIZ6H3PNdCrQ,11357
16
+ tesla_fleet_api-0.5.8.dist-info/METADATA,sha256=Yrzt0AyLUq2aQjQV3i7PI0vXijUflTkvMlHrmcTkGCg,3961
17
+ tesla_fleet_api-0.5.8.dist-info/WHEEL,sha256=GJ7t_kWBFywbagK5eo9IoUwLW6oyOeTKmQ-9iHFVNxQ,92
18
+ tesla_fleet_api-0.5.8.dist-info/top_level.txt,sha256=jeNbog_1saXBFrGpom9WyPWmilxsyP3szL_G7JLWQfM,16
19
+ tesla_fleet_api-0.5.8.dist-info/RECORD,,
@@ -1,19 +0,0 @@
1
- tesla_fleet_api/__init__.py,sha256=RL9KGtDjYwbBa5i6Lagzrya-yjvEE1EVfyge2lV49iI,375
2
- tesla_fleet_api/charging.py,sha256=N_mc8axrXj3iduqLj_jCt4Vx86tHqe3xqQT4R1R7HvU,1689
3
- tesla_fleet_api/const.py,sha256=IyRFbFzt-YqRTf4RrOo9Lng-Vg9TrWjeeDkqT2nT-3o,9277
4
- tesla_fleet_api/energy.py,sha256=Fgg4pdYc226WNOXHUnzBHbZoZ3jYLfN3GgjprazYLZA,5283
5
- tesla_fleet_api/energyspecific.py,sha256=kICxdeDoWR9JHlgjHvnmjJ1ErLOWJT8bCSESoXo9axU,3732
6
- tesla_fleet_api/exceptions.py,sha256=c6i_AegrLzlfrHxht_Z_xLl_kmxcd3DDJaSIcldcUo8,9171
7
- tesla_fleet_api/partner.py,sha256=1vIBUaxKLIfqcC0X6VXZN0dMAzj_CLNPUMjA6QVqZ1k,1223
8
- tesla_fleet_api/teslafleetapi.py,sha256=ErPfOz4M4WERrOlo_a_1ssVPcOIGeiBpbxd4vFJH_x4,4929
9
- tesla_fleet_api/teslafleetoauth.py,sha256=BmRAuwcgFMBo2_3AJzS3QTBm_cP9xt4yoz4vKjwgmsw,3501
10
- tesla_fleet_api/teslemetry.py,sha256=jB2OlYAjjl98mW4p2-VGTVl5lpG1Qox57mXgsdrF1vg,2005
11
- tesla_fleet_api/tessie.py,sha256=3ScOi8RaxHdvp6s5ZdSWYXwHZdey6IkX9SF1oohtSWk,2252
12
- tesla_fleet_api/user.py,sha256=TZE2oh-n5zrhKXmGRuiNL9voKVODD7rBhGE_IObYVGA,1179
13
- tesla_fleet_api/vehicle.py,sha256=8Ksg-IX5xuVGtACQrh1Su923oeLJqTAwq8ks9OPn6bA,32696
14
- tesla_fleet_api/vehiclespecific.py,sha256=DgXr8apVFPT_Biv_B4p4Zh9cJhxqztkZYCS8g584JQo,21361
15
- tesla_fleet_api-0.5.6.dist-info/LICENSE,sha256=xx0jnfkXJvxRnG63LTGOxlggYnIysveWIZ6H3PNdCrQ,11357
16
- tesla_fleet_api-0.5.6.dist-info/METADATA,sha256=sxLsftqajoj-jxD7liRX_n4NIbfGgdw4A9FXd-ZkS5s,3961
17
- tesla_fleet_api-0.5.6.dist-info/WHEEL,sha256=GJ7t_kWBFywbagK5eo9IoUwLW6oyOeTKmQ-9iHFVNxQ,92
18
- tesla_fleet_api-0.5.6.dist-info/top_level.txt,sha256=jeNbog_1saXBFrGpom9WyPWmilxsyP3szL_G7JLWQfM,16
19
- tesla_fleet_api-0.5.6.dist-info/RECORD,,