tescmd 0.1.2__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.
Files changed (81) hide show
  1. tescmd/__init__.py +3 -0
  2. tescmd/__main__.py +5 -0
  3. tescmd/_internal/__init__.py +0 -0
  4. tescmd/_internal/async_utils.py +25 -0
  5. tescmd/_internal/permissions.py +43 -0
  6. tescmd/_internal/vin.py +44 -0
  7. tescmd/api/__init__.py +1 -0
  8. tescmd/api/charging.py +102 -0
  9. tescmd/api/client.py +189 -0
  10. tescmd/api/command.py +540 -0
  11. tescmd/api/energy.py +146 -0
  12. tescmd/api/errors.py +76 -0
  13. tescmd/api/partner.py +40 -0
  14. tescmd/api/sharing.py +65 -0
  15. tescmd/api/signed_command.py +277 -0
  16. tescmd/api/user.py +38 -0
  17. tescmd/api/vehicle.py +150 -0
  18. tescmd/auth/__init__.py +1 -0
  19. tescmd/auth/oauth.py +312 -0
  20. tescmd/auth/server.py +108 -0
  21. tescmd/auth/token_store.py +273 -0
  22. tescmd/ble/__init__.py +0 -0
  23. tescmd/cache/__init__.py +6 -0
  24. tescmd/cache/keys.py +51 -0
  25. tescmd/cache/response_cache.py +213 -0
  26. tescmd/cli/__init__.py +0 -0
  27. tescmd/cli/_client.py +603 -0
  28. tescmd/cli/_options.py +126 -0
  29. tescmd/cli/auth.py +682 -0
  30. tescmd/cli/billing.py +240 -0
  31. tescmd/cli/cache.py +85 -0
  32. tescmd/cli/charge.py +610 -0
  33. tescmd/cli/climate.py +501 -0
  34. tescmd/cli/energy.py +385 -0
  35. tescmd/cli/key.py +611 -0
  36. tescmd/cli/main.py +601 -0
  37. tescmd/cli/media.py +146 -0
  38. tescmd/cli/nav.py +242 -0
  39. tescmd/cli/partner.py +112 -0
  40. tescmd/cli/raw.py +75 -0
  41. tescmd/cli/security.py +495 -0
  42. tescmd/cli/setup.py +786 -0
  43. tescmd/cli/sharing.py +188 -0
  44. tescmd/cli/software.py +81 -0
  45. tescmd/cli/status.py +106 -0
  46. tescmd/cli/trunk.py +240 -0
  47. tescmd/cli/user.py +145 -0
  48. tescmd/cli/vehicle.py +837 -0
  49. tescmd/config/__init__.py +0 -0
  50. tescmd/crypto/__init__.py +19 -0
  51. tescmd/crypto/ecdh.py +46 -0
  52. tescmd/crypto/keys.py +122 -0
  53. tescmd/deploy/__init__.py +0 -0
  54. tescmd/deploy/github_pages.py +268 -0
  55. tescmd/models/__init__.py +85 -0
  56. tescmd/models/auth.py +108 -0
  57. tescmd/models/command.py +18 -0
  58. tescmd/models/config.py +63 -0
  59. tescmd/models/energy.py +56 -0
  60. tescmd/models/sharing.py +26 -0
  61. tescmd/models/user.py +37 -0
  62. tescmd/models/vehicle.py +185 -0
  63. tescmd/output/__init__.py +5 -0
  64. tescmd/output/formatter.py +132 -0
  65. tescmd/output/json_output.py +83 -0
  66. tescmd/output/rich_output.py +809 -0
  67. tescmd/protocol/__init__.py +23 -0
  68. tescmd/protocol/commands.py +175 -0
  69. tescmd/protocol/encoder.py +122 -0
  70. tescmd/protocol/metadata.py +116 -0
  71. tescmd/protocol/payloads.py +621 -0
  72. tescmd/protocol/protobuf/__init__.py +6 -0
  73. tescmd/protocol/protobuf/messages.py +564 -0
  74. tescmd/protocol/session.py +318 -0
  75. tescmd/protocol/signer.py +84 -0
  76. tescmd/py.typed +0 -0
  77. tescmd-0.1.2.dist-info/METADATA +458 -0
  78. tescmd-0.1.2.dist-info/RECORD +81 -0
  79. tescmd-0.1.2.dist-info/WHEEL +4 -0
  80. tescmd-0.1.2.dist-info/entry_points.txt +2 -0
  81. tescmd-0.1.2.dist-info/licenses/LICENSE +21 -0
tescmd/cli/_options.py ADDED
@@ -0,0 +1,126 @@
1
+ """Shared CLI decorator that propagates global options to leaf commands."""
2
+
3
+ from __future__ import annotations
4
+
5
+ import functools
6
+ import logging
7
+ from typing import TYPE_CHECKING, Any
8
+
9
+ import click
10
+
11
+ if TYPE_CHECKING:
12
+ from tescmd.cli.main import AppContext
13
+
14
+
15
+ def global_options(f: Any) -> Any:
16
+ """Add global CLI options to a leaf command.
17
+
18
+ Allows ``--vin``, ``--profile``, ``--format``, ``--quiet``, ``--region``,
19
+ and ``--verbose`` to be specified **after** the subcommand name (e.g.
20
+ ``tescmd vehicle info --vin X``). Command-level values override the
21
+ root-group values stored in :class:`AppContext`.
22
+ """
23
+
24
+ @click.option(
25
+ "--units",
26
+ "local_units",
27
+ type=click.Choice(["us", "metric"]),
28
+ default=None,
29
+ help="Display units preset (us: °F/mi/psi, metric: °C/km/bar)",
30
+ )
31
+ @click.option(
32
+ "--wake",
33
+ "local_wake",
34
+ is_flag=True,
35
+ default=False,
36
+ help="Auto-wake vehicle without confirmation (billable)",
37
+ )
38
+ @click.option(
39
+ "--no-cache",
40
+ "--fresh",
41
+ "local_no_cache",
42
+ is_flag=True,
43
+ default=False,
44
+ help="Bypass response cache",
45
+ )
46
+ @click.option(
47
+ "--verbose",
48
+ "local_verbose",
49
+ is_flag=True,
50
+ default=False,
51
+ help="Enable verbose logging",
52
+ )
53
+ @click.option(
54
+ "--region",
55
+ "local_region",
56
+ type=click.Choice(["na", "eu", "cn"]),
57
+ default=None,
58
+ help="Tesla API region",
59
+ )
60
+ @click.option(
61
+ "--quiet",
62
+ "local_quiet",
63
+ is_flag=True,
64
+ default=False,
65
+ help="Suppress normal output",
66
+ )
67
+ @click.option(
68
+ "--format",
69
+ "local_output_format",
70
+ type=click.Choice(["rich", "json", "quiet"]),
71
+ default=None,
72
+ help="Output format (default: auto-detect)",
73
+ )
74
+ @click.option("--profile", "local_profile", default=None, help="Config profile name")
75
+ @click.option("--vin", "local_vin", default=None, help="Vehicle VIN")
76
+ @click.pass_obj
77
+ def wrapper(app_ctx: AppContext, /, **kwargs: Any) -> Any:
78
+ # Pop command-level global-option overrides
79
+ local_vin: str | None = kwargs.pop("local_vin", None)
80
+ local_profile: str | None = kwargs.pop("local_profile", None)
81
+ local_output_format: str | None = kwargs.pop("local_output_format", None)
82
+ local_quiet: bool = kwargs.pop("local_quiet", False)
83
+ local_region: str | None = kwargs.pop("local_region", None)
84
+ local_verbose: bool = kwargs.pop("local_verbose", False)
85
+ local_no_cache: bool = kwargs.pop("local_no_cache", False)
86
+ local_wake: bool = kwargs.pop("local_wake", False)
87
+ local_units: str | None = kwargs.pop("local_units", None)
88
+
89
+ # Merge overrides into AppContext (command-level wins)
90
+ if local_vin is not None:
91
+ app_ctx.vin = local_vin
92
+ if local_profile is not None:
93
+ app_ctx.profile = local_profile
94
+ if local_output_format is not None:
95
+ app_ctx.output_format = local_output_format
96
+ app_ctx._formatter = None # reset cached formatter
97
+ if local_quiet:
98
+ app_ctx.quiet = True
99
+ app_ctx._formatter = None
100
+ if local_region is not None:
101
+ app_ctx.region = local_region
102
+ if local_verbose:
103
+ app_ctx.verbose = True
104
+ logging.basicConfig(
105
+ level=logging.DEBUG,
106
+ format="%(name)s %(levelname)s: %(message)s",
107
+ )
108
+ if local_no_cache:
109
+ app_ctx.no_cache = True
110
+ if local_wake:
111
+ app_ctx.auto_wake = True
112
+ if local_units is not None:
113
+ if local_units == "metric":
114
+ app_ctx.temp_unit = "C"
115
+ app_ctx.distance_unit = "km"
116
+ app_ctx.pressure_unit = "bar"
117
+ else:
118
+ app_ctx.temp_unit = "F"
119
+ app_ctx.distance_unit = "mi"
120
+ app_ctx.pressure_unit = "psi"
121
+ app_ctx._formatter = None # reset cached formatter
122
+
123
+ return f(app_ctx, **kwargs)
124
+
125
+ functools.update_wrapper(wrapper, f)
126
+ return wrapper